1  | #include <cyu3system.h>
  | 
2  | #include <cyu3os.h>
  | 
3  | #include <cyu3dma.h>
  | 
4  | #include <cyu3error.h>
  | 
5  | #include <cyu3uart.h>
  | 
6  | #include <cyu3i2c.h>
  | 
7  | #include <cyu3types.h>
  | 
8  | #include <cyu3gpio.h>
  | 
9  | #include <cyu3utils.h>
  | 
10  | #include "sensor.h"
  | 
11  | 
  | 
12  | 
  | 
13  | 
  | 
14  | /* This function inserts a delay between successful I2C transfers to prevent
  | 
15  |  false errors due to the slave being busy.
  | 
16  |  */
  | 
17  | static void SensorI2CAccessDelay(CyU3PReturnStatus_t status) {
 | 
18  |   /* Add a 10us delay if the I2C operation that preceded this call was successful. */
  | 
19  |   if (status == CY_U3P_SUCCESS)
  | 
20  |     CyU3PBusyWait(10);
  | 
21  | }
  | 
22  | 
  | 
23  | /* Write to an I2C slave with two bytes of data. */
  | 
24  | CyU3PReturnStatus_t SensorWrite2B(uint8_t slaveAddr, uint8_t highAddr,
  | 
25  |     uint8_t lowAddr, uint8_t highData, uint8_t lowData) {
 | 
26  |   CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;
  | 
27  |   CyU3PI2cPreamble_t preamble;
  | 
28  |   uint8_t buf[2];
  | 
29  | 
  | 
30  |   /* Validate the I2C slave address. */
  | 
31  |   if ((slaveAddr != SENSOR_ADDR_WR) && (slaveAddr != I2C_MEMORY_ADDR_WR)) {
 | 
32  |     CyU3PDebugPrint(4, "I2C Slave address is not valid!\n");
  | 
33  |     return 1;
  | 
34  |   }
  | 
35  | 
  | 
36  |   /* Set the parameters for the I2C API access and then call the write API. */
  | 
37  |   preamble.buffer[0] = slaveAddr;
  | 
38  |   preamble.buffer[1] = highAddr;
  | 
39  |   preamble.buffer[2] = lowAddr;
  | 
40  |   preamble.length = 3; /*  Three byte preamble. */
  | 
41  |   preamble.ctrlMask = 0x0000; /*  No additional start and stop bits. */
  | 
42  | 
  | 
43  |   buf[0] = highData;
  | 
44  |   buf[1] = lowData;
  | 
45  | 
  | 
46  |   apiRetStatus = CyU3PI2cTransmitBytes(&preamble, buf, 2, 0);
  | 
47  |   SensorI2CAccessDelay(apiRetStatus);
  | 
48  | 
  | 
49  |   return apiRetStatus;
  | 
50  | }
  | 
51  | 
  | 
52  | CyU3PReturnStatus_t SensorWrite(uint8_t slaveAddr, uint8_t highAddr,
  | 
53  |     uint8_t lowAddr, uint8_t count, uint8_t *buf) {
 | 
54  |   CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;
  | 
55  |   CyU3PI2cPreamble_t preamble;
  | 
56  | 
  | 
57  |   /* Validate the I2C slave address. */
  | 
58  |   if ((slaveAddr != SENSOR_ADDR_WR) && (slaveAddr != I2C_MEMORY_ADDR_WR)) {
 | 
59  |     CyU3PDebugPrint(4, "I2C Slave address is not valid!\n");
  | 
60  |     return 1;
  | 
61  |   }
  | 
62  | 
  | 
63  |   if (count > 64) {
 | 
64  |     CyU3PDebugPrint(4, "ERROR: SensorWrite count > 64\n");
  | 
65  |     return 1;
  | 
66  |   }
  | 
67  | 
  | 
68  |   /* Set up the I2C control parameters and invoke the write API. */
  | 
69  |   preamble.buffer[0] = slaveAddr;
  | 
70  |   preamble.buffer[1] = highAddr;
  | 
71  |   preamble.buffer[2] = lowAddr;
  | 
72  |   preamble.length = 3;
  | 
73  |   preamble.ctrlMask = 0x0000;
  | 
74  | 
  | 
75  |   apiRetStatus = CyU3PI2cTransmitBytes(&preamble, buf, count, 0);
  | 
76  |   SensorI2CAccessDelay(apiRetStatus);
  | 
77  | 
  | 
78  |   return apiRetStatus;
  | 
79  | }
  | 
80  | 
  | 
81  | CyU3PReturnStatus_t SensorRead2B(uint8_t slaveAddr, uint8_t highAddr,
  | 
82  |     uint8_t lowAddr, uint8_t *buf) {
 | 
83  |   CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;
  | 
84  |   CyU3PI2cPreamble_t preamble;
  | 
85  | 
  | 
86  |   if ((slaveAddr != SENSOR_ADDR_RD) && (slaveAddr != I2C_MEMORY_ADDR_RD)) {
 | 
87  |     CyU3PDebugPrint(4, "I2C Slave address is not valid!\n");
  | 
88  |     return 1;
  | 
89  |   }
  | 
90  | 
  | 
91  |   preamble.buffer[0] = slaveAddr & I2C_SLAVEADDR_MASK; /*  Mask out the transfer type bit. */
  | 
92  |   preamble.buffer[1] = highAddr;
  | 
93  |   preamble.buffer[2] = lowAddr;
  | 
94  |   preamble.buffer[3] = slaveAddr;
  | 
95  |   preamble.length = 4;
  | 
96  |   preamble.ctrlMask = 0x0004; /*  Send start bit after third byte of preamble. */
  | 
97  | 
  | 
98  |   apiRetStatus = CyU3PI2cReceiveBytes(&preamble, buf, 2, 0);
  | 
99  |   SensorI2CAccessDelay(apiRetStatus);
  | 
100  | 
  | 
101  |   return apiRetStatus;
  | 
102  | }
  | 
