| 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>
13 #include "i2c_software_gpio_with_timer.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
21 TIMER_CALLBACK funPtr;
22 I2C_SW_FLAG_T I2C_SW_STATUS;
23
24 uint8_t u8I2C_Buffer;
25 uint8_t* p8I2C_Data;
26 uint32_t u32I2C_ByteSize,u32I2C_ByteSizeCount;
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 */
53 GPIO_SetMode(P3, 0x30, GPIO_PMD_OPEN_DRAIN);
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
81 void I2C_SW_I_Send_Stop(void)
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
105 void I2C_SW_I_Get_Byte(void)
106 {
107 if(I2C_SW_STATUS.COUNT<8)
108 {
109 if(I2C_SW_CLK)
110 {
111 u8I2C_Buffer |= I2C_SW_SDA << (7-I2C_SW_STATUS.COUNT++);
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;
125 if(u32I2C_ByteSizeCount == u32I2C_ByteSize)
126 {
127 funPtr = I2C_SW_I_Send_Stop;
128 }
129 else
130 {
131 I2C_SW_STATUS.COUNT = 0;
132 u8I2C_Buffer = 0;
133 }
134 }
135 else
136 {
137 *(p8I2C_Data + u32I2C_ByteSizeCount++) = u8I2C_Buffer;
138 I2C_SW_SDA = (u32I2C_ByteSizeCount == u32I2C_ByteSize)?1:0;
139 I2C_SW_CLK = 1;
140 }
141 }
142 }
143
149 void I2C_SW_I_Send_Byte(void)
150 {
151 if(I2C_SW_STATUS.COUNT<8)
152 {
153 if(I2C_SW_CLK)
154 {
155 I2C_SW_CLK = 0;
156 }
157 else
158 {
159 I2C_SW_SDA = u8I2C_Buffer >> (7 - I2C_SW_STATUS.COUNT++);
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;
172 I2C_SW_STATUS.COUNT++;
173 I2C_SW_CLK = 1;
174 }
175 }
176 else
177 {
178 I2C_SW_STATUS.NACK = I2C_SW_SDA;
179 if(I2C_SW_SDA)
180 {
181 funPtr = I2C_SW_I_Send_Stop;
182 }
183 else if(I2C_SW_STATUS.RW)
184 {
185 I2C_SW_STATUS.COUNT = 0;
186 u8I2C_Buffer = 0;
187 funPtr = I2C_SW_I_Get_Byte;
188 }
189 else
190 {
191 if(u32I2C_ByteSizeCount == u32I2C_ByteSize)
192 {
193 funPtr = I2C_SW_I_Send_Stop;
194 }
195 else
196 {
197 I2C_SW_STATUS.COUNT = 0;
198 u8I2C_Buffer = *(p8I2C_Data + u32I2C_ByteSizeCount++);
199 }
200 }
201 I2C_SW_CLK = 0;
202 }
203 }
204
210 void I2C_SW_I_Send_Start(void)
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;
220 funPtr = I2C_SW_I_Send_Byte;
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;
243 u32I2C_ByteSizeCount = 0;
244
245 outpw((uint32_t)&I2C_SW_STATUS,0);
246 I2C_SW_STATUS.BUSY = 1;
247 I2C_SW_STATUS.RW = 0;
248 funPtr = I2C_SW_I_Send_Start;
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;
295 u32I2C_ByteSizeCount = 0;
296
297 outpw((uint32_t)&I2C_SW_STATUS,0);
298 I2C_SW_STATUS.BUSY = 1;
299 I2C_SW_STATUS.RW = 1;
300 funPtr = I2C_SW_I_Send_Start;
301
302 TIMER0->TCSR |= TIMER_TCSR_CEN_Msk;
303
304 return 0;
305 }
306
307
p8I2C_Data
uint8_t * p8I2C_Data
Definition: i2c_software_gpio_with_timer.c:25
I2C_SW_FLAG_T::NACK
uint32_t NACK
Definition: i2c_software_gpio_with_timer.h:20
I2C_SW_I_Send_Byte
void I2C_SW_I_Send_Byte(void)
Send a byte.
Definition: i2c_software_gpio_with_timer.c:149
TIMER_TISR_TIF_Msk
#define TIMER_TISR_TIF_Msk
Definition: Mini51Series.h:8518
I2C_SW_CLK
#define I2C_SW_CLK
Definition: i2c_software_gpio_with_timer.c:17
I2C_SW_FLAG_T::BUSY
uint32_t BUSY
Definition: i2c_software_gpio_with_timer.h:24
TIMER_CALLBACK
void(* TIMER_CALLBACK)(void)
Definition: i2c_software_gpio_with_timer.c:19
u32I2C_ByteSizeCount
uint32_t u32I2C_ByteSizeCount
Definition: i2c_software_gpio_with_timer.c:26
TIMER_TCSR_CEN_Msk
#define TIMER_TCSR_CEN_Msk
Definition: Mini51Series.h:8509
P3
#define P3
Pointer to GPIO port 3 register structure.
Definition: Mini51Series.h:9942
CLK_CLKSEL1_TMR0_S_XTAL
#define CLK_CLKSEL1_TMR0_S_XTAL
Definition: clk.h:72
u8I2C_Buffer
uint8_t u8I2C_Buffer
Definition: i2c_software_gpio_with_timer.c:24
i2c_software_gpio_with_timer.h
This is the header file of i2c_software_gpio_with_timer.c.
TMR0_IRQHandler
void TMR0_IRQHandler(void)
ISR to handle TIMER0 interrupt event.
Definition: i2c_software_gpio_with_timer.c:65
I2C_SW_FLAG_T::RW
uint32_t RW
Definition: i2c_software_gpio_with_timer.h:23
TIMER0
#define TIMER0
Pointer to Timer 0 register structure.
Definition: Mini51Series.h:9924
TMR0_IRQn
Definition: Mini51Series.h:100
u32I2C_ByteSize
uint32_t u32I2C_ByteSize
Definition: i2c_software_gpio_with_timer.c:26
CLK_APBCLK_TMR0_EN_Msk
#define CLK_APBCLK_TMR0_EN_Msk
Definition: Mini51Series.h:1523
outpw
#define outpw(port, value)
Set a 32-bit unsigned value to specified I/O port.
Definition: Mini51Series.h:9990
I2C_SW_FLAG_T
Definition: i2c_software_gpio_with_timer.h:17
I2C_SW_I_Get_Byte
void I2C_SW_I_Get_Byte(void)
Read a byte.
Definition: i2c_software_gpio_with_timer.c:105
I2C_SW_I_Get
uint32_t I2C_SW_I_Get(uint8_t u8Address, uint8_t *p8Data, uint32_t u32ByteSize)
Read data.
Definition: i2c_software_gpio_with_timer.c:284
I2C_SW_I_Count
uint32_t I2C_SW_I_Count(void)
Return byte counter.
Definition: i2c_software_gpio_with_timer.c:271
I2C_SW_I_Send_Stop
void I2C_SW_I_Send_Stop(void)
Send I2C STOP signal.
Definition: i2c_software_gpio_with_timer.c:81
funPtr
TIMER_CALLBACK funPtr
Definition: i2c_software_gpio_with_timer.c:21
I2C_SW_FLAG_T::START
uint32_t START
Definition: i2c_software_gpio_with_timer.h:21
I2C_SW_SDA
#define I2C_SW_SDA
Definition: i2c_software_gpio_with_timer.c:16
GPIO_SetMode
void GPIO_SetMode(GPIO_T *gpio, uint32_t u32PinMask, uint32_t u32Mode)
Set GPIO operation mode.
Definition: gpio.c:40
I2C_SW_FLAG_T::COUNT
uint32_t COUNT
Definition: i2c_software_gpio_with_timer.h:19
NULL
#define NULL
NULL pointer.
Definition: Mini51Series.h:10093
CLK
#define CLK
Pointer to CLK register structure.
Definition: Mini51Series.h:9937
CLK_CLKSEL1_TMR0_S_Msk
#define CLK_CLKSEL1_TMR0_S_Msk
Definition: Mini51Series.h:1595
I2C_SW_I_Send_Start
void I2C_SW_I_Send_Start(void)
Send I2C START signal.
Definition: i2c_software_gpio_with_timer.c:210
I2C_SW_I_IsBZ
uint32_t I2C_SW_I_IsBZ(void)
Check if I2C is busy.
Definition: i2c_software_gpio_with_timer.c:261
GPIO_PMD_OPEN_DRAIN
#define GPIO_PMD_OPEN_DRAIN
Definition: gpio.h:39
__IRC22M
#define __IRC22M
Definition: system_Mini51Series.h:31
I2C_SW_I_Send
uint32_t I2C_SW_I_Send(uint8_t u8Address, uint8_t *p8Data, uint32_t u32ByteSize)
Send data.
Definition: i2c_software_gpio_with_timer.c:232
I2C_SW_I_Open
uint32_t I2C_SW_I_Open(uint32_t u32BusClock)
Prepare to start software I2C.
Definition: i2c_software_gpio_with_timer.c:33
I2C_SW_STATUS
I2C_SW_FLAG_T I2C_SW_STATUS
Definition: i2c_software_gpio_with_timer.c:22
I2C_SW_FLAG_T::STOP
uint32_t STOP
Definition: i2c_software_gpio_with_timer.h:22