Browse Source

use HSRUN functions in eeprom

teensy4-core
PaulStoffregen 8 years ago
parent
commit
4797fce596
1 changed files with 28 additions and 58 deletions
  1. +28
    -58
      teensy3/eeprom.c

+ 28
- 58
teensy3/eeprom.c View File

if (stat) FTFL_FSTAT = stat; if (stat) FTFL_FSTAT = stat;
// FlexRAM is configured as traditional RAM // FlexRAM is configured as traditional RAM
// We need to reconfigure for EEPROM usage // We need to reconfigure for EEPROM usage
kinetis_hsrun_disable();
FTFL_FCCOB0 = 0x80; // PGMPART = Program Partition Command FTFL_FCCOB0 = 0x80; // PGMPART = Program Partition Command
FTFL_FCCOB3 = 0; FTFL_FCCOB3 = 0;
FTFL_FCCOB4 = EEESPLIT | EEESIZE; FTFL_FCCOB4 = EEESPLIT | EEESIZE;
// do_flash_cmd() must execute from RAM. Luckily the C syntax is simple... // do_flash_cmd() must execute from RAM. Luckily the C syntax is simple...
(*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&FTFL_FSTAT); (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&FTFL_FSTAT);
__enable_irq(); __enable_irq();
kinetis_hsrun_enable();
status = FTFL_FSTAT; status = FTFL_FSTAT;
if (status & 0x70) { if (status & 0x70) {
FTFL_FSTAT = (status & 0x70); FTFL_FSTAT = (status & 0x70);
} }
} }


#if F_CPU > 120000000 && defined(__MK66FX1M0__)
static volatile uint16_t c_intrestore = 0;

void c_enable_irq( void );
void c_disable_irq( void );
static __inline__ uint32_t __get_primask(void) \
{ uint32_t primask = 0; \
__asm__ volatile ("MRS %[result], PRIMASK\n\t":[result]"=r"(primask)::); \
return primask; } // returns 0 if interrupts enabled, 1 if disabled
void c_enable_irq( void ){
if ( c_intrestore ) {
c_intrestore =0;
__enable_irq( );
}
}
void c_disable_irq( void ){
if ( !__get_primask() ) { // Returns 0 if they are enabled, or non-zero if disabled
__disable_irq( );
c_intrestore = 1;
}
}
static volatile uint8_t restore_hsrun = 0;
static void hsrun_off(void)
{
if (SMC_PMSTAT == SMC_PMSTAT_HSRUN) {
c_disable_irq( ); // Turn off interrupts for the DURATION !!!!
SMC_PMCTRL = SMC_PMCTRL_RUNM(0); // exit HSRUN mode
while (SMC_PMSTAT == SMC_PMSTAT_HSRUN) delayMicroseconds(2); // wait for !HSRUN
delayMicroseconds(100);
restore_hsrun = 1;
}
}

static void hsrun_on(void)
{
if (restore_hsrun) {
SMC_PMCTRL = SMC_PMCTRL_RUNM(3); // enter HSRUN mode
while (SMC_PMSTAT != SMC_PMSTAT_HSRUN) delayMicroseconds(2);; // wait for HSRUN
restore_hsrun = 0;
c_enable_irq( ); // Restore interrupts only when HSRUN restored }
}
}
#else
#define hsrun_off()
#define hsrun_on()
#endif


void eeprom_write_byte(uint8_t *addr, uint8_t value) void eeprom_write_byte(uint8_t *addr, uint8_t value)
{ {
uint32_t offset = (uint32_t)addr; uint32_t offset = (uint32_t)addr;


if (offset >= EEPROM_SIZE) return; if (offset >= EEPROM_SIZE) return;
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
hsrun_off();
if (FlexRAM[offset] != value) { if (FlexRAM[offset] != value) {
kinetis_hsrun_disable();
uint8_t stat = FTFL_FSTAT & 0x70; uint8_t stat = FTFL_FSTAT & 0x70;
if (stat) FTFL_FSTAT = stat; if (stat) FTFL_FSTAT = stat;
FlexRAM[offset] = value; FlexRAM[offset] = value;
flexram_wait(); flexram_wait();
kinetis_hsrun_enable();
} }
hsrun_on();
} }


void eeprom_write_word(uint16_t *addr, uint16_t value) void eeprom_write_word(uint16_t *addr, uint16_t value)


