HWA
Bare metal programming with style
swtwimaster.h
Go to the documentation of this file.
1
2
/* This file is part of the HWA project.
3
* Copyright (c) 2018 Christophe Duparquet.
4
* All rights reserved. Read LICENSE.TXT for details.
5
*/
6
7
#if !defined DOXYGEN && !defined HW_DEVICE_ARCH_AVR
8
# warning Class _swtwimaster may not be supported by your hardware
9
#endif
10
46
#define hw_class__swtwimaster
47
53
#define HW_SWTWIMASTER(...) _HW_SWTWIM_(__VA_ARGS__,,,,,,,)
54
#define _HW_SWTWIM_(k,...) HW_BW(_HW_SWTWIM_1,scl,k)(k,__VA_ARGS__)
55
#define _HW_SWTWIM_10(k,...) _HW_SWTWIM_E(k,__VA_ARGS__)
56
#define _HW_SWTWIM_11(k,...) _HW_SWTWIM_12(HW_AD(__VA_ARGS__))
/* Get SCL def */
57
#define _HW_SWTWIM_12(...) _HW_SWTWIM_13(__VA_ARGS__)
58
#define _HW_SWTWIM_13(scl,...) HW_B(_HW_SWTWIM_13,HW_A0 scl)(scl,__VA_ARGS__)
59
#define _HW_SWTWIM_131(scl,...) ,HW_SWTWIMASTER,HW_SWTWIMASTER(...): HW_A2 scl
60
#define _HW_SWTWIM_130(scl,k,...) HW_BW(_HW_SWTWIM_2,sda,k)(scl,k,__VA_ARGS__)
61
62
#define _HW_SWTWIM_20(scl,k,...) _HW_SWTWIM_E(k,__VA_ARGS__)
63
#define _HW_SWTWIM_21(scl,k,...) _HW_SWTWIM_22(scl,HW_AD(__VA_ARGS__))
/* Get SDA def */
64
#define _HW_SWTWIM_22(...) _HW_SWTWIM_23(__VA_ARGS__)
65
#define _HW_SWTWIM_23(scl,sda,...) HW_B(_HW_SWTWIM_23,HW_A0 sda)(scl,sda,__VA_ARGS__)
66
#define _HW_SWTWIM_231(scl,sda,...) ,HW_SWTWIMASTER,HW_SWTWIMASTER(...): HW_A2 sda
67
#define _HW_SWTWIM_230(scl,sda,k,...) HW_BW(_HW_SWTWIM_3,bps,k)(HW_A1 scl,scl,sda,k,__VA_ARGS__)
68
69
#define _HW_SWTWIM_30(sclo,scl,sda,k,...) _HW_SWTWIM_E(k,__VA_ARGS__)
70
#define _HW_SWTWIM_31(sclo,scl,sda,k,bps,g,...) HW_B(_HW_SWTWIM_4,g)(sclo,scl,sda,bps,g,__VA_ARGS__)
71
#define _HW_SWTWIM_40(sclo,scl,sda,bps,...) _HW_SWTWIM_E(k,__VA_ARGS__)
72
#define _HW_SWTWIM_41(sclo,scl,sda,bps,...) _swtwimaster,swtwimaster_##sclo,(-1,scl,sda,bps)
73
74
//#define _HW_SWTWIM_E(k,...) HW_E(HW_EM_SY("HW_SWTWIM(scl,..., sda,..., bps,...)" (k,__VA_ARGS__)))
75
#define _HW_SWTWIM_E(...) ,HW_SWTWIMASTER(),HW_EM_SY("HW_SWTWIMASTER(scl,..., sda,..., bps,...)")
76
77
87
#define HW_DECLARE__swtwimaster , _hw_dcswtwimaster
88
89
#define _hw_dcswtwimaster(o,a,...) HW_BV(_hw_dcswtwimaster,declare_,HW_A0(__VA_ARGS__),o)
90
#define _hw_dcswtwimaster0(v,...) HW_E(HW_EM_OVL(v,(weak)))
91
#define _hw_dcswtwimaster1(weak,o) \
92
\
93
extern uint8_t _hw_##o##__sr ; \
94
\
95
void weak _hw_##o##__delay ( ); \
96
void weak _hw_##o##_start ( ); \
97
void weak _hw_##o##_slar ( uint8_t ); \
98
void weak _hw_##o##_slaw ( uint8_t ); \
99
uint8_t weak _hw_##o##_write ( uint8_t ); \
100
uint8_t weak _hw_##o##_write ( uint8_t ); \
101
void weak _hw_##o##_stop ( ); \
102
uint8_t weak _hw_##o##_start_read_stop ( uint8_t ); \
103
void weak _hw_##o##_start_write_stop ( uint8_t, uint8_t )
104
105
115
#define HW_IMPLEMENT__swtwimaster , _hw_dfswtwimaster
116
117
#define _hw_dfswtwimaster(o,a,scl,sda,bps,...) \
118
\
119
extern void _hw_##o##__delay ( ) ; \
120
\
121
uint8_t _hw_##o##__sr ; \
122
\
123
void _hw_##o##__delay ( ) { \
124
hw_waste_cycles( HW_SYSHZ / (2*bps) - 8
/* CALL+RET */
); \
125
} \
126
\
127
void _hw_##o##_start ( ) { \
128
/* SDA goes low while SCL is high */
\
129
_hw( configure, sda, mode, digital_output ); \
130
_hw_##o##__delay(); \
131
_hw( configure, scl, mode, digital_output ); \
132
} \
133
\
134
void _hw_##o##_slar ( uint8_t sla ) { \
135
uint8_t ack = _hw_##o##_write( (sla<<1) + 1 ); \
136
if ( ack == 0 ) \
137
_hw_##o##__sr = 0x40 ;
/* HW_TWI_MR_SLA_ACK */
\
138
else \
139
_hw_##o##__sr = 0x48 ;
/* HW_TWI_MR_SLA_NACK */
\
140
} \
141
\
142
void _hw_##o##_slaw ( uint8_t sla ) { \
143
uint8_t ack = _hw_##o##_write( (sla<<1) + 0 ); \
144
if ( ack == 0 ) \
145
_hw_##o##__sr = 0x18 ;
/* HW_TWI_MT_SLA_ACK */
\
146
else \
147
_hw_##o##__sr = 0x20 ;
/* HW_TWI_MT_SLA_NACK */
\
148
} \
149
\
150
uint8_t _hw_##o##_write ( uint8_t byte ) { \
151
/* SDA can change while SCL is low */
\
152
for ( uint8_t bit=0x80 ; bit ; bit>>=1 ) { \
153
if ( (byte & bit) == 0 ) \
154
_hw( configure, sda, mode, digital_output ); \
155
else { \
156
_hw( configure, sda, mode, digital_input ); \
157
while ( !hw(read, sda) ) {} \
158
} \
159
_hw( configure, scl, mode, digital_input ); \
160
while ( !hw(read, scl) ) {}
/* The slave can extend the SCL low period */
\
161
_hw_##o##__delay(); \
162
_hw( configure, scl, mode, digital_output ) ; \
163
} \
164
_hw( configure, sda, mode, digital_input ); \
165
_hw( configure, scl, mode, digital_input ); \
166
while ( !hw(read, scl) ) {}
/* The slave can extend the SCL low period */
\
167
_hw_##o##__delay(); \
168
byte = hw(read, sda); \
169
_hw( configure, scl, mode, digital_output ) ; \
170
return byte ; \
171
} \
172
\
173
uint8_t _hw_##o##__read ( ) { \
174
/* SDA can change while SCL is low */
\
175
uint8_t data = 0 ; \
176
for ( uint8_t bit=0x80 ; bit ; bit>>=1 ) { \
177
_hw( configure, scl, mode, digital_input ); \
178
while ( !hw(read, scl) ) {}
/* The slave can extend the SCL low period */
\
179
_hw_##o##__delay(); \
180
if ( hw(read, sda) != 0 ) \
181
data |= bit ; \
182
_hw( configure, scl, mode, digital_output ) ; \
183
_hw_##o##__delay(); \
184
} \
185
return data ; \
186
} \
187
\
188
uint8_t _hw_##o##_read_ack ( ) { \
189
uint8_t data = _hw_##o##__read(); \
190
_hw( configure, sda, mode, digital_output ) ; \
191
_hw( configure, scl, mode, digital_input ); \
192
_hw_##o##__delay(); \
193
while ( !hw(read, scl) ) {}
/* The slave can extend the SCL low period */
\
194
_hw( configure, scl, mode, digital_output ) ; \
195
_hw_##o##__delay(); \
196
return data ; \
197
} \
198
\
199
uint8_t _hw_##o##_read_nack ( ) { \
200
uint8_t data = _hw_##o##__read(); \
201
_hw( configure, scl, mode, digital_input ); \
202
_hw_##o##__delay(); \
203
while ( !hw(read, scl) ) {}
/* The slave can extend the SCL low period */
\
204
_hw( configure, scl, mode, digital_output ) ; \
205
_hw( configure, sda, mode, digital_output ) ; \
206
_hw_##o##__delay(); \
207
return data ; \
208
} \
209
\
210
void _hw_##o##_stop ( ) { \
211
/* SDA goes high while SCL is high */
\
212
if ( hw(read, sda) ) \
213
_hw( configure, sda, mode, digital_output ) ; \
214
_hw( configure, scl, mode, digital_input ); \
215
_hw_##o##__delay(); \
216
_hw( configure, sda, mode, digital_input ); \
217
} \
218
\
219
void _hw_##o##_start_write_stop ( uint8_t sla, uint8_t v ) \
220
{ \
221
_hw_##o##_start(); \
222
_hw_##o##_slaw(sla); \
223
_hw_##o##_write(v); \
224
_hw_##o##_stop(); \
225
} \
226
\
227
uint8_t _hw_##o##_start_read_stop ( uint8_t sla ) \
228
{ \
229
_hw_##o##_start(); \
230
_hw_##o##_slar(sla); \
231
uint8_t v = _hw_##o##_read_nack(); \
232
_hw_##o##_stop(); \
233
return v; \
234
} \
235
\
236
extern uint8_t hw_foo()
237
238
252
#define hw_configure__swtwimaster , _hw_cfswtwimaster
253
254
/* SCL and SDA are set to 0 and then configured as digital_input /
255
* digital_output. External pullup resistors are required.
256
*/
257
#define _hw_cfswtwimaster(o,a,scl,sda,bps,...) \
258
do{ \
259
_hwa_begin_(,); \
260
_hwa( configure, scl, mode, digital_input_floating ); \
261
_hwa( configure, sda, mode, digital_input_floating ); \
262
_hwa( write, scl, 0 ); \
263
_hwa( write, sda, 0 ); \
264
_hwa_commit_(,); \
265
}while(0)
266
267
268
#define hwa_configure__swtwimaster , _hwa_cfswtwimaster
269
270
#define _hwa_cfswtwimaster(o,a,scl,sda,bps,...) \
271
do{ \
272
_hwa( configure, scl, mode, digital_input_floating ); \
273
_hwa( configure, sda, mode, digital_input_floating ); \
274
_hwa( write, scl, 0 ); \
275
_hwa( write, sda, 0 ); \
276
}while(0)
277
278
330
#define hw_xfr_start__swtwimaster , _hw_swtwimaster_start
331
#define _hw_swtwimaster_start(o,a,scl,sda,bps,...) _hw_##o##_start() HW_EOL(__VA_ARGS__)
332
333
#define hw_xfr_slar__swtwimaster , _hw_swtwimaster_slar
334
#define _hw_swtwimaster_slar(o,a,scl,sda,bps,sla,...) _hw_##o##_slar(sla) HW_EOL(__VA_ARGS__)
335
336
#define hw_xfr_slaw__swtwimaster , _hw_swtwimaster_slaw
337
#define _hw_swtwimaster_slaw(o,a,scl,sda,bps,sla,...) _hw_##o##_slaw(sla) HW_EOL(__VA_ARGS__)
338
339
#define hw_xfr_read__swtwimaster , _hw_swtwimasterrd
340
#define _hw_swtwimasterrd(o,a,k,...) HW_BW(_hw_swtwimasterrdack,ack,k)(o,k,__VA_ARGS__,,)
341
#define _hw_swtwimasterrdack1(o,k,...) _hw_##o##_read_ack() HW_EOL(__VA_ARGS__)
342
#define _hw_swtwimasterrdack0(o,k,...) HW_BW(_hw_swtwimasterrdnack,nack,k)(o,k,__VA_ARGS__)
343
#define _hw_swtwimasterrdnack1(o,ok,k,...) _hw_##o##_read_nack() HW_EOL(__VA_ARGS__)
344
#define _hw_swtwimasterrdnack0(o,k,...) HW_E(HW_EM_XNIL(k,(ack,nack)))
345
346
#define hw_xfr_write__swtwimaster , _hw_swtwimaster_write
347
#define _hw_swtwimaster_write(o,a,scl,sda,bps,data,...) _hw_##o##_write(data) HW_EOL(__VA_ARGS__)
348
349
#define hw_xfr_stop__swtwimaster , _hw_swtwimaster_stop
350
#define _hw_swtwimaster_stop(o,a,scl,sda,bps,...) _hw_##o##_stop() HW_EOL(__VA_ARGS__)
351
352
#define hw_stat__swtwimaster , _hw_swtwimaster_stat
353
#define _hw_swtwimaster_stat(o,a,scl,sda,bps,...) _hw_##o##__sr HW_EOL(__VA_ARGS__)
Generated for HWA by
1.8.6