diff options
| author | skullY <skullydazed@gmail.com> | 2019-08-30 11:19:03 -0700 |
|---|---|---|
| committer | skullydazed <skullydazed@users.noreply.github.com> | 2019-08-30 15:01:52 -0700 |
| commit | b624f32f944acdc59dcb130674c09090c5c404cb (patch) | |
| tree | bc13adbba137d122d9a2c2fb2fafcbb08ac10e25 /tmk_core/common/chibios | |
| parent | 61af76a10d00aba185b8338604171de490a13e3b (diff) | |
| download | qmk_firmware-b624f32f944acdc59dcb130674c09090c5c404cb.tar.gz qmk_firmware-b624f32f944acdc59dcb130674c09090c5c404cb.zip | |
clang-format changes
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 | } | ||
