|
-
-
- #include "kinetis.h"
- #include <stdint.h>
-
-
-
- #if defined(KINETISK)
-
-
-
-
-
-
-
-
-
- #define EEPROM_SIZE 2048
-
-
-
-
-
-
-
- #define HANDLE_UNALIGNED_WRITES
-
-
-
- #if (EEPROM_SIZE == 2048)
- #define EEESIZE 0x33
- #elif (EEPROM_SIZE == 1024)
- #define EEESIZE 0x34
- #elif (EEPROM_SIZE == 512)
- #define EEESIZE 0x35
- #elif (EEPROM_SIZE == 256)
- #define EEESIZE 0x36
- #elif (EEPROM_SIZE == 128)
- #define EEESIZE 0x37
- #elif (EEPROM_SIZE == 64)
- #define EEESIZE 0x38
- #elif (EEPROM_SIZE == 32)
- #define EEESIZE 0x39
- #endif
-
- void eeprom_initialize(void)
- {
- uint32_t count=0;
- uint16_t do_flash_cmd[] = {
- 0xf06f, 0x037f, 0x7003, 0x7803,
- 0xf013, 0x0f80, 0xd0fb, 0x4770};
- uint8_t status;
-
- if (FTFL_FCNFG & FTFL_FCNFG_RAMRDY) {
-
-
- FTFL_FCCOB0 = 0x80;
- FTFL_FCCOB4 = EEESIZE;
- FTFL_FCCOB5 = 0x03;
- __disable_irq();
-
- (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&FTFL_FSTAT);
- __enable_irq();
- status = FTFL_FSTAT;
- if (status & 0x70) {
- FTFL_FSTAT = (status & 0x70);
- return;
- }
- }
-
- while (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) {
- if (++count > 20000) break;
- }
- }
-
- #define FlexRAM ((uint8_t *)0x14000000)
-
- uint8_t eeprom_read_byte(const uint8_t *addr)
- {
- uint32_t offset = (uint32_t)addr;
- if (offset >= EEPROM_SIZE) return 0;
- if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
- return FlexRAM[offset];
- }
-
- uint16_t eeprom_read_word(const uint16_t *addr)
- {
- uint32_t offset = (uint32_t)addr;
- if (offset >= EEPROM_SIZE-1) return 0;
- if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
- return *(uint16_t *)(&FlexRAM[offset]);
- }
-
- uint32_t eeprom_read_dword(const uint32_t *addr)
- {
- uint32_t offset = (uint32_t)addr;
- if (offset >= EEPROM_SIZE-3) return 0;
- if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
- return *(uint32_t *)(&FlexRAM[offset]);
- }
-
- void eeprom_read_block(void *buf, const void *addr, uint32_t len)
- {
- uint32_t offset = (uint32_t)addr;
- uint8_t *dest = (uint8_t *)buf;
- uint32_t end = offset + len;
-
- if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
- if (end > EEPROM_SIZE) end = EEPROM_SIZE;
- while (offset < end) {
- *dest++ = FlexRAM[offset++];
- }
- }
-
- int eeprom_is_ready(void)
- {
- return (FTFL_FCNFG & FTFL_FCNFG_EEERDY) ? 1 : 0;
- }
-
- static void flexram_wait(void)
- {
- while (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) {
-
- }
- }
-
- void eeprom_write_byte(uint8_t *addr, uint8_t value)
- {
- uint32_t offset = (uint32_t)addr;
-
- if (offset >= EEPROM_SIZE) return;
- if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
- if (FlexRAM[offset] != value) {
- FlexRAM[offset] = value;
- flexram_wait();
- }
- }
-
- void eeprom_write_word(uint16_t *addr, uint16_t value)
- {
- uint32_t offset = (uint32_t)addr;
-
- if (offset >= EEPROM_SIZE-1) return;
- if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
- #ifdef HANDLE_UNALIGNED_WRITES
- if ((offset & 1) == 0) {
- #endif
- if (*(uint16_t *)(&FlexRAM[offset]) != value) {
- *(uint16_t *)(&FlexRAM[offset]) = value;
- flexram_wait();
- }
- #ifdef HANDLE_UNALIGNED_WRITES
- } else {
- if (FlexRAM[offset] != value) {
- FlexRAM[offset] = value;
- flexram_wait();
- }
- if (FlexRAM[offset + 1] != (value >> 8)) {
- FlexRAM[offset + 1] = value >> 8;
- flexram_wait();
- }
- }
- #endif
- }
-
- void eeprom_write_dword(uint32_t *addr, uint32_t value)
- {
- uint32_t offset = (uint32_t)addr;
-
- if (offset >= EEPROM_SIZE-3) return;
- if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
- #ifdef HANDLE_UNALIGNED_WRITES
- switch (offset & 3) {
- case 0:
- #endif
- if (*(uint32_t *)(&FlexRAM[offset]) != value) {
- *(uint32_t *)(&FlexRAM[offset]) = value;
- flexram_wait();
- }
- return;
- #ifdef HANDLE_UNALIGNED_WRITES
- case 2:
- if (*(uint16_t *)(&FlexRAM[offset]) != value) {
- *(uint16_t *)(&FlexRAM[offset]) = value;
- flexram_wait();
- }
- if (*(uint16_t *)(&FlexRAM[offset + 2]) != (value >> 16)) {
- *(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16;
- flexram_wait();
- }
- return;
- default:
- if (FlexRAM[offset] != value) {
- FlexRAM[offset] = value;
- flexram_wait();
- }
- if (*(uint16_t *)(&FlexRAM[offset + 1]) != (value >> 8)) {
- *(uint16_t *)(&FlexRAM[offset + 1]) = value >> 8;
- flexram_wait();
- }
- if (FlexRAM[offset + 3] != (value >> 24)) {
- FlexRAM[offset + 3] = value >> 24;
- flexram_wait();
- }
- }
- #endif
- }
-
- void eeprom_write_block(const void *buf, void *addr, uint32_t len)
- {
- uint32_t offset = (uint32_t)addr;
- const uint8_t *src = (const uint8_t *)buf;
-
- if (offset >= EEPROM_SIZE) return;
- if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
- if (len >= EEPROM_SIZE) len = EEPROM_SIZE;
- if (offset + len >= EEPROM_SIZE) len = EEPROM_SIZE - offset;
- while (len > 0) {
- uint32_t lsb = offset & 3;
- if (lsb == 0 && len >= 4) {
-
- uint32_t val32;
- val32 = *src++;
- val32 |= (*src++ << 8);
- val32 |= (*src++ << 16);
- val32 |= (*src++ << 24);
- if (*(uint32_t *)(&FlexRAM[offset]) != val32) {
- *(uint32_t *)(&FlexRAM[offset]) = val32;
- flexram_wait();
- }
- offset += 4;
- len -= 4;
- } else if ((lsb == 0 || lsb == 2) && len >= 2) {
-
- uint16_t val16;
- val16 = *src++;
- val16 |= (*src++ << 8);
- if (*(uint16_t *)(&FlexRAM[offset]) != val16) {
- *(uint16_t *)(&FlexRAM[offset]) = val16;
- flexram_wait();
- }
- offset += 2;
- len -= 2;
- } else {
-
- uint8_t val8 = *src++;
- if (FlexRAM[offset] != val8) {
- FlexRAM[offset] = val8;
- flexram_wait();
- }
- offset++;
- len--;
- }
- }
- }
-
-
-
- #elif defined(KINETISL)
-
- #define EEPROM_SIZE 128
-
- #define FLASH_BEGIN (uint16_t *)63488
- #define FLASH_END (uint16_t *)65536
- static uint16_t flashend = 0;
-
- void eeprom_initialize(void)
- {
- const uint16_t *p = FLASH_BEGIN;
-
- do {
- if (*p++ == 0xFFFF) {
- flashend = (uint32_t)(p - 2);
- return;
- }
- } while (p < FLASH_END);
- flashend = (uint32_t)(FLASH_END - 1);
- }
-
- uint8_t eeprom_read_byte(const uint8_t *addr)
- {
- uint32_t offset = (uint32_t)addr;
- const uint16_t *p = FLASH_BEGIN;
- const uint16_t *end = (const uint16_t *)((uint32_t)flashend);
- uint16_t val;
- uint8_t data=0xFF;
-
- if (!end) {
- eeprom_initialize();
- end = (const uint16_t *)((uint32_t)flashend);
- }
- if (offset < EEPROM_SIZE) {
- while (p <= end) {
- val = *p++;
- if ((val & 255) == offset) data = val >> 8;
- }
- }
- return data;
- }
-
- static void flash_write(const uint16_t *code, uint32_t addr, uint32_t data)
- {
-
- uint32_t stat;
- *(uint32_t *)&FTFL_FCCOB3 = 0x06000000 | (addr & 0x00FFFFFC);
- *(uint32_t *)&FTFL_FCCOB7 = data;
- __disable_irq();
- (*((void (*)(volatile uint8_t *))((uint32_t)code | 1)))(&FTFL_FSTAT);
- __enable_irq();
- stat = FTFL_FSTAT & 0x70;
- if (stat) {
- FTFL_FSTAT = stat;
- }
- MCM_PLACR |= MCM_PLACR_CFCC;
- }
-
- void eeprom_write_byte(uint8_t *addr, uint8_t data)
- {
- uint32_t offset = (uint32_t)addr;
- const uint16_t *p, *end = (const uint16_t *)((uint32_t)flashend);
- uint32_t i, val, flashaddr;
- uint16_t do_flash_cmd[] = {
- 0x2380, 0x7003, 0x7803, 0xb25b, 0x2b00, 0xdafb, 0x4770};
- uint8_t buf[EEPROM_SIZE];
-
- if (offset >= EEPROM_SIZE) return;
- if (!end) {
- eeprom_initialize();
- end = (const uint16_t *)((uint32_t)flashend);
- }
- if (++end < FLASH_END) {
- val = (data << 8) | offset;
- flashaddr = (uint32_t)end;
- flashend = flashaddr;
- if ((flashaddr & 2) == 0) {
- val |= 0xFFFF0000;
- } else {
- val <<= 16;
- val |= 0x0000FFFF;
- }
- flash_write(do_flash_cmd, flashaddr, val);
- } else {
- for (i=0; i < EEPROM_SIZE; i++) {
- buf[i] = 0xFF;
- }
- for (p = FLASH_BEGIN; p < FLASH_END; p++) {
- val = *p;
- if ((val & 255) < EEPROM_SIZE) {
- buf[val & 255] = val >> 8;
- }
- }
- buf[offset] = data;
- for (flashaddr=(uint32_t)FLASH_BEGIN; flashaddr < (uint32_t)FLASH_END; flashaddr += 1024) {
- *(uint32_t *)&FTFL_FCCOB3 = 0x09000000 | flashaddr;
- __disable_irq();
- (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&FTFL_FSTAT);
- __enable_irq();
- val = FTFL_FSTAT & 0x70;
- if (val) FTFL_FSTAT = val;
- MCM_PLACR |= MCM_PLACR_CFCC;
- }
- flashaddr=(uint32_t)FLASH_BEGIN;
- for (i=0; i < EEPROM_SIZE; i++) {
- if (buf[i] == 0xFF) continue;
- if ((flashaddr & 2) == 0) {
- val = (buf[i] << 8) | i;
- } else {
- val = val | (buf[i] << 24) | (i << 16);
- flash_write(do_flash_cmd, flashaddr, val);
- }
- flashaddr += 2;
- }
- flashend = flashaddr;
- if ((flashaddr & 2)) {
- val |= 0xFFFF0000;
- flash_write(do_flash_cmd, flashaddr, val);
- }
- }
- }
-
-
-
-
- uint16_t eeprom_read_word(const uint16_t *addr)
- {
- const uint8_t *p = (const uint8_t *)addr;
- return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8);
- }
-
- uint32_t eeprom_read_dword(const uint32_t *addr)
- {
- const uint8_t *p = (const uint8_t *)addr;
- return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8)
- | (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24);
- }
-
- void eeprom_read_block(void *buf, const void *addr, uint32_t len)
- {
- const uint8_t *p = (const uint8_t *)addr;
- uint8_t *dest = (uint8_t *)buf;
- while (len--) {
- *dest++ = eeprom_read_byte(p++);
- }
- }
-
- int eeprom_is_ready(void)
- {
- return 1;
- }
-
- void eeprom_write_word(uint16_t *addr, uint16_t value)
- {
- uint8_t *p = (uint8_t *)addr;
- eeprom_write_byte(p++, value);
- eeprom_write_byte(p, value >> 8);
- }
-
- void eeprom_write_dword(uint32_t *addr, uint32_t value)
- {
- uint8_t *p = (uint8_t *)addr;
- eeprom_write_byte(p++, value);
- eeprom_write_byte(p++, value >> 8);
- eeprom_write_byte(p++, value >> 16);
- eeprom_write_byte(p, value >> 24);
- }
-
- void eeprom_write_block(const void *buf, void *addr, uint32_t len)
- {
- uint8_t *p = (uint8_t *)addr;
- const uint8_t *src = (const uint8_t *)buf;
- while (len--) {
- eeprom_write_byte(p++, *src++);
- }
- }
-
-
- #endif
|