103  | 
  | 
104  | CyU3PReturnStatus_t SensorRead(uint8_t slaveAddr, uint8_t highAddr,
  | 
105  |     uint8_t lowAddr, uint8_t count, uint8_t *buf) {
 | 
106  |   CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;
  | 
107  |   CyU3PI2cPreamble_t preamble;
  | 
108  | 
  | 
109  |   /* Validate the parameters. */
  | 
110  |   if ((slaveAddr != SENSOR_ADDR_RD) && (slaveAddr != I2C_MEMORY_ADDR_RD)) {
 | 
111  |     CyU3PDebugPrint(4, "I2C Slave address is not valid!\n");
  | 
112  |     return 1;
  | 
113  |   }
  | 
114  |   if (count > 64) {
 | 
115  |     CyU3PDebugPrint(4, "ERROR: SensorWrite count > 64\n");
  | 
116  |     return 1;
  | 
117  |   }
  | 
118  | 
  | 
119  |   preamble.buffer[0] = slaveAddr & I2C_SLAVEADDR_MASK; /*  Mask out the transfer type bit. */
  | 
120  |   preamble.buffer[1] = highAddr;
  | 
121  |   preamble.buffer[2] = lowAddr;
  | 
122  |   preamble.buffer[3] = slaveAddr;
  | 
123  |   preamble.length = 4;
  | 
124  |   preamble.ctrlMask = 0x0004; /*  Send start bit after third byte of preamble. */
  | 
125  | 
  | 
126  |   apiRetStatus = CyU3PI2cReceiveBytes(&preamble, buf, count, 0);
  | 
127  |   SensorI2CAccessDelay(apiRetStatus);
  | 
128  | 
  | 
129  |   return apiRetStatus;
  | 
130  | }
  | 
131  | 
  | 
132  | /*
  | 
133  |  * Reset the image sensor using GPIO.
  | 
134  |  */
  | 
135  | void SensorReset(void) {
 | 
136  |   CyU3PReturnStatus_t apiRetStatus;
  | 
137  | 
  | 
138  |   /* Drive the GPIO low to reset the sensor. */
  | 
139  |   apiRetStatus = CyU3PGpioSetValue(SENSOR_RESET_GPIO, CyFalse);
  | 
140  |   if (apiRetStatus != CY_U3P_SUCCESS) {
 | 
141  |     CyU3PDebugPrint(4, "GPIO Set Value Error, Error Code = %d\n",
  | 
142  |         apiRetStatus);
  | 
143  |     return;
  | 
144  |   }
  | 
145  | 
  | 
146  |   /* Wait for some time to allow proper reset. */
  | 
147  |   CyU3PThreadSleep(10);
  | 
148  | 
  | 
149  |   /* Drive the GPIO high to bring the sensor out of reset. */
  | 
150  |   apiRetStatus = CyU3PGpioSetValue(SENSOR_RESET_GPIO, CyTrue);
  | 
151  |   if (apiRetStatus != CY_U3P_SUCCESS) {
 | 
152  |     CyU3PDebugPrint(4, "GPIO Set Value Error, Error Code = %d\n",
  | 
153  |         apiRetStatus);
  | 
154  |     return;
  | 
155  |   }
  | 
156  | 
  | 
157  |   /* Delay the allow the sensor to power up. */
  | 
158  |   CyU3PThreadSleep(10);
  | 
159  |   return;
  | 
160  | }
  | 
161  | 
  | 
162  | 
  | 
163  | 
  | 
164  | /*
  | 
165  |    Verify that the sensor can be accessed over the I2C bus from FX3.
  | 
166  |  */
  | 
167  | uint8_t SensorI2cBusTest(void) {
 | 
168  |   /* The sensor ID register can be read here to verify sensor connectivity. */
  | 
169  |   uint8_t buf[2];
  | 
170  | 
  | 
171  |   /* Reading sensor ID */
  | 
172  |   if (SensorRead2B(SENSOR_ADDR_RD, 0x00, 0x00, buf) == CY_U3P_SUCCESS) {
 | 
173  |     if ((buf[0] == 0x01) && (buf[1] == 0x02)) {
 | 
174  |       return CY_U3P_SUCCESS;
  | 
175  |     }
  | 
176  |   }
  | 
177  |   return 1;
  | 
178  | }
  | 
179  | 
  | 
180  | 
  | 
181  | 
  | 
182  | 
  | 
183  | 
  | 
184  | /*
  | 
185  |  Get the current brightness setting from the image sensor.
  | 
186  |  */
  | 
187  | uint8_t SensorGetBrightness(void) {
 | 
188  |   uint8_t buf[2];
  | 
189  | 
  | 
190  |   SensorRead2B(SENSOR_ADDR_RD, 0x00, 0x02, buf);
  | 
191  |   return (uint8_t) buf[1];
  | 
192  | }
  | 
193  | 
  | 
194  | /*
  | 
195  |  Update the brightness setting for the image sensor.
  | 
196  |  */
  | 
197  | void SensorSetBrightness(uint8_t brightness) {
 | 
198  |   SensorWrite2B(SENSOR_ADDR_WR, 0x00, 0x02, 0x00, brightness);
  | 
199  | }
  |