00001
00014 #include <stdio.h>
00015 #include "i2cspm.h"
00016 #include "em_i2c.h"
00017 #include "em_gpio.h"
00018 #include "string.h"
00019 #include "em_usb.h"
00020 #include "rtcdriver.h"
00021 #include "em_gpio.h"
00022 #include "si114x_functions.h"
00023 #include "si114x_sys_out.h"
00024 #include "si114xhrm.h"
00025
00026 #ifdef USB_DEBUG
00027 #include "usb_debug.h"
00028 #endif
00029
00030
00031 static Si114xPortConfig_t _handle;
00032
00033 static bool usbDebugEnable;
00034
00035 static uint16_t irqSequence = 0;
00036
00037 #define IRQ_QUEUE_SIZE 270
00038
00039 static u8 IrqQueue[IRQ_QUEUE_SIZE];
00040
00041 static u16 irqQueueGetIndex = 0;
00042
00043 static u16 irqQueuePutIndex = 0;
00044
00045
00046 static s16 Si114x_i2c_smbus_write_byte_data(HANDLE si114x_handle, u8 address, u8 data, bool block);
00047 static s16 Si114x_i2c_smbus_read_byte_data(HANDLE si114x_handle, u8 address, u8 *data, bool block);
00048 static s16 Si114x_i2c_smbus_write_i2c_block_data(HANDLE si114x_handle, u8 address, u8 length, u8 const* values, bool block);
00049 static s16 Si114x_i2c_smbus_read_i2c_block_data(HANDLE si114x_handle, u8 address, u8 length, u8* values, bool block);
00050 static s16 Si114xIrqQueue_Put(SI114X_IRQ_SAMPLE *samples);
00051
00052
00055 int si114xSetupDebug(HANDLE si114x_handle, void *si114x_debug)
00056 {
00057 int *enable_usb_debug = (int *)si114x_debug;
00058 (void) si114x_handle;
00059 if(*enable_usb_debug == 1)
00060 usbDebugEnable = true;
00061 else if(*enable_usb_debug == 0)
00062 usbDebugEnable = false;
00063
00064 return SI114xHRM_SUCCESS;
00065 }
00066
00067
00070 int si114xOutputDebugMessage(HANDLE si114x_handle, char *message)
00071 {
00072 uint16_t i;
00073 uint8_t message_buffer[((99)+3)&~3] __attribute__ ((aligned(4)));
00074 uint8_t *Message_Buffer[1] = {message_buffer};
00075 (void) si114x_handle;
00076 message_buffer[0] = 0x10;
00077 for(i=0; i<strlen(message); i++)
00078 message_buffer[i+1] = (uint8_t)message[i];
00079 message_buffer[strlen(message)+1] = 0x10;
00080 message_buffer[strlen(message)+2] = 0x0D;
00081 #ifdef USB_DEBUG
00082 USBD_Write(CDC_EP_DATA_IN, (void*) Message_Buffer[0], strlen(message)+3, NULL);
00083 #endif
00084 return SI114xHRM_SUCCESS;
00085 }
00086
00087
00090 int16_t Si114xWriteToRegister(HANDLE si114x_handle, uint8_t address, uint8_t data)
00091 {
00092 return Si114x_i2c_smbus_write_byte_data(si114x_handle, address, data, true);
00093 }
00094
00095
00098 int16_t Si114xReadFromRegister(HANDLE si114x_handle, uint8_t address)
00099 {
00100 u8 data;
00101 Si114x_i2c_smbus_read_byte_data(si114x_handle, address, &data, true);
00102 return data;
00103 }
00104
00105
00108 int16_t Si114xBlockWrite(HANDLE si114x_handle,
00109 uint8_t address, uint8_t length, uint8_t *values)
00110 {
00111 return Si114x_i2c_smbus_write_i2c_block_data(si114x_handle,
00112 address,
00113 length,
00114 values,
00115 true);
00116 }
00117
00118
00121 int16_t Si114xBlockRead(HANDLE si114x_handle,
00122 uint8_t address, uint8_t length, uint8_t *values)
00123 {
00124 return Si114x_i2c_smbus_read_i2c_block_data(si114x_handle,
00125 address, length, values, true);
00126 }
00127
00128
00131 void DisableSi114xInterrupt ()
00132 {
00133
00134 GPIO_IntDisable(1<<_handle.irqPin);
00135 }
00136
00137
00140 void EnableSi114xInterrupt ()
00141 {
00142 if (GPIO_PinInGet(_handle.irqPort, _handle.irqPin) == 0)
00143 GPIO_IntSet(1<<_handle.irqPin);
00144 GPIO_IntEnable(1<<_handle.irqPin);
00145 }
00146
00147
00150 s16 Si114xProcessIrq(HANDLE si114x_handle, u16 timestamp)
00151 {
00152 u8 data_buffer[13];
00153 s16 error;
00154 SI114X_IRQ_SAMPLE sample;
00155 irqSequence++;
00156 Si114x_i2c_smbus_read_i2c_block_data(si114x_handle, 0x21, 13, data_buffer, false);
00157 Si114x_i2c_smbus_write_byte_data(si114x_handle, 0x21, data_buffer[0], false);
00158
00159 sample.sequence = irqSequence;
00160 sample.timestamp = timestamp;
00161 sample.pad= 0;
00162 sample.irqstat = data_buffer[0];
00163 sample.vis = (((u16)(data_buffer[2]) << 8) & 0xff00) | data_buffer[1];
00164 sample.ir = (((u16)(data_buffer[4]) << 8) & 0xff00) | data_buffer[3];
00165 sample.ps1 = (((u16)(data_buffer[6]) << 8) & 0xff00) | data_buffer[5];
00166 sample.ps2 = (((u16)(data_buffer[8]) << 8) & 0xff00) | data_buffer[7];
00167 sample.ps3 = (((u16)(data_buffer[10]) << 8) & 0xff00) | data_buffer[9];
00168 sample.aux = (((u16)(data_buffer[12]) << 8) & 0xff00) | data_buffer[11];;
00169
00170 error = Si114xIrqQueue_Put(&sample);
00171 return error;
00172 }
00173
00174
00175
00178 s16 Si114xIrqQueueNumentries(HANDLE si114x_handle)
00179 {
00180 (void) si114x_handle;
00181 u16 runnerIndex = irqQueueGetIndex;
00182 s16 count=0;
00183 while (runnerIndex != irqQueuePutIndex)
00184 {
00185 runnerIndex++;
00186 count++;
00187 if(runnerIndex == IRQ_QUEUE_SIZE)
00188 runnerIndex = 0;
00189 }
00190 return (count/sizeof(SI114X_IRQ_SAMPLE));
00191
00192 }
00193
00194
00197 s16 Si114xIrqQueue_Get(HANDLE si114x_handle, SI114X_IRQ_SAMPLE *samples)
00198 {
00199 (void) si114x_handle;
00200 int16_t error = 0;
00201 uint16_t i;
00202 int8_t *data = (int8_t *)samples;
00203 DisableSi114xInterrupt ();
00204 if (irqQueueGetIndex == irqQueuePutIndex)
00205 error = -1;
00206 else
00207 {
00208 for(i=0; i<sizeof(SI114X_IRQ_SAMPLE); i++)
00209 {
00210 data[i] = IrqQueue[irqQueueGetIndex];
00211 irqQueueGetIndex++;
00212 if(irqQueueGetIndex == IRQ_QUEUE_SIZE)
00213 irqQueueGetIndex = 0;
00214
00215 }
00216
00217 }
00218 EnableSi114xInterrupt();
00219 #ifdef USB_DEBUG
00220 if (usbDebugEnable == 1)
00221 USBDebug_ProcessUSBOutput(data);
00222 #endif // si114xHRM_USB_DEBUG
00223 return error;
00224 }
00225
00226
00229 static s16 Si114xIrqQueue_Put(SI114X_IRQ_SAMPLE *samples)
00230 {
00231 uint16_t i;
00232 u8 *data = (u8 *)samples;
00233 for(i=0; i<sizeof(SI114X_IRQ_SAMPLE); i++)
00234 {
00235 IrqQueue[irqQueuePutIndex] = data[i];
00236 irqQueuePutIndex++;
00237 if(irqQueuePutIndex == IRQ_QUEUE_SIZE)
00238 irqQueuePutIndex = 0;
00239 }
00240 if (irqQueueGetIndex == irqQueuePutIndex)
00241 {
00242 irqQueueGetIndex += sizeof(SI114X_IRQ_SAMPLE);
00243 return -1;
00244 }
00245 return 0;
00246 }
00247
00248
00251 s16 Si114xIrqQueue_Clear(HANDLE si114x_handle)
00252 {
00253 (void) si114x_handle;
00254 irqQueueGetIndex = 0;
00255 irqQueuePutIndex = 0;
00256 return 0;
00257 }
00258
00259
00262 s16 Si114xInit(void *port, int options, HANDLE *si114x_handle)
00263 {
00264 s16 error = 0;
00265 u8 data;
00266
00267 (void) options;
00268
00269 *si114x_handle = (HANDLE)&_handle;
00270 _handle.i2cPort = ((Si114xPortConfig_t*)port)->i2cPort;
00271 _handle.i2cAddress = ((Si114xPortConfig_t*)port)->i2cAddress << 1;
00272 _handle.irqPort = ((Si114xPortConfig_t*)port)->irqPort;
00273 _handle.irqPin = ((Si114xPortConfig_t*)port)->irqPin;
00274
00275 data = Si114xReadFromRegister(*si114x_handle, REG_PART_ID);
00276
00277 if ((_handle.i2cAddress == (0x60 << 1)) && (data != 0x46) && (data != 0x47))
00278 error = -1;
00279 if ((_handle.i2cAddress == (0x5A << 1)) && (data != 0x43))
00280 error = -1;
00281
00282 Si114xIrqQueue_Clear(*si114x_handle);
00283
00284 return error;
00285 }
00286
00287
00290 s16 Si114xClose(HANDLE si114x_handle)
00291 {
00292 (void) si114x_handle;
00293 _handle.i2cAddress = 0xff;
00294 return 0;
00295 }
00296
00297
00300 s16 Si114xSysReset(HANDLE si114x_handle)
00301 {
00302 (void) si114x_handle;
00303 return 0;
00304 }
00305
00306
00309 void delay_10ms(void)
00310 {
00311 RTCDRV_Delay(10);
00312 return;
00313 }
00314
00315
00318 void delay_1ms(void)
00319 {
00320 RTCDRV_Delay(1);
00321 return;
00322 }
00323
00324
00325
00328 static s16 Si114x_i2c_smbus_write_byte_data(HANDLE si114x_handle, u8 address, u8 data, bool block)
00329 {
00330 I2C_TransferSeq_TypeDef seq;
00331 I2C_TransferReturn_TypeDef ret;
00332 Si114xPortConfig_t* handle;
00333 uint8_t i2c_write_data[2];
00334 uint8_t i2c_read_data[1];
00335
00336 if (block)
00337 DisableSi114xInterrupt();
00338 seq.addr = _handle.i2cAddress;
00339 seq.flags = I2C_FLAG_WRITE;
00340
00341 i2c_write_data[0] = address;
00342 i2c_write_data[1] = data;
00343 seq.buf[0].data = i2c_write_data;
00344 seq.buf[0].len = 2;
00345 seq.buf[1].data = i2c_read_data;
00346 seq.buf[1].len = 0;
00347
00348 handle = (Si114xPortConfig_t *)si114x_handle;
00349
00350 ret = I2CSPM_Transfer(handle->i2cPort, &seq);
00351
00352 if (block)
00353 EnableSi114xInterrupt();
00354 if (ret != i2cTransferDone)
00355 {
00356 return (s16)ret;
00357 }
00358 return (s16)0;
00359 }
00360
00361
00364 static s16 Si114x_i2c_smbus_read_byte_data(HANDLE si114x_handle, u8 address, u8 *data, bool block)
00365 {
00366
00367 I2C_TransferSeq_TypeDef seq;
00368 I2C_TransferReturn_TypeDef ret;
00369 uint8_t i2c_write_data[1];
00370 Si114xPortConfig_t* i2cDrvHandle;
00371
00372 if (block)
00373 DisableSi114xInterrupt ();
00374 seq.addr = _handle.i2cAddress;
00375 seq.flags = I2C_FLAG_WRITE_READ;
00376
00377 i2c_write_data[0] = address;
00378 seq.buf[0].data = i2c_write_data;
00379 seq.buf[0].len = 1;
00380
00381 seq.buf[1].data = data;
00382 seq.buf[1].len = 1;
00383
00384 i2cDrvHandle = (Si114xPortConfig_t *)si114x_handle;
00385
00386 ret = I2CSPM_Transfer(i2cDrvHandle->i2cPort, &seq);
00387
00388 if (block)
00389 EnableSi114xInterrupt();
00390 if (ret != i2cTransferDone)
00391 {
00392 *data = 0xff;
00393 return((int) ret);
00394 }
00395 return((int) 1);
00396 }
00397
00398
00401 static s16 Si114x_i2c_smbus_write_i2c_block_data(HANDLE si114x_handle, u8 address, u8 length, u8 const* data, bool block)
00402 {
00403 I2C_TransferSeq_TypeDef seq;
00404 I2C_TransferReturn_TypeDef ret;
00405 uint8_t i2c_write_data[10];
00406 uint8_t i2c_read_data[1];
00407 Si114xPortConfig_t* handle;
00408 int i;
00409
00410 if (block)
00411 DisableSi114xInterrupt ();
00412 seq.addr = _handle.i2cAddress;
00413 seq.flags = I2C_FLAG_WRITE;
00414
00415 i2c_write_data[0] = address;
00416 for (i=0; i<length;i++)
00417 {
00418 i2c_write_data[i+1] = data[i];
00419 }
00420 seq.buf[0].data = i2c_write_data;
00421 seq.buf[0].len = 1+length;
00422 seq.buf[1].data = i2c_read_data;
00423 seq.buf[1].len = 0;
00424
00425 handle = (Si114xPortConfig_t *)si114x_handle;
00426
00427 ret = I2CSPM_Transfer(handle->i2cPort, &seq);
00428
00429 if (block)
00430 EnableSi114xInterrupt ();
00431 if (ret != i2cTransferDone)
00432 {
00433 return((int) ret);
00434 }
00435
00436 return((int) 0);
00437 }
00438
00439
00442 static s16 Si114x_i2c_smbus_read_i2c_block_data(HANDLE si114x_handle, u8 address, u8 length, u8* data, bool block)
00443 {
00444 I2C_TransferSeq_TypeDef seq;
00445 I2C_TransferReturn_TypeDef ret;
00446 uint8_t i2c_write_data[1];
00447 Si114xPortConfig_t* handle;
00448
00449 seq.addr = _handle.i2cAddress;
00450 seq.flags = I2C_FLAG_WRITE_READ;
00451 if (block)
00452 DisableSi114xInterrupt ();
00453
00454 i2c_write_data[0] = address;
00455 seq.buf[0].data = i2c_write_data;
00456 seq.buf[0].len = 1;
00457
00458
00459 seq.buf[1].data = data;
00460 seq.buf[1].len = length;
00461
00462 handle = (Si114xPortConfig_t *)si114x_handle;
00463
00464 ret = I2CSPM_Transfer(handle->i2cPort, &seq);
00465
00466 if (block)
00467 EnableSi114xInterrupt ();
00468 if (ret != i2cTransferDone)
00469 {
00470 return((int) ret);
00471 }
00472
00473 return((int) 0);
00474 }
00475
00476 int si114xFindEvb(char *port_description, char *last_port, int num_ports_found)
00477 {
00478 (void) port_description;
00479 (void) last_port;
00480 (void) num_ports_found;
00481 return 0;
00482 }
00483