diff options
Diffstat (limited to 'tmk_core/common/chibios')
-rw-r--r-- | tmk_core/common/chibios/bootloader.c | 63 | ||||
-rw-r--r--[-rwxr-xr-x] | tmk_core/common/chibios/eeprom_stm32.c | 142 | ||||
-rw-r--r--[-rwxr-xr-x] | tmk_core/common/chibios/eeprom_stm32.h | 64 | ||||
-rw-r--r-- | tmk_core/common/chibios/eeprom_teensy.c | 782 | ||||
-rw-r--r--[-rwxr-xr-x] | tmk_core/common/chibios/flash_stm32.c | 162 | ||||
-rw-r--r--[-rwxr-xr-x] | tmk_core/common/chibios/flash_stm32.h | 15 | ||||
-rw-r--r-- | tmk_core/common/chibios/printf.c | 277 | ||||
-rw-r--r-- | tmk_core/common/chibios/printf.h | 59 | ||||
-rw-r--r-- | tmk_core/common/chibios/sleep_led.c | 128 | ||||
-rw-r--r-- | tmk_core/common/chibios/suspend.c | 46 | ||||
-rw-r--r-- | tmk_core/common/chibios/timer.c | 46 |
11 files changed, 827 insertions, 957 deletions
diff --git a/tmk_core/common/chibios/bootloader.c b/tmk_core/common/chibios/bootloader.c index f9895237b..4cf5dae7e 100644 --- a/tmk_core/common/chibios/bootloader.c +++ b/tmk_core/common/chibios/bootloader.c | |||
@@ -7,63 +7,62 @@ | |||
7 | /* STM32 */ | 7 | /* STM32 */ |
8 | 8 | ||
9 | /* This code should be checked whether it runs correctly on platforms */ | 9 | /* This code should be checked whether it runs correctly on platforms */ |
10 | #define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0)) | 10 | # define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0)) |
11 | extern uint32_t __ram0_end__; | 11 | extern uint32_t __ram0_end__; |
12 | #define BOOTLOADER_MAGIC 0xDEADBEEF | 12 | # define BOOTLOADER_MAGIC 0xDEADBEEF |
13 | #define MAGIC_ADDR (unsigned long*)(SYMVAL(__ram0_end__) - 4) | 13 | # define MAGIC_ADDR (unsigned long *)(SYMVAL(__ram0_end__) - 4) |
14 | |||
15 | 14 | ||
16 | /** \brief Jump to the bootloader | 15 | /** \brief Jump to the bootloader |
17 | * | 16 | * |
18 | * FIXME: needs doc | 17 | * FIXME: needs doc |
19 | */ | 18 | */ |
20 | void bootloader_jump(void) { | 19 | void bootloader_jump(void) { |
21 | *MAGIC_ADDR = BOOTLOADER_MAGIC; // set magic flag => reset handler will jump into boot loader | 20 | *MAGIC_ADDR = BOOTLOADER_MAGIC; // set magic flag => reset handler will jump into boot loader |
22 | NVIC_SystemReset(); | 21 | NVIC_SystemReset(); |
23 | } | 22 | } |
24 | 23 | ||
25 | /** \brief Enter bootloader mode if requested | 24 | /** \brief Enter bootloader mode if requested |
26 | * | 25 | * |
27 | * FIXME: needs doc | 26 | * FIXME: needs doc |
28 | */ | 27 | */ |
29 | void enter_bootloader_mode_if_requested(void) { | 28 | void enter_bootloader_mode_if_requested(void) { |
30 | unsigned long* check = MAGIC_ADDR; | 29 | unsigned long *check = MAGIC_ADDR; |
31 | if(*check == BOOTLOADER_MAGIC) { | 30 | if (*check == BOOTLOADER_MAGIC) { |
32 | *check = 0; | 31 | *check = 0; |
33 | __set_CONTROL(0); | 32 | __set_CONTROL(0); |
34 | __set_MSP(*(__IO uint32_t*)STM32_BOOTLOADER_ADDRESS); | 33 | __set_MSP(*(__IO uint32_t *)STM32_BOOTLOADER_ADDRESS); |
35 | __enable_irq(); | 34 | __enable_irq(); |
36 | 35 | ||
37 | typedef void (*BootJump_t)(void); | 36 | typedef void (*BootJump_t)(void); |
38 | BootJump_t boot_jump = *(BootJump_t*)(STM32_BOOTLOADER_ADDRESS + 4); | 37 | BootJump_t boot_jump = *(BootJump_t *)(STM32_BOOTLOADER_ADDRESS + 4); |
39 | boot_jump(); | 38 | boot_jump(); |
40 | while(1); | 39 | while (1) |
41 | } | 40 | ; |
42 | } | 41 | } |
42 | } | ||
43 | 43 | ||
44 | #elif defined(KL2x) || defined(K20x) /* STM32_BOOTLOADER_ADDRESS */ | 44 | #elif defined(KL2x) || defined(K20x) /* STM32_BOOTLOADER_ADDRESS */ |
45 | /* Kinetis */ | 45 | /* Kinetis */ |
46 | 46 | ||
47 | #if defined(KIIBOHD_BOOTLOADER) | 47 | # if defined(KIIBOHD_BOOTLOADER) |
48 | /* Kiibohd Bootloader (MCHCK and Infinity KB) */ | 48 | /* Kiibohd Bootloader (MCHCK and Infinity KB) */ |
49 | #define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000 | 49 | # define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000 |
50 | const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff"; | 50 | const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff"; |
51 | void bootloader_jump(void) { | 51 | void bootloader_jump(void) { |
52 | __builtin_memcpy((void *)VBAT, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic)); | 52 | __builtin_memcpy((void *)VBAT, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic)); |
53 | // request reset | 53 | // request reset |
54 | SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk; | 54 | SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk; |
55 | } | 55 | } |
56 | 56 | ||
57 | #else /* defined(KIIBOHD_BOOTLOADER) */ | 57 | # else /* defined(KIIBOHD_BOOTLOADER) */ |
58 | /* Default for Kinetis - expecting an ARM Teensy */ | 58 | /* Default for Kinetis - expecting an ARM Teensy */ |
59 | #include "wait.h" | 59 | # include "wait.h" |
60 | void bootloader_jump(void) { | 60 | void bootloader_jump(void) { |
61 | wait_ms(100); | 61 | wait_ms(100); |
62 | __BKPT(0); | 62 | __BKPT(0); |
63 | } | 63 | } |
64 | #endif /* defined(KIIBOHD_BOOTLOADER) */ | 64 | # endif /* defined(KIIBOHD_BOOTLOADER) */ |
65 | 65 | ||
66 | #else /* neither STM32 nor KINETIS */ | 66 | #else /* neither STM32 nor KINETIS */ |
67 | __attribute__((weak)) | 67 | __attribute__((weak)) void bootloader_jump(void) {} |
68 | void bootloader_jump(void) {} | ||
69 | #endif | 68 | #endif |
diff --git a/tmk_core/common/chibios/eeprom_stm32.c b/tmk_core/common/chibios/eeprom_stm32.c index 4b1abc968..926b581c6 100755..100644 --- a/tmk_core/common/chibios/eeprom_stm32.c +++ b/tmk_core/common/chibios/eeprom_stm32.c | |||
@@ -24,7 +24,7 @@ | |||
24 | * the functionality use the EEPROM_Init() function. Be sure that by reprogramming | 24 | * the functionality use the EEPROM_Init() function. Be sure that by reprogramming |
25 | * of the controller just affected pages will be deleted. In other case the non | 25 | * of the controller just affected pages will be deleted. In other case the non |
26 | * volatile data will be lost. | 26 | * volatile data will be lost. |
27 | ******************************************************************************/ | 27 | ******************************************************************************/ |
28 | 28 | ||
29 | /* Private macro -------------------------------------------------------------*/ | 29 | /* Private macro -------------------------------------------------------------*/ |
30 | /* Private variables ---------------------------------------------------------*/ | 30 | /* Private variables ---------------------------------------------------------*/ |
@@ -32,23 +32,22 @@ | |||
32 | 32 | ||
33 | uint8_t DataBuf[FEE_PAGE_SIZE]; | 33 | uint8_t DataBuf[FEE_PAGE_SIZE]; |
34 | /***************************************************************************** | 34 | /***************************************************************************** |
35 | * Delete Flash Space used for user Data, deletes the whole space between | 35 | * Delete Flash Space used for user Data, deletes the whole space between |
36 | * RW_PAGE_BASE_ADDRESS and the last uC Flash Page | 36 | * RW_PAGE_BASE_ADDRESS and the last uC Flash Page |
37 | ******************************************************************************/ | 37 | ******************************************************************************/ |
38 | uint16_t EEPROM_Init(void) { | 38 | uint16_t EEPROM_Init(void) { |
39 | // unlock flash | 39 | // unlock flash |
40 | FLASH_Unlock(); | 40 | FLASH_Unlock(); |
41 | 41 | ||
42 | // Clear Flags | 42 | // Clear Flags |
43 | //FLASH_ClearFlag(FLASH_SR_EOP|FLASH_SR_PGERR|FLASH_SR_WRPERR); | 43 | // FLASH_ClearFlag(FLASH_SR_EOP|FLASH_SR_PGERR|FLASH_SR_WRPERR); |
44 | 44 | ||
45 | return FEE_DENSITY_BYTES; | 45 | return FEE_DENSITY_BYTES; |
46 | } | 46 | } |
47 | /***************************************************************************** | 47 | /***************************************************************************** |
48 | * Erase the whole reserved Flash Space used for user Data | 48 | * Erase the whole reserved Flash Space used for user Data |
49 | ******************************************************************************/ | 49 | ******************************************************************************/ |
50 | void EEPROM_Erase (void) { | 50 | void EEPROM_Erase(void) { |
51 | |||
52 | int page_num = 0; | 51 | int page_num = 0; |
53 | 52 | ||
54 | // delete all pages from specified start page to the last page | 53 | // delete all pages from specified start page to the last page |
@@ -58,16 +57,15 @@ void EEPROM_Erase (void) { | |||
58 | } while (page_num < FEE_DENSITY_PAGES); | 57 | } while (page_num < FEE_DENSITY_PAGES); |
59 | } | 58 | } |
60 | /***************************************************************************** | 59 | /***************************************************************************** |
61 | * Writes once data byte to flash on specified address. If a byte is already | 60 | * Writes once data byte to flash on specified address. If a byte is already |
62 | * written, the whole page must be copied to a buffer, the byte changed and | 61 | * written, the whole page must be copied to a buffer, the byte changed and |
63 | * the manipulated buffer written after PageErase. | 62 | * the manipulated buffer written after PageErase. |
64 | *******************************************************************************/ | 63 | *******************************************************************************/ |
65 | uint16_t EEPROM_WriteDataByte (uint16_t Address, uint8_t DataByte) { | 64 | uint16_t EEPROM_WriteDataByte(uint16_t Address, uint8_t DataByte) { |
66 | |||
67 | FLASH_Status FlashStatus = FLASH_COMPLETE; | 65 | FLASH_Status FlashStatus = FLASH_COMPLETE; |
68 | 66 | ||
69 | uint32_t page; | 67 | uint32_t page; |
70 | int i; | 68 | int i; |
71 | 69 | ||
72 | // exit if desired address is above the limit (e.G. under 2048 Bytes for 4 pages) | 70 | // exit if desired address is above the limit (e.G. under 2048 Bytes for 4 pages) |
73 | if (Address > FEE_DENSITY_BYTES) { | 71 | if (Address > FEE_DENSITY_BYTES) { |
@@ -78,27 +76,25 @@ uint16_t EEPROM_WriteDataByte (uint16_t Address, uint8_t DataByte) { | |||
78 | page = FEE_ADDR_OFFSET(Address) / FEE_PAGE_SIZE; | 76 | page = FEE_ADDR_OFFSET(Address) / FEE_PAGE_SIZE; |
79 | 77 | ||
80 | // if current data is 0xFF, the byte is empty, just overwrite with the new one | 78 | // if current data is 0xFF, the byte is empty, just overwrite with the new one |
81 | if ((*(__IO uint16_t*)(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address))) == FEE_EMPTY_WORD) { | 79 | if ((*(__IO uint16_t *)(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address))) == FEE_EMPTY_WORD) { |
82 | |||
83 | FlashStatus = FLASH_ProgramHalfWord(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address), (uint16_t)(0x00FF & DataByte)); | 80 | FlashStatus = FLASH_ProgramHalfWord(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address), (uint16_t)(0x00FF & DataByte)); |
84 | } else { | 81 | } else { |
85 | |||
86 | // Copy Page to a buffer | 82 | // Copy Page to a buffer |
87 | memcpy(DataBuf, (uint8_t*)FEE_PAGE_BASE_ADDRESS + (page * FEE_PAGE_SIZE), FEE_PAGE_SIZE); // !!! Calculate base address for the desired page | 83 | memcpy(DataBuf, (uint8_t *)FEE_PAGE_BASE_ADDRESS + (page * FEE_PAGE_SIZE), FEE_PAGE_SIZE); // !!! Calculate base address for the desired page |
88 | 84 | ||
89 | // check if new data is differ to current data, return if not, proceed if yes | 85 | // check if new data is differ to current data, return if not, proceed if yes |
90 | if (DataByte == *(__IO uint8_t*)(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address))) { | 86 | if (DataByte == *(__IO uint8_t *)(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address))) { |
91 | return 0; | 87 | return 0; |
92 | } | 88 | } |
93 | 89 | ||
94 | // manipulate desired data byte in temp data array if new byte is differ to the current | 90 | // manipulate desired data byte in temp data array if new byte is differ to the current |
95 | DataBuf[FEE_ADDR_OFFSET(Address) % FEE_PAGE_SIZE] = DataByte; | 91 | DataBuf[FEE_ADDR_OFFSET(Address) % FEE_PAGE_SIZE] = DataByte; |
96 | 92 | ||
97 | //Erase Page | 93 | // Erase Page |
98 | FlashStatus = FLASH_ErasePage(FEE_PAGE_BASE_ADDRESS + (page * FEE_PAGE_SIZE)); | 94 | FlashStatus = FLASH_ErasePage(FEE_PAGE_BASE_ADDRESS + (page * FEE_PAGE_SIZE)); |
99 | 95 | ||
100 | // Write new data (whole page) to flash if data has been changed | 96 | // Write new data (whole page) to flash if data has been changed |
101 | for(i = 0; i < (FEE_PAGE_SIZE / 2); i++) { | 97 | for (i = 0; i < (FEE_PAGE_SIZE / 2); i++) { |
102 | if ((__IO uint16_t)(0xFF00 | DataBuf[FEE_ADDR_OFFSET(i)]) != 0xFFFF) { | 98 | if ((__IO uint16_t)(0xFF00 | DataBuf[FEE_ADDR_OFFSET(i)]) != 0xFFFF) { |
103 | FlashStatus = FLASH_ProgramHalfWord((FEE_PAGE_BASE_ADDRESS + (page * FEE_PAGE_SIZE)) + (i * 2), (uint16_t)(0xFF00 | DataBuf[FEE_ADDR_OFFSET(i)])); | 99 | FlashStatus = FLASH_ProgramHalfWord((FEE_PAGE_BASE_ADDRESS + (page * FEE_PAGE_SIZE)) + (i * 2), (uint16_t)(0xFF00 | DataBuf[FEE_ADDR_OFFSET(i)])); |
104 | } | 100 | } |
@@ -107,98 +103,86 @@ uint16_t EEPROM_WriteDataByte (uint16_t Address, uint8_t DataByte) { | |||
107 | return FlashStatus; | 103 | return FlashStatus; |
108 | } | 104 | } |
109 | /***************************************************************************** | 105 | /***************************************************************************** |
110 | * Read once data byte from a specified address. | 106 | * Read once data byte from a specified address. |
111 | *******************************************************************************/ | 107 | *******************************************************************************/ |
112 | uint8_t EEPROM_ReadDataByte (uint16_t Address) { | 108 | uint8_t EEPROM_ReadDataByte(uint16_t Address) { |
113 | |||
114 | uint8_t DataByte = 0xFF; | 109 | uint8_t DataByte = 0xFF; |
115 | 110 | ||
116 | // Get Byte from specified address | 111 | // Get Byte from specified address |
117 | DataByte = (*(__IO uint8_t*)(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address))); | 112 | DataByte = (*(__IO uint8_t *)(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address))); |
118 | 113 | ||
119 | return DataByte; | 114 | return DataByte; |
120 | } | 115 | } |
121 | 116 | ||
122 | /***************************************************************************** | 117 | /***************************************************************************** |
123 | * Wrap library in AVR style functions. | 118 | * Wrap library in AVR style functions. |
124 | *******************************************************************************/ | 119 | *******************************************************************************/ |
125 | uint8_t eeprom_read_byte (const uint8_t *Address) | 120 | uint8_t eeprom_read_byte(const uint8_t *Address) { |
126 | { | 121 | const uint16_t p = (const uint32_t)Address; |
127 | const uint16_t p = (const uint32_t) Address; | ||
128 | return EEPROM_ReadDataByte(p); | 122 | return EEPROM_ReadDataByte(p); |
129 | } | 123 | } |
130 | 124 | ||
131 | void eeprom_write_byte (uint8_t *Address, uint8_t Value) | 125 | void eeprom_write_byte(uint8_t *Address, uint8_t Value) { |
132 | { | 126 | uint16_t p = (uint32_t)Address; |
133 | uint16_t p = (uint32_t) Address; | ||
134 | EEPROM_WriteDataByte(p, Value); | 127 | EEPROM_WriteDataByte(p, Value); |
135 | } | 128 | } |
136 | 129 | ||
137 | void eeprom_update_byte (uint8_t *Address, uint8_t Value) | 130 | void eeprom_update_byte(uint8_t *Address, uint8_t Value) { |
138 | { | 131 | uint16_t p = (uint32_t)Address; |
139 | uint16_t p = (uint32_t) Address; | ||
140 | EEPROM_WriteDataByte(p, Value); | 132 | EEPROM_WriteDataByte(p, Value); |
141 | } | 133 | } |
142 | 134 | ||
143 | uint16_t eeprom_read_word (const uint16_t *Address) | 135 | uint16_t eeprom_read_word(const uint16_t *Address) { |
144 | { | 136 | const uint16_t p = (const uint32_t)Address; |
145 | const uint16_t p = (const uint32_t) Address; | 137 | return EEPROM_ReadDataByte(p) | (EEPROM_ReadDataByte(p + 1) << 8); |
146 | return EEPROM_ReadDataByte(p) | (EEPROM_ReadDataByte(p+1) << 8); | ||
147 | } | 138 | } |
148 | 139 | ||
149 | void eeprom_write_word (uint16_t *Address, uint16_t Value) | 140 | void eeprom_write_word(uint16_t *Address, uint16_t Value) { |
150 | { | 141 | uint16_t p = (uint32_t)Address; |
151 | uint16_t p = (uint32_t) Address; | 142 | EEPROM_WriteDataByte(p, (uint8_t)Value); |
152 | EEPROM_WriteDataByte(p, (uint8_t) Value); | 143 | EEPROM_WriteDataByte(p + 1, (uint8_t)(Value >> 8)); |
153 | EEPROM_WriteDataByte(p + 1, (uint8_t) (Value >> 8)); | ||
154 | } | 144 | } |
155 | 145 | ||
156 | void eeprom_update_word (uint16_t *Address, uint16_t Value) | 146 | void eeprom_update_word(uint16_t *Address, uint16_t Value) { |
157 | { | 147 | uint16_t p = (uint32_t)Address; |
158 | uint16_t p = (uint32_t) Address; | 148 | EEPROM_WriteDataByte(p, (uint8_t)Value); |
159 | EEPROM_WriteDataByte(p, (uint8_t) Value); | 149 | EEPROM_WriteDataByte(p + 1, (uint8_t)(Value >> 8)); |
160 | EEPROM_WriteDataByte(p + 1, (uint8_t) (Value >> 8)); | ||
161 | } | 150 | } |
162 | 151 | ||
163 | uint32_t eeprom_read_dword (const uint32_t *Address) | 152 | uint32_t eeprom_read_dword(const uint32_t *Address) { |
164 | { | 153 | const uint16_t p = (const uint32_t)Address; |
165 | const uint16_t p = (const uint32_t) Address; | 154 | return EEPROM_ReadDataByte(p) | (EEPROM_ReadDataByte(p + 1) << 8) | (EEPROM_ReadDataByte(p + 2) << 16) | (EEPROM_ReadDataByte(p + 3) << 24); |
166 | return EEPROM_ReadDataByte(p) | (EEPROM_ReadDataByte(p+1) << 8) | ||
167 | | (EEPROM_ReadDataByte(p+2) << 16) | (EEPROM_ReadDataByte(p+3) << 24); | ||
168 | } | 155 | } |
169 | 156 | ||
170 | void eeprom_write_dword (uint32_t *Address, uint32_t Value) | 157 | void eeprom_write_dword(uint32_t *Address, uint32_t Value) { |
171 | { | 158 | uint16_t p = (const uint32_t)Address; |
172 | uint16_t p = (const uint32_t) Address; | 159 | EEPROM_WriteDataByte(p, (uint8_t)Value); |
173 | EEPROM_WriteDataByte(p, (uint8_t) Value); | 160 | EEPROM_WriteDataByte(p + 1, (uint8_t)(Value >> 8)); |
174 | EEPROM_WriteDataByte(p+1, (uint8_t) (Value >> 8)); | 161 | EEPROM_WriteDataByte(p + 2, (uint8_t)(Value >> 16)); |
175 | EEPROM_WriteDataByte(p+2, (uint8_t) (Value >> 16)); | 162 | EEPROM_WriteDataByte(p + 3, (uint8_t)(Value >> 24)); |
176 | EEPROM_WriteDataByte(p+3, (uint8_t) (Value >> 24)); | ||
177 | } | 163 | } |
178 | 164 | ||
179 | void eeprom_update_dword (uint32_t *Address, uint32_t Value) | 165 | void eeprom_update_dword(uint32_t *Address, uint32_t Value) { |
180 | { | 166 | uint16_t p = (const uint32_t)Address; |
181 | uint16_t p = (const uint32_t) Address; | 167 | uint32_t existingValue = EEPROM_ReadDataByte(p) | (EEPROM_ReadDataByte(p + 1) << 8) | (EEPROM_ReadDataByte(p + 2) << 16) | (EEPROM_ReadDataByte(p + 3) << 24); |
182 | uint32_t existingValue = EEPROM_ReadDataByte(p) | (EEPROM_ReadDataByte(p+1) << 8) | 168 | if (Value != existingValue) { |
183 | | (EEPROM_ReadDataByte(p+2) << 16) | (EEPROM_ReadDataByte(p+3) << 24); | 169 | EEPROM_WriteDataByte(p, (uint8_t)Value); |
184 | if(Value != existingValue){ | 170 | EEPROM_WriteDataByte(p + 1, (uint8_t)(Value >> 8)); |
185 | EEPROM_WriteDataByte(p, (uint8_t) Value); | 171 | EEPROM_WriteDataByte(p + 2, (uint8_t)(Value >> 16)); |
186 | EEPROM_WriteDataByte(p+1, (uint8_t) (Value >> 8)); | 172 | EEPROM_WriteDataByte(p + 3, (uint8_t)(Value >> 24)); |
187 | EEPROM_WriteDataByte(p+2, (uint8_t) (Value >> 16)); | ||
188 | EEPROM_WriteDataByte(p+3, (uint8_t) (Value >> 24)); | ||
189 | } | 173 | } |
190 | } | 174 | } |
191 | 175 | ||
192 | void eeprom_read_block(void *buf, const void *addr, uint32_t len) { | 176 | void eeprom_read_block(void *buf, const void *addr, uint32_t len) { |
193 | const uint8_t *p = (const uint8_t *)addr; | 177 | const uint8_t *p = (const uint8_t *)addr; |
194 | uint8_t *dest = (uint8_t *)buf; | 178 | uint8_t * dest = (uint8_t *)buf; |
195 | while (len--) { | 179 | while (len--) { |
196 | *dest++ = eeprom_read_byte(p++); | 180 | *dest++ = eeprom_read_byte(p++); |
197 | } | 181 | } |
198 | } | 182 | } |
199 | 183 | ||
200 | void eeprom_write_block(const void *buf, void *addr, uint32_t len) { | 184 | void eeprom_write_block(const void *buf, void *addr, uint32_t len) { |
201 | uint8_t *p = (uint8_t *)addr; | 185 | uint8_t * p = (uint8_t *)addr; |
202 | const uint8_t *src = (const uint8_t *)buf; | 186 | const uint8_t *src = (const uint8_t *)buf; |
203 | while (len--) { | 187 | while (len--) { |
204 | eeprom_write_byte(p++, *src++); | 188 | eeprom_write_byte(p++, *src++); |
@@ -206,7 +190,7 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) { | |||
206 | } | 190 | } |
207 | 191 | ||
208 | void eeprom_update_block(const void *buf, void *addr, uint32_t len) { | 192 | void eeprom_update_block(const void *buf, void *addr, uint32_t len) { |
209 | uint8_t *p = (uint8_t *)addr; | 193 | uint8_t * p = (uint8_t *)addr; |
210 | const uint8_t *src = (const uint8_t *)buf; | 194 | const uint8_t *src = (const uint8_t *)buf; |
211 | while (len--) { | 195 | while (len--) { |
212 | eeprom_write_byte(p++, *src++); | 196 | eeprom_write_byte(p++, *src++); |
diff --git a/tmk_core/common/chibios/eeprom_stm32.h b/tmk_core/common/chibios/eeprom_stm32.h index 083eb16ee..e68914595 100755..100644 --- a/tmk_core/common/chibios/eeprom_stm32.h +++ b/tmk_core/common/chibios/eeprom_stm32.h | |||
@@ -31,53 +31,53 @@ | |||
31 | // HACK ALERT. This definition may not match your processor | 31 | // HACK ALERT. This definition may not match your processor |
32 | // To Do. Work out correct value for EEPROM_PAGE_SIZE on the STM32F103CT6 etc | 32 | // To Do. Work out correct value for EEPROM_PAGE_SIZE on the STM32F103CT6 etc |
33 | #if defined(EEPROM_EMU_STM32F303xC) | 33 | #if defined(EEPROM_EMU_STM32F303xC) |
34 | #define MCU_STM32F303CC | 34 | # define MCU_STM32F303CC |
35 | #elif defined(EEPROM_EMU_STM32F103xB) | 35 | #elif defined(EEPROM_EMU_STM32F103xB) |
36 | #define MCU_STM32F103RB | 36 | # define MCU_STM32F103RB |
37 | #elif defined(EEPROM_EMU_STM32F072xB) | 37 | #elif defined(EEPROM_EMU_STM32F072xB) |
38 | #define MCU_STM32F072CB | 38 | # define MCU_STM32F072CB |
39 | #else | 39 | #else |
40 | #error "not implemented." | 40 | # error "not implemented." |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | #ifndef EEPROM_PAGE_SIZE | 43 | #ifndef EEPROM_PAGE_SIZE |
44 | #if defined (MCU_STM32F103RB) | 44 | # if defined(MCU_STM32F103RB) |
45 | #define FEE_PAGE_SIZE (uint16_t)0x400 // Page size = 1KByte | 45 | # define FEE_PAGE_SIZE (uint16_t)0x400 // Page size = 1KByte |
46 | #define FEE_DENSITY_PAGES 2 // How many pages are used | 46 | # define FEE_DENSITY_PAGES 2 // How many pages are used |
47 | #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE) || defined (MCU_STM32F103RD) || defined (MCU_STM32F303CC) || defined(MCU_STM32F072CB) | 47 | # elif defined(MCU_STM32F103ZE) || defined(MCU_STM32F103RE) || defined(MCU_STM32F103RD) || defined(MCU_STM32F303CC) || defined(MCU_STM32F072CB) |
48 | #define FEE_PAGE_SIZE (uint16_t)0x800 // Page size = 2KByte | 48 | # define FEE_PAGE_SIZE (uint16_t)0x800 // Page size = 2KByte |
49 | #define FEE_DENSITY_PAGES 4 // How many pages are used | 49 | # define FEE_DENSITY_PAGES 4 // How many pages are used |
50 | #else | 50 | # else |
51 | #error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)." | 51 | # error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)." |
52 | #endif | 52 | # endif |
53 | #endif | 53 | #endif |
54 | 54 | ||
55 | #ifndef EEPROM_START_ADDRESS | 55 | #ifndef EEPROM_START_ADDRESS |
56 | #if defined (MCU_STM32F103RB) || defined(MCU_STM32F072CB) | 56 | # if defined(MCU_STM32F103RB) || defined(MCU_STM32F072CB) |
57 | #define FEE_MCU_FLASH_SIZE 128 // Size in Kb | 57 | # define FEE_MCU_FLASH_SIZE 128 // Size in Kb |
58 | #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE) | 58 | # elif defined(MCU_STM32F103ZE) || defined(MCU_STM32F103RE) |
59 | #define FEE_MCU_FLASH_SIZE 512 // Size in Kb | 59 | # define FEE_MCU_FLASH_SIZE 512 // Size in Kb |
60 | #elif defined (MCU_STM32F103RD) | 60 | # elif defined(MCU_STM32F103RD) |
61 | #define FEE_MCU_FLASH_SIZE 384 // Size in Kb | 61 | # define FEE_MCU_FLASH_SIZE 384 // Size in Kb |
62 | #elif defined (MCU_STM32F303CC) | 62 | # elif defined(MCU_STM32F303CC) |
63 | #define FEE_MCU_FLASH_SIZE 256 // Size in Kb | 63 | # define FEE_MCU_FLASH_SIZE 256 // Size in Kb |
64 | #else | 64 | # else |
65 | #error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)." | 65 | # error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)." |
66 | #endif | 66 | # endif |
67 | #endif | 67 | #endif |
68 | 68 | ||
69 | // DONT CHANGE | 69 | // DONT CHANGE |
70 | // Choose location for the first EEPROM Page address on the top of flash | 70 | // Choose location for the first EEPROM Page address on the top of flash |
71 | #define FEE_PAGE_BASE_ADDRESS ((uint32_t)(0x8000000 + FEE_MCU_FLASH_SIZE * 1024 - FEE_DENSITY_PAGES * FEE_PAGE_SIZE)) | 71 | #define FEE_PAGE_BASE_ADDRESS ((uint32_t)(0x8000000 + FEE_MCU_FLASH_SIZE * 1024 - FEE_DENSITY_PAGES * FEE_PAGE_SIZE)) |
72 | #define FEE_DENSITY_BYTES ((FEE_PAGE_SIZE / 2) * FEE_DENSITY_PAGES - 1) | 72 | #define FEE_DENSITY_BYTES ((FEE_PAGE_SIZE / 2) * FEE_DENSITY_PAGES - 1) |
73 | #define FEE_LAST_PAGE_ADDRESS (FEE_PAGE_BASE_ADDRESS + (FEE_PAGE_SIZE * FEE_DENSITY_PAGES)) | 73 | #define FEE_LAST_PAGE_ADDRESS (FEE_PAGE_BASE_ADDRESS + (FEE_PAGE_SIZE * FEE_DENSITY_PAGES)) |
74 | #define FEE_EMPTY_WORD ((uint16_t)0xFFFF) | 74 | #define FEE_EMPTY_WORD ((uint16_t)0xFFFF) |
75 | #define FEE_ADDR_OFFSET(Address)(Address * 2) // 1Byte per Word will be saved to preserve Flash | 75 | #define FEE_ADDR_OFFSET(Address) (Address * 2) // 1Byte per Word will be saved to preserve Flash |
76 | 76 | ||
77 | // Use this function to initialize the functionality | 77 | // Use this function to initialize the functionality |
78 | uint16_t EEPROM_Init(void); | 78 | uint16_t EEPROM_Init(void); |
79 | void EEPROM_Erase (void); | 79 | void EEPROM_Erase(void); |
80 | uint16_t EEPROM_WriteDataByte (uint16_t Address, uint8_t DataByte); | 80 | uint16_t EEPROM_WriteDataByte(uint16_t Address, uint8_t DataByte); |
81 | uint8_t EEPROM_ReadDataByte (uint16_t Address); | 81 | uint8_t EEPROM_ReadDataByte(uint16_t Address); |
82 | 82 | ||
83 | #endif /* __EEPROM_H */ | 83 | #endif /* __EEPROM_H */ |
diff --git a/tmk_core/common/chibios/eeprom_teensy.c b/tmk_core/common/chibios/eeprom_teensy.c index 9061b790c..a4093fb3b 100644 --- a/tmk_core/common/chibios/eeprom_teensy.c +++ b/tmk_core/common/chibios/eeprom_teensy.c | |||
@@ -21,10 +21,10 @@ | |||
21 | * permit persons to whom the Software is furnished to do so, subject to | 21 | * permit persons to whom the Software is furnished to do so, subject to |
22 | * the following conditions: | 22 | * the following conditions: |
23 | * | 23 | * |
24 | * 1. The above copyright notice and this permission notice shall be | 24 | * 1. The above copyright notice and this permission notice shall be |
25 | * included in all copies or substantial portions of the Software. | 25 | * included in all copies or substantial portions of the Software. |
26 | * | 26 | * |
27 | * 2. If the Software is incorporated into a build system that allows | 27 | * 2. If the Software is incorporated into a build system that allows |
28 | * selection among a list of target devices, then similar target | 28 | * selection among a list of target devices, then similar target |
29 | * devices manufactured by PJRC.COM must be included in the list of | 29 | * devices manufactured by PJRC.COM must be included in the list of |
30 | * target devices and selectable in the same manner. | 30 | * target devices and selectable in the same manner. |
@@ -39,7 +39,6 @@ | |||
39 | * SOFTWARE. | 39 | * SOFTWARE. |
40 | */ | 40 | */ |
41 | 41 | ||
42 | |||
43 | #if defined(K20x) /* chip selection */ | 42 | #if defined(K20x) /* chip selection */ |
44 | /* Teensy 3.0, 3.1, 3.2; mchck; infinity keyboard */ | 43 | /* Teensy 3.0, 3.1, 3.2; mchck; infinity keyboard */ |
45 | 44 | ||
@@ -51,7 +50,7 @@ | |||
51 | // (aligned to 2 or 4 byte boundaries) has twice the endurance | 50 | // (aligned to 2 or 4 byte boundaries) has twice the endurance |
52 | // compared to writing 8 bit bytes. | 51 | // compared to writing 8 bit bytes. |
53 | // | 52 | // |
54 | #define EEPROM_SIZE 32 | 53 | # define EEPROM_SIZE 32 |
55 | 54 | ||
56 | // Writing unaligned 16 or 32 bit data is handled automatically when | 55 | // Writing unaligned 16 or 32 bit data is handled automatically when |
57 | // this is defined, but at a cost of extra code size. Without this, | 56 | // this is defined, but at a cost of extra code size. Without this, |
@@ -59,286 +58,271 @@ | |||
59 | // absolutely sure all 16 and 32 bit writes will be aligned, you can | 58 | // absolutely sure all 16 and 32 bit writes will be aligned, you can |
60 | // remove the extra unnecessary code. | 59 | // remove the extra unnecessary code. |
61 | // | 60 | // |
62 | #define HANDLE_UNALIGNED_WRITES | 61 | # define HANDLE_UNALIGNED_WRITES |
63 | 62 | ||
64 | // Minimum EEPROM Endurance | 63 | // Minimum EEPROM Endurance |
65 | // ------------------------ | 64 | // ------------------------ |
66 | #if (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word | 65 | # if (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word |
67 | #define EEESIZE 0x33 | 66 | # define EEESIZE 0x33 |
68 | #elif (EEPROM_SIZE == 1024) // 75000 writes/byte or 150000 writes/word | 67 | # elif (EEPROM_SIZE == 1024) // 75000 writes/byte or 150000 writes/word |
69 | #define EEESIZE 0x34 | 68 | # define EEESIZE 0x34 |
70 | #elif (EEPROM_SIZE == 512) // 155000 writes/byte or 310000 writes/word | 69 | # elif (EEPROM_SIZE == 512) // 155000 writes/byte or 310000 writes/word |
71 | #define EEESIZE 0x35 | 70 | # define EEESIZE 0x35 |
72 | #elif (EEPROM_SIZE == 256) // 315000 writes/byte or 630000 writes/word | 71 | # elif (EEPROM_SIZE == 256) // 315000 writes/byte or 630000 writes/word |
73 | #define EEESIZE 0x36 | 72 | # define EEESIZE 0x36 |
74 | #elif (EEPROM_SIZE == 128) // 635000 writes/byte or 1270000 writes/word | 73 | # elif (EEPROM_SIZE == 128) // 635000 writes/byte or 1270000 writes/word |
75 | #define EEESIZE 0x37 | 74 | # define EEESIZE 0x37 |
76 | #elif (EEPROM_SIZE == 64) // 1275000 writes/byte or 2550000 writes/word | 75 | # elif (EEPROM_SIZE == 64) // 1275000 writes/byte or 2550000 writes/word |
77 | #define EEESIZE 0x38 | 76 | # define EEESIZE 0x38 |
78 | #elif (EEPROM_SIZE == 32) // 2555000 writes/byte or 5110000 writes/word | 77 | # elif (EEPROM_SIZE == 32) // 2555000 writes/byte or 5110000 writes/word |
79 | #define EEESIZE 0x39 | 78 | # define EEESIZE 0x39 |
80 | #endif | 79 | # endif |
81 | 80 | ||
82 | /** \brief eeprom initialization | 81 | /** \brief eeprom initialization |
83 | * | 82 | * |
84 | * FIXME: needs doc | 83 | * FIXME: needs doc |
85 | */ | 84 | */ |
86 | void eeprom_initialize(void) | 85 | void eeprom_initialize(void) { |
87 | { | 86 | uint32_t count = 0; |
88 | uint32_t count=0; | 87 | uint16_t do_flash_cmd[] = {0xf06f, 0x037f, 0x7003, 0x7803, 0xf013, 0x0f80, 0xd0fb, 0x4770}; |
89 | uint16_t do_flash_cmd[] = { | 88 | uint8_t status; |
90 | 0xf06f, 0x037f, 0x7003, 0x7803, | 89 | |
91 | 0xf013, 0x0f80, 0xd0fb, 0x4770}; | 90 | if (FTFL->FCNFG & FTFL_FCNFG_RAMRDY) { |
92 | uint8_t status; | 91 | // FlexRAM is configured as traditional RAM |
93 | 92 | // We need to reconfigure for EEPROM usage | |
94 | if (FTFL->FCNFG & FTFL_FCNFG_RAMRDY) { | 93 | FTFL->FCCOB0 = 0x80; // PGMPART = Program Partition Command |
95 | // FlexRAM is configured as traditional RAM | 94 | FTFL->FCCOB4 = EEESIZE; // EEPROM Size |
96 | // We need to reconfigure for EEPROM usage | 95 | FTFL->FCCOB5 = 0x03; // 0K for Dataflash, 32K for EEPROM backup |
97 | FTFL->FCCOB0 = 0x80; // PGMPART = Program Partition Command | 96 | __disable_irq(); |
98 | FTFL->FCCOB4 = EEESIZE; // EEPROM Size | 97 | // do_flash_cmd() must execute from RAM. Luckily the C syntax is simple... |
99 | FTFL->FCCOB5 = 0x03; // 0K for Dataflash, 32K for EEPROM backup | 98 | (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFL->FSTAT)); |
100 | __disable_irq(); | 99 | __enable_irq(); |
101 | // do_flash_cmd() must execute from RAM. Luckily the C syntax is simple... | 100 | status = FTFL->FSTAT; |
102 | (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFL->FSTAT)); | 101 | if (status & (FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL)) { |
103 | __enable_irq(); | 102 | FTFL->FSTAT = (status & (FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL)); |
104 | status = FTFL->FSTAT; | 103 | return; // error |
105 | if (status & (FTFL_FSTAT_RDCOLERR|FTFL_FSTAT_ACCERR|FTFL_FSTAT_FPVIOL)) { | 104 | } |
106 | FTFL->FSTAT = (status & (FTFL_FSTAT_RDCOLERR|FTFL_FSTAT_ACCERR|FTFL_FSTAT_FPVIOL)); | 105 | } |
107 | return; // error | 106 | // wait for eeprom to become ready (is this really necessary?) |
108 | } | 107 | while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) { |
109 | } | 108 | if (++count > 20000) break; |
110 | // wait for eeprom to become ready (is this really necessary?) | 109 | } |
111 | while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) { | 110 | } |
112 | if (++count > 20000) break; | 111 | |
113 | } | 112 | # define FlexRAM ((uint8_t *)0x14000000) |
114 | } | ||
115 | |||
116 | #define FlexRAM ((uint8_t *)0x14000000) | ||
117 | 113 | ||
118 | /** \brief eeprom read byte | 114 | /** \brief eeprom read byte |
119 | * | 115 | * |
120 | * FIXME: needs doc | 116 | * FIXME: needs doc |
121 | */ | 117 | */ |
122 | uint8_t eeprom_read_byte(const uint8_t *addr) | 118 | uint8_t eeprom_read_byte(const uint8_t *addr) { |
123 | { | 119 | uint32_t offset = (uint32_t)addr; |
124 | uint32_t offset = (uint32_t)addr; | 120 | if (offset >= EEPROM_SIZE) return 0; |
125 | if (offset >= EEPROM_SIZE) return 0; | 121 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); |
126 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); | 122 | return FlexRAM[offset]; |
127 | return FlexRAM[offset]; | ||
128 | } | 123 | } |
129 | 124 | ||
130 | /** \brief eeprom read word | 125 | /** \brief eeprom read word |
131 | * | 126 | * |
132 | * FIXME: needs doc | 127 | * FIXME: needs doc |
133 | */ | 128 | */ |
134 | uint16_t eeprom_read_word(const uint16_t *addr) | 129 | uint16_t eeprom_read_word(const uint16_t *addr) { |
135 | { | 130 | uint32_t offset = (uint32_t)addr; |
136 | uint32_t offset = (uint32_t)addr; | 131 | if (offset >= EEPROM_SIZE - 1) return 0; |
137 | if (offset >= EEPROM_SIZE-1) return 0; | 132 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); |
138 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); | 133 | return *(uint16_t *)(&FlexRAM[offset]); |
139 | return *(uint16_t *)(&FlexRAM[offset]); | ||
140 | } | 134 | } |
141 | 135 | ||
142 | /** \brief eeprom read dword | 136 | /** \brief eeprom read dword |
143 | * | 137 | * |
144 | * FIXME: needs doc | 138 | * FIXME: needs doc |
145 | */ | 139 | */ |
146 | uint32_t eeprom_read_dword(const uint32_t *addr) | 140 | uint32_t eeprom_read_dword(const uint32_t *addr) { |
147 | { | 141 | uint32_t offset = (uint32_t)addr; |
148 | uint32_t offset = (uint32_t)addr; | 142 | if (offset >= EEPROM_SIZE - 3) return 0; |
149 | if (offset >= EEPROM_SIZE-3) return 0; | 143 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); |
150 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); | 144 | return *(uint32_t *)(&FlexRAM[offset]); |
151 | return *(uint32_t *)(&FlexRAM[offset]); | ||
152 | } | 145 | } |
153 | 146 | ||
154 | /** \brief eeprom read block | 147 | /** \brief eeprom read block |
155 | * | 148 | * |
156 | * FIXME: needs doc | 149 | * FIXME: needs doc |
157 | */ | 150 | */ |
158 | void eeprom_read_block(void *buf, const void *addr, uint32_t len) | 151 | void eeprom_read_block(void *buf, const void *addr, uint32_t len) { |
159 | { | 152 | uint32_t offset = (uint32_t)addr; |
160 | uint32_t offset = (uint32_t)addr; | 153 | uint8_t *dest = (uint8_t *)buf; |
161 | uint8_t *dest = (uint8_t *)buf; | 154 | uint32_t end = offset + len; |
162 | uint32_t end = offset + len; | 155 | |
163 | 156 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); | |
164 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); | 157 | if (end > EEPROM_SIZE) end = EEPROM_SIZE; |
165 | if (end > EEPROM_SIZE) end = EEPROM_SIZE; | 158 | while (offset < end) { |
166 | while (offset < end) { | 159 | *dest++ = FlexRAM[offset++]; |
167 | *dest++ = FlexRAM[offset++]; | 160 | } |
168 | } | ||
169 | } | 161 | } |
170 | 162 | ||
171 | /** \brief eeprom is ready | 163 | /** \brief eeprom is ready |
172 | * | 164 | * |
173 | * FIXME: needs doc | 165 | * FIXME: needs doc |
174 | */ | 166 | */ |
175 | int eeprom_is_ready(void) | 167 | int eeprom_is_ready(void) { return (FTFL->FCNFG & FTFL_FCNFG_EEERDY) ? 1 : 0; } |
176 | { | ||
177 | return (FTFL->FCNFG & FTFL_FCNFG_EEERDY) ? 1 : 0; | ||
178 | } | ||
179 | 168 | ||
180 | /** \brief flexram wait | 169 | /** \brief flexram wait |
181 | * | 170 | * |
182 | * FIXME: needs doc | 171 | * FIXME: needs doc |
183 | */ | 172 | */ |
184 | static void flexram_wait(void) | 173 | static void flexram_wait(void) { |
185 | { | 174 | while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) { |
186 | while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) { | 175 | // TODO: timeout |
187 | // TODO: timeout | 176 | } |
188 | } | ||
189 | } | 177 | } |
190 | 178 | ||
191 | /** \brief eeprom_write_byte | 179 | /** \brief eeprom_write_byte |
192 | * | 180 | * |
193 | * FIXME: needs doc | 181 | * FIXME: needs doc |
194 | */ | 182 | */ |
195 | void eeprom_write_byte(uint8_t *addr, uint8_t value) | 183 | void eeprom_write_byte(uint8_t *addr, uint8_t value) { |
196 | { | 184 | uint32_t offset = (uint32_t)addr; |
197 | uint32_t offset = (uint32_t)addr; | ||
198 | 185 | ||
199 | if (offset >= EEPROM_SIZE) return; | 186 | if (offset >= EEPROM_SIZE) return; |
200 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); | 187 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); |
201 | if (FlexRAM[offset] != value) { | 188 | if (FlexRAM[offset] != value) { |
202 | FlexRAM[offset] = value; | 189 | FlexRAM[offset] = value; |
203 | flexram_wait(); | 190 | flexram_wait(); |
204 | } | 191 | } |
205 | } | 192 | } |
206 | 193 | ||
207 | /** \brief eeprom write word | 194 | /** \brief eeprom write word |
208 | * | 195 | * |
209 | * FIXME: needs doc | 196 | * FIXME: needs doc |
210 | */ | 197 | */ |
211 | void eeprom_write_word(uint16_t *addr, uint16_t value) | 198 | void eeprom_write_word(uint16_t *addr, uint16_t value) { |
212 | { | 199 | uint32_t offset = (uint32_t)addr; |
213 | uint32_t offset = (uint32_t)addr; | 200 | |
214 | 201 | if (offset >= EEPROM_SIZE - 1) return; | |
215 | if (offset >= EEPROM_SIZE-1) return; | 202 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); |
216 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); | 203 | # ifdef HANDLE_UNALIGNED_WRITES |
217 | #ifdef HANDLE_UNALIGNED_WRITES | 204 | if ((offset & 1) == 0) { |
218 | if ((offset & 1) == 0) { | 205 | # endif |
219 | #endif | 206 | if (*(uint16_t *)(&FlexRAM[offset]) != value) { |
220 | if (*(uint16_t *)(&FlexRAM[offset]) != value) { | 207 | *(uint16_t *)(&FlexRAM[offset]) = value; |
221 | *(uint16_t *)(&FlexRAM[offset]) = value; | 208 | flexram_wait(); |
222 | flexram_wait(); | 209 | } |
223 | } | 210 | # ifdef HANDLE_UNALIGNED_WRITES |
224 | #ifdef HANDLE_UNALIGNED_WRITES | 211 | } else { |
225 | } else { | 212 | if (FlexRAM[offset] != value) { |
226 | if (FlexRAM[offset] != value) { | 213 | FlexRAM[offset] = value; |
227 | FlexRAM[offset] = value; | 214 | flexram_wait(); |
228 | flexram_wait(); | 215 | } |
229 | } | 216 | if (FlexRAM[offset + 1] != (value >> 8)) { |
230 | if (FlexRAM[offset + 1] != (value >> 8)) { | 217 | FlexRAM[offset + 1] = value >> 8; |
231 | FlexRAM[offset + 1] = value >> 8; | 218 | flexram_wait(); |
232 | flexram_wait(); | 219 | } |
233 | } | 220 | } |
234 | } | 221 | # endif |
235 | #endif | ||
236 | } | 222 | } |
237 | 223 | ||
238 | /** \brief eeprom write dword | 224 | /** \brief eeprom write dword |
239 | * | 225 | * |
240 | * FIXME: needs doc | 226 | * FIXME: needs doc |
241 | */ | 227 | */ |
242 | void eeprom_write_dword(uint32_t *addr, uint32_t value) | 228 | void eeprom_write_dword(uint32_t *addr, uint32_t value) { |
243 | { | 229 | uint32_t offset = (uint32_t)addr; |
244 | uint32_t offset = (uint32_t)addr; | 230 | |
245 | 231 | if (offset >= EEPROM_SIZE - 3) return; | |
246 | if (offset >= EEPROM_SIZE-3) return; | 232 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); |
247 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); | 233 | # ifdef HANDLE_UNALIGNED_WRITES |
248 | #ifdef HANDLE_UNALIGNED_WRITES | 234 | switch (offset & 3) { |
249 | switch (offset & 3) { | 235 | case 0: |
250 | case 0: | 236 | # endif |
251 | #endif | 237 | if (*(uint32_t *)(&FlexRAM[offset]) != value) { |
252 | if (*(uint32_t *)(&FlexRAM[offset]) != value) { | 238 | *(uint32_t *)(&FlexRAM[offset]) = value; |
253 | *(uint32_t *)(&FlexRAM[offset]) = value; | 239 | flexram_wait(); |
254 | flexram_wait(); | 240 | } |
255 | } | 241 | return; |
256 | return; | 242 | # ifdef HANDLE_UNALIGNED_WRITES |
257 | #ifdef HANDLE_UNALIGNED_WRITES | 243 | case 2: |
258 | case 2: | 244 | if (*(uint16_t *)(&FlexRAM[offset]) != value) { |
259 | if (*(uint16_t *)(&FlexRAM[offset]) != value) { | 245 | *(uint16_t *)(&FlexRAM[offset]) = value; |
260 | *(uint16_t *)(&FlexRAM[offset]) = value; | 246 | flexram_wait(); |
261 | flexram_wait(); | 247 | } |
262 | } | 248 | if (*(uint16_t *)(&FlexRAM[offset + 2]) != (value >> 16)) { |
263 | if (*(uint16_t *)(&FlexRAM[offset + 2]) != (value >> 16)) { | 249 | *(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16; |
264 | *(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16; | 250 | flexram_wait(); |
265 | flexram_wait(); | 251 | } |
266 | } | 252 | return; |
267 | return; | 253 | default: |
268 | default: | 254 | if (FlexRAM[offset] != value) { |
269 | if (FlexRAM[offset] != value) { | 255 | FlexRAM[offset] = value; |
270 | FlexRAM[offset] = value; | 256 | flexram_wait(); |
271 | flexram_wait(); | 257 | } |
272 | } | 258 | if (*(uint16_t *)(&FlexRAM[offset + 1]) != (value >> 8)) { |
273 | if (*(uint16_t *)(&FlexRAM[offset + 1]) != (value >> 8)) { | 259 | *(uint16_t *)(&FlexRAM[offset + 1]) = value >> 8; |
274 | *(uint16_t *)(&FlexRAM[offset + 1]) = value >> 8; | 260 | flexram_wait(); |
275 | flexram_wait(); | 261 | } |
276 | } | 262 | if (FlexRAM[offset + 3] != (value >> 24)) { |
277 | if (FlexRAM[offset + 3] != (value >> 24)) { | 263 | FlexRAM[offset + 3] = value >> 24; |
278 | FlexRAM[offset + 3] = value >> 24; | 264 | flexram_wait(); |
279 | flexram_wait(); | 265 | } |
280 | } | 266 | } |
281 | } | 267 | # endif |
282 | #endif | ||
283 | } | 268 | } |
284 | 269 | ||
285 | /** \brief eeprom write block | 270 | /** \brief eeprom write block |
286 | * | 271 | * |
287 | * FIXME: needs doc | 272 | * FIXME: needs doc |
288 | */ | 273 | */ |
289 | void eeprom_write_block(const void *buf, void *addr, uint32_t len) | 274 | void eeprom_write_block(const void *buf, void *addr, uint32_t len) { |
290 | { | 275 | uint32_t offset = (uint32_t)addr; |
291 | uint32_t offset = (uint32_t)addr; | 276 | const uint8_t *src = (const uint8_t *)buf; |
292 | const uint8_t *src = (const uint8_t *)buf; | 277 | |
293 | 278 | if (offset >= EEPROM_SIZE) return; | |
294 | if (offset >= EEPROM_SIZE) return; | 279 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); |
295 | if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); | 280 | if (len >= EEPROM_SIZE) len = EEPROM_SIZE; |
296 | if (len >= EEPROM_SIZE) len = EEPROM_SIZE; | 281 | if (offset + len >= EEPROM_SIZE) len = EEPROM_SIZE - offset; |
297 | if (offset + len >= EEPROM_SIZE) len = EEPROM_SIZE - offset; | 282 | while (len > 0) { |
298 | while (len > 0) { | 283 | uint32_t lsb = offset & 3; |
299 | uint32_t lsb = offset & 3; | 284 | if (lsb == 0 && len >= 4) { |
300 | if (lsb == 0 && len >= 4) { | 285 | // write aligned 32 bits |
301 | // write aligned 32 bits | 286 | uint32_t val32; |
302 | uint32_t val32; | 287 | val32 = *src++; |
303 | val32 = *src++; | 288 | val32 |= (*src++ << 8); |
304 | val32 |= (*src++ << 8); | 289 | val32 |= (*src++ << 16); |
305 | val32 |= (*src++ << 16); | 290 | val32 |= (*src++ << 24); |
306 | val32 |= (*src++ << 24); | 291 | if (*(uint32_t *)(&FlexRAM[offset]) != val32) { |
307 | if (*(uint32_t *)(&FlexRAM[offset]) != val32) { | 292 | *(uint32_t *)(&FlexRAM[offset]) = val32; |
308 | *(uint32_t *)(&FlexRAM[offset]) = val32; | 293 | flexram_wait(); |
309 | flexram_wait(); | 294 | } |
310 | } | 295 | offset += 4; |
311 | offset += 4; | 296 | len -= 4; |
312 | len -= 4; | 297 | } else if ((lsb == 0 || lsb == 2) && len >= 2) { |
313 | } else if ((lsb == 0 || lsb == 2) && len >= 2) { | 298 | // write aligned 16 bits |
314 | // write aligned 16 bits | 299 | uint16_t val16; |
315 | uint16_t val16; | 300 | val16 = *src++; |
316 | val16 = *src++; | 301 | val16 |= (*src++ << 8); |
317 | val16 |= (*src++ << 8); | 302 | if (*(uint16_t *)(&FlexRAM[offset]) != val16) { |
318 | if (*(uint16_t *)(&FlexRAM[offset]) != val16) { | 303 | *(uint16_t *)(&FlexRAM[offset]) = val16; |
319 | *(uint16_t *)(&FlexRAM[offset]) = val16; | 304 | flexram_wait(); |
320 | flexram_wait(); | 305 | } |
321 | } | 306 | offset += 2; |
322 | offset += 2; | 307 | len -= 2; |
323 | len -= 2; | 308 | } else { |
324 | } else { | 309 | // write 8 bits |
325 | // write 8 bits | 310 | uint8_t val8 = *src++; |
326 | uint8_t val8 = *src++; | 311 | if (FlexRAM[offset] != val8) { |
327 | if (FlexRAM[offset] != val8) { | 312 | FlexRAM[offset] = val8; |
328 | FlexRAM[offset] = val8; | 313 | flexram_wait(); |
329 | flexram_wait(); | 314 | } |
330 | } | 315 | offset++; |
331 | offset++; | 316 | len--; |
332 | len--; | 317 | } |
333 | } | 318 | } |
334 | } | ||
335 | } | 319 | } |
336 | 320 | ||
337 | /* | 321 | /* |
338 | void do_flash_cmd(volatile uint8_t *fstat) | 322 | void do_flash_cmd(volatile uint8_t *fstat) |
339 | { | 323 | { |
340 | *fstat = 0x80; | 324 | *fstat = 0x80; |
341 | while ((*fstat & 0x80) == 0) ; // wait | 325 | while ((*fstat & 0x80) == 0) ; // wait |
342 | } | 326 | } |
343 | 00000000 <do_flash_cmd>: | 327 | 00000000 <do_flash_cmd>: |
344 | 0: f06f 037f mvn.w r3, #127 ; 0x7f | 328 | 0: f06f 037f mvn.w r3, #127 ; 0x7f |
@@ -352,128 +336,124 @@ void do_flash_cmd(volatile uint8_t *fstat) | |||
352 | #elif defined(KL2x) /* chip selection */ | 336 | #elif defined(KL2x) /* chip selection */ |
353 | /* Teensy LC (emulated) */ | 337 | /* Teensy LC (emulated) */ |
354 | 338 | ||
355 | #define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0)) | 339 | # define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0)) |
356 | 340 | ||
357 | extern uint32_t __eeprom_workarea_start__; | 341 | extern uint32_t __eeprom_workarea_start__; |
358 | extern uint32_t __eeprom_workarea_end__; | 342 | extern uint32_t __eeprom_workarea_end__; |
359 | 343 | ||
360 | #define EEPROM_SIZE 128 | 344 | # define EEPROM_SIZE 128 |
361 | 345 | ||
362 | static uint32_t flashend = 0; | 346 | static uint32_t flashend = 0; |
363 | 347 | ||
364 | void eeprom_initialize(void) | 348 | void eeprom_initialize(void) { |
365 | { | 349 | const uint16_t *p = (uint16_t *)SYMVAL(__eeprom_workarea_start__); |
366 | const uint16_t *p = (uint16_t *)SYMVAL(__eeprom_workarea_start__); | ||
367 | 350 | ||
368 | do { | 351 | do { |
369 | if (*p++ == 0xFFFF) { | 352 | if (*p++ == 0xFFFF) { |
370 | flashend = (uint32_t)(p - 2); | 353 | flashend = (uint32_t)(p - 2); |
371 | return; | 354 | return; |
372 | } | 355 | } |
373 | } while (p < (uint16_t *)SYMVAL(__eeprom_workarea_end__)); | 356 | } while (p < (uint16_t *)SYMVAL(__eeprom_workarea_end__)); |
374 | flashend = (uint32_t)((uint16_t *)SYMVAL(__eeprom_workarea_end__) - 1); | 357 | flashend = (uint32_t)((uint16_t *)SYMVAL(__eeprom_workarea_end__) - 1); |
375 | } | 358 | } |
376 | 359 | ||
377 | uint8_t eeprom_read_byte(const uint8_t *addr) | 360 | uint8_t eeprom_read_byte(const uint8_t *addr) { |
378 | { | 361 | uint32_t offset = (uint32_t)addr; |
379 | uint32_t offset = (uint32_t)addr; | 362 | const uint16_t *p = (uint16_t *)SYMVAL(__eeprom_workarea_start__); |
380 | const uint16_t *p = (uint16_t *)SYMVAL(__eeprom_workarea_start__); | 363 | const uint16_t *end = (const uint16_t *)((uint32_t)flashend); |
381 | const uint16_t *end = (const uint16_t *)((uint32_t)flashend); | 364 | uint16_t val; |
382 | uint16_t val; | 365 | uint8_t data = 0xFF; |
383 | uint8_t data=0xFF; | 366 | |
384 | 367 | if (!end) { | |
385 | if (!end) { | 368 | eeprom_initialize(); |
386 | eeprom_initialize(); | 369 | end = (const uint16_t *)((uint32_t)flashend); |
387 | end = (const uint16_t *)((uint32_t)flashend); | 370 | } |
388 | } | 371 | if (offset < EEPROM_SIZE) { |
389 | if (offset < EEPROM_SIZE) { | 372 | while (p <= end) { |
390 | while (p <= end) { | 373 | val = *p++; |
391 | val = *p++; | 374 | if ((val & 255) == offset) data = val >> 8; |
392 | if ((val & 255) == offset) data = val >> 8; | 375 | } |
393 | } | 376 | } |
394 | } | 377 | return data; |
395 | return data; | 378 | } |
396 | } | 379 | |
397 | 380 | static void flash_write(const uint16_t *code, uint32_t addr, uint32_t data) { | |
398 | static void flash_write(const uint16_t *code, uint32_t addr, uint32_t data) | 381 | // with great power comes great responsibility.... |
399 | { | 382 | uint32_t stat; |
400 | // with great power comes great responsibility.... | 383 | *(uint32_t *)&(FTFA->FCCOB3) = 0x06000000 | (addr & 0x00FFFFFC); |
401 | uint32_t stat; | 384 | *(uint32_t *)&(FTFA->FCCOB7) = data; |
402 | *(uint32_t *)&(FTFA->FCCOB3) = 0x06000000 | (addr & 0x00FFFFFC); | 385 | __disable_irq(); |
403 | *(uint32_t *)&(FTFA->FCCOB7) = data; | 386 | (*((void (*)(volatile uint8_t *))((uint32_t)code | 1)))(&(FTFA->FSTAT)); |
404 | __disable_irq(); | 387 | __enable_irq(); |
405 | (*((void (*)(volatile uint8_t *))((uint32_t)code | 1)))(&(FTFA->FSTAT)); | 388 | stat = FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR | FTFA_FSTAT_ACCERR | FTFA_FSTAT_FPVIOL); |
406 | __enable_irq(); | 389 | if (stat) { |
407 | stat = FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR|FTFA_FSTAT_ACCERR|FTFA_FSTAT_FPVIOL); | 390 | FTFA->FSTAT = stat; |
408 | if (stat) { | 391 | } |
409 | FTFA->FSTAT = stat; | 392 | MCM->PLACR |= MCM_PLACR_CFCC; |
410 | } | 393 | } |
411 | MCM->PLACR |= MCM_PLACR_CFCC; | 394 | |
412 | } | 395 | void eeprom_write_byte(uint8_t *addr, uint8_t data) { |
413 | 396 | uint32_t offset = (uint32_t)addr; | |
414 | void eeprom_write_byte(uint8_t *addr, uint8_t data) | 397 | const uint16_t *p, *end = (const uint16_t *)((uint32_t)flashend); |
415 | { | 398 | uint32_t i, val, flashaddr; |
416 | uint32_t offset = (uint32_t)addr; | 399 | uint16_t do_flash_cmd[] = {0x2380, 0x7003, 0x7803, 0xb25b, 0x2b00, 0xdafb, 0x4770}; |
417 | const uint16_t *p, *end = (const uint16_t *)((uint32_t)flashend); | 400 | uint8_t buf[EEPROM_SIZE]; |
418 | uint32_t i, val, flashaddr; | 401 | |
419 | uint16_t do_flash_cmd[] = { | 402 | if (offset >= EEPROM_SIZE) return; |
420 | 0x2380, 0x7003, 0x7803, 0xb25b, 0x2b00, 0xdafb, 0x4770}; | 403 | if (!end) { |
421 | uint8_t buf[EEPROM_SIZE]; | 404 | eeprom_initialize(); |
422 | 405 | end = (const uint16_t *)((uint32_t)flashend); | |
423 | if (offset >= EEPROM_SIZE) return; | 406 | } |
424 | if (!end) { | 407 | if (++end < (uint16_t *)SYMVAL(__eeprom_workarea_end__)) { |
425 | eeprom_initialize(); | 408 | val = (data << 8) | offset; |
426 | end = (const uint16_t *)((uint32_t)flashend); | 409 | flashaddr = (uint32_t)end; |
427 | } | 410 | flashend = flashaddr; |
428 | if (++end < (uint16_t *)SYMVAL(__eeprom_workarea_end__)) { | 411 | if ((flashaddr & 2) == 0) { |
429 | val = (data << 8) | offset; | 412 | val |= 0xFFFF0000; |
430 | flashaddr = (uint32_t)end; | 413 | } else { |
431 | flashend = flashaddr; | 414 | val <<= 16; |
432 | if ((flashaddr & 2) == 0) { | 415 | val |= 0x0000FFFF; |
433 | val |= 0xFFFF0000; | 416 | } |
434 | } else { | 417 | flash_write(do_flash_cmd, flashaddr, val); |
435 | val <<= 16; | 418 | } else { |
436 | val |= 0x0000FFFF; | 419 | for (i = 0; i < EEPROM_SIZE; i++) { |
437 | } | 420 | buf[i] = 0xFF; |
438 | flash_write(do_flash_cmd, flashaddr, val); | 421 | } |
439 | } else { | 422 | val = 0; |
440 | for (i=0; i < EEPROM_SIZE; i++) { | 423 | for (p = (uint16_t *)SYMVAL(__eeprom_workarea_start__); p < (uint16_t *)SYMVAL(__eeprom_workarea_end__); p++) { |
441 | buf[i] = 0xFF; | 424 | val = *p; |
442 | } | 425 | if ((val & 255) < EEPROM_SIZE) { |
443 | val = 0; | 426 | buf[val & 255] = val >> 8; |
444 | for (p = (uint16_t *)SYMVAL(__eeprom_workarea_start__); p < (uint16_t *)SYMVAL(__eeprom_workarea_end__); p++) { | 427 | } |
445 | val = *p; | 428 | } |
446 | if ((val & 255) < EEPROM_SIZE) { | 429 | buf[offset] = data; |
447 | buf[val & 255] = val >> 8; | 430 | for (flashaddr = (uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_start__); flashaddr < (uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_end__); flashaddr += 1024) { |
448 | } | 431 | *(uint32_t *)&(FTFA->FCCOB3) = 0x09000000 | flashaddr; |
449 | } | 432 | __disable_irq(); |
450 | buf[offset] = data; | 433 | (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFA->FSTAT)); |
451 | for (flashaddr=(uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_start__); flashaddr < (uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_end__); flashaddr += 1024) { | 434 | __enable_irq(); |
452 | *(uint32_t *)&(FTFA->FCCOB3) = 0x09000000 | flashaddr; | 435 | val = FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR | FTFA_FSTAT_ACCERR | FTFA_FSTAT_FPVIOL); |
453 | __disable_irq(); | 436 | ; |
454 | (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFA->FSTAT)); | 437 | if (val) FTFA->FSTAT = val; |
455 | __enable_irq(); | 438 | MCM->PLACR |= MCM_PLACR_CFCC; |
456 | val = FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR|FTFA_FSTAT_ACCERR|FTFA_FSTAT_FPVIOL);; | 439 | } |
457 | if (val) FTFA->FSTAT = val; | 440 | flashaddr = (uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_start__); |
458 | MCM->PLACR |= MCM_PLACR_CFCC; | 441 | for (i = 0; i < EEPROM_SIZE; i++) { |
459 | } | 442 | if (buf[i] == 0xFF) continue; |
460 | flashaddr=(uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_start__); | 443 | if ((flashaddr & 2) == 0) { |
461 | for (i=0; i < EEPROM_SIZE; i++) { | 444 | val = (buf[i] << 8) | i; |
462 | if (buf[i] == 0xFF) continue; | 445 | } else { |
463 | if ((flashaddr & 2) == 0) { | 446 | val = val | (buf[i] << 24) | (i << 16); |
464 | val = (buf[i] << 8) | i; | 447 | flash_write(do_flash_cmd, flashaddr, val); |
465 | } else { | 448 | } |
466 | val = val | (buf[i] << 24) | (i << 16); | 449 | flashaddr += 2; |
467 | flash_write(do_flash_cmd, flashaddr, val); | 450 | } |
468 | } | 451 | flashend = flashaddr; |
469 | flashaddr += 2; | 452 | if ((flashaddr & 2)) { |
470 | } | 453 | val |= 0xFFFF0000; |
471 | flashend = flashaddr; | 454 | flash_write(do_flash_cmd, flashaddr, val); |
472 | if ((flashaddr & 2)) { | 455 | } |
473 | val |= 0xFFFF0000; | 456 | } |
474 | flash_write(do_flash_cmd, flashaddr, val); | ||
475 | } | ||
476 | } | ||
477 | } | 457 | } |
478 | 458 | ||
479 | /* | 459 | /* |
@@ -492,141 +472,127 @@ void do_flash_cmd(volatile uint8_t *fstat) | |||
492 | c: 4770 bx lr | 472 | c: 4770 bx lr |
493 | */ | 473 | */ |
494 | 474 | ||
495 | 475 | uint16_t eeprom_read_word(const uint16_t *addr) { | |
496 | uint16_t eeprom_read_word(const uint16_t *addr) | 476 | const uint8_t *p = (const uint8_t *)addr; |
497 | { | 477 | return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8); |
498 | const uint8_t *p = (const uint8_t *)addr; | ||
499 | return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8); | ||
500 | } | 478 | } |
501 | 479 | ||
502 | uint32_t eeprom_read_dword(const uint32_t *addr) | 480 | uint32_t eeprom_read_dword(const uint32_t *addr) { |
503 | { | 481 | const uint8_t *p = (const uint8_t *)addr; |
504 | const uint8_t *p = (const uint8_t *)addr; | 482 | return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8) | (eeprom_read_byte(p + 2) << 16) | (eeprom_read_byte(p + 3) << 24); |
505 | return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8) | ||
506 | | (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24); | ||
507 | } | 483 | } |
508 | 484 | ||
509 | void eeprom_read_block(void *buf, const void *addr, uint32_t len) | 485 | void eeprom_read_block(void *buf, const void *addr, uint32_t len) { |
510 | { | 486 | const uint8_t *p = (const uint8_t *)addr; |
511 | const uint8_t *p = (const uint8_t *)addr; | 487 | uint8_t * dest = (uint8_t *)buf; |
512 | uint8_t *dest = (uint8_t *)buf; | 488 | while (len--) { |
513 | while (len--) { | 489 | *dest++ = eeprom_read_byte(p++); |
514 | *dest++ = eeprom_read_byte(p++); | 490 | } |
515 | } | ||
516 | } | 491 | } |
517 | 492 | ||
518 | int eeprom_is_ready(void) | 493 | int eeprom_is_ready(void) { return 1; } |
519 | { | ||
520 | return 1; | ||
521 | } | ||
522 | 494 | ||
523 | void eeprom_write_word(uint16_t *addr, uint16_t value) | 495 | void eeprom_write_word(uint16_t *addr, uint16_t value) { |
524 | { | 496 | uint8_t *p = (uint8_t *)addr; |
525 | uint8_t *p = (uint8_t *)addr; | 497 | eeprom_write_byte(p++, value); |
526 | eeprom_write_byte(p++, value); | 498 | eeprom_write_byte(p, value >> 8); |
527 | eeprom_write_byte(p, value >> 8); | ||
528 | } | 499 | } |
529 | 500 | ||
530 | void eeprom_write_dword(uint32_t *addr, uint32_t value) | 501 | void eeprom_write_dword(uint32_t *addr, uint32_t value) { |
531 | { | 502 | uint8_t *p = (uint8_t *)addr; |
532 | uint8_t *p = (uint8_t *)addr; | 503 | eeprom_write_byte(p++, value); |
533 | eeprom_write_byte(p++, value); | 504 | eeprom_write_byte(p++, value >> 8); |
534 | eeprom_write_byte(p++, value >> 8); | 505 | eeprom_write_byte(p++, value >> 16); |
535 | eeprom_write_byte(p++, value >> 16); | 506 | eeprom_write_byte(p, value >> 24); |
536 | eeprom_write_byte(p, value >> 24); | ||
537 | } | 507 | } |
538 | 508 | ||
539 | void eeprom_write_block(const void *buf, void *addr, uint32_t len) | 509 | void eeprom_write_block(const void *buf, void *addr, uint32_t len) { |
540 | { | 510 | uint8_t * p = (uint8_t *)addr; |
541 | uint8_t *p = (uint8_t *)addr; | 511 | const uint8_t *src = (const uint8_t *)buf; |
542 | const uint8_t *src = (const uint8_t *)buf; | 512 | while (len--) { |
543 | while (len--) { | 513 | eeprom_write_byte(p++, *src++); |
544 | eeprom_write_byte(p++, *src++); | 514 | } |
545 | } | ||
546 | } | 515 | } |
547 | 516 | ||
548 | #else | 517 | #else |
549 | // No EEPROM supported, so emulate it | 518 | // No EEPROM supported, so emulate it |
550 | 519 | ||
551 | #define EEPROM_SIZE 32 | 520 | # define EEPROM_SIZE 32 |
552 | static uint8_t buffer[EEPROM_SIZE]; | 521 | static uint8_t buffer[EEPROM_SIZE]; |
553 | 522 | ||
554 | uint8_t eeprom_read_byte(const uint8_t *addr) { | 523 | uint8_t eeprom_read_byte(const uint8_t *addr) { |
555 | uint32_t offset = (uint32_t)addr; | 524 | uint32_t offset = (uint32_t)addr; |
556 | return buffer[offset]; | 525 | return buffer[offset]; |
557 | } | 526 | } |
558 | 527 | ||
559 | void eeprom_write_byte(uint8_t *addr, uint8_t value) { | 528 | void eeprom_write_byte(uint8_t *addr, uint8_t value) { |
560 | uint32_t offset = (uint32_t)addr; | 529 | uint32_t offset = (uint32_t)addr; |
561 | buffer[offset] = value; | 530 | buffer[offset] = value; |
562 | } | 531 | } |
563 | 532 | ||
564 | uint16_t eeprom_read_word(const uint16_t *addr) { | 533 | uint16_t eeprom_read_word(const uint16_t *addr) { |
565 | const uint8_t *p = (const uint8_t *)addr; | 534 | const uint8_t *p = (const uint8_t *)addr; |
566 | return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8); | 535 | return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8); |
567 | } | 536 | } |
568 | 537 | ||
569 | uint32_t eeprom_read_dword(const uint32_t *addr) { | 538 | uint32_t eeprom_read_dword(const uint32_t *addr) { |
570 | const uint8_t *p = (const uint8_t *)addr; | 539 | const uint8_t *p = (const uint8_t *)addr; |
571 | return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8) | 540 | return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8) | (eeprom_read_byte(p + 2) << 16) | (eeprom_read_byte(p + 3) << 24); |
572 | | (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24); | ||
573 | } | 541 | } |
574 | 542 | ||
575 | void eeprom_read_block(void *buf, const void *addr, uint32_t len) { | 543 | void eeprom_read_block(void *buf, const void *addr, uint32_t len) { |
576 | const uint8_t *p = (const uint8_t *)addr; | 544 | const uint8_t *p = (const uint8_t *)addr; |
577 | uint8_t *dest = (uint8_t *)buf; | 545 | uint8_t * dest = (uint8_t *)buf; |
578 | while (len--) { | 546 | while (len--) { |
579 | *dest++ = eeprom_read_byte(p++); | 547 | *dest++ = eeprom_read_byte(p++); |
580 | } | 548 | } |
581 | } | 549 | } |
582 | 550 | ||
583 | void eeprom_write_word(uint16_t *addr, uint16_t value) { | 551 | void eeprom_write_word(uint16_t *addr, uint16_t value) { |
584 | uint8_t *p = (uint8_t *)addr; | 552 | uint8_t *p = (uint8_t *)addr; |
585 | eeprom_write_byte(p++, value); | 553 | eeprom_write_byte(p++, value); |
586 | eeprom_write_byte(p, value >> 8); | 554 | eeprom_write_byte(p, value >> 8); |
587 | } | 555 | } |
588 | 556 | ||
589 | void eeprom_write_dword(uint32_t *addr, uint32_t value) { | 557 | void eeprom_write_dword(uint32_t *addr, uint32_t value) { |
590 | uint8_t *p = (uint8_t *)addr; | 558 | uint8_t *p = (uint8_t *)addr; |
591 | eeprom_write_byte(p++, value); | 559 | eeprom_write_byte(p++, value); |
592 | eeprom_write_byte(p++, value >> 8); | 560 | eeprom_write_byte(p++, value >> 8); |
593 | eeprom_write_byte(p++, value >> 16); | 561 | eeprom_write_byte(p++, value >> 16); |
594 | eeprom_write_byte(p, value >> 24); | 562 | eeprom_write_byte(p, value >> 24); |
595 | } | 563 | } |
596 | 564 | ||
597 | void eeprom_write_block(const void *buf, void *addr, uint32_t len) { | 565 | void eeprom_write_block(const void *buf, void *addr, uint32_t len) { |
598 | uint8_t *p = (uint8_t *)addr; | 566 | uint8_t * p = (uint8_t *)addr; |
599 | const uint8_t *src = (const uint8_t *)buf; | 567 | const uint8_t *src = (const uint8_t *)buf; |
600 | while (len--) { | 568 | while (len--) { |
601 | eeprom_write_byte(p++, *src++); | 569 | eeprom_write_byte(p++, *src++); |
602 | } | 570 | } |
603 | } | 571 | } |
604 | 572 | ||
605 | #endif /* chip selection */ | 573 | #endif /* chip selection */ |
606 | // The update functions just calls write for now, but could probably be optimized | 574 | // The update functions just calls write for now, but could probably be optimized |
607 | 575 | ||
608 | void eeprom_update_byte(uint8_t *addr, uint8_t value) { | 576 | void eeprom_update_byte(uint8_t *addr, uint8_t value) { eeprom_write_byte(addr, value); } |
609 | eeprom_write_byte(addr, value); | ||
610 | } | ||
611 | 577 | ||
612 | void eeprom_update_word(uint16_t *addr, uint16_t value) { | 578 | void eeprom_update_word(uint16_t *addr, uint16_t value) { |
613 | uint8_t *p = (uint8_t *)addr; | 579 | uint8_t *p = (uint8_t *)addr; |
614 | eeprom_write_byte(p++, value); | 580 | eeprom_write_byte(p++, value); |
615 | eeprom_write_byte(p, value >> 8); | 581 | eeprom_write_byte(p, value >> 8); |
616 | } | 582 | } |
617 | 583 | ||
618 | void eeprom_update_dword(uint32_t *addr, uint32_t value) { | 584 | void eeprom_update_dword(uint32_t *addr, uint32_t value) { |
619 | uint8_t *p = (uint8_t *)addr; | 585 | uint8_t *p = (uint8_t *)addr; |
620 | eeprom_write_byte(p++, value); | 586 | eeprom_write_byte(p++, value); |
621 | eeprom_write_byte(p++, value >> 8); | 587 | eeprom_write_byte(p++, value >> 8); |
622 | eeprom_write_byte(p++, value >> 16); | 588 | eeprom_write_byte(p++, value >> 16); |
623 | eeprom_write_byte(p, value >> 24); | 589 | eeprom_write_byte(p, value >> 24); |
624 | } | 590 | } |
625 | 591 | ||
626 | void eeprom_update_block(const void *buf, void *addr, uint32_t len) { | 592 | void eeprom_update_block(const void *buf, void *addr, uint32_t len) { |
627 | uint8_t *p = (uint8_t *)addr; | 593 | uint8_t * p = (uint8_t *)addr; |
628 | const uint8_t *src = (const uint8_t *)buf; | 594 | const uint8_t *src = (const uint8_t *)buf; |
629 | while (len--) { | 595 | while (len--) { |
630 | eeprom_write_byte(p++, *src++); | 596 | eeprom_write_byte(p++, *src++); |
631 | } | 597 | } |
632 | } | 598 | } |
diff --git a/tmk_core/common/chibios/flash_stm32.c b/tmk_core/common/chibios/flash_stm32.c index 832bf3908..e166fc5e6 100755..100644 --- a/tmk_core/common/chibios/flash_stm32.c +++ b/tmk_core/common/chibios/flash_stm32.c | |||
@@ -17,105 +17,95 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #if defined(EEPROM_EMU_STM32F303xC) | 19 | #if defined(EEPROM_EMU_STM32F303xC) |
20 | #define STM32F303xC | 20 | # define STM32F303xC |
21 | #include "stm32f3xx.h" | 21 | # include "stm32f3xx.h" |
22 | #elif defined(EEPROM_EMU_STM32F103xB) | 22 | #elif defined(EEPROM_EMU_STM32F103xB) |
23 | #define STM32F103xB | 23 | # define STM32F103xB |
24 | #include "stm32f1xx.h" | 24 | # include "stm32f1xx.h" |
25 | #elif defined(EEPROM_EMU_STM32F072xB) | 25 | #elif defined(EEPROM_EMU_STM32F072xB) |
26 | #define STM32F072xB | 26 | # define STM32F072xB |
27 | #include "stm32f0xx.h" | 27 | # include "stm32f0xx.h" |
28 | #else | 28 | #else |
29 | #error "not implemented." | 29 | # error "not implemented." |
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | #include "flash_stm32.h" | 32 | #include "flash_stm32.h" |
33 | 33 | ||
34 | #if defined(EEPROM_EMU_STM32F103xB) | 34 | #if defined(EEPROM_EMU_STM32F103xB) |
35 | #define FLASH_SR_WRPERR FLASH_SR_WRPRTERR | 35 | # define FLASH_SR_WRPERR FLASH_SR_WRPRTERR |
36 | #endif | 36 | #endif |
37 | 37 | ||
38 | /* Delay definition */ | 38 | /* Delay definition */ |
39 | #define EraseTimeout ((uint32_t)0x00000FFF) | 39 | #define EraseTimeout ((uint32_t)0x00000FFF) |
40 | #define ProgramTimeout ((uint32_t)0x0000001F) | 40 | #define ProgramTimeout ((uint32_t)0x0000001F) |
41 | 41 | ||
42 | #define ASSERT(exp) (void)((0)) | 42 | #define ASSERT(exp) (void)((0)) |
43 | 43 | ||
44 | /** | 44 | /** |
45 | * @brief Inserts a time delay. | 45 | * @brief Inserts a time delay. |
46 | * @param None | 46 | * @param None |
47 | * @retval None | 47 | * @retval None |
48 | */ | 48 | */ |
49 | static void delay(void) | 49 | static void delay(void) { |
50 | { | ||
51 | __IO uint32_t i = 0; | 50 | __IO uint32_t i = 0; |
52 | for(i = 0xFF; i != 0; i--) { } | 51 | for (i = 0xFF; i != 0; i--) { |
52 | } | ||
53 | } | 53 | } |
54 | 54 | ||
55 | /** | 55 | /** |
56 | * @brief Returns the FLASH Status. | 56 | * @brief Returns the FLASH Status. |
57 | * @param None | 57 | * @param None |
58 | * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, | 58 | * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, |
59 | * FLASH_ERROR_WRP or FLASH_COMPLETE | 59 | * FLASH_ERROR_WRP or FLASH_COMPLETE |
60 | */ | 60 | */ |
61 | FLASH_Status FLASH_GetStatus(void) | 61 | FLASH_Status FLASH_GetStatus(void) { |
62 | { | 62 | if ((FLASH->SR & FLASH_SR_BSY) == FLASH_SR_BSY) return FLASH_BUSY; |
63 | if ((FLASH->SR & FLASH_SR_BSY) == FLASH_SR_BSY) | ||
64 | return FLASH_BUSY; | ||
65 | 63 | ||
66 | if ((FLASH->SR & FLASH_SR_PGERR) != 0) | 64 | if ((FLASH->SR & FLASH_SR_PGERR) != 0) return FLASH_ERROR_PG; |
67 | return FLASH_ERROR_PG; | ||
68 | 65 | ||
69 | if ((FLASH->SR & FLASH_SR_WRPERR) != 0 ) | 66 | if ((FLASH->SR & FLASH_SR_WRPERR) != 0) return FLASH_ERROR_WRP; |
70 | return FLASH_ERROR_WRP; | ||
71 | 67 | ||
72 | if ((FLASH->SR & FLASH_OBR_OPTERR) != 0 ) | 68 | if ((FLASH->SR & FLASH_OBR_OPTERR) != 0) return FLASH_ERROR_OPT; |
73 | return FLASH_ERROR_OPT; | ||
74 | 69 | ||
75 | return FLASH_COMPLETE; | 70 | return FLASH_COMPLETE; |
76 | } | 71 | } |
77 | 72 | ||
78 | /** | 73 | /** |
79 | * @brief Waits for a Flash operation to complete or a TIMEOUT to occur. | 74 | * @brief Waits for a Flash operation to complete or a TIMEOUT to occur. |
80 | * @param Timeout: FLASH progamming Timeout | 75 | * @param Timeout: FLASH progamming Timeout |
81 | * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, | 76 | * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, |
82 | * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. | 77 | * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. |
83 | */ | 78 | */ |
84 | FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout) | 79 | FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout) { |
85 | { | ||
86 | FLASH_Status status; | 80 | FLASH_Status status; |
87 | 81 | ||
88 | /* Check for the Flash Status */ | 82 | /* Check for the Flash Status */ |
89 | status = FLASH_GetStatus(); | 83 | status = FLASH_GetStatus(); |
90 | /* Wait for a Flash operation to complete or a TIMEOUT to occur */ | 84 | /* Wait for a Flash operation to complete or a TIMEOUT to occur */ |
91 | while ((status == FLASH_BUSY) && (Timeout != 0x00)) | 85 | while ((status == FLASH_BUSY) && (Timeout != 0x00)) { |
92 | { | ||
93 | delay(); | 86 | delay(); |
94 | status = FLASH_GetStatus(); | 87 | status = FLASH_GetStatus(); |
95 | Timeout--; | 88 | Timeout--; |
96 | } | 89 | } |
97 | if (Timeout == 0) | 90 | if (Timeout == 0) status = FLASH_TIMEOUT; |
98 | status = FLASH_TIMEOUT; | ||
99 | /* Return the operation status */ | 91 | /* Return the operation status */ |
100 | return status; | 92 | return status; |
101 | } | 93 | } |
102 | 94 | ||
103 | /** | 95 | /** |
104 | * @brief Erases a specified FLASH page. | 96 | * @brief Erases a specified FLASH page. |
105 | * @param Page_Address: The page address to be erased. | 97 | * @param Page_Address: The page address to be erased. |
106 | * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, | 98 | * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG, |
107 | * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. | 99 | * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. |
108 | */ | 100 | */ |
109 | FLASH_Status FLASH_ErasePage(uint32_t Page_Address) | 101 | FLASH_Status FLASH_ErasePage(uint32_t Page_Address) { |
110 | { | ||
111 | FLASH_Status status = FLASH_COMPLETE; | 102 | FLASH_Status status = FLASH_COMPLETE; |
112 | /* Check the parameters */ | 103 | /* Check the parameters */ |
113 | ASSERT(IS_FLASH_ADDRESS(Page_Address)); | 104 | ASSERT(IS_FLASH_ADDRESS(Page_Address)); |
114 | /* Wait for last operation to be completed */ | 105 | /* Wait for last operation to be completed */ |
115 | status = FLASH_WaitForLastOperation(EraseTimeout); | 106 | status = FLASH_WaitForLastOperation(EraseTimeout); |
116 | 107 | ||
117 | if(status == FLASH_COMPLETE) | 108 | if (status == FLASH_COMPLETE) { |
118 | { | ||
119 | /* if the previous operation is completed, proceed to erase the page */ | 109 | /* if the previous operation is completed, proceed to erase the page */ |
120 | FLASH->CR |= FLASH_CR_PER; | 110 | FLASH->CR |= FLASH_CR_PER; |
121 | FLASH->AR = Page_Address; | 111 | FLASH->AR = Page_Address; |
@@ -123,8 +113,7 @@ FLASH_Status FLASH_ErasePage(uint32_t Page_Address) | |||
123 | 113 | ||
124 | /* Wait for last operation to be completed */ | 114 | /* Wait for last operation to be completed */ |
125 | status = FLASH_WaitForLastOperation(EraseTimeout); | 115 | status = FLASH_WaitForLastOperation(EraseTimeout); |
126 | if(status != FLASH_TIMEOUT) | 116 | if (status != FLASH_TIMEOUT) { |
127 | { | ||
128 | /* if the erase operation is completed, disable the PER Bit */ | 117 | /* if the erase operation is completed, disable the PER Bit */ |
129 | FLASH->CR &= ~FLASH_CR_PER; | 118 | FLASH->CR &= ~FLASH_CR_PER; |
130 | } | 119 | } |
@@ -135,29 +124,25 @@ FLASH_Status FLASH_ErasePage(uint32_t Page_Address) | |||
135 | } | 124 | } |
136 | 125 | ||
137 | /** | 126 | /** |
138 | * @brief Programs a half word at a specified address. | 127 | * @brief Programs a half word at a specified address. |
139 | * @param Address: specifies the address to be programmed. | 128 | * @param Address: specifies the address to be programmed. |
140 | * @param Data: specifies the data to be programmed. | 129 | * @param Data: specifies the data to be programmed. |
141 | * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, | 130 | * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, |
142 | * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. | 131 | * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. |
143 | */ | 132 | */ |
144 | FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) | 133 | FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) { |
145 | { | ||
146 | FLASH_Status status = FLASH_BAD_ADDRESS; | 134 | FLASH_Status status = FLASH_BAD_ADDRESS; |
147 | 135 | ||
148 | if (IS_FLASH_ADDRESS(Address)) | 136 | if (IS_FLASH_ADDRESS(Address)) { |
149 | { | ||
150 | /* Wait for last operation to be completed */ | 137 | /* Wait for last operation to be completed */ |
151 | status = FLASH_WaitForLastOperation(ProgramTimeout); | 138 | status = FLASH_WaitForLastOperation(ProgramTimeout); |
152 | if(status == FLASH_COMPLETE) | 139 | if (status == FLASH_COMPLETE) { |
153 | { | ||
154 | /* if the previous operation is completed, proceed to program the new data */ | 140 | /* if the previous operation is completed, proceed to program the new data */ |
155 | FLASH->CR |= FLASH_CR_PG; | 141 | FLASH->CR |= FLASH_CR_PG; |
156 | *(__IO uint16_t*)Address = Data; | 142 | *(__IO uint16_t*)Address = Data; |
157 | /* Wait for last operation to be completed */ | 143 | /* Wait for last operation to be completed */ |
158 | status = FLASH_WaitForLastOperation(ProgramTimeout); | 144 | status = FLASH_WaitForLastOperation(ProgramTimeout); |
159 | if(status != FLASH_TIMEOUT) | 145 | if (status != FLASH_TIMEOUT) { |
160 | { | ||
161 | /* if the program operation is completed, disable the PG Bit */ | 146 | /* if the program operation is completed, disable the PG Bit */ |
162 | FLASH->CR &= ~FLASH_CR_PG; | 147 | FLASH->CR &= ~FLASH_CR_PG; |
163 | } | 148 | } |
@@ -168,39 +153,36 @@ FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) | |||
168 | } | 153 | } |
169 | 154 | ||
170 | /** | 155 | /** |
171 | * @brief Unlocks the FLASH Program Erase Controller. | 156 | * @brief Unlocks the FLASH Program Erase Controller. |
172 | * @param None | 157 | * @param None |
173 | * @retval None | 158 | * @retval None |
174 | */ | 159 | */ |
175 | void FLASH_Unlock(void) | 160 | void FLASH_Unlock(void) { |
176 | { | ||
177 | /* Authorize the FPEC Access */ | 161 | /* Authorize the FPEC Access */ |
178 | FLASH->KEYR = FLASH_KEY1; | 162 | FLASH->KEYR = FLASH_KEY1; |
179 | FLASH->KEYR = FLASH_KEY2; | 163 | FLASH->KEYR = FLASH_KEY2; |
180 | } | 164 | } |
181 | 165 | ||
182 | /** | 166 | /** |
183 | * @brief Locks the FLASH Program Erase Controller. | 167 | * @brief Locks the FLASH Program Erase Controller. |
184 | * @param None | 168 | * @param None |
185 | * @retval None | 169 | * @retval None |
186 | */ | 170 | */ |
187 | void FLASH_Lock(void) | 171 | void FLASH_Lock(void) { |
188 | { | ||
189 | /* Set the Lock Bit to lock the FPEC and the FCR */ | 172 | /* Set the Lock Bit to lock the FPEC and the FCR */ |
190 | FLASH->CR |= FLASH_CR_LOCK; | 173 | FLASH->CR |= FLASH_CR_LOCK; |
191 | } | 174 | } |
192 | 175 | ||
193 | /** | 176 | /** |
194 | * @brief Clears the FLASH's pending flags. | 177 | * @brief Clears the FLASH's pending flags. |
195 | * @param FLASH_FLAG: specifies the FLASH flags to clear. | 178 | * @param FLASH_FLAG: specifies the FLASH flags to clear. |
196 | * This parameter can be any combination of the following values: | 179 | * This parameter can be any combination of the following values: |
197 | * @arg FLASH_FLAG_PGERR: FLASH Programming error flag flag | 180 | * @arg FLASH_FLAG_PGERR: FLASH Programming error flag flag |
198 | * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag | 181 | * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag |
199 | * @arg FLASH_FLAG_EOP: FLASH End of Programming flag | 182 | * @arg FLASH_FLAG_EOP: FLASH End of Programming flag |
200 | * @retval None | 183 | * @retval None |
201 | */ | 184 | */ |
202 | void FLASH_ClearFlag(uint32_t FLASH_FLAG) | 185 | void FLASH_ClearFlag(uint32_t FLASH_FLAG) { |
203 | { | ||
204 | /* Clear the flags */ | 186 | /* Clear the flags */ |
205 | FLASH->SR = FLASH_FLAG; | 187 | FLASH->SR = FLASH_FLAG; |
206 | } | 188 | } |
diff --git a/tmk_core/common/chibios/flash_stm32.h b/tmk_core/common/chibios/flash_stm32.h index 3c99cc566..33ab7867d 100755..100644 --- a/tmk_core/common/chibios/flash_stm32.h +++ b/tmk_core/common/chibios/flash_stm32.h | |||
@@ -10,7 +10,7 @@ | |||
10 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 10 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
11 | * DEALINGS IN THE SOFTWARE. | 11 | * DEALINGS IN THE SOFTWARE. |
12 | * | 12 | * |
13 | * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and | 13 | * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and |
14 | * https://github.com/leaflabs/libmaple | 14 | * https://github.com/leaflabs/libmaple |
15 | * | 15 | * |
16 | * Modifications for QMK and STM32F303 by Yiancar | 16 | * Modifications for QMK and STM32F303 by Yiancar |
@@ -20,22 +20,13 @@ | |||
20 | #define __FLASH_STM32_H | 20 | #define __FLASH_STM32_H |
21 | 21 | ||
22 | #ifdef __cplusplus | 22 | #ifdef __cplusplus |
23 | extern "C" { | 23 | extern "C" { |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | #include "ch.h" | 26 | #include "ch.h" |
27 | #include "hal.h" | 27 | #include "hal.h" |
28 | 28 | ||
29 | typedef enum | 29 | typedef enum { FLASH_BUSY = 1, FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_ERROR_OPT, FLASH_COMPLETE, FLASH_TIMEOUT, FLASH_BAD_ADDRESS } FLASH_Status; |
30 | { | ||
31 | FLASH_BUSY = 1, | ||
32 | FLASH_ERROR_PG, | ||
33 | FLASH_ERROR_WRP, | ||
34 | FLASH_ERROR_OPT, | ||
35 | FLASH_COMPLETE, | ||
36 | FLASH_TIMEOUT, | ||
37 | FLASH_BAD_ADDRESS | ||
38 | } FLASH_Status; | ||
39 | 30 | ||
40 | #define IS_FLASH_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08000000) && ((ADDRESS) < 0x0807FFFF)) | 31 | #define IS_FLASH_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08000000) && ((ADDRESS) < 0x0807FFFF)) |
41 | 32 | ||
diff --git a/tmk_core/common/chibios/printf.c b/tmk_core/common/chibios/printf.c index 72e3d4f8c..dbd059448 100644 --- a/tmk_core/common/chibios/printf.c +++ b/tmk_core/common/chibios/printf.c | |||
@@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
26 | 26 | ||
27 | #include "printf.h" | 27 | #include "printf.h" |
28 | 28 | ||
29 | typedef void (*putcf) (void*,char); | 29 | typedef void (*putcf)(void*, char); |
30 | static putcf stdout_putf; | 30 | static putcf stdout_putf; |
31 | static void* stdout_putp; | 31 | static void* stdout_putp; |
32 | 32 | ||
@@ -35,206 +35,185 @@ static void* stdout_putp; | |||
35 | 35 | ||
36 | #ifdef PRINTF_LONG_SUPPORT | 36 | #ifdef PRINTF_LONG_SUPPORT |
37 | 37 | ||
38 | static void uli2a(unsigned long int num, unsigned int base, int uc,char * bf) | 38 | static void uli2a(unsigned long int num, unsigned int base, int uc, char* bf) { |
39 | { | 39 | int n = 0; |
40 | int n=0; | 40 | unsigned int d = 1; |
41 | unsigned int d=1; | 41 | while (num / d >= base) d *= base; |
42 | while (num/d >= base) | 42 | while (d != 0) { |
43 | d*=base; | ||
44 | while (d!=0) { | ||
45 | int dgt = num / d; | 43 | int dgt = num / d; |
46 | num%=d; | 44 | num %= d; |
47 | d/=base; | 45 | d /= base; |
48 | if (n || dgt>0|| d==0) { | 46 | if (n || dgt > 0 || d == 0) { |
49 | *bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10); | 47 | *bf++ = dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10); |
50 | ++n; | 48 | ++n; |
51 | } | ||
52 | } | 49 | } |
53 | *bf=0; | ||
54 | } | 50 | } |
51 | *bf = 0; | ||
52 | } | ||
55 | 53 | ||
56 | static void li2a (long num, char * bf) | 54 | static void li2a(long num, char* bf) { |
57 | { | 55 | if (num < 0) { |
58 | if (num<0) { | 56 | num = -num; |
59 | num=-num; | ||
60 | *bf++ = '-'; | 57 | *bf++ = '-'; |
61 | } | ||
62 | uli2a(num,10,0,bf); | ||
63 | } | 58 | } |
59 | uli2a(num, 10, 0, bf); | ||
60 | } | ||
64 | 61 | ||
65 | #endif | 62 | #endif |
66 | 63 | ||
67 | static void ui2a(unsigned int num, unsigned int base, int uc,char * bf) | 64 | static void ui2a(unsigned int num, unsigned int base, int uc, char* bf) { |
68 | { | 65 | int n = 0; |
69 | int n=0; | 66 | unsigned int d = 1; |
70 | unsigned int d=1; | 67 | while (num / d >= base) d *= base; |
71 | while (num/d >= base) | 68 | while (d != 0) { |
72 | d*=base; | ||
73 | while (d!=0) { | ||
74 | int dgt = num / d; | 69 | int dgt = num / d; |
75 | num%= d; | 70 | num %= d; |
76 | d/=base; | 71 | d /= base; |
77 | if (n || dgt>0 || d==0) { | 72 | if (n || dgt > 0 || d == 0) { |
78 | *bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10); | 73 | *bf++ = dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10); |
79 | ++n; | 74 | ++n; |
80 | } | ||
81 | } | 75 | } |
82 | *bf=0; | ||
83 | } | 76 | } |
77 | *bf = 0; | ||
78 | } | ||
84 | 79 | ||
85 | static void i2a (int num, char * bf) | 80 | static void i2a(int num, char* bf) { |
86 | { | 81 | if (num < 0) { |
87 | if (num<0) { | 82 | num = -num; |
88 | num=-num; | ||
89 | *bf++ = '-'; | 83 | *bf++ = '-'; |
90 | } | ||
91 | ui2a(num,10,0,bf); | ||
92 | } | 84 | } |
93 | 85 | ui2a(num, 10, 0, bf); | |
94 | static int a2d(char ch) | 86 | } |
95 | { | 87 | |
96 | if (ch>='0' && ch<='9') | 88 | static int a2d(char ch) { |
97 | return ch-'0'; | 89 | if (ch >= '0' && ch <= '9') |
98 | else if (ch>='a' && ch<='f') | 90 | return ch - '0'; |
99 | return ch-'a'+10; | 91 | else if (ch >= 'a' && ch <= 'f') |
100 | else if (ch>='A' && ch<='F') | 92 | return ch - 'a' + 10; |
101 | return ch-'A'+10; | 93 | else if (ch >= 'A' && ch <= 'F') |
102 | else return -1; | 94 | return ch - 'A' + 10; |
95 | else | ||
96 | return -1; | ||
97 | } | ||
98 | |||
99 | static char a2i(char ch, char** src, int base, int* nump) { | ||
100 | char* p = *src; | ||
101 | int num = 0; | ||
102 | int digit; | ||
103 | while ((digit = a2d(ch)) >= 0) { | ||
104 | if (digit > base) break; | ||
105 | num = num * base + digit; | ||
106 | ch = *p++; | ||
103 | } | 107 | } |
104 | 108 | *src = p; | |
105 | static char a2i(char ch, char** src,int base,int* nump) | 109 | *nump = num; |
106 | { | ||
107 | char* p= *src; | ||
108 | int num=0; | ||
109 | int digit; | ||
110 | while ((digit=a2d(ch))>=0) { | ||
111 | if (digit>base) break; | ||
112 | num=num*base+digit; | ||
113 | ch=*p++; | ||
114 | } | ||
115 | *src=p; | ||
116 | *nump=num; | ||
117 | return ch; | 110 | return ch; |
118 | } | 111 | } |
119 | 112 | ||
120 | static void putchw(void* putp,putcf putf,int n, char z, char* bf) | 113 | static void putchw(void* putp, putcf putf, int n, char z, char* bf) { |
121 | { | 114 | char fc = z ? '0' : ' '; |
122 | char fc=z? '0' : ' '; | 115 | char ch; |
123 | char ch; | 116 | char* p = bf; |
124 | char* p=bf; | 117 | while (*p++ && n > 0) n--; |
125 | while (*p++ && n > 0) | 118 | while (n-- > 0) putf(putp, fc); |
126 | n--; | 119 | while ((ch = *bf++)) putf(putp, ch); |
127 | while (n-- > 0) | 120 | } |
128 | putf(putp,fc); | 121 | |
129 | while ((ch= *bf++)) | 122 | void tfp_format(void* putp, putcf putf, char* fmt, va_list va) { |
130 | putf(putp,ch); | ||
131 | } | ||
132 | |||
133 | void tfp_format(void* putp,putcf putf,char *fmt, va_list va) | ||
134 | { | ||
135 | char bf[12]; | 123 | char bf[12]; |
136 | |||
137 | char ch; | ||
138 | 124 | ||
125 | char ch; | ||
139 | 126 | ||
140 | while ((ch=*(fmt++))) { | 127 | while ((ch = *(fmt++))) { |
141 | if (ch!='%') | 128 | if (ch != '%') |
142 | putf(putp,ch); | 129 | putf(putp, ch); |
143 | else { | 130 | else { |
144 | char lz=0; | 131 | char lz = 0; |
145 | #ifdef PRINTF_LONG_SUPPORT | 132 | #ifdef PRINTF_LONG_SUPPORT |
146 | char lng=0; | 133 | char lng = 0; |
147 | #endif | 134 | #endif |
148 | int w=0; | 135 | int w = 0; |
149 | ch=*(fmt++); | 136 | ch = *(fmt++); |
150 | if (ch=='0') { | 137 | if (ch == '0') { |
151 | ch=*(fmt++); | 138 | ch = *(fmt++); |
152 | lz=1; | 139 | lz = 1; |
153 | } | 140 | } |
154 | if (ch>='0' && ch<='9') { | 141 | if (ch >= '0' && ch <= '9') { |
155 | ch=a2i(ch,&fmt,10,&w); | 142 | ch = a2i(ch, &fmt, 10, &w); |
156 | } | 143 | } |
157 | #ifdef PRINTF_LONG_SUPPORT | 144 | #ifdef PRINTF_LONG_SUPPORT |
158 | if (ch=='l') { | 145 | if (ch == 'l') { |
159 | ch=*(fmt++); | 146 | ch = *(fmt++); |
160 | lng=1; | 147 | lng = 1; |
161 | } | 148 | } |
162 | #endif | 149 | #endif |
163 | switch (ch) { | 150 | switch (ch) { |
164 | case 0: | 151 | case 0: |
165 | goto abort; | 152 | goto abort; |
166 | case 'u' : { | 153 | case 'u': { |
167 | #ifdef PRINTF_LONG_SUPPORT | 154 | #ifdef PRINTF_LONG_SUPPORT |
168 | if (lng) | 155 | if (lng) |
169 | uli2a(va_arg(va, unsigned long int),10,0,bf); | 156 | uli2a(va_arg(va, unsigned long int), 10, 0, bf); |
170 | else | 157 | else |
171 | #endif | 158 | #endif |
172 | ui2a(va_arg(va, unsigned int),10,0,bf); | 159 | ui2a(va_arg(va, unsigned int), 10, 0, bf); |
173 | putchw(putp,putf,w,lz,bf); | 160 | putchw(putp, putf, w, lz, bf); |
174 | break; | 161 | break; |
175 | } | 162 | } |
176 | case 'd' : { | 163 | case 'd': { |
177 | #ifdef PRINTF_LONG_SUPPORT | 164 | #ifdef PRINTF_LONG_SUPPORT |
178 | if (lng) | 165 | if (lng) |
179 | li2a(va_arg(va, unsigned long int),bf); | 166 | li2a(va_arg(va, unsigned long int), bf); |
180 | else | 167 | else |
181 | #endif | 168 | #endif |
182 | i2a(va_arg(va, int),bf); | 169 | i2a(va_arg(va, int), bf); |
183 | putchw(putp,putf,w,lz,bf); | 170 | putchw(putp, putf, w, lz, bf); |
184 | break; | 171 | break; |
185 | } | 172 | } |
186 | case 'x': case 'X' : | 173 | case 'x': |
187 | #ifdef PRINTF_LONG_SUPPORT | 174 | case 'X': |
175 | #ifdef PRINTF_LONG_SUPPORT | ||
188 | if (lng) | 176 | if (lng) |
189 | uli2a(va_arg(va, unsigned long int),16,(ch=='X'),bf); | 177 | uli2a(va_arg(va, unsigned long int), 16, (ch == 'X'), bf); |
190 | else | 178 | else |
191 | #endif | 179 | #endif |
192 | ui2a(va_arg(va, unsigned int),16,(ch=='X'),bf); | 180 | ui2a(va_arg(va, unsigned int), 16, (ch == 'X'), bf); |
193 | putchw(putp,putf,w,lz,bf); | 181 | putchw(putp, putf, w, lz, bf); |
194 | break; | 182 | break; |
195 | case 'c' : | 183 | case 'c': |
196 | putf(putp,(char)(va_arg(va, int))); | 184 | putf(putp, (char)(va_arg(va, int))); |
197 | break; | 185 | break; |
198 | case 's' : | 186 | case 's': |
199 | putchw(putp,putf,w,0,va_arg(va, char*)); | 187 | putchw(putp, putf, w, 0, va_arg(va, char*)); |
200 | break; | 188 | break; |
201 | case '%' : | 189 | case '%': |
202 | putf(putp,ch); | 190 | putf(putp, ch); |
203 | default: | 191 | default: |
204 | break; | 192 | break; |
205 | } | ||
206 | } | 193 | } |
207 | } | 194 | } |
208 | abort:; | ||
209 | } | 195 | } |
196 | abort:; | ||
197 | } | ||
210 | 198 | ||
199 | void init_printf(void* putp, void (*putf)(void*, char)) { | ||
200 | stdout_putf = putf; | ||
201 | stdout_putp = putp; | ||
202 | } | ||
211 | 203 | ||
212 | void init_printf(void* putp,void (*putf) (void*,char)) | 204 | void tfp_printf(char* fmt, ...) { |
213 | { | ||
214 | stdout_putf=putf; | ||
215 | stdout_putp=putp; | ||
216 | } | ||
217 | |||
218 | void tfp_printf(char *fmt, ...) | ||
219 | { | ||
220 | va_list va; | 205 | va_list va; |
221 | va_start(va,fmt); | 206 | va_start(va, fmt); |
222 | tfp_format(stdout_putp,stdout_putf,fmt,va); | 207 | tfp_format(stdout_putp, stdout_putf, fmt, va); |
223 | va_end(va); | 208 | va_end(va); |
224 | } | 209 | } |
225 | |||
226 | static void putcp(void* p,char c) | ||
227 | { | ||
228 | *(*((char**)p))++ = c; | ||
229 | } | ||
230 | 210 | ||
211 | static void putcp(void* p, char c) { *(*((char**)p))++ = c; } | ||
231 | 212 | ||
232 | 213 | void tfp_sprintf(char* s, char* fmt, ...) { | |
233 | void tfp_sprintf(char* s,char *fmt, ...) | ||
234 | { | ||
235 | va_list va; | 214 | va_list va; |
236 | va_start(va,fmt); | 215 | va_start(va, fmt); |
237 | tfp_format(&s,putcp,fmt,va); | 216 | tfp_format(&s, putcp, fmt, va); |
238 | putcp(&s,0); | 217 | putcp(&s, 0); |
239 | va_end(va); | 218 | va_end(va); |
240 | } | 219 | } |
diff --git a/tmk_core/common/chibios/printf.h b/tmk_core/common/chibios/printf.h index 678a100c6..2cdf55ed9 100644 --- a/tmk_core/common/chibios/printf.h +++ b/tmk_core/common/chibios/printf.h | |||
@@ -15,7 +15,7 @@ version 2.1 of the License, or (at your option) any later version. | |||
15 | 15 | ||
16 | This library is distributed in the hope that it will be useful, | 16 | This library is distributed in the hope that it will be useful, |
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
19 | See the GNU Lesser General Public License for more details. | 19 | See the GNU Lesser General Public License for more details. |
20 | 20 | ||
21 | You should have received a copy of the GNU Lesser General Public | 21 | You should have received a copy of the GNU Lesser General Public |
@@ -24,35 +24,35 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
24 | 24 | ||
25 | This library is realy just two files: 'printf.h' and 'printf.c'. | 25 | This library is realy just two files: 'printf.h' and 'printf.c'. |
26 | 26 | ||
27 | They provide a simple and small (+200 loc) printf functionality to | 27 | They provide a simple and small (+200 loc) printf functionality to |
28 | be used in embedded systems. | 28 | be used in embedded systems. |
29 | 29 | ||
30 | I've found them so usefull in debugging that I do not bother with a | 30 | I've found them so usefull in debugging that I do not bother with a |
31 | debugger at all. | 31 | debugger at all. |
32 | 32 | ||
33 | They are distributed in source form, so to use them, just compile them | 33 | They are distributed in source form, so to use them, just compile them |
34 | into your project. | 34 | into your project. |
35 | 35 | ||
36 | Two printf variants are provided: printf and sprintf. | 36 | Two printf variants are provided: printf and sprintf. |
37 | 37 | ||
38 | The formats supported by this implementation are: 'd' 'u' 'c' 's' 'x' 'X'. | 38 | The formats supported by this implementation are: 'd' 'u' 'c' 's' 'x' 'X'. |
39 | 39 | ||
40 | Zero padding and field width are also supported. | 40 | Zero padding and field width are also supported. |
41 | 41 | ||
42 | If the library is compiled with 'PRINTF_SUPPORT_LONG' defined then the | 42 | If the library is compiled with 'PRINTF_SUPPORT_LONG' defined then the |
43 | long specifier is also | 43 | long specifier is also |
44 | supported. Note that this will pull in some long math routines (pun intended!) | 44 | supported. Note that this will pull in some long math routines (pun intended!) |
45 | and thus make your executable noticably longer. | 45 | and thus make your executable noticably longer. |
46 | 46 | ||
47 | The memory foot print of course depends on the target cpu, compiler and | 47 | The memory foot print of course depends on the target cpu, compiler and |
48 | compiler options, but a rough guestimate (based on a H8S target) is about | 48 | compiler options, but a rough guestimate (based on a H8S target) is about |
49 | 1.4 kB for code and some twenty 'int's and 'char's, say 60 bytes of stack space. | 49 | 1.4 kB for code and some twenty 'int's and 'char's, say 60 bytes of stack space. |
50 | Not too bad. Your milage may vary. By hacking the source code you can | 50 | Not too bad. Your milage may vary. By hacking the source code you can |
51 | get rid of some hunred bytes, I'm sure, but personally I feel the balance of | 51 | get rid of some hunred bytes, I'm sure, but personally I feel the balance of |
52 | functionality and flexibility versus code size is close to optimal for | 52 | functionality and flexibility versus code size is close to optimal for |
53 | many embedded systems. | 53 | many embedded systems. |
54 | 54 | ||
55 | To use the printf you need to supply your own character output function, | 55 | To use the printf you need to supply your own character output function, |
56 | something like : | 56 | something like : |
57 | 57 | ||
58 | void putc ( void* p, char c) | 58 | void putc ( void* p, char c) |
@@ -61,25 +61,25 @@ something like : | |||
61 | SERIAL_PORT_TX_REGISTER = c; | 61 | SERIAL_PORT_TX_REGISTER = c; |
62 | } | 62 | } |
63 | 63 | ||
64 | Before you can call printf you need to initialize it to use your | 64 | Before you can call printf you need to initialize it to use your |
65 | character output function with something like: | 65 | character output function with something like: |
66 | 66 | ||
67 | init_printf(NULL,putc); | 67 | init_printf(NULL,putc); |
68 | 68 | ||
69 | Notice the 'NULL' in 'init_printf' and the parameter 'void* p' in 'putc', | 69 | Notice the 'NULL' in 'init_printf' and the parameter 'void* p' in 'putc', |
70 | the NULL (or any pointer) you pass into the 'init_printf' will eventually be | 70 | the NULL (or any pointer) you pass into the 'init_printf' will eventually be |
71 | passed to your 'putc' routine. This allows you to pass some storage space (or | 71 | passed to your 'putc' routine. This allows you to pass some storage space (or |
72 | anything realy) to the character output function, if necessary. | 72 | anything realy) to the character output function, if necessary. |
73 | This is not often needed but it was implemented like that because it made | 73 | This is not often needed but it was implemented like that because it made |
74 | implementing the sprintf function so neat (look at the source code). | 74 | implementing the sprintf function so neat (look at the source code). |
75 | 75 | ||
76 | The code is re-entrant, except for the 'init_printf' function, so it | 76 | The code is re-entrant, except for the 'init_printf' function, so it |
77 | is safe to call it from interupts too, although this may result in mixed output. | 77 | is safe to call it from interupts too, although this may result in mixed output. |
78 | If you rely on re-entrancy, take care that your 'putc' function is re-entrant! | 78 | If you rely on re-entrancy, take care that your 'putc' function is re-entrant! |
79 | 79 | ||
80 | The printf and sprintf functions are actually macros that translate to | 80 | The printf and sprintf functions are actually macros that translate to |
81 | 'tfp_printf' and 'tfp_sprintf'. This makes it possible | 81 | 'tfp_printf' and 'tfp_sprintf'. This makes it possible |
82 | to use them along with 'stdio.h' printf's in a single source file. | 82 | to use them along with 'stdio.h' printf's in a single source file. |
83 | You just need to undef the names before you include the 'stdio.h'. | 83 | You just need to undef the names before you include the 'stdio.h'. |
84 | Note that these are not function like macros, so if you have variables | 84 | Note that these are not function like macros, so if you have variables |
85 | or struct members with these names, things will explode in your face. | 85 | or struct members with these names, things will explode in your face. |
@@ -92,20 +92,19 @@ For further details see source code. | |||
92 | regs Kusti, 23.10.2004 | 92 | regs Kusti, 23.10.2004 |
93 | */ | 93 | */ |
94 | 94 | ||
95 | |||
96 | #ifndef __TFP_PRINTF__ | 95 | #ifndef __TFP_PRINTF__ |
97 | #define __TFP_PRINTF__ | 96 | #define __TFP_PRINTF__ |
98 | 97 | ||
99 | #include <stdarg.h> | 98 | #include <stdarg.h> |
100 | 99 | ||
101 | void init_printf(void* putp,void (*putf) (void*,char)); | 100 | void init_printf(void* putp, void (*putf)(void*, char)); |
102 | 101 | ||
103 | void tfp_printf(char *fmt, ...); | 102 | void tfp_printf(char* fmt, ...); |
104 | void tfp_sprintf(char* s,char *fmt, ...); | 103 | void tfp_sprintf(char* s, char* fmt, ...); |
105 | 104 | ||
106 | void tfp_format(void* putp,void (*putf) (void*,char),char *fmt, va_list va); | 105 | void tfp_format(void* putp, void (*putf)(void*, char), char* fmt, va_list va); |
107 | 106 | ||
108 | #define printf tfp_printf | 107 | #define printf tfp_printf |
109 | #define sprintf tfp_sprintf | 108 | #define sprintf tfp_sprintf |
110 | 109 | ||
111 | #endif | 110 | #endif |
diff --git a/tmk_core/common/chibios/sleep_led.c b/tmk_core/common/chibios/sleep_led.c index 4c35cfcba..df1a1b5fc 100644 --- a/tmk_core/common/chibios/sleep_led.c +++ b/tmk_core/common/chibios/sleep_led.c | |||
@@ -12,14 +12,14 @@ | |||
12 | #if defined(KL2x) || defined(K20x) | 12 | #if defined(KL2x) || defined(K20x) |
13 | 13 | ||
14 | /* Use Low Power Timer (LPTMR) */ | 14 | /* Use Low Power Timer (LPTMR) */ |
15 | #define TIMER_INTERRUPT_VECTOR KINETIS_LPTMR0_IRQ_VECTOR | 15 | # define TIMER_INTERRUPT_VECTOR KINETIS_LPTMR0_IRQ_VECTOR |
16 | #define RESET_COUNTER LPTMR0->CSR |= LPTMRx_CSR_TCF | 16 | # define RESET_COUNTER LPTMR0->CSR |= LPTMRx_CSR_TCF |
17 | 17 | ||
18 | #elif defined(STM32F0XX) | 18 | #elif defined(STM32F0XX) |
19 | 19 | ||
20 | /* Use TIM14 manually */ | 20 | /* Use TIM14 manually */ |
21 | #define TIMER_INTERRUPT_VECTOR STM32_TIM14_HANDLER | 21 | # define TIMER_INTERRUPT_VECTOR STM32_TIM14_HANDLER |
22 | #define RESET_COUNTER STM32_TIM14->SR &= ~STM32_TIM_SR_UIF | 22 | # define RESET_COUNTER STM32_TIM14->SR &= ~STM32_TIM_SR_UIF |
23 | 23 | ||
24 | #endif | 24 | #endif |
25 | 25 | ||
@@ -31,39 +31,34 @@ | |||
31 | * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63 | 31 | * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63 |
32 | * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i } | 32 | * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i } |
33 | */ | 33 | */ |
34 | static const uint8_t breathing_table[64] = { | 34 | static const uint8_t breathing_table[64] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10, 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252, 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23, 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; |
35 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10, | ||
36 | 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252, | ||
37 | 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23, | ||
38 | 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||
39 | }; | ||
40 | 35 | ||
41 | /* interrupt handler */ | 36 | /* interrupt handler */ |
42 | OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) { | 37 | OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) { |
43 | OSAL_IRQ_PROLOGUE(); | 38 | OSAL_IRQ_PROLOGUE(); |
44 | 39 | ||
45 | /* Software PWM | 40 | /* Software PWM |
46 | * timer:1111 1111 1111 1111 | 41 | * timer:1111 1111 1111 1111 |
47 | * \_____/\/ \_______/____ count(0-255) | 42 | * \_____/\/ \_______/____ count(0-255) |
48 | * \ \______________ duration of step(4) | 43 | * \ \______________ duration of step(4) |
49 | * \__________________ index of step table(0-63) | 44 | * \__________________ index of step table(0-63) |
50 | */ | 45 | */ |
51 | 46 | ||
52 | // this works for cca 65536 irqs/sec | 47 | // this works for cca 65536 irqs/sec |
53 | static union { | 48 | static union { |
54 | uint16_t row; | 49 | uint16_t row; |
55 | struct { | 50 | struct { |
56 | uint8_t count:8; | 51 | uint8_t count : 8; |
57 | uint8_t duration:2; | 52 | uint8_t duration : 2; |
58 | uint8_t index:6; | 53 | uint8_t index : 6; |
59 | } pwm; | 54 | } pwm; |
60 | } timer = { .row = 0 }; | 55 | } timer = {.row = 0}; |
61 | 56 | ||
62 | timer.row++; | 57 | timer.row++; |
63 | 58 | ||
64 | // LED on | 59 | // LED on |
65 | if (timer.pwm.count == 0) { | 60 | if (timer.pwm.count == 0) { |
66 | led_set(1<<USB_LED_CAPS_LOCK); | 61 | led_set(1 << USB_LED_CAPS_LOCK); |
67 | } | 62 | } |
68 | // LED off | 63 | // LED off |
69 | if (timer.pwm.count == breathing_table[timer.pwm.index]) { | 64 | if (timer.pwm.count == breathing_table[timer.pwm.index]) { |
@@ -78,19 +73,18 @@ OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) { | |||
78 | 73 | ||
79 | #endif /* common parts for known platforms */ | 74 | #endif /* common parts for known platforms */ |
80 | 75 | ||
81 | |||
82 | #if defined(KL2x) || defined(K20x) /* platform selection: familiar Kinetis chips */ | 76 | #if defined(KL2x) || defined(K20x) /* platform selection: familiar Kinetis chips */ |
83 | 77 | ||
84 | /* LPTMR clock options */ | 78 | /* LPTMR clock options */ |
85 | #define LPTMR_CLOCK_MCGIRCLK 0 /* 4MHz clock */ | 79 | # define LPTMR_CLOCK_MCGIRCLK 0 /* 4MHz clock */ |
86 | #define LPTMR_CLOCK_LPO 1 /* 1kHz clock */ | 80 | # define LPTMR_CLOCK_LPO 1 /* 1kHz clock */ |
87 | #define LPTMR_CLOCK_ERCLK32K 2 /* external 32kHz crystal */ | 81 | # define LPTMR_CLOCK_ERCLK32K 2 /* external 32kHz crystal */ |
88 | #define LPTMR_CLOCK_OSCERCLK 3 /* output from OSC */ | 82 | # define LPTMR_CLOCK_OSCERCLK 3 /* output from OSC */ |
89 | 83 | ||
90 | /* Work around inconsistencies in Freescale naming */ | 84 | /* Work around inconsistencies in Freescale naming */ |
91 | #if !defined(SIM_SCGC5_LPTMR) | 85 | # if !defined(SIM_SCGC5_LPTMR) |
92 | #define SIM_SCGC5_LPTMR SIM_SCGC5_LPTIMER | 86 | # define SIM_SCGC5_LPTMR SIM_SCGC5_LPTIMER |
93 | #endif | 87 | # endif |
94 | 88 | ||
95 | /* Initialise the timer */ | 89 | /* Initialise the timer */ |
96 | void sleep_led_init(void) { | 90 | void sleep_led_init(void) { |
@@ -101,52 +95,52 @@ void sleep_led_init(void) { | |||
101 | /* Set the compare value */ | 95 | /* Set the compare value */ |
102 | LPTMR0->CMR = 0; // trigger on counter value (i.e. every time) | 96 | LPTMR0->CMR = 0; // trigger on counter value (i.e. every time) |
103 | 97 | ||
104 | /* Set up clock source and prescaler */ | 98 | /* Set up clock source and prescaler */ |
105 | /* Software PWM | 99 | /* Software PWM |
106 | * ______ ______ __ | 100 | * ______ ______ __ |
107 | * | ON |___OFF___| ON |___OFF___| .... | 101 | * | ON |___OFF___| ON |___OFF___| .... |
108 | * |<-------------->|<-------------->|<- .... | 102 | * |<-------------->|<-------------->|<- .... |
109 | * PWM period PWM period | 103 | * PWM period PWM period |
110 | * | 104 | * |
111 | * R interrupts/period[resolution] | 105 | * R interrupts/period[resolution] |
112 | * F periods/second[frequency] | 106 | * F periods/second[frequency] |
113 | * R * F interrupts/second | 107 | * R * F interrupts/second |
114 | */ | 108 | */ |
115 | 109 | ||
116 | /* === OPTION 1 === */ | 110 | /* === OPTION 1 === */ |
117 | #if 0 | 111 | # if 0 |
118 | // 1kHz LPO | 112 | // 1kHz LPO |
119 | // No prescaler => 1024 irqs/sec | 113 | // No prescaler => 1024 irqs/sec |
120 | // Note: this is too slow for a smooth breathe | 114 | // Note: this is too slow for a smooth breathe |
121 | LPTMR0->PSR = LPTMRx_PSR_PCS(LPTMR_CLOCK_LPO)|LPTMRx_PSR_PBYP; | 115 | LPTMR0->PSR = LPTMRx_PSR_PCS(LPTMR_CLOCK_LPO)|LPTMRx_PSR_PBYP; |
122 | #endif /* OPTION 1 */ | 116 | # endif /* OPTION 1 */ |
123 | 117 | ||
124 | /* === OPTION 2 === */ | 118 | /* === OPTION 2 === */ |
125 | #if 1 | 119 | # if 1 |
126 | // nMHz IRC (n=4 on KL25Z, KL26Z and K20x; n=2 or 8 on KL27Z) | 120 | // nMHz IRC (n=4 on KL25Z, KL26Z and K20x; n=2 or 8 on KL27Z) |
127 | MCG->C2 |= MCG_C2_IRCS; // fast (4MHz) internal ref clock | 121 | MCG->C2 |= MCG_C2_IRCS; // fast (4MHz) internal ref clock |
128 | #if defined(KL27) // divide the 8MHz IRC by 2, to have the same MCGIRCLK speed as others | 122 | # if defined(KL27) // divide the 8MHz IRC by 2, to have the same MCGIRCLK speed as others |
129 | MCG->MC |= MCG_MC_LIRC_DIV2_DIV2; | 123 | MCG->MC |= MCG_MC_LIRC_DIV2_DIV2; |
130 | #endif /* KL27 */ | 124 | # endif /* KL27 */ |
131 | MCG->C1 |= MCG_C1_IRCLKEN; // enable internal ref clock | 125 | MCG->C1 |= MCG_C1_IRCLKEN; // enable internal ref clock |
132 | // to work in stop mode, also MCG_C1_IREFSTEN | 126 | // to work in stop mode, also MCG_C1_IREFSTEN |
133 | // Divide 4MHz by 2^N (N=6) => 62500 irqs/sec => | 127 | // Divide 4MHz by 2^N (N=6) => 62500 irqs/sec => |
134 | // => approx F=61, R=256, duration = 4 | 128 | // => approx F=61, R=256, duration = 4 |
135 | LPTMR0->PSR = LPTMRx_PSR_PCS(LPTMR_CLOCK_MCGIRCLK)|LPTMRx_PSR_PRESCALE(6); | 129 | LPTMR0->PSR = LPTMRx_PSR_PCS(LPTMR_CLOCK_MCGIRCLK) | LPTMRx_PSR_PRESCALE(6); |
136 | #endif /* OPTION 2 */ | 130 | # endif /* OPTION 2 */ |
137 | 131 | ||
138 | /* === OPTION 3 === */ | 132 | /* === OPTION 3 === */ |
139 | #if 0 | 133 | # if 0 |
140 | // OSC output (external crystal), usually 8MHz or 16MHz | 134 | // OSC output (external crystal), usually 8MHz or 16MHz |
141 | OSC0->CR |= OSC_CR_ERCLKEN; // enable ext ref clock | 135 | OSC0->CR |= OSC_CR_ERCLKEN; // enable ext ref clock |
142 | // to work in stop mode, also OSC_CR_EREFSTEN | 136 | // to work in stop mode, also OSC_CR_EREFSTEN |
143 | // Divide by 2^N | 137 | // Divide by 2^N |
144 | LPTMR0->PSR = LPTMRx_PSR_PCS(LPTMR_CLOCK_OSCERCLK)|LPTMRx_PSR_PRESCALE(7); | 138 | LPTMR0->PSR = LPTMRx_PSR_PCS(LPTMR_CLOCK_OSCERCLK)|LPTMRx_PSR_PRESCALE(7); |
145 | #endif /* OPTION 3 */ | 139 | # endif /* OPTION 3 */ |
146 | /* === END OPTIONS === */ | 140 | /* === END OPTIONS === */ |
147 | 141 | ||
148 | /* Interrupt on TCF set (compare flag) */ | 142 | /* Interrupt on TCF set (compare flag) */ |
149 | nvicEnableVector(LPTMR0_IRQn, 2); // vector, priority | 143 | nvicEnableVector(LPTMR0_IRQn, 2); // vector, priority |
150 | LPTMR0->CSR |= LPTMRx_CSR_TIE; | 144 | LPTMR0->CSR |= LPTMRx_CSR_TIE; |
151 | } | 145 | } |
152 | 146 | ||
@@ -205,20 +199,14 @@ void sleep_led_toggle(void) { | |||
205 | STM32_TIM14->CR1 ^= STM32_TIM_CR1_CEN; | 199 | STM32_TIM14->CR1 ^= STM32_TIM_CR1_CEN; |
206 | } | 200 | } |
207 | 201 | ||
208 | |||
209 | #else /* platform selection: not on familiar chips */ | 202 | #else /* platform selection: not on familiar chips */ |
210 | 203 | ||
211 | void sleep_led_init(void) { | 204 | void sleep_led_init(void) {} |
212 | } | 205 | |
213 | 206 | void sleep_led_enable(void) { led_set(1 << USB_LED_CAPS_LOCK); } | |
214 | void sleep_led_enable(void) { | 207 | |
215 | led_set(1<<USB_LED_CAPS_LOCK); | 208 | void sleep_led_disable(void) { led_set(0); } |
216 | } | 209 | |
217 | |||
218 | void sleep_led_disable(void) { | ||
219 | led_set(0); | ||
220 | } | ||
221 | |||
222 | void sleep_led_toggle(void) { | 210 | void sleep_led_toggle(void) { |
223 | // not implemented | 211 | // not implemented |
224 | } | 212 | } |
diff --git a/tmk_core/common/chibios/suspend.c b/tmk_core/common/chibios/suspend.c index 6027d69b7..ae1c6f53e 100644 --- a/tmk_core/common/chibios/suspend.c +++ b/tmk_core/common/chibios/suspend.c | |||
@@ -17,49 +17,44 @@ | |||
17 | * FIXME: needs doc | 17 | * FIXME: needs doc |
18 | */ | 18 | */ |
19 | void suspend_idle(uint8_t time) { | 19 | void suspend_idle(uint8_t time) { |
20 | // TODO: this is not used anywhere - what units is 'time' in? | 20 | // TODO: this is not used anywhere - what units is 'time' in? |
21 | wait_ms(time); | 21 | wait_ms(time); |
22 | } | 22 | } |
23 | 23 | ||
24 | /** \brief Run keyboard level Power down | 24 | /** \brief Run keyboard level Power down |
25 | * | 25 | * |
26 | * FIXME: needs doc | 26 | * FIXME: needs doc |
27 | */ | 27 | */ |
28 | __attribute__ ((weak)) | 28 | __attribute__((weak)) void suspend_power_down_user(void) {} |
29 | void suspend_power_down_user (void) { } | ||
30 | /** \brief Run keyboard level Power down | 29 | /** \brief Run keyboard level Power down |
31 | * | 30 | * |
32 | * FIXME: needs doc | 31 | * FIXME: needs doc |
33 | */ | 32 | */ |
34 | __attribute__ ((weak)) | 33 | __attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); } |
35 | void suspend_power_down_kb(void) { | ||
36 | suspend_power_down_user(); | ||
37 | } | ||
38 | 34 | ||
39 | /** \brief suspend power down | 35 | /** \brief suspend power down |
40 | * | 36 | * |
41 | * FIXME: needs doc | 37 | * FIXME: needs doc |
42 | */ | 38 | */ |
43 | void suspend_power_down(void) { | 39 | void suspend_power_down(void) { |
44 | // TODO: figure out what to power down and how | 40 | // TODO: figure out what to power down and how |
45 | // shouldn't power down TPM/FTM if we want a breathing LED | 41 | // shouldn't power down TPM/FTM if we want a breathing LED |
46 | // also shouldn't power down USB | 42 | // also shouldn't power down USB |
47 | 43 | ||
48 | suspend_power_down_kb(); | 44 | suspend_power_down_kb(); |
49 | // on AVR, this enables the watchdog for 15ms (max), and goes to | 45 | // on AVR, this enables the watchdog for 15ms (max), and goes to |
50 | // SLEEP_MODE_PWR_DOWN | 46 | // SLEEP_MODE_PWR_DOWN |
51 | 47 | ||
52 | wait_ms(17); | 48 | wait_ms(17); |
53 | } | 49 | } |
54 | 50 | ||
55 | /** \brief suspend wakeup condition | 51 | /** \brief suspend wakeup condition |
56 | * | 52 | * |
57 | * FIXME: needs doc | 53 | * FIXME: needs doc |
58 | */ | 54 | */ |
59 | __attribute__ ((weak)) void matrix_power_up(void) {} | 55 | __attribute__((weak)) void matrix_power_up(void) {} |
60 | __attribute__ ((weak)) void matrix_power_down(void) {} | 56 | __attribute__((weak)) void matrix_power_down(void) {} |
61 | bool suspend_wakeup_condition(void) | 57 | bool suspend_wakeup_condition(void) { |
62 | { | ||
63 | matrix_power_up(); | 58 | matrix_power_up(); |
64 | matrix_scan(); | 59 | matrix_scan(); |
65 | matrix_power_down(); | 60 | matrix_power_down(); |
@@ -73,25 +68,20 @@ bool suspend_wakeup_condition(void) | |||
73 | * | 68 | * |
74 | * FIXME: needs doc | 69 | * FIXME: needs doc |
75 | */ | 70 | */ |
76 | __attribute__ ((weak)) | 71 | __attribute__((weak)) void suspend_wakeup_init_user(void) {} |
77 | void suspend_wakeup_init_user(void) { } | ||
78 | 72 | ||
79 | /** \brief run keyboard level code immediately after wakeup | 73 | /** \brief run keyboard level code immediately after wakeup |
80 | * | 74 | * |
81 | * FIXME: needs doc | 75 | * FIXME: needs doc |
82 | */ | 76 | */ |
83 | __attribute__ ((weak)) | 77 | __attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); } |
84 | void suspend_wakeup_init_kb(void) { | ||
85 | suspend_wakeup_init_user(); | ||
86 | } | ||
87 | 78 | ||
88 | /** \brief suspend wakeup condition | 79 | /** \brief suspend wakeup condition |
89 | * | 80 | * |
90 | * run immediately after wakeup | 81 | * run immediately after wakeup |
91 | * FIXME: needs doc | 82 | * FIXME: needs doc |
92 | */ | 83 | */ |
93 | void suspend_wakeup_init(void) | 84 | void suspend_wakeup_init(void) { |
94 | { | ||
95 | // clear keyboard state | 85 | // clear keyboard state |
96 | // need to do it manually, because we're running from ISR | 86 | // need to do it manually, because we're running from ISR |
97 | // and clear_keyboard() calls print | 87 | // and clear_keyboard() calls print |
@@ -111,5 +101,5 @@ void suspend_wakeup_init(void) | |||
111 | #ifdef BACKLIGHT_ENABLE | 101 | #ifdef BACKLIGHT_ENABLE |
112 | backlight_init(); | 102 | backlight_init(); |
113 | #endif /* BACKLIGHT_ENABLE */ | 103 | #endif /* BACKLIGHT_ENABLE */ |
114 | suspend_wakeup_init_kb(); | 104 | suspend_wakeup_init_kb(); |
115 | } | 105 | } |
diff --git a/tmk_core/common/chibios/timer.c b/tmk_core/common/chibios/timer.c index 473e533ca..1ce9d1d17 100644 --- a/tmk_core/common/chibios/timer.c +++ b/tmk_core/common/chibios/timer.c | |||
@@ -2,40 +2,32 @@ | |||
2 | 2 | ||
3 | #include "timer.h" | 3 | #include "timer.h" |
4 | 4 | ||
5 | static systime_t last_systime = 0; | 5 | static systime_t last_systime = 0; |
6 | static systime_t overflow = 0; | 6 | static systime_t overflow = 0; |
7 | static uint32_t current_time_ms = 0; | 7 | static uint32_t current_time_ms = 0; |
8 | 8 | ||
9 | void timer_init(void) { | 9 | void timer_init(void) { timer_clear(); } |
10 | timer_clear(); | ||
11 | } | ||
12 | 10 | ||
13 | void timer_clear(void) { | 11 | void timer_clear(void) { |
14 | last_systime = chVTGetSystemTime(); | 12 | last_systime = chVTGetSystemTime(); |
15 | overflow = 0; | 13 | overflow = 0; |
16 | current_time_ms = 0; | 14 | current_time_ms = 0; |
17 | } | 15 | } |
18 | 16 | ||
19 | uint16_t timer_read(void) { | 17 | uint16_t timer_read(void) { return (uint16_t)timer_read32(); } |
20 | return (uint16_t)timer_read32(); | ||
21 | } | ||
22 | 18 | ||
23 | uint32_t timer_read32(void) { | 19 | uint32_t timer_read32(void) { |
24 | // Note: We assume that the timer update is called at least once betweeen every wrap around of the system time | 20 | // Note: We assume that the timer update is called at least once betweeen every wrap around of the system time |
25 | systime_t current_systime = chVTGetSystemTime(); | 21 | systime_t current_systime = chVTGetSystemTime(); |
26 | systime_t elapsed = current_systime - last_systime + overflow; | 22 | systime_t elapsed = current_systime - last_systime + overflow; |
27 | uint32_t elapsed_ms = ST2MS(elapsed); | 23 | uint32_t elapsed_ms = ST2MS(elapsed); |
28 | current_time_ms += elapsed_ms; | 24 | current_time_ms += elapsed_ms; |
29 | overflow = elapsed - MS2ST(elapsed_ms); | 25 | overflow = elapsed - MS2ST(elapsed_ms); |
30 | last_systime = current_systime; | 26 | last_systime = current_systime; |
31 | 27 | ||
32 | return current_time_ms; | 28 | return current_time_ms; |
33 | } | 29 | } |
34 | 30 | ||
35 | uint16_t timer_elapsed(uint16_t last) { | 31 | uint16_t timer_elapsed(uint16_t last) { return timer_read() - last; } |
36 | return timer_read() - last; | ||
37 | } | ||
38 | 32 | ||
39 | uint32_t timer_elapsed32(uint32_t last) { | 33 | uint32_t timer_elapsed32(uint32_t last) { return timer_read32() - last; } |
40 | return timer_read32() - last; | ||
41 | } | ||