if (offset >= EEPROM_SIZE-1) return; if (offset >= EEPROM_SIZE-1) return;
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
hsrun_off();
#ifdef HANDLE_UNALIGNED_WRITES #ifdef HANDLE_UNALIGNED_WRITES
if ((offset & 1) == 0) { if ((offset & 1) == 0) {
#endif #endif
if (*(uint16_t *)(&FlexRAM[offset]) != value) { if (*(uint16_t *)(&FlexRAM[offset]) != value) {
kinetis_hsrun_disable();
uint8_t stat = FTFL_FSTAT & 0x70; uint8_t stat = FTFL_FSTAT & 0x70;
if (stat) FTFL_FSTAT = stat; if (stat) FTFL_FSTAT = stat;
*(uint16_t *)(&FlexRAM[offset]) = value; *(uint16_t *)(&FlexRAM[offset]) = value;
flexram_wait(); flexram_wait();
kinetis_hsrun_enable();
} }
#ifdef HANDLE_UNALIGNED_WRITES #ifdef HANDLE_UNALIGNED_WRITES
} else { } else {
if (FlexRAM[offset] != value) { if (FlexRAM[offset] != value) {
kinetis_hsrun_disable();
uint8_t stat = FTFL_FSTAT & 0x70; uint8_t stat = FTFL_FSTAT & 0x70;
if (stat) FTFL_FSTAT = stat; if (stat) FTFL_FSTAT = stat;
FlexRAM[offset] = value; FlexRAM[offset] = value;
flexram_wait(); flexram_wait();
kinetis_hsrun_enable();
} }
if (FlexRAM[offset + 1] != (value >> 8)) { if (FlexRAM[offset + 1] != (value >> 8)) {
kinetis_hsrun_disable();
uint8_t stat = FTFL_FSTAT & 0x70; uint8_t stat = FTFL_FSTAT & 0x70;
if (stat) FTFL_FSTAT = stat; if (stat) FTFL_FSTAT = stat;
FlexRAM[offset + 1] = value >> 8; FlexRAM[offset + 1] = value >> 8;
flexram_wait(); flexram_wait();
kinetis_hsrun_enable();
} }
} }
#endif #endif
hsrun_on();
} }


void eeprom_write_dword(uint32_t *addr, uint32_t value) void eeprom_write_dword(uint32_t *addr, uint32_t value)


if (offset >= EEPROM_SIZE-3) return; if (offset >= EEPROM_SIZE-3) return;
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
hsrun_off();
#ifdef HANDLE_UNALIGNED_WRITES #ifdef HANDLE_UNALIGNED_WRITES
switch (offset & 3) { switch (offset & 3) {
case 0: case 0:
#endif #endif
if (*(uint32_t *)(&FlexRAM[offset]) != value) { if (*(uint32_t *)(&FlexRAM[offset]) != value) {
kinetis_hsrun_disable();
uint8_t stat = FTFL_FSTAT & 0x70; uint8_t stat = FTFL_FSTAT & 0x70;
if (stat) FTFL_FSTAT = stat; if (stat) FTFL_FSTAT = stat;
*(uint32_t *)(&FlexRAM[offset]) = value; *(uint32_t *)(&FlexRAM[offset]) = value;
flexram_wait(); flexram_wait();
kinetis_hsrun_enable();
} }
hsrun_on();
return; return;
#ifdef HANDLE_UNALIGNED_WRITES #ifdef HANDLE_UNALIGNED_WRITES
case 2: case 2:
if (*(uint16_t *)(&FlexRAM[offset]) != value) { if (*(uint16_t *)(&FlexRAM[offset]) != value) {
kinetis_hsrun_disable();
uint8_t stat = FTFL_FSTAT & 0x70; uint8_t stat = FTFL_FSTAT & 0x70;
if (stat) FTFL_FSTAT = stat; if (stat) FTFL_FSTAT = stat;
*(uint16_t *)(&FlexRAM[offset]) = value; *(uint16_t *)(&FlexRAM[offset]) = value;
flexram_wait(); flexram_wait();
kinetis_hsrun_enable();
} }
if (*(uint16_t *)(&FlexRAM[offset + 2]) != (value >> 16)) { if (*(uint16_t *)(&FlexRAM[offset + 2]) != (value >> 16)) {
kinetis_hsrun_disable();
uint8_t stat = FTFL_FSTAT & 0x70; uint8_t stat = FTFL_FSTAT & 0x70;
if (stat) FTFL_FSTAT = stat; if (stat) FTFL_FSTAT = stat;
*(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16; *(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16;
flexram_wait(); flexram_wait();
kinetis_hsrun_enable();
} }
hsrun_on();
return; return;
default: default:
if (FlexRAM[offset] != value) { if (FlexRAM[offset] != value) {
kinetis_hsrun_disable();
uint8_t stat = FTFL_FSTAT & 0x70; uint8_t stat = FTFL_FSTAT & 0x70;
if (stat) FTFL_FSTAT = stat; if (stat) FTFL_FSTAT = stat;
FlexRAM[offset] = value; FlexRAM[offset] = value;
flexram_wait(); flexram_wait();
kinetis_hsrun_enable();
} }
if (*(uint16_t *)(&FlexRAM[offset + 1]) != (value >> 8)) { if (*(uint16_t *)(&FlexRAM[offset + 1]) != (value >> 8)) {
kinetis_hsrun_disable();
uint8_t stat = FTFL_FSTAT & 0x70; uint8_t stat = FTFL_FSTAT & 0x70;
if (stat) FTFL_FSTAT = stat; if (stat) FTFL_FSTAT = stat;
*(uint16_t *)(&FlexRAM[offset + 1]) = value >> 8; *(uint16_t *)(&FlexRAM[offset + 1]) = value >> 8;
flexram_wait(); flexram_wait();
kinetis_hsrun_enable();
} }
if (FlexRAM[offset + 3] != (value >> 24)) { if (FlexRAM[offset + 3] != (value >> 24)) {
kinetis_hsrun_disable();
uint8_t stat = FTFL_FSTAT & 0x70; uint8_t stat = FTFL_FSTAT & 0x70;
if (stat) FTFL_FSTAT = stat; if (stat) FTFL_FSTAT = stat;
FlexRAM[offset + 3] = value >> 24; FlexRAM[offset + 3] = value >> 24;
flexram_wait(); flexram_wait();
kinetis_hsrun_enable();
} }
} }
#endif #endif
hsrun_on();
} }


