Advertisement
Guest User

Untitled

a guest
Mar 26th, 2019
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.56 KB | None | 0 0
  1. #define MAX_BUFFER 32
  2.  
  3.  
  4. // SLAVE
  5. void I2C_SlaveInit(unsigned char addr);
  6. void I2C_SlaveInterruptRoutine(void);
  7.  
  8. typedef struct _I2C_BufferInfo{
  9. unsigned char size;
  10. unsigned char* buffer;
  11. }I2C_BufferInfo;
  12.  
  13. void I2C_InputCallback(unsigned char buffer[], unsigned char count);
  14. void I2C_OutputCallback(I2C_BufferInfo* bufferInfo);
  15.  
  16. // STRUCTURES
  17.  
  18. typedef struct _I2C_BaseData{
  19. char size;
  20. unsigned char type;
  21. } I2C_BaseData;
  22.  
  23.  
  24. typedef struct _I2C_SingleChangeData{
  25. I2C_BaseData i2cbase;
  26. char index;
  27. char state;
  28. } I2C_SingleChangeData;
  29.  
  30.  
  31. typedef struct _I2C_UnitInfo{
  32. I2C_BaseData i2cbase;
  33. char inputs;
  34. char outputs;
  35. }I2C_UnitInfo;
  36.  
  37.  
  38. typedef struct _ARP {
  39. unsigned long UDID;
  40. unsigned char I2CAddress;
  41. } ARP_INFO;
  42.  
  43.  
  44. unsigned char inputBuffer[MAX_BUFFER];
  45. I2C_BufferInfo bufferInfo;
  46. //char* bufferData;
  47. //char expectedWriteSize = 0;
  48.  
  49.  
  50.  
  51.  
  52.  
  53. /****************************************************************************
  54. * Function:
  55. * static void I2C_SlaveInit(unsigned char addr)
  56. *
  57. * Description:
  58. * This routine initializes I2C in slave mode.
  59. *
  60. *
  61. * Preconditions:
  62. * None
  63. *
  64. * Parameters:
  65. * None
  66. *
  67. * Returns:
  68. * None
  69. *
  70. * Remarks:
  71. * None
  72. *
  73. ****************************************************************************/
  74. void I2C_SlaveInit(unsigned char addr){
  75. char temp;
  76. SSP1CON1bits.WCOL = 0;
  77. SSP1CON1bits.SSPOV = 0;
  78. SSP1CON1bits.SSPEN = 0;
  79. SSP1CON1bits.CKP = 1;
  80. SSP1CON1bits.SSPM3 = 0;
  81. SSP1CON1bits.SSPM2 = 1;
  82. SSP1CON1bits.SSPM1 = 1;
  83. SSP1CON1bits.SSPM0 = 0;
  84. SSP1CON2bits.GCEN = 0;
  85. SSP1CON2bits.RCEN = 0;
  86. SSP1CON2bits.RSEN = 0;
  87. SSP1CON2bits.SEN = 1;
  88. //I2C_AHEN = 1;
  89. //I2C_SDAHT = 1;
  90. SSP1CON2bits.ACKSTAT = 0;
  91. SSP1CON2bits.ACKDT = 0;
  92. SSP1CON2bits.ACKEN = 0;
  93. SSP1CON2bits.PEN = 0;
  94. SSP1ADD = addr;
  95. SSP1STATbits.SMP = 1; // Slew Rate Control Disabled (1Mhz)
  96. temp = SSP1BUF;
  97. PIR1bits.SSPIF = 0;
  98. PIE1bits.SSPIE = 1;
  99. SSP1CON1bits.SSPEN = 1; // Enable SSP
  100. }
  101.  
  102. /****************************************************************************
  103. * Function:
  104. * void I2C_SlaveInterruptRoutine(void)
  105. *
  106. * Description:
  107. * This routine should be called when an interrupt was generated to
  108. * check if it was I2C-related
  109. *
  110. *
  111. * Preconditions:
  112. * None
  113. *
  114. * Parameters:
  115. * None
  116. *
  117. * Returns:
  118. * None
  119. *
  120. * Remarks:
  121. * None
  122. *
  123. ****************************************************************************/
  124. void I2C_SlaveInterruptRoutine(void){
  125. if(PIR1bits.SSPIF && PIE1bits.SSPIE){
  126. char SSP_status = (SSP1STAT & 0b00101101); // Mask out State bits
  127. char Temp;
  128. static char Widx = 0;
  129. static char Ridx = 0;
  130. //LED_INT_B_IO = !LED_INT_B_IO;
  131. switch(SSP_status)
  132. {
  133. case 0b00001001: // I2C master write last byte was an address byte 0 0 A 0 S W 0 BF
  134. if(SSP1CON1bits.SSPOV){ // Recive overflow
  135. SSP1CON1bits.SSPOV = 0;
  136. }
  137. Temp = SSP1BUF; // Read out buffer to clear BF flag
  138. Widx = 0;
  139. break;
  140.  
  141. //case I2C_Write_Data2:
  142. case 0b00101001: // I2C master write last byte was a data byte 0 0 D 0 S W 0 BF
  143. if(SSP1CON1bits.SSPOV){ // Recive overflow
  144. SSP1CON1bits.SSPOV = 0;
  145. }
  146. if( Widx >= sizeof(I2C_BaseData)){
  147. I2C_BaseData* i2cbase = (I2C_BaseData*)&inputBuffer;
  148. if(i2cbase->size == Widx){
  149. Temp = SSP1BUF; // Read out buffer to clear BF flag
  150. }else{
  151. inputBuffer[Widx++] = SSP1BUF;
  152. }
  153. if(i2cbase->size == Widx){
  154. I2C_InputCallback(inputBuffer, Widx);
  155. }
  156. }else{
  157. inputBuffer[Widx++] = SSP1BUF;// Store data in buffer
  158. }
  159. break;
  160.  
  161. case 0b00001101: // I2C master read last byte was an address byte 0 0 A 0 S R 0 0
  162. case 0b00001100: // I2C master read last byte was an address byte 0 0 A 0 S R 0 0
  163. I2C_OutputCallback(&bufferInfo);
  164. SSP1BUF = bufferInfo.buffer[0]; // Write data to I2C
  165. Ridx = 1;
  166. break;
  167.  
  168. case 0b00101101: // I2C master read last byte was a data byte 0 0 D 0 S R 0 0
  169. case 0b00101100: // I2C master read last byte was a data byte 0 0 D 0 S R 0 0
  170. if(Ridx == bufferInfo.size){ // Prevent reading beond buffer
  171. SSP1BUF = 0; // Write dummy data to I2C
  172. }else{
  173. SSP1BUF = bufferInfo.buffer[Ridx++];// Write next data to I2C
  174. }
  175. if(SSP1CON1bits.WCOL){ // Writing while prev not
  176. SSP1CON1bits.WCOL = 0;
  177. }
  178. break;
  179.  
  180. case 0b00101000: // I2C slave reset by nack from master 0 0 D 0 S W 0 0
  181. Temp = SSP1BUF; // Read out buffer to clear BF flag
  182. break;
  183.  
  184. default:
  185. Temp = SSP1BUF; // Read out buffer to clear BF flag
  186. break;
  187. }
  188. PIR1bits.SSPIF = 0; // Clear activity flag
  189. SSP1CON1bits.CKP = 1; // Enable clock
  190. }
  191. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement