Electgpl

8051 - TI I2C CC2530

Nov 10th, 2016
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 16.36 KB | None | 0 0
  1. //***************************************************************************
  2. // NOMBRE:             hal_i2c.c
  3. // FECHA:              09/11/2016
  4. // DESCRIPCION:        Rutina de Bit Banging para protocolo i2c.      
  5. // LOG MOFICIACIONES:  N/A
  6. //***************************************************************************
  7. #include "ioCC2530.h"
  8. #include "zcomdef.h"
  9. #include "hal_i2c.h"
  10. #define STATIC static
  11. //***************************************************************************
  12. //                      DEFINICION DE PINES DEL CC2530
  13. //                            SDA: 1.6 y SCL: 1.5
  14. //***************************************************************************
  15. #ifndef OCM_DATA_PORT
  16.   #define OCM_DATA_PORT 1
  17. #endif
  18. #ifndef OCM_DATA_PIN
  19.   #define OCM_DATA_PIN  6
  20. #endif
  21. #ifndef OCM_CLK_PORT
  22.   #define OCM_CLK_PORT  1
  23. #endif
  24. #ifndef OCM_CLK_PIN
  25.   #define OCM_CLK_PIN   5
  26. #endif
  27. //***************************************************************************
  28. //                            DEFINICION DE GPIO
  29. //***************************************************************************
  30. #define IO_GIO  0               // General purpose I/O
  31. #define IO_PER  1               // Peripheral function
  32. #define IO_IN   0               // Input pin
  33. #define IO_OUT  1               // Output pin
  34. #define IO_PUD  0               // Pullup/pulldn input
  35. #define IO_TRI  1               // Tri-state input
  36. #define IO_PUP  0               // Pull-up input pin
  37. #define IO_PDN  1               // Pull-down input pin
  38. #define OCM_ADDRESS  (0xA0)
  39. #define OCM_READ     (0x01)
  40. #define OCM_WRITE    (0x00)
  41. #define SMB_ACK      (0)
  42. #define SMB_NAK      (1)
  43. #define SEND_STOP    (0)
  44. #define NOSEND_STOP  (1)
  45. #define SEND_START   (0)
  46. #define NOSEND_START (1)
  47. //#define hali2cWait(a)  asm("NOP")
  48. //***************************************************************************
  49. //                         DEFINICION DE MACROS
  50. //***************************************************************************
  51. #undef P
  52. // I/O PORT CONFIGURATION
  53. #define CAT1(x,y) x##y          // Concatenates 2 strings
  54. #define CAT2(x,y) CAT1(x,y)     // Forces evaluation of CAT1
  55. // OCM port I/O defintions
  56. // Builds I/O port name: PNAME(1,INP) ==> P1INP
  57. #define PNAME(y,z) CAT2(P,CAT2(y,z))
  58. // Builds I/O bit name: BNAME(1,2) ==> P1_2
  59. #define BNAME(port,pin) CAT2(CAT2(P,port),CAT2(_,pin))
  60. //***************************************************************************
  61. //                         DEFINICION DE PUERTOS
  62. //***************************************************************************
  63. #define OCM_SCL BNAME(OCM_CLK_PORT, OCM_CLK_PIN)
  64. #define OCM_SDA BNAME(OCM_DATA_PORT, OCM_DATA_PIN)
  65. #define IO_DIR_PORT_PIN(port, pin, dir) \
  66. {\
  67.   if ( dir == IO_OUT ) \
  68.     PNAME(port,DIR) |= (1<<(pin)); \
  69.   else \
  70.     PNAME(port,DIR) &= ~(1<<(pin)); \
  71. }
  72. #define OCM_DATA_HIGH()\
  73. { \
  74.   IO_DIR_PORT_PIN(OCM_DATA_PORT, OCM_DATA_PIN, IO_IN); \
  75. }
  76. #define OCM_DATA_LOW() \
  77. { \
  78.   IO_DIR_PORT_PIN(OCM_DATA_PORT, OCM_DATA_PIN, IO_OUT); \
  79.   OCM_SDA = 0;\
  80. }
  81. #define IO_FUNC_PORT_PIN(port, pin, func) \
  82. { \
  83.   if( port < 2 ) \
  84.   { \
  85.     if ( func == IO_PER ) \
  86.       PNAME(port,SEL) |= (1<<(pin)); \
  87.     else \
  88.       PNAME(port,SEL) &= ~(1<<(pin)); \
  89.   } \
  90.   else \
  91.   { \
  92.     if ( func == IO_PER ) \
  93.       P2SEL |= (1<<(pin>>1)); \
  94.     else \
  95.       P2SEL &= ~(1<<(pin>>1)); \
  96.   } \
  97. }
  98. #define IO_IMODE_PORT_PIN(port, pin, mode) \
  99. { \
  100.   if ( mode == IO_TRI ) \
  101.     PNAME(port,INP) |= (1<<(pin)); \
  102.   else \
  103.     PNAME(port,INP) &= ~(1<<(pin)); \
  104. }
  105. #define IO_PUD_PORT(port, dir) \
  106. { \
  107.   if ( dir == IO_PDN ) \
  108.     P2INP |= (1<<(port+5)); \
  109.   else \
  110.     P2INP &= ~(1<<(port+5)); \
  111. }
  112. //***************************************************************************
  113. //                         PROTOTIPO DE FUNCIONES
  114. //***************************************************************************
  115. STATIC void   hali2cInit(void);
  116. STATIC _Bool  hali2cWriteByte(uint8 dByte);
  117. STATIC _Bool  hali2cWriteByteAdd(uint8 dByte);
  118. STATIC _Bool  hali2cReadByteAdd(uint8 dByte);
  119. STATIC void   hali2cClock(bool dir);
  120. STATIC void   hali2cStart(void);
  121. STATIC void   hali2cStop(void);
  122. STATIC uint8  hali2cReadByte(void);
  123. STATIC __near_func void   hali2cWait(uint8);
  124. STATIC uint8 s_xmemIsInit;
  125. STATIC _Bool  i2cRead(uint8  i2cNumber,
  126.                       uint8  i2cSlaveAddress,
  127.                       uint8* dataToReadBuffer,
  128.                       uint16 dataToReadBufferSize,
  129.                       bool   sendWriteStop,
  130.                       uint8* receiveDataBuffer,
  131.                       uint16 receiveDataBufferSize,
  132.                       bool   sendReadStop );
  133. STATIC _Bool i2cWrite(uint8  i2cNumber,
  134.                       uint8  i2cSlaveAddress,
  135.                       uint8* transmitDataBuffer,
  136.                       uint16 transmitDataBufferSize,
  137.                       bool   sendWriteStop );
  138. //***************************************************************************
  139. // TRAMA I2C A EJECUTAR
  140. //***************************************************************************
  141. void HalI2CProc(void)
  142. {
  143.   uint8 valor=0;
  144.   uint8 address=0x55;
  145.   uint8 buffer[2]={0xfe,0x03};
  146.  
  147.   hali2cInit();
  148.  
  149.   i2cRead(0,address,buffer,2,1,&valor,1,1);
  150.  
  151.   //i2cWrite();
  152. }
  153. //***************************************************************************
  154. // FUNCION i2cRead PARA NFC
  155. //
  156. // ENTRADA DE LA FUNCION
  157. // i2cNumber: Puerto I2C (si hay 1, porner 0).
  158. // i2cSlaveAddress: Direccion del esclavo.
  159. // dataToReadBuffer: Vector de direccion, sub direccion, a leer
  160. // dataToReadBufferSize: Tamaño del vector
  161. // sendWriteStop: True (1) si mando stop.
  162. // receiveDataBuffer: Donde recivo los datos.
  163. // receiveDataBufferSize: Tamaño del vector.
  164. // sendReadStop: True (1) si mando stop.
  165. //
  166. // SALIDA DE LA FUNCION
  167. // retVal: True si salio bien.
  168. //***************************************************************************
  169. STATIC _Bool i2cRead(uint8  i2cNumber,
  170.                      uint8  i2cSlaveAddress,
  171.                      uint8* dataToReadBuffer,
  172.                      uint16 dataToReadBufferSize,
  173.                      bool   sendWriteStop,
  174.                      uint8* receiveDataBuffer,
  175.                      uint16 receiveDataBufferSize,
  176.                      bool   sendReadStop)
  177. {
  178.    bool retVal = TRUE;
  179.    uint16 i = 0;
  180.    // Check Errors
  181.    if((dataToReadBuffer == NULL)||(dataToReadBufferSize < 0)||
  182.       (receiveDataBuffer == NULL)||(receiveDataBufferSize <= 0)){
  183.       return FALSE;  
  184.    }
  185.    // First Write
  186.    // Start condition
  187.    hali2cStart();        
  188.    // 7 bit address + Write = 0
  189.    hali2cWriteByteAdd(i2cSlaveAddress);
  190.    hali2cWait(1);
  191.    // Write all data buffer
  192.    for(i=0; i<dataToReadBufferSize; i++){
  193.       hali2cWriteByte(dataToReadBuffer[i]);
  194.       hali2cWait(1);
  195.    }
  196.    // Send Stop condition
  197.    if(sendWriteStop){
  198.       hali2cStop();      
  199.    }
  200.    // Then Read
  201.    // Start condition
  202.    hali2cStart();        
  203.    // 7 bit address + Read = 1
  204.    hali2cReadByteAdd(i2cSlaveAddress);
  205.    hali2cWait(1);
  206.    // Write all data buffer
  207.    for(i=0; i<receiveDataBufferSize; i++){
  208.       receiveDataBuffer[i] = hali2cReadByte();
  209.       hali2cWait(1);
  210.    }
  211.    // Send Stop condition
  212.    if(sendReadStop){
  213.       hali2cStop();      
  214.    }
  215.    return retVal;
  216. }
  217. //***************************************************************************
  218. // FUNCION i2cWrite PARA NFC
  219. //
  220. // ENTRADA DE LA FUNCION
  221. // i2cNumber: Puerto I2C (si hay 1, porner 0).
  222. // i2cSlaveAddress: Direccion del esclavo.
  223. // transmitDataBuffer: Vector a transmitir.
  224. // transmitDataBufferSize: Tamaño del vector.
  225. // sendWriteStop: True (1) si mando stop.
  226. //
  227. // SALIDA DE LA FUNCION
  228. // retVal: True si salio bien.
  229. //***************************************************************************
  230. STATIC _Bool i2cWrite(uint8  i2cNumber,
  231.                       uint8  i2cSlaveAddress,
  232.                       uint8* transmitDataBuffer,
  233.                       uint16 transmitDataBufferSize,
  234.                       bool   sendWriteStop)
  235. {
  236.    bool retVal = TRUE;
  237.    uint16 i = 0;
  238.    // Check Errors
  239.    if((transmitDataBuffer == NULL)||(transmitDataBufferSize <= 0)){
  240.       return FALSE;  
  241.    }
  242.    // Start condition
  243.    hali2cStart();        
  244.    // 7 bit address + Write = 0
  245.    hali2cWriteByteAdd(i2cSlaveAddress);
  246.    // Write all data buffer
  247.    for(i=0; i<transmitDataBufferSize; i++){
  248.       hali2cWriteByte(transmitDataBuffer[i]);  
  249.    }
  250.    // Send Stop condition
  251.    if(sendWriteStop){
  252.       hali2cStop();      
  253.    }
  254.    return retVal;
  255. }
  256. //***************************************************************************
  257. // INICIALIZA PUERTOS Y REALIZA TRAMA
  258. //***************************************************************************
  259. void hali2cInit(void)
  260. {
  261.   if (!s_xmemIsInit)            
  262.   {
  263.     s_xmemIsInit = 1;
  264. // Seteo de pines como ENTRADA
  265.       IO_DIR_PORT_PIN( OCM_CLK_PORT, OCM_CLK_PIN, IO_IN );
  266.       IO_DIR_PORT_PIN( OCM_DATA_PORT, OCM_DATA_PIN, IO_IN );
  267. // Seteo de pines como GPIO
  268.       IO_FUNC_PORT_PIN( OCM_CLK_PORT, OCM_CLK_PIN, IO_GIO );
  269.       IO_FUNC_PORT_PIN( OCM_DATA_PORT, OCM_DATA_PIN, IO_GIO );
  270. // Seteo de GPIO para pull-up/pull-down
  271. //    IO_IMODE_PORT_PIN( OCM_CLK_PORT, OCM_CLK_PIN, IO_PUD );
  272. //    IO_IMODE_PORT_PIN( OCM_DATA_PORT, OCM_DATA_PIN, IO_PUD );
  273. // Seteo de pines con pull-up
  274. //    IO_PUD_PORT( OCM_CLK_PORT, IO_PUP );
  275. //    IO_PUD_PORT( OCM_DATA_PORT, IO_PUP );
  276.   }
  277. }
  278. //***************************************************************************
  279. // ESCRIBE BYTE DE DATO PARA ESCRITURA [WRITE BYTE]
  280. //***************************************************************************
  281. STATIC _Bool hali2cWriteByte(uint8 dByte)
  282. {
  283.   uint8 i;
  284.   for (i=0;i<8;i++)             //Lazo para enviar el dato serial
  285.   {
  286.     hali2cClock(0);             //Clock (SCL) LOW
  287.     hali2cWait(1);              //Demora 1 Ciclo
  288.     if (dByte & 0x80)           //Mascara del dato contra 1000 0000
  289.     {
  290.       OCM_DATA_HIGH();          //Data (SDA) HIGH
  291.     }
  292.     else
  293.     {
  294.       OCM_DATA_LOW();           //Data (SDA) LOW
  295.     }
  296.     hali2cClock(1);             //Clock (SCL) HIGH
  297.     hali2cWait(1);              //Demora 1 Ciclo
  298.     dByte <<= 1;                //Shift a la izquierda
  299.   }
  300.   hali2cWait(2);                //Demora 2 Ciclos
  301.   hali2cClock(0);               //Clock (SCL) LOW
  302.   hali2cWait(2);                //Demora 2 Ciclos
  303.   hali2cClock(1);               //Clock (SCL) HIGH
  304.   OCM_SDA;                      //Lee Data (SDA)
  305.   hali2cWait(3);                //Demora 3 Ciclos
  306.   hali2cClock(0);               //Clock (SCL) LOW
  307.   hali2cWait(8);                //Demora 8 Ciclos
  308.   return (!OCM_SDA);            
  309. }
  310. //***************************************************************************
  311. // ESCRIBE BYTE DE DIRECCION PARA ESCRITURA [WRITE ADDRESS]
  312. //***************************************************************************
  313. STATIC _Bool hali2cWriteByteAdd(uint8 dByte)
  314. {
  315.   uint8 i;
  316.   for (i=0;i<8;i++)             //Lazo para enviar el dato serial
  317.   {
  318.     hali2cClock(0);             //Clock (SCL) LOW
  319.     hali2cWait(1);              //Demora 1 Ciclo
  320.     if (dByte & 0x40)           //Mascara del dato contra 0100 0000
  321.     {
  322.       OCM_DATA_HIGH();          //Data (SDA) HIGH
  323.     }
  324.     else
  325.     {
  326.       OCM_DATA_LOW();           //Data (SDA) LOW
  327.     }
  328.     hali2cClock(1);             //Clock (SCL) HIGH
  329.     hali2cWait(1);              //Demora 1 Ciclo
  330.     dByte <<= 1;                //Shift a la izquierda
  331.   }
  332.   hali2cWait(2);                //Demora 2 Ciclos
  333.   hali2cClock(0);               //Clock (SCL) LOW
  334.   hali2cWait(2);                //Demora 2 Ciclos
  335.   hali2cClock(1);               //Clock (SCL) HIGH
  336.   OCM_SDA;                      //Lee Data (SDA)
  337.   hali2cWait(3);                //Demora 3 Ciclos
  338.   hali2cClock(0);               //Clock (SCL) LOW
  339.   hali2cWait(8);                //Demora 8 Ciclos
  340.   return (!OCM_SDA);
  341. }
  342. //***************************************************************************
  343. // ESCRIBE BYTE DE DIRECCION PARA LECTURA [READ BYTE]
  344. //***************************************************************************
  345. STATIC _Bool hali2cReadByteAdd(uint8 dByte)
  346. {
  347.   uint8 i;
  348.   for (i=0;i<7;i++)             //Lazo para enviar el dato serial
  349.   {
  350.     hali2cClock(0);             //Clock (SCL) LOW
  351.     hali2cWait(1);              //Demora 1 Ciclo
  352.     if (dByte & 0x40)           //Mascara del dato contra 0100 0000
  353.     {
  354.       OCM_DATA_HIGH();          //Data (SDA) HIGH
  355.     }
  356.     else
  357.     {
  358.       OCM_DATA_LOW();           //Data (SDA) LOW
  359.     }
  360.     hali2cClock(1);             //Clock (SCL) HIGH
  361.     hali2cWait(1);              //Demora 1 Ciclo
  362.     dByte <<= 1;                //Shift a la izquierda
  363.   }
  364.   hali2cClock(0);               //Clock (SCL) LOW
  365.   hali2cWait(1);                //Demora 1 Ciclo
  366.   OCM_DATA_HIGH();              //Data (SDA) HIGH
  367.   hali2cClock(1);               //Clock (SCL) HIGH
  368.   hali2cWait(1);                //Demora 1 Ciclo
  369.   dByte <<= 1;                  //Shift a la izquierda
  370.   hali2cWait(2);                //Demora 2 Ciclos
  371.   hali2cClock(0);               //Clock (SCL) LOW
  372.   hali2cWait(2);                //Demora 2 Ciclos
  373.   hali2cClock(1);               //Clock (SCL) HIGH
  374.   OCM_SDA;                      //Lee Data (SDA)
  375.   hali2cWait(3);                //Demora 3 Ciclos
  376.   hali2cClock(0);               //Clock (SCL) LOW
  377.   hali2cWait(8);                //Demora 8 Ciclos
  378.   return (!OCM_SDA);
  379. }
  380. //***************************************************************************
  381. // CAMBIA DE ESTADO EL CLOCK [SCL]
  382. //***************************************************************************
  383. STATIC void hali2cClock( bool dir )
  384. {
  385.   if ( dir )
  386.   {
  387.     IO_DIR_PORT_PIN( OCM_CLK_PORT, OCM_CLK_PIN, IO_IN );
  388.     while(!OCM_SCL)             //Espera hasta que el clock este en alto
  389.         hali2cWait(1);          //Demora 1 Ciclo
  390.   }
  391.   else
  392.   {
  393.     IO_DIR_PORT_PIN( OCM_CLK_PORT, OCM_CLK_PIN, IO_OUT );
  394.     OCM_SCL = 0;                //Setea el clock a LOW
  395.   }
  396.   hali2cWait(1);                //Demora 1 Ciclo
  397. }
  398. //***************************************************************************
  399. // DEMORA DE PROCESO [DELAY]
  400. //***************************************************************************
  401. STATIC __near_func void hali2cWait( uint8 count )
  402. {
  403.     while ( count-- );          //15us por iteracion
  404.       asm("NOP");               //Demora NOP de ensamblador
  405. }
  406. //***************************************************************************
  407. // RECIVE BYTE DE DATOS [READ]
  408. //***************************************************************************
  409. STATIC uint8 hali2cReadByte()
  410. {
  411.   uint8 *buffer;                //Variable de salida de la funcion
  412.   int8 i;                      
  413.   for (i=7; i>=0; --i)          //Iteracion de lectura serie
  414.   {
  415.     hali2cClock(0);             //Clock (SCL) LOW
  416.     hali2cWait(1);              //Demora 1 Ciclo
  417.     hali2cClock(1);             //Clock (SCL) HIGH
  418.     hali2cWait(1);              //Demora 1 Ciclo
  419.     if (OCM_SDA)                //Consulta el bit presente en Data
  420.     {
  421.        buffer[i] |= 1<<i;       //Shift bajada del valor a la variable
  422.     }
  423.   }
  424.   return *buffer;
  425. }
  426. //***************************************************************************
  427. // START
  428. // SCL ------___
  429. // SDA ---______
  430. //***************************************************************************
  431. STATIC void hali2cStart(void)
  432. {
  433.   OCM_DATA_HIGH();              //Data (SDA) HIGH
  434.   hali2cClock(1);               //Clock (SCL) HIGH
  435.   hali2cWait(1);                //Demora 1 Ciclo
  436.   OCM_DATA_LOW();               //Data (SDA) LOW
  437.   hali2cWait(1);                //Demora 1 Ciclo
  438.   hali2cClock(0);               //Clock (SCL) LOW
  439.   hali2cWait(1);                //Demora 1 Ciclo
  440. }
  441. //***************************************************************************
  442. // STOP
  443. // SCL ___------
  444. // SDA ______---
  445. //***************************************************************************
  446. STATIC void hali2cStop(void)
  447. {
  448.   OCM_DATA_LOW();               //Data (SDA) LOW
  449.   hali2cClock(0);               //Clock (SCL) LOW
  450.   hali2cWait(1);                //Demora 1 Ciclo
  451.   hali2cClock(1);               //Clock (SCL) HIGH
  452.   hali2cWait(1);                //Demora 1 Ciclo
  453.   OCM_DATA_HIGH();              //Data (SDA) HIGH
  454.   hali2cWait(1);                //Demora 1 Ciclo
  455. }
  456. //***************************************************************************
  457. // FIN DE LA FUNCION I2C
  458. //***************************************************************************
Add Comment
Please, Sign In to add comment