HWA
Bare metal programming with style
usia_2.h
Go to the documentation of this file.
1 
2 /* This file is part of the HWA project.
3  * Copyright (c) 2012,2015 Christophe Duparquet.
4  * All rights reserved. Read LICENSE.TXT for details.
5  */
6 
35 #define hwa_configure__usia , _hwa_cfusia
36 
37 #define _hw_usia_mode_disconnected , 1
38 #define _hw_usia_mode_spi_master , 2
39 #define _hw_usia_mode_spi_slave , 3
40 #define _hw_usia_mode_twi_master , 4
41 #define _hw_usia_mode_twi_slave , 5
42 
43 #define _hw_usia_clock_software , 0
44 #define _hw_usia_clock_compare0 , 1 /* FIXME: compare or overflow? */
45 #define _hw_usia_clock_external_rising , 2
46 #define _hw_usia_clock_external_falling , 3
47 
48 /* Mandatory argument `mode`
49  */
50 #define _hwa_cfusia(o,a,k,...) \
51  do { \
52  uint8_t mode, clock ; \
53  HW_B(_hwa_cfusia_kmode_,_hw_is_mode_##k)(o,k,__VA_ARGS__,,) \
54  } while(0)
55 #define _hwa_cfusia_kmode_0(o,k,...) HW_E(HW_EM_AN(k, mode))
56 #define _hwa_cfusia_kmode_1(o,k,v,...) HW_B(_hwa_cfusia_vmode_,_hw_usia_mode_##v)(o,v,__VA_ARGS__)
57 #define _hwa_cfusia_vmode_0(o,v,...) HW_E(HW_EM_VAL(v,mode,(disconnected,spi_master,spi_slave,twi_master,twi_slave)))
58 #define _hwa_cfusia_vmode_1(o,v,k,...) \
59  mode = HW_A1(_hw_usia_mode_##v); \
60  HW_B(_hwa_cfusia_kclock_,_hw_is_clock_##k)(o,k,__VA_ARGS__)
61 
62 #define _hwa_cfusia_kclock_0(o,k,...) HW_E(HW_EM_AN(k,clock))
63 
64 /* Mandatory argument `clock`
65  */
66 #define _hwa_cfusia_kclock_1(o,k,v,...) HW_B(_hwa_cfusia_vclock_,_hw_usia_clock_##v)(o,v,__VA_ARGS__)
67 #define _hwa_cfusia_vclock_0(o,v,...) HW_E(HW_EM_VAL(v,clock,(software,compare0,external_rising,external_falling)))
68 #define _hwa_cfusia_vclock_1(o,v,...) \
69  clock = HW_A1(_hw_usia_clock_##v); \
70  _hwa_docfusia(o,mode,clock) HW_EOL(__VA_ARGS__);
71 
72 #define _hwa_docfusia( o, _mode, _clock ) \
73  if ( _mode != HW_A1(_hw_usia_mode_spi_master) \
74  && _mode != HW_A1(_hw_usia_mode_spi_slave) ) \
75  HWA_E(HW_EM_TBD(mode,_mode)); \
76  if ( _clock != HW_A1(_hw_usia_clock_software) ) \
77  HWA_E(HW_EM_TBD(clock,_clock)); \
78  _hwa_write( o, wm, 1 ); \
79  _hwa_write( o, cs, 2 ); \
80  if ( _mode == HW_A1(_hw_usia_mode_spi_master) ) { \
81  _hwa( configure, (o,ck), mode, digital_output ); \
82  _hwa( configure, (o,do), mode, digital_output ); \
83  _hwa( configure, (o,di), mode, digital_input ); \
84  _hwa_write( o, clk, 1 ); \
85  } \
86  else \
87  _hwa_write( o, clk, 0 );
88 
89 
100 #define hw_read__usia , _hw_rdusia
101 
102 /* FIXME: the datasheet advices using br instead of dr but does not tell at
103  * what moment br is valid. Reading br returns weird values...
104  */
105 #define _hw_rdusia(o,a,...) _hw_read( o, dr ) HW_EOL(__VA_ARGS__)
106 
107 
118 #define hw_write__usia , _hw_wrusia
119 
120 #define _hw_wrusia(o,a,v,...) _hw_write( o, dr, v ) HW_EOL(__VA_ARGS__)
121 
122 
134  /* FIXME: 2 types of clocking should be handled. Look at the datasheet. */
135 
136 #define hw_trigger__usia , _hw_tgusia
137 
138 #define _hw_tgusia(o,a,...) _hw_write(o,tc,1) HW_EOL(__VA_ARGS__)
139 
140 
141 
155 #define hwa_configure__usia_spimaster_swclk , _hwa_cfspimswclk
156 
157 #define _hwa_cfspimswclk(p,o,...) _hwa_docfspimswclk(o) HW_EOL(__VA_ARGS__)
158 
159 #define _hwa_docfspimswclk( o ) \
160  do { \
161  _hwa( configure, (o,ck), mode, digital_output ); \
162  _hwa( configure, (o,do), mode, digital_output ); \
163  _hwa_write( o, wm, 1 ); \
164  _hwa_write( o, cs, 2 ); \
165  _hwa_write( o, clk, 1 ); \
166  } while(0)
167 
168 
181 #define hw_read__usia_spimaster_swclk , _hw_rdspimswclk
182 
183 #define _hw_rdspimswclk(o,usio,...) _hw_read( usio, dr ) HW_EOL(__VA_ARGS__)
184 
185 
196 #define hw_write__usia_spimaster_swclk , _hw_wrspimswclk
197 
198 #define _hw_wrspimswclk(p,usin,v,...) \
199  do { \
200  _hw_write(usin, dr, v ); \
201  _hw_write(usin, ifov, 1 ); \
202  do \
203  _hw_write(usin, tc, 1); \
204  while( _hw_read(usin, ifov) == 0 ); \
205  }while(0) \
206  HW_EOL( __VA_ARGS__ )
207 
208 
209 
210 /* Configuration of USI as SPI master with counter0_overflow clock
211  */
212 #define hwa_configure_usia_spimaster_c0clk , _hwa_cfspimc0clk
213 
214 #define _hwa_docfspimc0clk( hwa, o ) \
215  do { \
216  _hwa( configure, (o,ck), mode, digital_output ); \
217  _hwa( configure, (o,do), mode, digital_output ); \
218  _hwa( configure, (o,di), mode, digital_input ); \
219  _hwa_write( o, wm, 1 ); \
220  _hwa_write( o, cs, 1 ); \
221  _hwa_write( o, clk, 0 ); \
222  } while(0)
223 
224 
225 #define hw_write_usia_spimaster_c0clk , _hw_write_usia_spimaster_c0clk
226 
227 #define _hw_write_usia_spimaster_c0clk(c,n, usin, v) \
228  _hw_write(##usin, dr, v )
229 
230 
231 #define hw_read_usia_spimaster_c0clk , _hw_read_usia
232 
233 
234 /*******************************************************************************
235  * *
236  * Context management *
237  * *
238  *******************************************************************************/
239 
240 #define _hwa_setup__usia(o,a) _hwa_setup_r( o, cr )
241 #define _hwa_init__usia(o,a) _hwa_init_r( o, cr, 0x00 )
242 #define _hwa_commit__usia(o,a) _hwa_commit_r( o, cr )