1 /**************************************************************************//**
2 *
3 * @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Change Logs:
8 * Date            Author       Notes
9 * 2022-8-16       Wayne        First version
10 *
11 ******************************************************************************/
12 
13 #include <rtdevice.h>
14 
15 #include "ccap_sensor.h"
16 
17 #define DBG_ENABLE
18 #define DBG_LEVEL DBG_LOG
19 #define DBG_SECTION_NAME  "ccap.sensor"
20 #define DBG_COLOR
21 #include <rtdbg.h>
22 
ccap_sensor_i2c_write(struct rt_i2c_bus_device * i2cdev,rt_uint16_t addr,rt_uint8_t * puBuf,int i32BufLen)23 rt_err_t ccap_sensor_i2c_write(struct rt_i2c_bus_device *i2cdev, rt_uint16_t addr, rt_uint8_t *puBuf, int i32BufLen)
24 {
25     struct rt_i2c_msg msg;
26 
27     msg.addr  = addr;       /* Slave address */
28     msg.flags = RT_I2C_WR;  /* Write flag */
29     msg.buf   = puBuf;      /* Slave register address */
30     msg.len   = i32BufLen;  /* Number of bytes sent */
31 
32     if (i2cdev && rt_i2c_transfer(i2cdev, &msg, 1) != 1)
33     {
34         return -RT_ERROR;
35     }
36     return RT_EOK;
37 }
38 
ccap_sensor_i2c_read(struct rt_i2c_bus_device * i2cdev,rt_uint16_t addr,rt_uint8_t * puWBuf,int i32WBufLen,rt_uint8_t * puRBuf,int i32RBufLen)39 rt_err_t ccap_sensor_i2c_read(struct rt_i2c_bus_device *i2cdev, rt_uint16_t addr, rt_uint8_t *puWBuf, int i32WBufLen, rt_uint8_t *puRBuf, int i32RBufLen)
40 {
41     struct rt_i2c_msg msgs[2];
42 
43     msgs[0].addr  = addr;                  /* Slave address */
44     msgs[0].flags = RT_I2C_WR;             /* Write flag */
45     msgs[0].buf   = (rt_uint8_t *)puWBuf;  /* Slave register address */
46     msgs[0].len   = i32WBufLen;            /* Number of bytes sent */
47 
48     msgs[1].addr  = addr;                  /* Slave address */
49     msgs[1].flags = RT_I2C_RD;             /* Read flag without READ_ACK */
50     msgs[1].buf   = (rt_uint8_t *)puRBuf;  /* Read data pointer */
51     msgs[1].len   = i32RBufLen;            /* Number of bytes read */
52 
53     if (rt_i2c_transfer(i2cdev, &msgs[0], 2) != 2)
54     {
55         return -RT_ERROR;
56     }
57 
58     return RT_EOK;
59 }
60 
ccap_sensor_set_mode_general(struct rt_i2c_bus_device * i2cdev,sensor_priv * pdev,sensor_mode_info * psInfo)61 static rt_err_t ccap_sensor_set_mode_general(struct rt_i2c_bus_device *i2cdev, sensor_priv *pdev, sensor_mode_info *psInfo)
62 {
63     uint8_t au8TxData[4];
64     int i;
65 
66     RT_ASSERT(i2cdev);
67     RT_ASSERT(pdev);
68     RT_ASSERT(psInfo);
69 
70     LOG_I("Selected Sensor ID:%d, Width:%d, Height:%d, FMT:%08x",
71           pdev->eId,
72           psInfo->sViewInfo.u32Width,
73           psInfo->sViewInfo.u32Height,
74           psInfo->sViewInfo.u32PixFmt);
75 
76     for (i = 0; i < psInfo->u32RegArrSize; i++)
77     {
78         const sensor_reg_val *psRegVal = &psInfo->psRegArr[i];
79 
80         switch (pdev->u16AddrBL)
81         {
82         case 2:
83             au8TxData[0] = (uint8_t)((psRegVal->u16Addr >> 8) & 0x00FF); //addr [15:8]
84             au8TxData[1] = (uint8_t)((psRegVal->u16Addr) & 0x00FF); //addr [ 7:0]
85             break;
86 
87         case 1:
88             au8TxData[0] = (uint8_t)((psRegVal->u16Addr) & 0x00FF); //addr [ 7:0]
89             break;
90 
91         default:
92             return -RT_ERROR;
93         }
94 
95         switch (pdev->u16ValBL)
96         {
97         case 2:
98             au8TxData[pdev->u16AddrBL] = (uint8_t)((psRegVal->u16Val >> 8) & 0x00FF); //data [15:8]
99             au8TxData[pdev->u16AddrBL + 1] = (uint8_t)((psRegVal->u16Val) & 0x00FF); //data [ 7:0]
100             break;
101 
102         case 1:
103             au8TxData[pdev->u16AddrBL] = (uint8_t)((psRegVal->u16Val) & 0x00FF);  //data [ 7:0]
104             break;
105 
106         default:
107             return -RT_ERROR;
108         }
109 
110         //LOG_I("SlaveID=0x%02x, Addr: [0x%02X,0x%02X], Value: [0x%02X,0x%02X], Length: %d", msg.addr, au8TxData[0], au8TxData[1], au8TxData[2], au8TxData[3], msg.len  );
111         if (ccap_sensor_i2c_write(i2cdev, pdev->u16DevAddr, (rt_uint8_t *)&au8TxData[0], pdev->u16AddrBL + pdev->u16ValBL) != RT_EOK)
112         {
113             LOG_E("[Failed] addr=%x, data=%d\n", psRegVal->u16Addr, psRegVal->u16Val);
114             return -RT_ERROR;
115         }
116     }
117 
118     return RT_EOK;
119 }
120 
ccap_sensor_setpower(ccap_sensor_dev * pdev,rt_bool_t bOn)121 static rt_err_t ccap_sensor_setpower(ccap_sensor_dev *pdev, rt_bool_t bOn)
122 {
123     ccap_sensor_io_t psIo;
124     sensor_priv_t    psSensorPriv;
125 
126     if (pdev == RT_NULL)
127         return -RT_ERROR;
128 
129     psIo = pdev->psIo;
130     psSensorPriv = (sensor_priv_t)((rt_device_t)pdev)->user_data;
131 
132     LOG_I("sensor power pin: %d, Active low: %s", psIo->PwrDwnPin, bOn ? "TRUE" : "FALSE");
133 
134     rt_pin_mode(psIo->PwrDwnPin, PIN_MODE_OUTPUT);
135 
136     if (bOn == RT_TRUE)
137     {
138         (psSensorPriv->PwrDwnActLow == RT_TRUE) ? rt_pin_write(psIo->PwrDwnPin, PIN_HIGH) : rt_pin_write(psIo->PwrDwnPin, PIN_LOW);
139     }
140     else
141     {
142         (psSensorPriv->PwrDwnActLow == RT_TRUE) ? rt_pin_write(psIo->PwrDwnPin, PIN_LOW) : rt_pin_write(psIo->PwrDwnPin, PIN_HIGH);
143     }
144 
145     return RT_EOK;
146 }
147 
ccap_sensor_reset(ccap_sensor_dev * pdev)148 static rt_err_t ccap_sensor_reset(ccap_sensor_dev *pdev)
149 {
150     ccap_sensor_io_t psIo;
151     sensor_priv_t    psSensorPriv;
152 
153     if (pdev == RT_NULL)
154         return -RT_ERROR;
155 
156     psIo = pdev->psIo;
157     psSensorPriv = (sensor_priv_t)((rt_device_t)pdev)->user_data;
158 
159     LOG_I("sensor reset pin: %d, Active low: %s", psIo->RstPin, psSensorPriv->RstActLow ? "TRUE" : "FALSE");
160 
161     rt_pin_mode(psIo->RstPin, PIN_MODE_OUTPUT);
162 
163     (psSensorPriv->RstActLow == RT_TRUE) ?
164     rt_pin_write(psIo->RstPin, PIN_LOW) :
165     rt_pin_write(psIo->RstPin, PIN_HIGH);
166 
167     rt_thread_mdelay(psSensorPriv->RstHoldTimeInMs);
168 
169     (psSensorPriv->RstActLow == RT_TRUE) ?
170     rt_pin_write(psIo->RstPin, PIN_HIGH) :
171     rt_pin_write(psIo->RstPin, PIN_LOW);
172 
173     return RT_EOK;
174 }
175 
176 /* common device interface */
ccap_sensor_open(rt_device_t dev,rt_uint16_t oflag)177 static rt_err_t ccap_sensor_open(rt_device_t dev, rt_uint16_t oflag)
178 {
179     ccap_sensor_dev *pdev = (ccap_sensor_dev *)dev;
180     rt_err_t ret = -RT_ERROR;
181 
182     if (pdev == RT_NULL)
183         goto fail_ccap_sensor_open;
184 
185     /* Power-on */
186     ret = ccap_sensor_setpower(pdev, RT_TRUE);
187     if (ret != RT_EOK)
188         goto fail_ccap_sensor_open;
189 
190     /* Reset */
191     ret = ccap_sensor_reset(pdev);
192 
193 fail_ccap_sensor_open:
194 
195     return ret;
196 }
197 
ccap_sensor_close(rt_device_t dev)198 static rt_err_t ccap_sensor_close(rt_device_t dev)
199 {
200     ccap_sensor_dev *pdev = (ccap_sensor_dev *)dev;
201 
202     if (pdev == RT_NULL)
203         return -RT_ERROR;
204 
205     /* Power-off */
206     return ccap_sensor_setpower(pdev, RT_FALSE);
207 }
208 
ccap_find_suit_mode(ccap_view_info_t psViewInfo,const sensor_priv_t psSensorPriv)209 static ccap_view_info_t ccap_find_suit_mode(ccap_view_info_t psViewInfo, const sensor_priv_t psSensorPriv)
210 {
211     int i = 0;
212     sensor_mode_info_t psSensorModeInfo = RT_NULL;
213 
214     for (i = 0; i < psSensorPriv->ModeInfoSize; i++)
215     {
216         if ((psViewInfo->u32Width <= psSensorPriv->psModeInfo[i].sViewInfo.u32Width) &&
217                 (psViewInfo->u32Height <= psSensorPriv->psModeInfo[i].sViewInfo.u32Height))
218             break;
219     }
220 
221     if (i != psSensorPriv->ModeInfoSize)
222         psSensorModeInfo = &psSensorPriv->psModeInfo[i];
223     else
224     {
225         /* Failed to get suit mode. Here, we gave latest Sensor mode to user. */
226         psSensorModeInfo = &psSensorPriv->psModeInfo[i - 1];
227     }
228 
229     return (ccap_view_info_t)psSensorModeInfo;
230 }
231 
ccap_sensor_control(rt_device_t dev,int cmd,void * args)232 static rt_err_t ccap_sensor_control(rt_device_t dev, int cmd, void *args)
233 {
234     rt_err_t result = RT_EOK;
235     ccap_sensor_dev *pdev = (ccap_sensor_dev *)dev;
236 
237     RT_ASSERT(dev);
238 
239     switch (cmd)
240     {
241     case CCAP_SENSOR_CMD_RESET:
242         result = ccap_sensor_reset(pdev);
243         break;
244 
245     case CCAP_SENSOR_CMD_SET_POWER:
246     {
247         rt_bool_t bOn = (rt_bool_t)args;
248         result = ccap_sensor_setpower(pdev, bOn);
249     }
250     break;
251 
252     case CCAP_SENSOR_CMD_SET_MODE:
253     {
254         ccap_sensor_io *psIo = pdev->psIo;
255         struct rt_i2c_bus_device *i2cbus;
256         sensor_mode_info *psInfo;
257         sensor_priv *psSensorPriv = (sensor_priv *)dev->user_data;
258 
259         RT_ASSERT(args);
260         RT_ASSERT(psIo);
261         RT_ASSERT(psIo->I2cName);
262 
263         i2cbus = (struct rt_i2c_bus_device *)rt_device_find(psIo->I2cName);
264         RT_ASSERT(i2cbus);
265 
266         psInfo = (sensor_mode_info *) args;
267 
268         if (psSensorPriv->pfnSetMode != RT_NULL)
269             result = psSensorPriv->pfnSetMode(i2cbus, psSensorPriv, psInfo);
270         else
271             result = ccap_sensor_set_mode_general(i2cbus, psSensorPriv, psInfo);
272     }
273     break;
274 
275     case CCAP_SENSOR_CMD_GET_SUIT_MODE:
276     {
277         /* Get private data of sensor */
278         sensor_priv_t psSensorPriv = (sensor_priv_t)dev->user_data;
279         ccap_view_info_t psViewInfo;
280 
281         RT_ASSERT(args);
282         RT_ASSERT(psSensorPriv);
283 
284         psViewInfo = *((ccap_view_info_t *)args);
285         RT_ASSERT(psViewInfo);
286 
287         psViewInfo = ccap_find_suit_mode(psViewInfo, (sensor_priv_t)psSensorPriv);
288 
289         *((ccap_view_info_t *)args) = psViewInfo;
290     }
291     break;
292 
293     default:
294         result = -RT_ENOSYS;
295         break;
296     }
297 
298     return result;
299 }
300 
301 #ifdef RT_USING_DEVICE_OPS
302 static struct rt_device_ops ccap_ops =
303 {
304     .init = RT_NULL,
305     .open = ccap_sensor_open,
306     .close = ccap_sensor_close,
307     .read = RT_NULL,
308     .write = RT_NULL,
309     .control = ccap_sensor_control,
310 }
311 #endif
312 
313 rt_err_t ccap_sensor_register(struct rt_device *device, const char *name, void *user_data)
314 {
315     RT_ASSERT(device);
316 
317     device->type        = RT_Device_Class_Miscellaneous;
318     device->rx_indicate = RT_NULL;
319     device->tx_complete = RT_NULL;
320 
321 #ifdef RT_USING_DEVICE_OPS
322     device->ops         = &ccap_ops;
323 #else
324     device->init        = RT_NULL;
325     device->open        = ccap_sensor_open;
326     device->close       = ccap_sensor_close;
327     device->read        = RT_NULL;
328     device->write       = RT_NULL;
329     device->control     = ccap_sensor_control;
330 #endif
331     device->user_data   = user_data;
332 
333     return rt_device_register(device, name, RT_DEVICE_FLAG_RDONLY | RT_DEVICE_FLAG_STANDALONE);
334 }
335 
336 rt_err_t nu_ccap_sensor_create(ccap_sensor_io *psIo, ccap_sensor_id evSensorId, const char *szName)
337 {
338     static int i32AllocatedSensorId = 0;
339     rt_err_t ret = -RT_ERROR;
340     ccap_sensor_dev_t pdev = RT_NULL;
341 
342     RT_ASSERT(psIo);
343     RT_ASSERT((evSensorId >= 0) && (evSensorId < evCCAPSNR_CNT));
344 
345     switch (evSensorId)
346     {
347     case evCCAPSNR_HM1055:
348         pdev = nu_create_hm1055(psIo, szName);
349         break;
350 
351     case evCCAPSNR_ADV728X:
352         pdev = nu_create_adv728x(psIo, szName);
353         break;
354 
355     default:
356         break;
357     }
358 
359     if (pdev != RT_NULL)
360     {
361         ccap_sensor_setpower(pdev, RT_FALSE);
362         i32AllocatedSensorId++;
363         ret = RT_EOK;
364     }
365 
366     return ret;
367 }
368