i2c.c
Upload User: yyyd609
Upload Date: 2022-07-18
Package Size: 183k
Code Size: 17k
Development Platform:

C/C++

  1.   /******************** (C) COPYRIGHT 2003 STMicroelectronics ********************
  2. * File Name          : i2c.c
  3. * Author             : MCD Application Team
  4. * Date First Issued  : 09/05/2003
  5. * Description        : This file provides Code sources I2C functions
  6. ********************************************************************************
  7. * History:
  8. *  01/01/2004 : V1.2
  9. *  14/07/2004 : V1.3
  10. *******************************************************************************/
  11. #include "i2c.h"
  12. #include "rccu.h"
  13. /*******************************************************************************
  14. * Function Name  : I2C_Init
  15. * Description    : Initializes I2C peripheral control and registers to their
  16. *                  default reset values.
  17. * Input          : I2Cx ( I2C0 or I2C1 )
  18. * Return         : None.
  19. *******************************************************************************/
  20. void I2C_Init (I2C_TypeDef *I2Cx)
  21. {
  22.   //Initialize all the register of the specified I2C passed as parameter
  23.   I2Cx->CR=0x0;
  24.   I2Cx->CCR=0x0;
  25.   I2Cx->ECCR=0x0;
  26.   I2Cx->OAR1=0x0;
  27.   I2Cx->OAR2=0x20;
  28.   (void)I2Cx->SR1;
  29.   (void)I2Cx->SR2;
  30.   I2Cx->DR=0x0;
  31. }
  32. /*******************************************************************************
  33. * Function Name  : I2C_OnOffConfig
  34. * Description    : Enables or disables I2C peripheral.
  35. * Input          : I2Cx ( I2C0 or I2C1 )
  36. *                  condition(ENABLE or DISABLE).
  37. * Return         : None.
  38. *******************************************************************************/
  39. void I2C_OnOffConfig (I2C_TypeDef *I2Cx, FunctionalState NewState)
  40. {
  41.   if (NewState == ENABLE)
  42.     {
  43.       // Enable the I2C selected by setting twice the PE bit on the CR register
  44.       I2Cx->CR |= I2C_PESET_Mask;
  45.       I2Cx->CR |= I2C_PESET_Mask;
  46.     }
  47.   else
  48.       // Disable the I2C selected
  49.       I2Cx->CR &= ~I2C_PESET_Mask;
  50. }
  51. /*******************************************************************************
  52. * Function Name  : I2C_FlagStatus
  53. * Description    : Checks whether any I2C Flag is set or not.
  54. * Input          : I2Cx ( I2C0 or I2C1 )
  55. *                  Access(DIRECT or INDIRECT)
  56. *                  Flag : the flag to be read
  57. *                  input 4: an (u8) variable needed in the case
  58. *                                     of the INDIRECT access
  59. * Return         : the NewState of the Flag (SET or RESET).
  60. *******************************************************************************/
  61. FlagStatus I2C_FlagStatus (I2C_TypeDef *I2Cx, RegisterAccess Access, I2C_Flags Flag, ...)
  62. {
  63.   u16 Tmp;
  64.   if (Access == DIRECT)
  65.     // Store in Tmp variable the register where is located the flag
  66.     Tmp = I2C_GetStatus(I2Cx)&Flag;
  67.   else
  68.     //Get the fourth register
  69.     Tmp = ((u16)*((u32 *)&Flag + sizeof(Flag)))&Flag;
  70.   //Return the Flag NewState
  71.   return Tmp != 0 ? SET : RESET;
  72. }
  73. /*******************************************************************************
  74. * Function Name  :  I2C_FlagClear
  75. * Description    : Clears the I2C Flag passed as a parameter
  76. * Input          : I2Cx ( I2C0 or I2C1 )
  77. *                  Flag : the flag to be read
  78. *                  input3: an (u8) parameter needed in the case that the flag
  79. *                         to be cleared need a write in one register
  80. * Return         : None.
  81. *******************************************************************************/
  82. void I2C_FlagClear (I2C_TypeDef *I2Cx, I2C_Flags Flag, ...)
  83. {
  84.   u8 Tmp = (u8)*((u32 *)&Flag + sizeof(Flag));
  85.   if (Flag==I2C_ADD10 || Flag==I2C_EVF || Flag==I2C_BERR || Flag==I2C_ARLO ||
  86.       Flag==I2C_STOPF || Flag==I2C_AF  || Flag==I2C_ENDAD)
  87.   //flags that need a read of the SR2 register to be cleared
  88.   {
  89.     // Read the SR2 register
  90.     (void)I2Cx->SR2;
  91.     // Two flags need a second step to be cleared
  92.     switch (Flag)
  93.     {
  94.       case  I2C_ADD10: I2Cx->DR = Tmp; break;
  95.       case  I2C_ENDAD: I2Cx->CR|=0x20; break;
  96.     }
  97.   }
  98.   else if (Flag==I2C_SB || Flag==I2C_ADSL || Flag==I2C_BTF || Flag==I2C_TRA)
  99.   //flags that need a read of the SR1 register to be cleared
  100.   {
  101.    // Read the SR1 register
  102.     (void)I2Cx->SR1;
  103.     if (Flag==I2C_SB) I2Cx->DR=Tmp;
  104.     else if (Flag==I2C_BTF || Flag==I2C_TRA) (void)I2Cx->DR;
  105.   }
  106.   else if ( Flag==I2C_M_SL || Flag==I2C_GCAL)
  107.   //flags that need the PE bit to be cleared
  108.   {
  109.     I2C_OnOffConfig (I2Cx, DISABLE);
  110.     I2C_OnOffConfig (I2Cx, ENABLE);
  111.   }
  112. }
  113. /*******************************************************************************
  114. * Function Name  : I2C_SpeedConfig
  115. * Description    : Selects I2C clock speed and configures its corresponding mode.
  116. * Input          : I2Cx ( I2C0 or I2C1 )
  117. *                  Clock: I2C expected clock in Hertz.
  118. * Return         : None.
  119. *******************************************************************************/
  120. void I2C_SpeedConfig (I2C_TypeDef *I2Cx, u32 Clock)
  121. {
  122.   u32 FCLK;
  123.   u16 result;
  124.   // Get the FCLK frequency using the RCCU library
  125.   FCLK = RCCU_FrequencyValue ( RCCU_FCLK );
  126.   // Test on speed mode
  127.   // Update the CCR and ECCR are updated
  128.   if (Clock <=100000)
  129.   // Standard mode selected
  130.   {
  131.     result = ((FCLK/Clock)/2)-7;
  132.     //Clear FM/SM bit
  133.     I2Cx->CCR=result &0x7f;
  134.   }
  135.   else if (Clock <=400000)
  136.   {
  137.     // Fast mode selected
  138.     result = ((FCLK/Clock)/3)-9;
  139.     //set FM/SM bit
  140.     I2Cx->CCR=result |0x80;
  141.   }
  142.   I2Cx->ECCR= result >>7;
  143. }
  144. /*******************************************************************************
  145. * Function Name  : I2C_AddressConfig
  146. * Description    : Defines the I2C bus address of the interface.
  147. * Input          : I2Cx ( I2C0 or I2C1 ).
  148. *                  Address: an u16 parameter indicating the address
  149. *                           of the interface.
  150. *                  Mode (I2C_Mode10,I2C_Mode7).
  151. * Return         : None.
  152. *******************************************************************************/
  153. void I2C_AddressConfig (I2C_TypeDef *I2Cx, u16 Address, I2C_Addressing Mode)
  154. {
  155.   //Update OAR1 bit[7:1] by the lowest byte of address
  156.   I2Cx->OAR1 = (u8)Address;
  157.   if (Mode == I2C_Mode10)
  158.     //Update Add8 and add9 bits in OAR2
  159.     I2Cx->OAR2 |= (Address & 0x0300)>>7;
  160. }
  161. /*******************************************************************************
  162. * Function Name  : I2C_FCLKConfig
  163. * Description    : Configures frequency bits according to RCLK frequency.
  164. *                  the I2C selected must be disabled
  165. * Input          : I2Cx ( I2C0 or I2C1 )
  166. * Return         : None.
  167. *******************************************************************************/
  168. void I2C_FCLKConfig (I2C_TypeDef *I2Cx)
  169. {
  170.   u32 FCLK;
  171.      // Get the FCLK frequency using the RCCU library
  172.   FCLK = RCCU_FrequencyValue ( RCCU_FCLK );
  173.      // Test the value of the FCLK and affect FR0,FR1&FR2 of the OAR2 register
  174.   if (FCLK > 5000000)
  175.     {
  176.     if (FCLK <10000000)
  177.       I2Cx->OAR2 |= 0x00;
  178.     else if (FCLK <16670000)
  179.       I2Cx->OAR2 |= 0x20;
  180.     else if (FCLK < 26670000)
  181.       I2Cx->OAR2 |= 0x40;
  182.     else if (FCLK <40000000)
  183.       I2Cx->OAR2 |= 0x60;
  184.     else if (FCLK < 53330000)
  185.       I2Cx->OAR2 |= 0x80;
  186.     else if (FCLK < 66000000)
  187.       I2Cx->OAR2 |= 0xA0;
  188.     else if (FCLK <80000000)
  189.       I2Cx->OAR2 |= 0xC0;
  190.     else if (FCLK <100000000)
  191.       I2Cx->OAR2 |= 0xE0;
  192.    }
  193. }
  194. /*******************************************************************************
  195. * Function Name  : I2C_AddressSend
  196. * Description    : Transmits the address byte to select the slave device.
  197. * Input          : I2Cx ( I2C0 or I2C1 )
  198. *                  Address: an u16 parameter indicating the slave address
  199. *                  Mode (I2C_Mode10,I2C_Mode7).
  200. *                  Direction (I2C_RX,I2C_TX).
  201. * Return         : None.
  202. ********************************************************************************/
  203. void I2C_AddressSend (I2C_TypeDef *I2Cx, u16 Address, I2C_Addressing Mode, I2C_Direction Direction)
  204. {
  205.   if (Mode == I2C_Mode10 )
  206.   //10 bit addressing mode
  207.   {
  208.     // Update the DR register by generated header
  209.     I2Cx->DR = ((Address>>7)|0xf0)&0xfe;
  210.     //Wait till I2C_ADD10 flag is set
  211.     while ((I2Cx->SR1&0x40)==0);
  212.     //clear I2C_ADD10 flag
  213.     (void)I2Cx->SR2;
  214.     I2Cx->DR=(u8)Address;
  215.     //Test on the direction to define the read/write bit
  216.     if (Direction == I2C_RX)
  217.     {
  218.       //Wait till I2C_ENDAD flag is set
  219.       while ((I2Cx->SR2&0x20)==0);
  220.       I2Cx->CR|=0x20;
  221.       //Repeated START Generate
  222.       I2C_STARTGenerate (I2Cx, ENABLE);
  223.       //Test on SB flag status
  224.       while ((I2Cx->SR1&0x01)==0);
  225.       I2Cx->DR = ((Address>>7)|0xf1);
  226.     }
  227.   }
  228.   else
  229.   // 7 bit addressing mode
  230.   {
  231.     if (Direction == I2C_RX) Address|=0x01; else Address&=~0x01;
  232.     I2Cx->DR=(u8)Address;
  233.   }
  234. }
  235. /*******************************************************************************
  236. * Function Name  : I2C_ByteSend
  237. * Description    : Send a single byte of data.
  238. * Input          : I2Cx ( I2C0 or I2C1 )
  239. *                  Data : the byte to be sent to the slave
  240. * Return         : None.
  241. *******************************************************************************/
  242. void I2C_ByteSend (I2C_TypeDef *I2Cx, u8 Data)
  243. {
  244.   //Wait until the I2C_BTF bit is set
  245.   while ((I2Cx->SR1 & 0x08)==0);
  246.   //Write in the DR register the byte to be sent
  247.   I2Cx->DR = Data;
  248. }
  249. /*******************************************************************************
  250. * Function Name  : I2C_BufferSend
  251. * Description    : Send data from a buffer whose number of bytes is known
  252. * Input          : I2Cx ( I2C0 or I2C1 )
  253. *                  PtrToBuffer :pointer to the byte of buffer to be transmitted.
  254. *                  NbOfBytes:Number of byte of the buffer
  255. * Return         : I2C_Tx_Status :transmission status (I2C_TX_AF, I2C_TX_ARLO,
  256. *                  I2C_TX_BERR,I2C_TX_DATA_OK)
  257. *******************************************************************************/
  258. I2C_Tx_Status I2C_BufferSend (I2C_TypeDef *I2Cx, u8 *PtrToBuffer, u8 NbOfBytes)
  259. {
  260.   u8 Interruption_Status;
  261.   u8 SentBytes;
  262.   u8 error;
  263.   I2C_Tx_Status I2C_TXTMP;
  264.   //Test of the interrupt status
  265.   Interruption_Status=0;
  266.   Interruption_Status=I2Cx->CR & 0x01;
  267.   I2C_ITConfig (I2Cx, DISABLE);
  268.   //Wait till I2C_BTF bit is set
  269.   while ((I2Cx->SR1 & 0x08 )==0);
  270.   SentBytes=0;
  271.   while (SentBytes<NbOfBytes)
  272.   {
  273.     I2Cx->DR= *(PtrToBuffer+SentBytes);
  274.     //Wait till I2C_BTF bit is set or error detected
  275.     do
  276.       error = I2Cx->SR2 & 0x16;
  277.     while ((I2Cx->SR1 & 0x08)==0 && error==0);
  278.     // In case of error exit
  279.     if (error) break;
  280.     // increment SentBytes counter
  281.     SentBytes++;
  282.   }
  283.   if (error)
  284.   {
  285.     if (error & 0x10)
  286.       // I2C_TX_AF if Acknowledge failure is detected
  287.       I2C_TXTMP = I2C_TX_AF;
  288.     if (error & 0x02)
  289.       //I2C_TX_ARLO if the ARLO bit is set in the SR2 register
  290.       I2C_TXTMP = I2C_TX_ARLO;
  291.     if (error & 0x04)
  292.       // I2C_TX_BERR if the BERR bit is set in the SR2 register
  293.       I2C_TXTMP=  I2C_TX_BERR;
  294.   }
  295.   else
  296.     //I2C_TX_DATA_OK to show that the buffer is well sent
  297.     I2C_TXTMP= I2C_TX_DATA_OK;
  298.   //Restore the interrupt status
  299.   if (Interruption_Status==1)
  300.   I2C_ITConfig (I2Cx, ENABLE);
  301.   return I2C_TXTMP;
  302. }
  303. /*******************************************************************************
  304. * Function Name  : I2C_StringSend
  305. * Description    : Send data from a buffer
  306. * Input          : I2Cx ( I2C0 or I2C1 )
  307. *                  PtrToBuffer :pointer to the byte of string to be transmitted.
  308. * Return         : I2C_Tx_Status :transmission status (I2C_TX_AF, I2C_TX_ARLO,
  309. *                  I2C_TX_BERR,I2C_TX_DATA_OK)
  310. *******************************************************************************/
  311. I2C_Tx_Status I2C_StringSend (I2C_TypeDef *I2Cx, char *PtrToString)
  312. {
  313.   u8 NbOfBytes=0;
  314.   // count the number of byte composing the string passed as parameter.
  315.   while (*(PtrToString+NbOfBytes)!= '')
  316.     NbOfBytes++;
  317.   // call I2C_BufferSend function to execute the send part
  318.   return I2C_BufferSend (I2Cx,(u8 *)PtrToString,NbOfBytes);
  319. }
  320. /*******************************************************************************
  321. * Function Name  : I2C_TransmissionStatus
  322. * Description    : Report the NewState of the transmission
  323. * Input          : I2Cx ( I2C0 or I2C1 )
  324. * Return         : I2C_Tx_Status :transmission status (I2C_TX_NO, I2C_TX_SB,
  325. *                   I2C_TX_AF, I2C_TX_ARLO, I2C_TX_BERR,I2C_TX_ADD_OK,
  326. *                   I2C_TX_DATA_OK,I2C_TX_ONGOING)
  327. *******************************************************************************/
  328. I2C_Tx_Status I2C_TransmissionStatus (I2C_TypeDef *I2Cx)
  329. {
  330.   u8 SR1value;
  331.   u8 SR2value;
  332.   I2C_Tx_Status NewState;
  333.   SR1value = I2Cx->SR1;
  334.   SR2value = I2Cx->SR2;
  335.   if ((I2Cx->SR1&0x10)==0)
  336.     NewState=I2C_TX_NO;
  337.   else if (I2Cx->SR1&0x01)
  338.     //I2C_SB bit is set
  339.     NewState=I2C_TX_SB;
  340.   else if ((SR2value & 0x10)&&(I2Cx->CR&0x04))
  341.     //I2C_ACK &I2C_AF are both set
  342.     NewState=I2C_TX_AF;
  343.   else if (SR2value & 0x04)
  344.     //I2C_ARLO is set in multimaster mode
  345.     NewState=I2C_TX_ARLO;
  346.   else if (SR2value & 0x02)
  347.     //I2C_BERR bit is set
  348.     NewState=I2C_TX_BERR;
  349.   else if ((SR1value & 0x80)&& (I2Cx->SR2&0x20))
  350.     //I2C_EVF and I2C_ENDAD are both set
  351.     NewState=I2C_TX_ADD_OK;
  352.   else if ((I2Cx->SR1&0x20)&& (I2Cx->SR1&0x08))
  353.     //I2C_TRA and I2C_BTF are both set
  354.     NewState=I2C_TX_DATA_OK;
  355.   else
  356.     NewState=I2C_TX_ONGOING;
  357.   return NewState;
  358. }
  359. /*******************************************************************************
  360. * Function Name  : I2C_ByteReceive
  361. * Description    : Returns the received byte.
  362. * Input          : I2Cx ( I2C0 or I2C1 )
  363. * Return         : the byte received
  364. *******************************************************************************/
  365. u8 I2C_ByteReceive (I2C_TypeDef *I2Cx)
  366. {
  367.   //Wait till I2C_BTF bit is set
  368.   while ((I2Cx->SR1 & 0x08)==0);
  369.   return I2Cx->DR;
  370. }
  371. /*******************************************************************************
  372. * Function Name  : I2C_BufferReceive
  373. * Description    : received a buffer. and return the status of error.
  374. * Input          : I2Cx ( I2C0 or I2C1 )
  375. *                  PtrToBuffer :pointer to the byte of buffer received.
  376. *                  NbOfBytes:Number of byte to be received
  377. * Return         : I2C_Rx_Status:the NewState of the reception (,I2C_RX_AF,
  378. *                               I2C_RX_ARLO,I2C_RX_BERR, I2C_RX_DATA_OK)
  379. *******************************************************************************/
  380. I2C_Rx_Status I2C_BufferReceive (I2C_TypeDef *I2Cx, u8 *PtrToBuffer, u8 NbOfBytes)
  381. {
  382.   u8 Interruption_Status;
  383.   u8 ReceivedBytes;
  384.   u8 error;
  385.   I2C_Rx_Status I2C_RXTMP;
  386.   //Test of the interrupt status
  387.   Interruption_Status=0;
  388.   Interruption_Status=I2Cx->CR & 0x01;
  389.   I2C_ITConfig (I2Cx, DISABLE);
  390.   ReceivedBytes=0;
  391.   while (ReceivedBytes<NbOfBytes)
  392.   {
  393.     do
  394.       error = I2Cx->SR2 & 0x16;
  395.     while ((I2Cx->SR1 & 0x08)==0 && !error);
  396.     if (error==0)
  397.     // No error detected
  398.     {
  399.       *(PtrToBuffer+ReceivedBytes) = I2Cx->DR;
  400.       ReceivedBytes++;
  401.     }
  402.     else break;
  403.   }
  404.   if (error)
  405.   {
  406.     if (error & 0x10)
  407.       // I2C_RX_AF if Acknowledge failure is detected
  408.       I2C_RXTMP= I2C_RX_AF;
  409.     else if (error & 0x02)
  410.       // I2C_RX_ARLO if the ARLO bit is set in the SR2 register
  411.       I2C_RXTMP=  I2C_RX_ARLO;
  412.     else if (error & 0x04)
  413.       // I2C_RX_BERR if the BERR bit is set in the SR2 register
  414.       I2C_RXTMP=  I2C_RX_BERR;
  415.   }
  416.   else
  417.     //I2C_RX_DATA_OK to show that the buffer is well sent
  418.     I2C_RXTMP= I2C_RX_DATA_OK;
  419.   //Restore the interrupt status
  420.   if (Interruption_Status==1)
  421.   I2C_ITConfig (I2Cx, ENABLE);
  422.   return I2C_RXTMP;
  423. }
  424. /*******************************************************************************
  425. * Function Name  :I2C_ReceptionStatus
  426. * Description    : Report the reception NewState.
  427. * Input          : I2Cx ( I2C0 or I2C1 )
  428. * Return         : I2C_Rx_Status:the NewState of the reception ( I2C_RX_NO,
  429. *                  I2C_RX_SB,I2C_RX_AF,I2C_RX_ARLO,I2C_RX_BERR,I2C_RX_ADD_OK,
  430. *                  I2C_RX_DATA_OK, I2C_RX_ONGOING)
  431. *******************************************************************************/
  432. I2C_Rx_Status I2C_ReceptionStatus (I2C_TypeDef *I2Cx)
  433. {
  434.   u8 SR1value;
  435.   u8 SR2value;
  436.   I2C_Rx_Status NewState;
  437.   SR1value= I2Cx->SR1;
  438.   SR2value= I2Cx->SR2;
  439.   if ((I2Cx->SR1&0x10) == 0)
  440.     NewState=I2C_RX_NO;
  441.   else if (I2Cx->SR1&0x01)
  442.     //I2C_SB bit is set
  443.     NewState=I2C_RX_SB;
  444.   else if ((SR2value & 0x10) && (I2Cx->CR&0x04))
  445.     //I2C_ACK &I2C_AF are both set
  446.     NewState=I2C_RX_AF;
  447.   else if (SR2value & 0x04)
  448.     //I2C_ARLO is set
  449.     NewState=I2C_RX_ARLO;
  450.   else if (SR2value & 0x02)
  451.     //I2C_BERR bit is set
  452.     NewState=I2C_RX_BERR;
  453.   else if ((SR1value & 0x80) && (I2Cx->SR1&0x08)==0)
  454.     //2C_EVF is set & I2C_BTF is not set
  455.     NewState=I2C_RX_ADD_OK;
  456.   else if ((I2Cx->SR1&0x20)==0 && (I2Cx->SR1&0x08))
  457.     //II2C_TRA is cleared & I2C_BTF is set
  458.     NewState=I2C_RX_DATA_OK;
  459.   else
  460.   NewState=I2C_RX_ONGOING;
  461.   return NewState;
  462. }
  463. /******************* (C) COPYRIGHT 2003 STMicroelectronics *****END OF FILE****/