void eeprom_write_block(const void *buf, void *addr, uint32_t len) void eeprom_write_block(const void *buf, void *addr, uint32_t len)


if (offset >= EEPROM_SIZE) return; if (offset >= EEPROM_SIZE) return;
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
hsrun_off();
if (len >= EEPROM_SIZE) len = EEPROM_SIZE; if (len >= EEPROM_SIZE) len = EEPROM_SIZE;
if (offset + len >= EEPROM_SIZE) len = EEPROM_SIZE - offset; if (offset + len >= EEPROM_SIZE) len = EEPROM_SIZE - offset;
while (len > 0) { while (len > 0) {
val32 |= (*src++ << 16); val32 |= (*src++ << 16);
val32 |= (*src++ << 24); val32 |= (*src++ << 24);
if (*(uint32_t *)(&FlexRAM[offset]) != val32) { if (*(uint32_t *)(&FlexRAM[offset]) != val32) {
kinetis_hsrun_disable();
uint8_t stat = FTFL_FSTAT & 0x70; uint8_t stat = FTFL_FSTAT & 0x70;
if (stat) FTFL_FSTAT = stat; if (stat) FTFL_FSTAT = stat;
*(uint32_t *)(&FlexRAM[offset]) = val32; *(uint32_t *)(&FlexRAM[offset]) = val32;
flexram_wait(); flexram_wait();
kinetis_hsrun_enable();
} }
offset += 4; offset += 4;
len -= 4; len -= 4;
val16 = *src++; val16 = *src++;
val16 |= (*src++ << 8); val16 |= (*src++ << 8);
if (*(uint16_t *)(&FlexRAM[offset]) != val16) { if (*(uint16_t *)(&FlexRAM[offset]) != val16) {
kinetis_hsrun_disable();
uint8_t stat = FTFL_FSTAT & 0x70; uint8_t stat = FTFL_FSTAT & 0x70;
if (stat) FTFL_FSTAT = stat; if (stat) FTFL_FSTAT = stat;
*(uint16_t *)(&FlexRAM[offset]) = val16; *(uint16_t *)(&FlexRAM[offset]) = val16;
flexram_wait(); flexram_wait();
kinetis_hsrun_enable();
} }
offset += 2; offset += 2;
len -= 2; len -= 2;
// write 8 bits // write 8 bits
uint8_t val8 = *src++; uint8_t val8 = *src++;
if (FlexRAM[offset] != val8) { if (FlexRAM[offset] != val8) {
kinetis_hsrun_disable();
uint8_t stat = FTFL_FSTAT & 0x70; uint8_t stat = FTFL_FSTAT & 0x70;
if (stat) FTFL_FSTAT = stat; if (stat) FTFL_FSTAT = stat;
FlexRAM[offset] = val8; FlexRAM[offset] = val8;
flexram_wait(); flexram_wait();
kinetis_hsrun_enable();
} }
offset++; offset++;
len--; len--;
} }
} }
hsrun_on();
} }


/* /*

Loading…
Cancel
Save