| @@ -1,6 +1,6 @@ | |||
| /* Teensyduino Core Library | |||
| * http://www.pjrc.com/teensy/ | |||
| * Copyright (c) 2013 PJRC.COM, LLC. | |||
| * Copyright (c) 2016 PJRC.COM, LLC. | |||
| * | |||
| * Permission is hereby granted, free of charge, to any person obtaining | |||
| * a copy of this software and associated documentation files (the | |||
| @@ -36,12 +36,15 @@ | |||
| #if defined(__MK20DX128__) || defined(__MK20DX256__) | |||
| #define EEPROM_MAX 2048 | |||
| #define EEPARTITION 0x03 // all 32K dataflash for EEPROM, none for Data | |||
| #define EEESPLIT 0x30 // must be 0x30 on these chips | |||
| #elif defined(__MK64FX512__) | |||
| #define EEPROM_MAX 4096 | |||
| #define EEPARTITION 0x04 // 64K dataflash for EEPROM, 64K for Data | |||
| #define EEPARTITION 0x05 // all 128K dataflash for EEPROM | |||
| #define EEESPLIT 0x10 // best endurance: 0x00 = first 12%, 0x10 = first 25%, 0x30 = all equal | |||
| #elif defined(__MK66FX1M0__) | |||
| #define EEPROM_MAX 4096 | |||
| #define EEPARTITION 0x05 // 128K dataflash for EEPROM, 128K for Data | |||
| #define EEESPLIT 0x10 // best endurance: 0x00 = first 12%, 0x10 = first 25%, 0x30 = all equal | |||
| #elif defined(__MKL26Z64__) | |||
| #define EEPROM_MAX 255 | |||
| #endif | |||
| @@ -63,28 +66,28 @@ | |||
| #if E2END < 32 | |||
| #define EEPROM_SIZE 32 | |||
| #define EEESIZE 0x39 | |||
| #define EEESIZE 0x09 | |||
| #elif E2END < 64 | |||
| #define EEPROM_SIZE 64 | |||
| #define EEESIZE 0x38 | |||
| #define EEESIZE 0x08 | |||
| #elif E2END < 128 | |||
| #define EEPROM_SIZE 128 | |||
| #define EEESIZE 0x37 | |||
| #define EEESIZE 0x07 | |||
| #elif E2END < 256 | |||
| #define EEPROM_SIZE 256 | |||
| #define EEESIZE 0x36 | |||
| #define EEESIZE 0x06 | |||
| #elif E2END < 512 | |||
| #define EEPROM_SIZE 512 | |||
| #define EEESIZE 0x35 | |||
| #define EEESIZE 0x05 | |||
| #elif E2END < 1024 | |||
| #define EEPROM_SIZE 1024 | |||
| #define EEESIZE 0x34 | |||
| #define EEESIZE 0x04 | |||
| #elif E2END < 2048 | |||
| #define EEPROM_SIZE 2048 | |||
| #define EEESIZE 0x33 | |||
| #define EEESIZE 0x03 | |||
| #elif E2END < 4096 | |||
| #define EEPROM_SIZE 4096 | |||
| #define EEESIZE 0x32 | |||
| #define EEESIZE 0x02 | |||
| #endif | |||
| // Writing unaligned 16 or 32 bit data is handled automatically when | |||
| @@ -105,10 +108,13 @@ void eeprom_initialize(void) | |||
| uint8_t status; | |||
| if (FTFL_FCNFG & FTFL_FCNFG_RAMRDY) { | |||
| uint8_t stat = FTFL_FSTAT & 0x70; | |||
| if (stat) FTFL_FSTAT = stat; | |||
| // FlexRAM is configured as traditional RAM | |||
| // We need to reconfigure for EEPROM usage | |||
| FTFL_FCCOB0 = 0x80; // PGMPART = Program Partition Command | |||
| FTFL_FCCOB4 = EEESIZE; // EEPROM Size | |||
| FTFL_FCCOB3 = 0; | |||
| FTFL_FCCOB4 = EEESPLIT | EEESIZE; | |||
| FTFL_FCCOB5 = EEPARTITION; | |||
| __disable_irq(); | |||
| // do_flash_cmd() must execute from RAM. Luckily the C syntax is simple... | |||
| @@ -122,11 +128,11 @@ void eeprom_initialize(void) | |||
| } | |||
| // wait for eeprom to become ready (is this really necessary?) | |||
| while (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) { | |||
| if (++count > 20000) break; | |||
| if (++count > 200000) break; | |||
| } | |||
| } | |||
| #define FlexRAM ((uint8_t *)0x14000000) | |||
| #define FlexRAM ((volatile uint8_t *)0x14000000) | |||
| uint8_t eeprom_read_byte(const uint8_t *addr) | |||
| { | |||
| @@ -184,6 +190,8 @@ void eeprom_write_byte(uint8_t *addr, uint8_t value) | |||
| if (offset >= EEPROM_SIZE) return; | |||
| if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); | |||
| if (FlexRAM[offset] != value) { | |||
| uint8_t stat = FTFL_FSTAT & 0x70; | |||
| if (stat) FTFL_FSTAT = stat; | |||
| FlexRAM[offset] = value; | |||
| flexram_wait(); | |||
| } | |||
| @@ -199,16 +207,22 @@ void eeprom_write_word(uint16_t *addr, uint16_t value) | |||
| if ((offset & 1) == 0) { | |||
| #endif | |||
| if (*(uint16_t *)(&FlexRAM[offset]) != value) { | |||
| uint8_t stat = FTFL_FSTAT & 0x70; | |||
| if (stat) FTFL_FSTAT = stat; | |||
| *(uint16_t *)(&FlexRAM[offset]) = value; | |||
| flexram_wait(); | |||
| } | |||
| #ifdef HANDLE_UNALIGNED_WRITES | |||
| } else { | |||
| if (FlexRAM[offset] != value) { | |||
| uint8_t stat = FTFL_FSTAT & 0x70; | |||
| if (stat) FTFL_FSTAT = stat; | |||
| FlexRAM[offset] = value; | |||
| flexram_wait(); | |||
| } | |||
| if (FlexRAM[offset + 1] != (value >> 8)) { | |||
| uint8_t stat = FTFL_FSTAT & 0x70; | |||
| if (stat) FTFL_FSTAT = stat; | |||
| FlexRAM[offset + 1] = value >> 8; | |||
| flexram_wait(); | |||
| } | |||
| @@ -227,6 +241,8 @@ void eeprom_write_dword(uint32_t *addr, uint32_t value) | |||
| case 0: | |||
| #endif | |||
| if (*(uint32_t *)(&FlexRAM[offset]) != value) { | |||
| uint8_t stat = FTFL_FSTAT & 0x70; | |||
| if (stat) FTFL_FSTAT = stat; | |||
| *(uint32_t *)(&FlexRAM[offset]) = value; | |||
| flexram_wait(); | |||
| } | |||
| @@ -234,24 +250,34 @@ void eeprom_write_dword(uint32_t *addr, uint32_t value) | |||
| #ifdef HANDLE_UNALIGNED_WRITES | |||
| case 2: | |||
| if (*(uint16_t *)(&FlexRAM[offset]) != value) { | |||
| uint8_t stat = FTFL_FSTAT & 0x70; | |||
| if (stat) FTFL_FSTAT = stat; | |||
| *(uint16_t *)(&FlexRAM[offset]) = value; | |||
| flexram_wait(); | |||
| } | |||
| if (*(uint16_t *)(&FlexRAM[offset + 2]) != (value >> 16)) { | |||
| uint8_t stat = FTFL_FSTAT & 0x70; | |||
| if (stat) FTFL_FSTAT = stat; | |||
| *(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16; | |||
| flexram_wait(); | |||
| } | |||
| return; | |||
| default: | |||
| if (FlexRAM[offset] != value) { | |||
| uint8_t stat = FTFL_FSTAT & 0x70; | |||
| if (stat) FTFL_FSTAT = stat; | |||
| FlexRAM[offset] = value; | |||
| flexram_wait(); | |||
| } | |||
| if (*(uint16_t *)(&FlexRAM[offset + 1]) != (value >> 8)) { | |||
| uint8_t stat = FTFL_FSTAT & 0x70; | |||
| if (stat) FTFL_FSTAT = stat; | |||
| *(uint16_t *)(&FlexRAM[offset + 1]) = value >> 8; | |||
| flexram_wait(); | |||
| } | |||
| if (FlexRAM[offset + 3] != (value >> 24)) { | |||
| uint8_t stat = FTFL_FSTAT & 0x70; | |||
| if (stat) FTFL_FSTAT = stat; | |||
| FlexRAM[offset + 3] = value >> 24; | |||
| flexram_wait(); | |||
| } | |||
| @@ -278,6 +304,8 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) | |||
| val32 |= (*src++ << 16); | |||
| val32 |= (*src++ << 24); | |||
| if (*(uint32_t *)(&FlexRAM[offset]) != val32) { | |||
| uint8_t stat = FTFL_FSTAT & 0x70; | |||
| if (stat) FTFL_FSTAT = stat; | |||
| *(uint32_t *)(&FlexRAM[offset]) = val32; | |||
| flexram_wait(); | |||
| } | |||
| @@ -289,6 +317,8 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) | |||
| val16 = *src++; | |||
| val16 |= (*src++ << 8); | |||
| if (*(uint16_t *)(&FlexRAM[offset]) != val16) { | |||
| uint8_t stat = FTFL_FSTAT & 0x70; | |||
| if (stat) FTFL_FSTAT = stat; | |||
| *(uint16_t *)(&FlexRAM[offset]) = val16; | |||
| flexram_wait(); | |||
| } | |||
| @@ -298,6 +328,8 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) | |||
| // write 8 bits | |||
| uint8_t val8 = *src++; | |||
| if (FlexRAM[offset] != val8) { | |||
| uint8_t stat = FTFL_FSTAT & 0x70; | |||
| if (stat) FTFL_FSTAT = stat; | |||
| FlexRAM[offset] = val8; | |||
| flexram_wait(); | |||
| } | |||