22 #define hw_read__fla , _hw_read_fla
23 #define _hw_read_fla(o,a,addr,...) _hw_flardbyte((intptr_t)(addr)) HW_EOL(__VA_ARGS__)
25 HW_INLINE uint8_t _hw_flardbyte( uint16_t a )
51 #define hw_read_bytes__fla , _hw_read_bytes_fla
53 #define _hw_read_bytes_fla(o,a,dst,addr,n,...) _hw_flardbytes(dst,addr,n) HW_EOL(__VA_ARGS__)
57 HW_INLINE
void _hw_flardbytes( uint8_t *dst, uint16_t addr, uint8_t count )
59 hw_asm(
"1: lpm __tmp_reg__, Z+" "\n"
60 " st %a2+, __tmp_reg__" "\n"
68 "0" (count),
"1" (addr),
"2" (dst)
99 #define hw_load_buffer__fla , _hw_fla_load_buffer
100 #define _hw_fla_load_buffer(o,a,src,...) _hw_fla_ldpgbf(o,src) HW_EOL(__VA_ARGS__)
102 #define hw_erase_page__fla , _hw_fla_erase_page
103 #define _hw_fla_erase_page(o,a,src,...) _hw_fla_pgers(o,src) HW_EOL(__VA_ARGS__)
105 #define hw_write_page__fla , _hw_fla_write_page
106 #define _hw_fla_write_page(o,a,src,...) _hw_fla_pgwrt(o,src) HW_EOL(__VA_ARGS__)
109 #if !defined HW_DEVICE_FUSE_BOOTRST
114 #define _hw_fla_pgers(o, ptr) \
116 _hw_write( o, csr, 1<<HW_POSITION((o, pgers)) | 1<<HW_POSITION((o, spmen)) ); \
117 _hw_fla_spm( ptr ); \
120 #define _hw_fla_pgwrt(o, ptr) \
122 _hw_write( o, csr, 1<<HW_POSITION((o, pgwrt)) | 1<<HW_POSITION((o, spmen)) ); \
123 _hw_fla_spm( ptr ); \
129 HW_INLINE
void _hw_fla_spm( intptr_t ptr )
137 #define _hw_fla_ldpgbf(o, src) \
139 hw_asm("CSR = " HW_Q(HW_ADDRESS((o, csr))-0x20) "\n" \
140 "BP_RWWSRE = " HW_Q(HW_POSITION((o, rwwsre))) "\n" \
141 "BP_SPMEN = " HW_Q(HW_POSITION((o, spmen))) "\n" \
142 "PGSIZE = " HW_Q(HW_DEVICE_FLASH_PAGE_SIZE) "\n" \
144 _hw___fla_ldpgbf( src ); \
150 HW_INLINE
void _hw___fla_ldpgbf(
void *src )
154 #if HW_DEVICE_FLASH_PAGE_SIZE > 256
161 " ldi %[r1], 1<<BP_RWWSRE|1<<BP_SPMEN \n"
165 " sts CSR+0x20, %[r1] \n"
176 " sbi CSR, BP_SPMEN \n"
178 " ldi %[r1], 1<<BP_SPMEN \n"
182 " sts CSR+0x20, %[r1] \n"
188 " cpi r30, PGSIZE \n"
206 #define _hw_fla_pgers(o, ptr) \
209 _hw___fla_dospm( HW_ADDRESS((o,csr)), ptr, \
210 1<<HW_POSITION((o, pgers)) | 1<<HW_POSITION((o, spmen))); \
213 #define _hw_fla_pgwrt(o, ptr) \
216 _hw___fla_dospm( HW_ADDRESS((o,csr)), ptr, \
217 1<<HW_POSITION((o, pgwrt)) | 1<<HW_POSITION((o, spmen))); \
222 HW_INLINE
void _hw___fla_dospm( intptr_t csr, intptr_t ptr, uint8_t cmd )
224 if ( csr-0x20 < 0x20 ) {
225 hw_asm(
" out CSR, %[r1] \n"
227 "1: sbic CSR, BP_SPMEN \n"
229 " out CSR, 1<<BP_RWWSRE | 1<<BP_SPMEN \n"
231 "1: sbic CSR, BP_SPMEN \n"
237 else if ( csr-0x20 < 0x40 ) {
238 hw_asm(
" out CSR, %[r1] \n"
240 "1: in %[r1], CSR \n"
241 " sbrc %[r1], BP_SPMEN \n"
243 " out CSR, 1<<BP_RWWSRE | 1<<BP_SPMEN \n"
245 "1: in %[r1], CSR \n"
246 " sbrc %[r1], BP_SPMEN \n"
249 :
"0" (cmd),
"z" (ptr) :
253 hw_asm(
" sts CSR+0x20, %[r1] \n"
255 "1: lds %[r1], CSR+0x20 \n"
256 " sbrc %[r1], BP_SPMEN \n"
258 " out CSR, 1<<BP_RWWSRE | 1<<BP_SPMEN \n"
260 "1: lds %[r1], CSR+0x20 \n"
261 " sbrc %[r1], BP_SPMEN \n"
270 #define _hw_fla_ldpgbf(o, src) \
272 hw_asm("CSR = " HW_Q(HW_ADDRESS((o, csr))-0x20) "\n" \
273 "BP_RWWSRE = " HW_Q(HW_POSITION((o, rwwsre))) "\n" \
274 "BP_SPMEN = " HW_Q(HW_POSITION((o, spmen))) "\n" \
275 "PGSIZE = " HW_Q(HW_DEVICE_FLASH_PAGE_SIZE) "\n" \
277 _hw___fla_ldpgbf( src ); \
283 HW_INLINE
void _hw___fla_ldpgbf(
void *src )
287 #if HW_DEVICE_FLASH_PAGE_SIZE > 256
299 " sbi CSR, BP_SPMEN \n"
301 " ldi %[r1], 1<<BP_SPMEN \n"
305 " sts CSR+0x20, %[r1] \n"
311 " cpi r30, PGSIZE \n"
327 HW_INLINE
void _hw___fla_ldpgbf( intptr_t dst,
void *src )
334 " ldi %[r1], 1<<BP_RWWSRE|1<<BP_SPMEN \n"
338 " sts CSR+0x20, %[r1] \n"
348 " sbi CSR, BP_SPMEN \n"
350 " ldi %[r2], 1<<BP_SPMEN \n"
354 " sts CSR+0x20, %[r2] \n"
365 "=e" (src),
"=z" (dst)