1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13:
14: #include <sys/machine.h>
15: #ifdef CPU_STM32L4
16:
17: #include <tk/tkernel.h>
18: #include "../../i2c.h"
19: #include "../../../include/dev_def.h"
20: #if DEV_IIC_ENABLE
21: 22: 23: 24: 25:
26:
27: 28: 29:
30: const LOCAL UW ba[DEV_I2C_UNITNM] = { I2C1_BASE, I2C2_BASE, I2C3_BASE };
31:
32: #define I2C_CR1(u) (ba[u] + I2Cx_CR1)
33: #define I2C_CR2(u) (ba[u] + I2Cx_CR2)
34: #define I2C_TIMINGR(u) (ba[u] + I2Cx_TIMINGR)
35: #define I2C_ISR(u) (ba[u] + I2Cx_ISR)
36: #define I2C_ICR(u) (ba[u] + I2Cx_ICR)
37: #define I2C_ICR(u) (ba[u] + I2Cx_ICR)
38: #define I2C_RXDR(u) (ba[u] + I2Cx_RXDR)
39: #define I2C_TXDR(u) (ba[u] + I2Cx_TXDR)
40:
41: 42: 43:
44: const LOCAL struct {
45: UINT intno;
46: PRI intpri;
47: TMO timout;
48: } ll_devdat[DEV_I2C_UNITNM] = {
49: {
50: .intno = INTNO_I2C1_EV,
51: .intpri = DEVCNF_I2C1_INTPRI,
52: .timout = DEVCNF_I2C1_TMO,
53: },
54: {
55: .intno = INTNO_I2C2_EV,
56: .intpri = DEVCNF_I2C2_INTPRI,
57: .timout = DEVCNF_I2C2_TMO,
58: },
59: {
60: .intno = INTNO_I2C3_EV,
61: .intpri = DEVCNF_I2C3_INTPRI,
62: .timout = DEVCNF_I2C3_TMO,
63: },
64: };
65:
66: 67: 68:
69: typedef struct {
70: ID wait_tskid;
71: UW state;
72: UW sadr;
73: ER ioerr;
74: UW sdat_num;
75: UW rdat_num;
76: UB *sbuf;
77: UB *rbuf;
78: } T_I2C_LLDCB;
79: LOCAL T_I2C_LLDCB ll_devcb[DEV_I2C_UNITNM];
80:
81:
82: 83: 84:
85: 86: 87:
88: LOCAL void i2c_evhdr( UINT intno )
89: {
90: T_I2C_LLDCB *p_cb;
91: UW i2c_st;
92: INT unit;
93: BOOL wup = FALSE;
94:
95: for ( unit = 0; unit < DEV_I2C_UNITNM; unit++ ) {
96: if ( ll_devdat[unit].intno == intno ) {
97: p_cb = &ll_devcb[unit];
98: break;
99: }
100: }
101: if(unit >= DEV_I2C_UNITNM) return;
102:
103: i2c_st = in_w(I2C_ISR(unit));
104: if( i2c_st & I2C_ISR_NACKF) {
105: p_cb->ioerr = E_IO;
106: wup = TRUE;
107:
108: } else if( i2c_st & I2C_ISR_TXIS) {
109: out_w(I2C_TXDR(unit),*p_cb->sbuf++);
110: if(--(p_cb->sdat_num) <= 0) {
111: if(p_cb->rdat_num == 0) {
112: out_w(I2C_CR1(unit), I2C_CR1_PE);
113: p_cb->state = I2C_STS_STOP;
114: wup = TRUE;
115: } else {
116: out_w(I2C_CR1(unit), I2C_CR1_PE | I2C_CR1_TCIE | I2C_CR1_RXIE | I2C_CR1_NACKIE | I2C_CR1_ERRIE );
117: }
118: }
119:
120: } else if( i2c_st & I2C_ISR_TC) {
121: out_w(I2C_CR1(unit), I2C_CR1_PE | I2C_CR1_RXIE | I2C_CR1_NACKIE | I2C_CR1_ERRIE );
122: p_cb->state = I2C_STS_START;
123: wup = TRUE;
124:
125: } else if( i2c_st & I2C_ISR_RXNE) {
126: *(p_cb->rbuf++) = (UB)in_w(I2C_RXDR(unit));
127: if(--(p_cb->rdat_num) <= 0) {
128: out_w(I2C_CR1(unit), I2C_CR1_PE);
129: p_cb->state = I2C_STS_STOP;
130: wup = TRUE;
131: }
132: } else {
133: out_w(I2C_CR1(unit), I2C_CR1_PE);
134: p_cb->ioerr = E_IO;
135: }
136:
137: out_w(I2C_ICR(unit), I2C_ICR_ALL);
138: ClearInt(intno);
139:
140: if(wup) {
141: if(p_cb->wait_tskid) {
142: tk_wup_tsk(p_cb->wait_tskid);
143: p_cb->wait_tskid = 0;
144: }
145: }
146: }
147:
148: 149: 150:
151: LOCAL void i2c_erhdr( UINT intno )
152: {
153: T_I2C_LLDCB *p_cb;
154: INT unit;
155:
156: intno--;
157: for ( unit = 0; unit < DEV_I2C_UNITNM; unit++ ) {
158: if ( ll_devdat[unit].intno == intno ) {
159: p_cb = &ll_devcb[unit];
160: break;
161: }
162: }
163: if(unit >= DEV_I2C_UNITNM) return;
164:
165: out_w(I2C_ICR(unit), I2C_ICR_ALL);
166: ClearInt(intno);
167:
168: out_w(I2C_CR1(unit), I2C_CR1_PE);
169:
170: p_cb->ioerr = E_IO;
171: if(p_cb->wait_tskid) {
172: tk_wup_tsk(p_cb->wait_tskid);
173: p_cb->wait_tskid = 0;
174: }
175: }
176:
177: 178: 179:
180: LOCAL ER i2c_trans(INT unit, T_I2C_LLDCB *p_cb)
181: {
182: UW i2c_ctl;
183: UINT imask;
184: ER err;
185:
186: p_cb->ioerr = E_OK;
187: p_cb->wait_tskid = 0;
188:
189:
190: out_w(I2C_CR1(unit), I2C_CR1_PE | I2C_CR1_TXIE | I2C_CR1_RXIE | I2C_CR1_NACKIE | I2C_CR1_ERRIE );
191:
192: while ((err = p_cb->ioerr) == E_OK ) {
193:
194: switch ( p_cb->state ) {
195: case I2C_STS_START:
196: DI(imask);
197: i2c_ctl = p_cb->sadr <<1;
198: if(p_cb->sdat_num > 0 ) {
199: i2c_ctl |= p_cb->sdat_num <<16 ;
200: if( p_cb->rdat_num == 0) {
201: i2c_ctl |= I2C_CR2_AUTOEND;
202: }
203: out_w(I2C_CR2(unit), i2c_ctl);
204: p_cb->state = I2C_STS_SEND;
205: } else {
206: i2c_ctl |= p_cb->rdat_num <<16 | I2C_CR2_RD_WRN | I2C_CR2_AUTOEND;
207: p_cb->state = I2C_STS_RECV;
208: out_w(I2C_CR2(unit), i2c_ctl);
209: }
210:
211: out_w(I2C_CR2(unit), i2c_ctl | I2C_CR2_START);
212: EI(imask);
213: break;
214:
215: case I2C_STS_STOP:
216: while(in_w(I2C_ISR(unit)) & I2C_ISR_BUSY) {
217: tk_dly_tsk(1);
218: }
219: break;
220: }
221: if ( p_cb->state == I2C_STS_STOP ) break;
222:
223: p_cb->wait_tskid = tk_get_tid();
224: err = tk_slp_tsk(ll_devdat[unit].timout);
225: if ( err < E_OK ) break;
226: }
227:
228: out_w(I2C_CR1(unit), 0);
229:
230: return err;
231: }
232:
233: 234: 235:
236: Inline void set_com_start(UW unit, UW sadr, UW sdat_num, UW rdat_num, UB *sbuf, UB *rbuf)
237: {
238: ll_devcb[unit].state = I2C_STS_START;
239: ll_devcb[unit].sadr = sadr;
240: ll_devcb[unit].sdat_num = sdat_num;
241: ll_devcb[unit].rdat_num = rdat_num;
242: ll_devcb[unit].sbuf = sbuf;
243: ll_devcb[unit].rbuf = rbuf;
244: }
245:
246:
247: 248: 249:
250: EXPORT W dev_i2c_llctl( UW unit, INT cmd, UW p1, UW p2, UW *pp)
251: {
252: T_I2C_EXEC *p_ex;
253: ER err = E_OK;
254:
255: switch(cmd) {
256: case LLD_I2C_OPEN:
257:
258: out_w(I2C_TIMINGR(unit), I2C_TIMINGR_INIT);
259:
260:
261: EnableInt(ll_devdat[unit].intno, ll_devdat[unit].intpri);
262: EnableInt(ll_devdat[unit].intno + 1, ll_devdat[unit].intpri);
263: break;
264:
265: case LLD_I2C_CLOSE:
266:
267: DisableInt(ll_devdat[unit].intno);
268: DisableInt(ll_devdat[unit].intno + 1);
269: break;
270:
271: case LLD_I2C_READ:
272: set_com_start( unit, p1, 0, p2, NULL, (UB*)pp);
273: err = i2c_trans(unit, &ll_devcb[unit]);
274: if(err >= E_OK) err = p1 - ll_devcb[unit].sdat_num;
275: break;
276:
277: case LLD_I2C_WRITE:
278: set_com_start( unit, p1, p2, 0, (UB*)pp, NULL);
279: err = i2c_trans(unit, &ll_devcb[unit]);
280: if(err >= E_OK) err = p1 - ll_devcb[unit].sdat_num;
281: break;
282:
283: case LLD_I2C_EXEC:
284: p_ex = (T_I2C_EXEC*)pp;
285: set_com_start( unit, p_ex->sadr, p_ex->snd_size, p_ex->rcv_size, p_ex->snd_data, p_ex->rcv_data);
286: err = i2c_trans(unit, &ll_devcb[unit]);
287: if(err >= E_OK) err = p_ex->snd_size + p_ex->rcv_size;
288: break;
289: }
290:
291: return (W)err;
292: }
293:
294: 295: 296:
297: EXPORT ER dev_i2c_llinit( T_I2C_DCB *p_dcb)
298: {
299: T_DINT dint;
300:
301: UW unit;
302: UW intno;
303: ER err;
304:
305: unit = p_dcb->unit;
306:
307: #if DEVCONF_I2C_INIT_MCLK
308: UW ccipr;
309: ccipr = in_w(RCC_CCIPR) & ~(RCC_CCIPR_I2CSEL << (unit<<1));
310: out_w(RCC_CCIPR, ccipr |(DEVCNF_I2CSEL << (12 + (unit<<1))));
311:
312: *(_UW*)RCC_APB1ENR1 |= (RCC_APB1ENR1_I2C1EN << unit);
313: #endif
314:
315:
316: intno = ll_devdat[unit].intno;
317: dint.intatr = TA_HLNG;
318: dint.inthdr = i2c_evhdr;
319:
320: err = tk_def_int(intno, &dint);
321: if(err < E_OK) return err;
322:
323: dint.inthdr = i2c_erhdr;
324: err = tk_def_int(intno + 1, &dint);
325:
326: return err;
327: }
328:
329: #endif
330: #endif