HWA
Bare metal programming with style
psb_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 
41 #define hwa_configure__psb , _hwa_cfpsb
42 
43 /* Mandatory argument `clock`
44  *
45  * A second void argument is added to the end of the list so that there are
46  * always at least 2 arguments following the last non-void argument.
47  *
48  * The `clock` value is stored in the `config` part of the context. The
49  * `commit` function handles the hardware configuration.
50  */
51 #define _hwa_cfpsb(o,a,k,...) \
52  do { HW_B(_hwa_cfpsb_kclock_,_hw_is_clock_##k)(o,k,__VA_ARGS__,) } while(0)
53 
54 #define _hwa_cfpsb_kclock_0(o,k,...) HW_E(HW_EM_AN(k,clock))
55 #define _hwa_cfpsb_kclock_1(o,k,v,...) HW_B(_hwa_cfpsb_vclock_,_hw_psb_clock_##v)(o,v,__VA_ARGS__)
56 
57 #define _hw_psb_clock_ioclk , 0
58 #define _hw_psb_clock_pll_32MHz , 1
59 #define _hw_psb_clock_pll_64MHz , 2
60 
61 #define _hwa_cfpsb_vclock_0(o,v,...) HW_E(HW_EM_VAL(v,clock,(ioclk,pll_32MHz,pll_64MHz)))
62 
63 #if HW_IS(HW_DEVICE_CLK_SRC, rc_pll_16MHz)
64 # define _hwa_cfpsb_vclock_1(o,v,...) \
65  if ( HW_A1(_hw_psb_clock_##v) == HW_A1(_hw_psb_clock_pll_32MHz) ) \
66  HWA_E(HW_EM_VAL(v,clock,(ioclk, pll_64MHz))); \
67  _hwa_write( o, pcke, HW_A1(_hw_psb_clock_##v) != HW_A1(_hw_psb_clock_ioclk) ); \
68  HW_EOL(__VA_ARGS__)
69 #else
70 # define _hwa_cfpsb_vclock_1(o,v,...) \
71  if ( HW_DEVICE_BODLEVEL==6 && HW_A1(_hw_psb_clock_##v)==HW_A1(_hw_psb_clock_pll_64MHz) ) \
72  HWA_E(HW_EM_VAL(v,clock,(ioclk, pll_32MHz))); \
73  if ( HW_A1(_hw_psb_clock_##v) == HW_A1(_hw_psb_clock_pll_32MHz) ) \
74  _hwa_write(o,lsm,1); \
75  else if ( HW_A1(_hw_psb_clock_##v) == HW_A1(_hw_psb_clock_pll_64MHz) ) \
76  _hwa_write(o,lsm,0); \
77  hwa->o.config.clock = HW_A1(_hw_psb_clock_##v); \
78  HW_EOL(__VA_ARGS__)
79 #endif
80 
81 
92 #define hw_reset__psb , _hw_psb_reset
93 #define _hw_psb_reset(o,a, ...) _hw_write(o,psr,1)
94 
95 
96 /*******************************************************************************
97  * *
98  * Context management *
99  * *
100  *******************************************************************************/
101 
102 #define _hwa_setup__psb(o,a) \
103  _hwa_setup_r( o, pllcsr ); \
104  hwa->o.config.clock = 0xFF ;
105 
106 #if HW_IS(HW_DEVICE_CLK_SRC, rc_pll_16MHz)
107 # define _hwa_init__psb(o,a) _hwa_init_r( o, pllcsr, 0x02 );
108 #else
109 # define _hwa_init__psb(o,a) _hwa_init_r( o, pllcsr, 0x00 );
110 #endif
111 
112 
113 #if HW_IS(HW_DEVICE_CLK_SRC, rc_pll_16MHz)
114 # define _hwa_commit__psb(o,a) _hwa_commit_r(o,pllcsr);
115 #else
116 # define _hwa_commit__psb(o,a) \
117  if ( hwa->o.config.clock != 0xFF ) { \
118  if ( hwa->o.config.clock == HW_A1(_hw_psb_clock_ioclk) ) \
119  _hwa_write( o, pcke, 0 ); \
120  else if ( _hwa_ovalue( o, plle ) == 0 ) { \
121  /* PLL start procedure (once started, it is never stopped). */ \
122  _hwa_write(o,plle,1); \
123  _hwa_commit_r(o,pllcsr); \
124  hw_waste_cycles(100e-6 * HW_SYSHZ); \
125  while( !_hw_read(o,plock) ) {} \
126  _hwa_write(o,pcke,1); \
127  } \
128  } \
129  _hwa_commit_r(o,pllcsr)
130 #endif