Nano100BN Series BSP  V3.03.002
The Board Support Package for Nano100BN Series
NuEdu-Basic01_I2C_EEPROM.c
Go to the documentation of this file.
1 /**************************************************************************/
12 #include <stdio.h>
13 #include "Nano100Series.h"
15 
28 /*---------------------------------------------------------------------------------------------------------*/
30 /* Definitons */
31 /*---------------------------------------------------------------------------------------------------------*/
32 #define I2C_EEPROM I2C1
33 #define I2C_EEPROM_IRQn I2C1_IRQn
34 
35 /*---------------------------------------------------------------------------------------------------------*/
36 /* Global variables */
37 /*---------------------------------------------------------------------------------------------------------*/
38 uint8_t g_u8DeviceAddr = 0x50;
39 uint8_t g_au8TxData[3];
40 uint8_t g_u8RxData;
41 uint8_t g_u8DataLen;
42 volatile uint8_t g_u8EndFlag = 0;
43 typedef void (*I2C_FUNC)(uint32_t u32Status);
44 static I2C_FUNC s_I2CHandlerFn = NULL;
46 
52 __INLINE void I2C_PIN_Init(void)
53 {
54  /* Set GPA10,11 multi-function pins for I2C1 SDA and SCL */
56 
57  /* Enable I2C1 clock */
58  CLK->APBCLK |= CLK_APBCLK_I2C1_EN;
59 
60  /* Reset I2C1 */
61  SYS->IPRST_CTL2 |= SYS_IPRST_CTL2_I2C1_RST_Msk;
62  SYS->IPRST_CTL2 &= ~SYS_IPRST_CTL2_I2C1_RST_Msk;
63 }
64 
71 void I2C1_IRQHandler(void)
72 {
73  uint32_t u32Status;
74 
75  // clear interrupt flag
76  I2C1->INTSTS = I2C_INTSTS_INTSTS_Msk;
77 
78  u32Status = I2C_EEPROM->STATUS;
79 
80  if (I2C_EEPROM->INTSTS & I2C_INTSTS_TIF_Msk)
81  {
82  /* Clear I2C Timeout Flag */
83  I2C_EEPROM->INTSTS = I2C_INTSTS_TIF_Msk;
84  }
85  else
86  {
87  if (s_I2CHandlerFn != NULL)
88  s_I2CHandlerFn(u32Status);
89  }
90 }
91 
99 void I2C_EEPROM_Init(uint8_t u8Divider)
100 {
101  I2C_PIN_Init();
102  /* Enable I2C Controller */
103  I2C_EEPROM->CON |= I2C_CON_IPEN_Msk;
104 
105  /* I2C clock divider, I2C Bus Clock = PCLK / (4*120) = 100kHz */
106  I2C_EEPROM->DIV = u8Divider;
107 
108  /* Enable I2C interrupt and set corresponding NVIC bit */
109  I2C_EEPROM->CON |= I2C_CON_INTEN_Msk;
110  NVIC_EnableIRQ(I2C_EEPROM_IRQn);
111 }
112 
121 void I2C_MasterRx(uint32_t u32Status)
122 {
123  if (u32Status == 0x08) /* START has been transmitted and prepare SLA+W */
124  {
125  I2C_EEPROM->DATA = g_u8DeviceAddr << 1; /* Write SLA+W to Register I2CDAT */
126  I2C_SET_CONTROL_REG(I2C_EEPROM, I2C_SI);
127  }
128  else if (u32Status == 0x18) /* SLA+W has been transmitted and ACK has been received */
129  {
130  I2C_EEPROM->DATA = g_au8TxData[g_u8DataLen++];
131  I2C_SET_CONTROL_REG(I2C_EEPROM, I2C_SI);
132  }
133  else if (u32Status == 0x20) /* SLA+W has been transmitted and NACK has been received */
134  {
135  I2C_SET_CONTROL_REG(I2C_EEPROM, I2C_STA | I2C_STO | I2C_SI);
136  }
137  else if (u32Status == 0x28) /* DATA has been transmitted and ACK has been received */
138  {
139  if (g_u8DataLen != 2)
140  {
141  I2C_EEPROM->DATA = g_au8TxData[g_u8DataLen++];
142  I2C_SET_CONTROL_REG(I2C_EEPROM, I2C_SI);
143  }
144  else
145  {
146  I2C_SET_CONTROL_REG(I2C_EEPROM, I2C_STA | I2C_SI);
147  }
148  }
149  else if (u32Status == 0x10) /* Repeat START has been transmitted and prepare SLA+R */
150  {
151  I2C_EEPROM->DATA = ((g_u8DeviceAddr << 1) | 0x01); /* Write SLA+R to Register I2CDAT */
152  I2C_SET_CONTROL_REG(I2C_EEPROM, I2C_SI);
153  }
154  else if (u32Status == 0x40) /* SLA+R has been transmitted and ACK has been received */
155  {
156  I2C_SET_CONTROL_REG(I2C_EEPROM, I2C_SI);
157  }
158  else if (u32Status == 0x58) /* DATA has been received and NACK has been returned */
159  {
160  g_u8RxData = I2C_EEPROM->DATA;
161  I2C_SET_CONTROL_REG(I2C_EEPROM, I2C_STO | I2C_SI);
162  g_u8EndFlag = 1;
163  }
164  else if (u32Status == 0xF8) /*I2C wave keeps going*/
165  {
166 
167  }
168  else
169  {
170  /* TO DO */
171  //printf("Status 0x%x is NOT processed\n", u32Status);
172  while(1);
173  }
174 }
175 
184 void I2C_MasterTx(uint32_t u32Status)
185 {
186  if (u32Status == 0x08) /* START has been transmitted */
187  {
188  I2C_EEPROM->DATA = g_u8DeviceAddr << 1; /* Write SLA+W to Register I2CDAT */
189  I2C_SET_CONTROL_REG(I2C_EEPROM, I2C_SI);
190  }
191  else if (u32Status == 0x18) /* SLA+W has been transmitted and ACK has been received */
192  {
193  I2C_EEPROM->DATA = g_au8TxData[g_u8DataLen++];
194  I2C_SET_CONTROL_REG(I2C_EEPROM, I2C_SI);
195  }
196  else if (u32Status == 0x20) /* SLA+W has been transmitted and NACK has been received */
197  {
198  I2C_SET_CONTROL_REG(I2C_EEPROM, I2C_STA | I2C_STO | I2C_SI);
199  }
200  else if (u32Status == 0x28) /* DATA has been transmitted and ACK has been received */
201  {
202  if (g_u8DataLen != 3)
203  {
204  I2C_EEPROM->DATA = g_au8TxData[g_u8DataLen++];
205  I2C_SET_CONTROL_REG(I2C_EEPROM, I2C_SI);
206  }
207  else
208  {
209  I2C_SET_CONTROL_REG(I2C_EEPROM, I2C_STO | I2C_SI);
210  g_u8EndFlag = 1;
211  }
212  }
213  else if (u32Status == 0xF8) /*I2C wave keeps going*/
214  {
215 
216  }
217  else
218  {
219  /* TO DO */
220  //printf("Status 0x%x is NOT processed\n", u32Status);
221  while(1);
222  }
223 }
224 
234 void I2C_EEPROM_Write(uint16_t u16Address, uint8_t u8Data)
235 {
236  g_au8TxData[0] = u16Address >> 8;
237  g_au8TxData[1] = u16Address & 0xFF;
238  g_au8TxData[2] = u8Data;
239 
240  g_u8DataLen = 0;
241  g_u8EndFlag = 0;
242 
243  /* I2C function to write data to slave */
244  s_I2CHandlerFn = (I2C_FUNC)I2C_MasterTx;
245 
246  /* I2C as master sends START signal */
247  I2C_SET_CONTROL_REG(I2C_EEPROM, I2C_STA);
248 
249  /* Wait I2C Tx Finish */
250  while (g_u8EndFlag == 0);
251 }
252 
260 uint8_t I2C_EEPROM_Read(uint16_t u16Address)
261 {
262  g_au8TxData[0] = u16Address >> 8;
263  g_au8TxData[1] = u16Address & 0xFF;
264 
265  g_u8DataLen = 0;
266  g_u8EndFlag = 0;
267 
268  /* I2C function to write data to slave */
269  s_I2CHandlerFn = (I2C_FUNC)I2C_MasterRx;
270 
271  /* I2C as master sends START signal */
272  I2C_SET_CONTROL_REG(I2C_EEPROM, I2C_STA);
273 
274  /* Wait I2C Tx Finish */
275  while (g_u8EndFlag == 0);
276 
277  return g_u8RxData;
278 }
279 
280  /* end of group Nano130_Basic01_FUNCTIONS */
282  /* end of group NuEdu-SDK-Nano130_Basic01 */
284  /* end of group NANO100_Library */
286 
287 /*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/
288 
289 
290 
void I2C1_IRQHandler(void)
I2C interrupt handler. Checks the I2C interrupt flag, clears the corresponding event flag and calls t...
#define SYS_PA_H_MFP_PA10_MFP_I2C1_SDA
Definition: sys.h:189
NuEdu-Basic01_I2C_EEPROM I2C driver header file for NuEdu-SDK-Nano130.
#define I2C1
Pointer to I2C1 register structure.
#define I2C_STO
Definition: i2c.h:34
#define I2C_INTSTS_INTSTS_Msk
void I2C_MasterRx(uint32_t u32Status)
This function checks the status of I2C, sets the related control bit and data if needed when this I2C...
#define CLK
Pointer to CLK register structure.
#define I2C_SI
Definition: i2c.h:35
#define CLK_APBCLK_I2C1_EN
Definition: clk.h:73
#define SYS_PA_H_MFP_PA11_MFP_I2C1_SCL
Definition: sys.h:181
#define I2C_STA
Definition: i2c.h:33
Nano100 series peripheral access layer header file. This file contains all the peripheral register's ...
#define NULL
NULL pointer.
void I2C_MasterTx(uint32_t u32Status)
This function checks the status of I2C, sets the related control bit and data if needed when this I2C...
#define I2C_INTSTS_TIF_Msk
#define SYS_IPRST_CTL2_I2C1_RST_Msk
__INLINE void I2C_PIN_Init(void)
Open GPIO port for I2C interface and enable this I2C controller clock and reset it.
#define I2C_CON_IPEN_Msk
#define I2C_CON_INTEN_Msk
uint8_t I2C_EEPROM_Read(uint16_t u16Address)
This function do the I2C data reading from EEPROM device.
void I2C_EEPROM_Write(uint16_t u16Address, uint8_t u8Data)
This function do the I2C data writing to EEPROM device.
void I2C_EEPROM_Init(uint8_t u8Divider)
This function initializes the I2C module, bit-rate = 100 kHz and enable the corresponding interrupt.
#define I2C_SET_CONTROL_REG(i2c, u8Ctrl)
This macro sets the I2C control register at one time.
Definition: i2c.h:55
#define SYS
Pointer to SYS register structure.