Mini51 BSP  V3.02.002
The Board Support Package for Mini51 Series
i2c_software_gpio_with_timer.c
Go to the documentation of this file.
1 /**************************************************************************/
12 #include <stdio.h>
14 
15 /* SDA = GP3.4, CLK = GP3.5 */
16 #define I2C_SW_SDA P34
17 #define I2C_SW_CLK P35
18 
19 typedef void (*TIMER_CALLBACK)(void);
20 
23 
24 uint8_t u8I2C_Buffer;
25 uint8_t* p8I2C_Data;
27 
33 uint32_t I2C_SW_I_Open(uint32_t u32BusClock)
34 {
35  /* Setup TIMER0 clock source */
36  CLK->CLKSEL1 = (CLK->CLKSEL1 & ~CLK_CLKSEL1_TMR0_S_Msk) | CLK_CLKSEL1_TMR0_S_XTAL;
37 
38  /* Enable TIMER0's clock */
39  CLK->APBCLK |= CLK_APBCLK_TMR0_EN_Msk;
40 
41  NVIC_EnableIRQ(TMR0_IRQn);
42 
43  if(u32BusClock>50000)
44  u32BusClock = 50000;
45 
46  outpw((uint32_t)&I2C_SW_STATUS,0);
47  funPtr = NULL;
48 
49  TIMER0->TCMPR = ((__IRC22M/2)/ u32BusClock)-1;
50  TIMER0->TCSR = 0x28000000;
51 
52  /* Configure P3.4 and P3.5 as open-drain mode */
54 
55  I2C_SW_SDA = 1;
56  I2C_SW_CLK = 1;
57  return 0;
58 }
59 
65 void TMR0_IRQHandler(void)
66 {
67  TIMER0->TISR |= TIMER_TISR_TIF_Msk;
68 
69  if (funPtr!=NULL)
70  {
71  (*funPtr)();
72  }
73 }
74 
82 {
83  if(I2C_SW_CLK)
84  {
85  I2C_SW_SDA = 1;
86  I2C_SW_STATUS.STOP = 1;
87  I2C_SW_STATUS.BUSY = 0;
88  funPtr = NULL;
89  }
90  else if(I2C_SW_SDA)
91  {
92  I2C_SW_SDA = 0;
93  }
94  else
95  {
96  I2C_SW_CLK = 1;
97  }
98 }
99 
106 {
107  if(I2C_SW_STATUS.COUNT<8)
108  {
109  if(I2C_SW_CLK)
110  {
112  I2C_SW_CLK = 0;
113  }
114  else
115  {
116  I2C_SW_CLK = 1;
117  }
118  }
119  else
120  {
121  if(I2C_SW_CLK)
122  {
123  I2C_SW_CLK = 0;
124  I2C_SW_SDA = 1;
126  {
128  }
129  else
130  {
131  I2C_SW_STATUS.COUNT = 0;
132  u8I2C_Buffer = 0;
133  }
134  }
135  else
136  {
139  I2C_SW_CLK = 1;
140  }
141  }
142 }
143 
150 {
151  if(I2C_SW_STATUS.COUNT<8)
152  {
153  if(I2C_SW_CLK)
154  {
155  I2C_SW_CLK = 0;
156  }
157  else
158  {
160  I2C_SW_CLK = 1;
161  }
162  }
163  else if(I2C_SW_STATUS.COUNT==8)
164  {
165  if(I2C_SW_CLK)
166  {
167  I2C_SW_CLK = 0;
168  }
169  else
170  {
171  I2C_SW_SDA = 1;
173  I2C_SW_CLK = 1;
174  }
175  }
176  else
177  {
179  if(I2C_SW_SDA)
180  {
182  }
183  else if(I2C_SW_STATUS.RW)
184  {
185  I2C_SW_STATUS.COUNT = 0;
186  u8I2C_Buffer = 0;
188  }
189  else
190  {
192  {
194  }
195  else
196  {
197  I2C_SW_STATUS.COUNT = 0;
199  }
200  }
201  I2C_SW_CLK = 0;
202  }
203 }
204 
211 {
212  if(I2C_SW_SDA)
213  {
214  I2C_SW_SDA = 0;
215  }
216  else
217  {
218  I2C_SW_CLK = 0;
219  I2C_SW_STATUS.START = 1;
221  }
222 }
223 
232 uint32_t I2C_SW_I_Send(uint8_t u8Address, uint8_t* p8Data, uint32_t u32ByteSize)
233 {
234  if(I2C_SW_STATUS.BUSY)
235  return 1;
236 
237  I2C_SW_SDA = 1;
238  I2C_SW_CLK = 1;
239 
240  u8I2C_Buffer = u8Address<<1;
241  p8I2C_Data = p8Data;
242  u32I2C_ByteSize = u32ByteSize;
244 
245  outpw((uint32_t)&I2C_SW_STATUS,0);
246  I2C_SW_STATUS.BUSY = 1;
247  I2C_SW_STATUS.RW = 0;
249 
250  TIMER0->TCSR |= TIMER_TCSR_CEN_Msk;
251 
252  return 0;
253 }
254 
261 uint32_t I2C_SW_I_IsBZ(void)
262 {
263  return I2C_SW_STATUS.BUSY;
264 }
265 
271 uint32_t I2C_SW_I_Count(void)
272 {
273  return u32I2C_ByteSizeCount;
274 }
275 
284 uint32_t I2C_SW_I_Get(uint8_t u8Address, uint8_t* p8Data, uint32_t u32ByteSize)
285 {
286  if(I2C_SW_STATUS.BUSY)
287  return 1;
288 
289  I2C_SW_SDA = 1;
290  I2C_SW_CLK = 1;
291 
292  u8I2C_Buffer = (u8Address<<1)+1;
293  p8I2C_Data = p8Data;
294  u32I2C_ByteSize = u32ByteSize;
296 
297  outpw((uint32_t)&I2C_SW_STATUS,0);
298  I2C_SW_STATUS.BUSY = 1;
299  I2C_SW_STATUS.RW = 1;
301 
302  TIMER0->TCSR |= TIMER_TCSR_CEN_Msk;
303 
304  return 0;
305 }
306 
307 
uint8_t * p8I2C_Data
void I2C_SW_I_Send_Byte(void)
Send a byte.
#define TIMER_TISR_TIF_Msk
#define I2C_SW_CLK
void(* TIMER_CALLBACK)(void)
uint32_t u32I2C_ByteSizeCount
#define TIMER_TCSR_CEN_Msk
#define P3
Pointer to GPIO port 3 register structure.
#define CLK_CLKSEL1_TMR0_S_XTAL
Definition: clk.h:72
uint8_t u8I2C_Buffer
This is the header file of i2c_software_gpio_with_timer.c.
void TMR0_IRQHandler(void)
ISR to handle TIMER0 interrupt event.
#define TIMER0
Pointer to Timer 0 register structure.
uint32_t u32I2C_ByteSize
#define CLK_APBCLK_TMR0_EN_Msk
#define outpw(port, value)
Set a 32-bit unsigned value to specified I/O port.
void I2C_SW_I_Get_Byte(void)
Read a byte.
uint32_t I2C_SW_I_Get(uint8_t u8Address, uint8_t *p8Data, uint32_t u32ByteSize)
Read data.
uint32_t I2C_SW_I_Count(void)
Return byte counter.
void I2C_SW_I_Send_Stop(void)
Send I2C STOP signal.
TIMER_CALLBACK funPtr
#define I2C_SW_SDA
void GPIO_SetMode(GPIO_T *gpio, uint32_t u32PinMask, uint32_t u32Mode)
Set GPIO operation mode.
Definition: gpio.c:40
#define NULL
NULL pointer.
#define CLK
Pointer to CLK register structure.
#define CLK_CLKSEL1_TMR0_S_Msk
void I2C_SW_I_Send_Start(void)
Send I2C START signal.
uint32_t I2C_SW_I_IsBZ(void)
Check if I2C is busy.
#define GPIO_PMD_OPEN_DRAIN
Definition: gpio.h:39
#define __IRC22M
uint32_t I2C_SW_I_Send(uint8_t u8Address, uint8_t *p8Data, uint32_t u32ByteSize)
Send data.
uint32_t I2C_SW_I_Open(uint32_t u32BusClock)
Prepare to start software I2C.
I2C_SW_FLAG_T I2C_SW_STATUS