19 static uint32_t popcount(uint32_t val) {
20 using T = uint32_t (*) (uint32_t);
21 return ((T) find_function(rom_code(
'P',
'3')))(val);
24 static uint32_t reverse(uint32_t val) {
25 using T = uint32_t (*) (uint32_t);
26 return ((T) find_function(rom_code(
'R',
'3')))(val);
36 static void FORCE_INLINE connect_internal_flash() {
37 using T = void (*) ();
38 return ((T) find_function(rom_code(
'I',
'F')))();
41 static void FORCE_INLINE flash_exit_xip() {
42 using T = void (*) ();
43 return ((T) find_function(rom_code(
'E',
'X')))();
46 static void FORCE_INLINE flash_range_erase(uint32_t addr,
50 using T = void (*) (uint32_t, size_t, uint32_t, uint8_t);
51 return ((T) find_function(rom_code(
'R',
'E')))(addr, count, block_size, block_cmd);
54 static void FORCE_INLINE flash_range_program(uint32_t addr,
57 using T = void (*) (uint32_t, uint8_t *, size_t);
58 return ((T) find_function(rom_code(
'R',
'P')))(addr, data, count);
61 static void FORCE_INLINE flash_flush_cache() {
62 using T = void (*) ();
63 return ((T) find_function(rom_code(
'F',
'C')))();
66 static void FORCE_INLINE flash_enter_cmd_xip() {
67 using T = void (*) ();
68 return ((T) find_function(rom_code(
'C',
'X')))();
71 static std::array<uint8_t, 8> read_unique_id();
72 static std::array<char, 17> read_unique_id_string();
76 static constexpr uint32_t rom_code(
char c1,
char c2) {
77 return (c2 << 8) | c1;
80 static inline void * find_function(uint32_t code) {
81 using T =
void * (*)(uint16_t * table, uint32_t code);
82 auto func = (T)(_rom_header->lookup_function);
83 auto table = (uint16_t *)(_rom_header->function_table);
84 return func(table, code);
90 void (*reset_handler)();
91 void (*nmi_handler)();
92 void (*hard_fault_handler)();
95 uint16_t function_table;
97 uint16_t lookup_function;
99 static_assert(
sizeof(rom_header_t) == 26);
101 static uint8_t _tx_buffer[13];
102 static uint8_t _rx_buffer[13];
104 static uint32_t _boot2_copy[64];