HWA
Bare metal programming with style
eea_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 
22 #define hw_read__eea , _hw_read_eea
23 
24 #define _hw_read_eea(o,a,addr,...) \
25  _hw_rdeeproma( HW_ADDRESS((o,ar)), \
26  HW_ADDRESS((o,re)), \
27  HW_POSITION((o,re)), \
28  HW_ADDRESS((o,dr)), \
29  addr) \
30  HW_EOL(__VA_ARGS__)
31 
32 
33 HW_INLINE uint8_t _hw_rdeeproma( intptr_t ar,
34  intptr_t cr, uint8_t cb,
35  intptr_t dr,
36  uint16_t a )
37 {
38  *(volatile uint16_t*)ar = a ;
39  *(volatile uint8_t*)cr |= (1<<cb) ;
40  return *(volatile uint8_t*) dr ;
41 }
42 
43 
55 #define hw_read_bytes__eea , _hw_eea_read_bytes
56 
57 #define _hw_eea_read_bytes(o,a,dst,src,n,...) \
58  _hw_eea_rdn( (uint8_t*)dst, (intptr_t)src, n, \
59  HW_ADDRESS((o,ar)), \
60  HW_ADDRESS((o,re)), \
61  HW_POSITION((o,re)), \
62  HW_ADDRESS((o,dr)) ) \
63  HW_EOL(__VA_ARGS__)
64 
65 
66 HW_INLINE void _hw_eea_rdn( uint8_t *dst, intptr_t src, uint8_t n,
67  intptr_t ar,
68  intptr_t cr, uint8_t cb,
69  intptr_t dr)
70 {
71  while ( n-- ) {
72  *(volatile uint16_t*)ar = src++ ;
73  *(volatile uint8_t*)cr |= (1<<cb) ;
74  *dst++ = *(volatile uint8_t*) dr ;
75  }
76 }
77 
78 
88 #define hw_write__eea , _hw_write_eea
89 
90 #define _hw_write_eea(o,a,addr,v,...) \
91  _hw_wreeproma( addr, v, \
92  HW_ADDRESS((o,ar)), \
93  HW_ADDRESS((o,dr)), \
94  HW_ADDRESS((o,mpe)), HW_POSITION((o,mpe)), \
95  HW_ADDRESS((o,pe)), HW_POSITION((o,pe)) ) \
96  HW_EOL(__VA_ARGS__)
97 
98 
99 HW_INLINE void _hw_wreeproma( uint16_t a, uint8_t v,
100  intptr_t ar,
101  intptr_t dr,
102  intptr_t mpe_ra, uint8_t mpe_bp,
103  intptr_t pe_ra, uint8_t pe_bp )
104 {
105  /* Assume EECR is 0, programming mode is 'Erase & write'
106  */
107  *(volatile uint16_t*)ar = a ;
108  *(volatile uint8_t*)dr = v ;
109  *(volatile uint8_t*)mpe_ra |= (1U<<mpe_bp) ;
110  *(volatile uint8_t*)pe_ra |= (1U<<pe_bp) ;
111 }
112 
113 
124 #define hw_write_bytes__eea , _hw_eea_write_bytes
125 
126 #define _hw_eea_write_bytes(o,a,dst,src,n,...) \
127  _hw_eea_wrn( (intptr_t)(dst), (uint8_t*)(src), n, \
128  HW_ADDRESS((o,ar)), \
129  HW_ADDRESS((o,dr)), \
130  HW_ADDRESS((o,mpe)), HW_POSITION((o,mpe)), \
131  HW_ADDRESS((o,pe)), HW_POSITION((o,pe)) ) \
132  HW_EOL(__VA_ARGS__)
133 
134 
135 HW_INLINE void _hw_eea_wrn ( intptr_t dst,
136  uint8_t *src, uint8_t n,
137  intptr_t ar,
138  intptr_t dr,
139  intptr_t mpe_ra, uint8_t mpe_bp,
140  intptr_t pe_ra, uint8_t pe_bp )
141 {
142  /* Assume EECR is 0, programming mode is 'Erase & write' */
143 
144  while ( n-- ) {
145  /*
146  * Wait for completion of previous write
147  */
148  while ( *(volatile uint8_t*)pe_ra & (1U<<pe_bp) ) {}
149  /*
150  * Write byte
151  */
152  *(volatile uint8_t*)dr = *src++ ;
153  *(volatile uint16_t*)ar = dst++ ;
154  *(volatile uint8_t*)mpe_ra |= (1U<<mpe_bp) ;
155  *(volatile uint8_t*)pe_ra |= (1U<<pe_bp) ;
156  }
157 }