HWA
Bare metal programming with style
24cxx.h
Go to the documentation of this file.
1
2
/* This file is part of the HWA project.
3
* Copyright (c) 2020 Christophe Duparquet.
4
* All rights reserved. Read LICENSE.TXT for details.
5
*/
6
63
/* _24cxx, name, twi, sla, as, ps
64
*
65
* as: address size (larger EEPROM devices (from 24C32) have 16-bit address)
66
* ps: page size
67
*/
68
69
#define HW_24CXX(...) _HW_24CXX0(__VA_ARGS__,,,,,,,,,)
70
#define _HW_24CXX0(k1,v1,k2,v2,k3,v3,k4,v4,eol,...) \
71
HW_B(_HW_24CXX0_,_hw_is_interfaceaddressaddresssizepagesize_##k1##k2##k3##k4##eol)(k1,v1,k2,v2,k3,v3,k4,v4)
72
#define _HW_24CXX0_0(...) \
73
,HW_24CXX(...),"HW_24CXX(...)" must be defined as "HW_24CXX(interface,...,address,...,addresssize,...,pagesize,...)"
74
#define _HW_24CXX0_1(k1,twi,k2,sla,k3,as,k4,ps) _HW_24CXX1(HW_XO(twi),sla,as,ps)
75
#define _HW_24CXX1(...) _HW_24CXX2(__VA_ARGS__)
76
//#define _HW_24CXX_03(otwi,sla,as,ps) _24cxx,24cxx_##otwi,(otwi,sla,as,ps)
77
#define _HW_24CXX2(x,...) _HW_B(_HW_24CXX3_,x)(x,__VA_ARGS__)
78
#define _HW_24CXX3_1(z,o,e,...) ,o,e
79
#define _HW_24CXX3_0(c,o,d,sla,as,ps) _24cxx,24cxx_##o,(o,sla,as,ps)
80
81
#define hw_class__24cxx
82
83
#define _hw_is_interfaceaddressaddresssizepagesize_interfaceaddressaddresssizepagesize , 1
84
85
91
#define HW_DECLARE__24cxx , _hw_dc24cxx
92
93
#define _hw_dc24cxx(o,twi,sla,as,ps,...) HW_BV(_hw_dc24cxx,declare_,HW_A0(__VA_ARGS__),o)
94
#define _hw_dc24cxx0(v,o) HW_E(HW_EM_OVL(v,(weak)))
95
#define _hw_dc24cxx1(weak,o) \
96
uint8_t _hw_##o##_read_bytes ( uint8_t, uint8_t, uint16_t, int, uint8_t* ) weak ; \
97
uint8_t _hw_##o##_write_page ( uint8_t, uint8_t, uint8_t, uint16_t, int, const uint8_t* ) weak ; \
98
uint8_t _hw_##o##_write_bytes ( uint8_t, uint8_t, uint8_t, uint16_t, int, const uint8_t* ) weak ; \
99
extern uint8_t hw_foo()
100
106
#define HW_IMPLEMENT__24cxx , _hw_im24cxx
107
108
#define _hw_im24cxx(o,twi,...) \
109
_hw_im24cxx_read_bytes(twi) \
110
_hw_im24cxx_write_page(twi) \
111
_hw_im24cxx_write_bytes(twi) \
112
extern uint8_t hw_foo()
113
114
130
#define hw_read__24cxx , _hw_rd24cxx
131
132
#define _hw_rd24cxx(...) _hw_rd24cxx0(__VA_ARGS__,,,,,,)
133
134
#define _hw_rd24cxx0(o,twi,sla,as,ps,ka,va,ks,vs,kb,vb,eol,...) \
135
HW_B(_hw_rd24cxx0,_hw_is_addresssizebuffer_##ka##ks##kb##eol)(o,twi,sla,as,ka,va,ks,vs,kb,vb,eol)
136
#define _hw_rd24cxx00(o,twi,sla,as,ka,va,ks,vs,kb,vb,eol) \
137
HW_E(HW_EM_SY("hw(read,object,address,..., size,..., buffer,... )"))
138
#define _hw_rd24cxx01(o,twi,sla,as,ka,va,ks,vs,kb,vb,eol) \
139
_hw_24cxx_##twi##_read_bytes(sla,as,va,vs,(uint8_t*)vb)
140
141
142
143
#define _hw_im24cxx_read_bytes(twi) \
144
uint8_t _hw_24cxx_##twi##_read_bytes ( uint8_t sla, uint8_t as, uint16_t addr, int len, uint8_t *buf ) \
145
{ \
146
uint8_t _twst ; \
147
uint8_t _sla ; \
148
uint8_t rv = 0 ; \
149
\
150
if ( as == 2 ) \
151
_sla = sla | ((addr >> 8) & 0x07); \
152
else \
153
_sla = sla ; \
154
\
155
begin: \
156
hw( xfr_start, twi ); \
157
\
158
while( !hw(read,(twi,irq)) ) {} \
159
switch( (_twst=hw(stat,twi)) ) \
160
{ \
161
case HW_TWI_START: \
162
case HW_TWI_REP_START: \
163
break; \
164
\
165
case HW_TWI_MT_ARB_LOST: \
166
goto begin; \
167
\
168
default: \
169
goto error ; \
170
} \
171
\
172
hw( xfr_slaw, twi, _sla>>1 ); \
173
while( !hw(read,(twi,irq)) ) {} \
174
switch( (_twst=hw(stat,twi)) ) \
175
{ \
176
case HW_TWI_MT_SLA_ACK: \
177
break; \
178
\
179
case HW_TWI_MT_ARB_LOST: \
180
goto begin; \
181
\
182
default: \
183
goto error; \
184
} \
185
\
186
if ( as == 2 ) { \
187
hw( xfr_write, twi, addr >> 8 ); \
188
while( !hw(read,(twi,irq)) ) {} \
189
switch( (_twst=hw(stat,twi)) ) \
190
{ \
191
case HW_TWI_MT_DATA_ACK: \
192
break; \
193
\
194
case HW_TWI_MT_DATA_NACK: \
195
goto quit; \
196
\
197
case HW_TWI_MT_ARB_LOST: \
198
goto begin; \
199
\
200
default: \
201
goto error; \
202
} \
203
} \
204
\
205
hw( xfr_write, twi, addr & 255 ); \
206
while( !hw(read,(twi,irq)) ) {} \
207
switch( (_twst=hw(stat,twi)) ) \
208
{ \
209
case HW_TWI_MT_DATA_ACK: \
210
break; \
211
\
212
case HW_TWI_MT_DATA_NACK: \
213
goto quit; \
214
\
215
case HW_TWI_MT_ARB_LOST: \
216
goto begin; \
217
\
218
default: \
219
goto error; \
220
} \
221
\
222
hw( xfr_start, twi ); \
223
while( !hw(read,(twi,irq)) ) {} \
224
switch( (_twst=hw(stat,twi)) ) \
225
{ \
226
case HW_TWI_START: \
227
case HW_TWI_REP_START: \
228
break; \
229
\
230
case HW_TWI_MT_ARB_LOST: \
231
goto begin; \
232
\
233
default: \
234
goto error; \
235
} \
236
\
237
hw( xfr_slar, twi, sla & 127 ); \
238
while( !hw(read,(twi,irq)) ) {} \
239
switch( (_twst=hw(stat,twi)) ) \
240
{ \
241
case HW_TWI_MR_SLA_ACK: \
242
break; \
243
\
244
case HW_TWI_MR_SLA_NACK: \
245
goto quit; \
246
\
247
case HW_TWI_MR_ARB_LOST: \
248
goto begin; \
249
\
250
default: \
251
goto error; \
252
} \
253
\
254
for ( ; len>0 ; len-- ) { \
255
if (len == 1) \
256
hw( xfr_read, twi, nack ); \
257
else \
258
hw( xfr_read, twi, ack ); \
259
\
260
while( !hw(read,(twi,irq)) ) {} \
261
switch( (_twst=hw(stat,twi)) ) \
262
{ \
263
case HW_TWI_MR_DATA_NACK: \
264
len = 0; \
265
case HW_TWI_MR_DATA_ACK: \
266
*buf++ = hw(read,twi); \
267
rv++; \
268
if(_twst == HW_TWI_MR_DATA_NACK) \
269
goto quit; \
270
break; \
271
\
272
default: \
273
goto error; \
274
} \
275
} \
276
\
277
error: \
278
quit: \
279
hw( xfr_stop, twi ); \
280
return rv; \
281
}
282
283
299
#define hw_write__24cxx , _hw_wr24cxx
300
301
#define _hw_is_addresssizebuffer_addresssizebuffer , 1
302
303
#define _hw_wr24cxx(...) _hw_wr24cxx0(__VA_ARGS__,,,,,,)
304
#define _hw_wr24cxx0(o,twi,sla,as,ps,ka,va,ks,vs,kb,vb,eol,...) \
305
HW_B(_hw_wr24cxx0,_hw_is_addresssizebuffer_##ka##ks##kb##eol)(o,twi,sla,as,ps,ka,va,ks,vs,kb,vb,eol)
306
#define _hw_wr24cxx00(o,twi,sla,as,ps,ka,va,ks,vs,kb,vb,eol) \
307
HW_E(HW_EM_SY("hw(write,object,address,..., size,..., buffer,... )"))
308
#define _hw_wr24cxx01(o,twi,sla,as,ps,ka,va,ks,vs,kb,vb,eol) \
309
_hw_24cxx_##twi##_write_bytes(sla,as,ps,va,vs,(const uint8_t*)vb)
310
311
312
#define _hw_im24cxx_write_page(twi) \
313
uint8_t _hw_24cxx_##twi##_write_page ( uint8_t sla, uint8_t as, uint8_t ps, uint16_t addr, int len, const uint8_t *buf ) \
314
{ \
315
uint8_t _twst ; \
316
uint8_t _sla ; \
317
uint8_t rv = 0; \
318
uint16_t endaddr; \
319
\
320
if (addr + len <= (addr | (ps - 1))) \
321
endaddr = addr + len; \
322
else \
323
endaddr = (addr | (ps - 1)) + 1; \
324
len = endaddr - addr; \
325
\
326
if ( as == 2 ) \
327
_sla = sla | ((addr >> 8) & 0x07); \
328
else \
329
_sla = sla ; \
330
\
331
begin: \
332
hw( xfr_start, twi ); \
333
while( !hw(read,(twi,irq)) ) {} \
334
switch( (_twst=hw(stat,twi)) ) \
335
{ \
336
case HW_TWI_REP_START: \
337
case HW_TWI_START: \
338
break; \
339
\
340
case HW_TWI_MT_ARB_LOST: \
341
goto begin; \
342
\
343
default: \
344
goto error ; \
345
} \
346
\
347
hw( xfr_slaw, twi, _sla>>1 ); \
348
while( !hw(read,(twi,irq)) ) {} \
349
switch( (_twst=hw(stat,twi)) ) \
350
{ \
351
case HW_TWI_MT_SLA_ACK: \
352
break; \
353
\
354
case HW_TWI_MT_ARB_LOST: \
355
goto begin; \
356
\
357
default: \
358
goto error; \
359
} \
360
\
361
if ( as == 2 ) { \
362
hw( xfr_write, twi, addr>>8 ); \
363
while( !hw(read,(twi,irq)) ) {} \
364
switch( (_twst=hw(stat,twi)) ) \
365
{ \
366
case HW_TWI_MT_DATA_ACK: \
367
break; \
368
\
369
case HW_TWI_MT_DATA_NACK: \
370
goto quit; \
371
\
372
case HW_TWI_MT_ARB_LOST: \
373
goto begin; \
374
\
375
default: \
376
goto error; \
377
} \
378
} \
379
\
380
hw( xfr_write, twi, addr ); \
381
while( !hw(read,(twi,irq)) ) {} \
382
switch( (_twst=hw(stat,twi)) ) \
383
{ \
384
case HW_TWI_MT_DATA_ACK: \
385
break; \
386
\
387
case HW_TWI_MT_DATA_NACK: \
388
goto quit; \
389
\
390
case HW_TWI_MT_ARB_LOST: \
391
goto begin; \
392
\
393
default: \
394
goto error; \
395
} \
396
\
397
\
398
for ( ; len>0 ; len-- ) { \
399
\
400
hw( xfr_write, twi, (*buf++) ); \
401
\
402
while( !hw(read,(twi,irq)) ) {} \
403
switch( (_twst=hw(stat,twi)) ) \
404
{ \
405
case HW_TWI_MT_DATA_NACK: \
406
goto error; \
407
\
408
case HW_TWI_MT_DATA_ACK: \
409
rv++; \
410
break; \
411
\
412
default: \
413
goto error; \
414
} \
415
} \
416
\
417
error: \
418
quit: \
419
hw( xfr_stop, twi ); \
420
return rv; \
421
}
422
423
424
#define _hw_im24cxx_write_bytes(twi) \
425
uint8_t _hw_24cxx_##twi##_write_bytes ( uint8_t sla, uint8_t as, uint8_t ps, \
426
uint16_t eeaddr, int len, const uint8_t *buf) \
427
{ \
428
uint8_t rv, total; \
429
\
430
total = 0; \
431
do \
432
{ \
433
rv = _hw_24cxx_##twi##_write_page( sla, as, ps, eeaddr, len, buf); \
434
if (rv == (uint8_t)-1) \
435
return -1; \
436
\
437
eeaddr += rv; \
438
len -= rv; \
439
buf += rv; \
440
total += rv; \
441
} \
442
while (len > 0); \
443
\
444
return total; \
445
}
Generated for HWA by
1.8.6