Browse Source

Merge pull request #177 from Defragster/master

EEPROM write on T_3.6 under HSRUN - Drop and Raise
teensy4-core
Paul Stoffregen 8 years ago
parent
commit
9aecd75406
2 changed files with 69 additions and 1 deletions
  1. +61
    -0
      teensy3/eeprom.c
  2. +8
    -1
      teensy3/usb_desc.c

+ 61
- 0
teensy3/eeprom.c View File

@@ -31,6 +31,9 @@
#include "kinetis.h"
#include <avr/eeprom.h>
//#include "HardwareSerial.h"
#if F_CPU > 120000000 && defined(__MK66FX1M0__)
#include "core_pins.h" // delayMicroseconds()
#endif


#if defined(__MK20DX128__) || defined(__MK20DX256__)
@@ -183,18 +186,68 @@ static void flexram_wait(void)
}
}

#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)
{
uint32_t offset = (uint32_t)addr;

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

void eeprom_write_word(uint16_t *addr, uint16_t value)
@@ -203,6 +256,7 @@ void eeprom_write_word(uint16_t *addr, uint16_t value)

if (offset >= EEPROM_SIZE-1) return;
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
hsrun_off();
#ifdef HANDLE_UNALIGNED_WRITES
if ((offset & 1) == 0) {
#endif
@@ -228,6 +282,7 @@ void eeprom_write_word(uint16_t *addr, uint16_t value)
}
}
#endif
hsrun_on();
}

void eeprom_write_dword(uint32_t *addr, uint32_t value)
@@ -236,6 +291,7 @@ void eeprom_write_dword(uint32_t *addr, uint32_t value)

if (offset >= EEPROM_SIZE-3) return;
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
hsrun_off();
#ifdef HANDLE_UNALIGNED_WRITES
switch (offset & 3) {
case 0:
@@ -246,6 +302,7 @@ void eeprom_write_dword(uint32_t *addr, uint32_t value)
*(uint32_t *)(&FlexRAM[offset]) = value;
flexram_wait();
}
hsrun_on();
return;
#ifdef HANDLE_UNALIGNED_WRITES
case 2:
@@ -261,6 +318,7 @@ void eeprom_write_dword(uint32_t *addr, uint32_t value)
*(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16;
flexram_wait();
}
hsrun_on();
return;
default:
if (FlexRAM[offset] != value) {
@@ -283,6 +341,7 @@ void eeprom_write_dword(uint32_t *addr, uint32_t value)
}
}
#endif
hsrun_on();
}

void eeprom_write_block(const void *buf, void *addr, uint32_t len)
@@ -292,6 +351,7 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len)

if (offset >= EEPROM_SIZE) return;
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
hsrun_off();
if (len >= EEPROM_SIZE) len = EEPROM_SIZE;
if (offset + len >= EEPROM_SIZE) len = EEPROM_SIZE - offset;
while (len > 0) {
@@ -337,6 +397,7 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len)
len--;
}
}
hsrun_on();
}

/*

+ 8
- 1
teensy3/usb_desc.c View File

@@ -1229,12 +1229,19 @@ void usb_init_serialnumber(void)
while (!(FTFL_FSTAT & FTFL_FSTAT_CCIF)) ; // wait
num = *(uint32_t *)&FTFL_FCCOB7;
#elif defined(HAS_KINETIS_FLASH_FTFE)
// TODO: does not work in HSRUN mode
#if F_CPU > 120000000 // Disable HSRUN mode across ser# read
SMC_PMCTRL = SMC_PMCTRL_RUNM(0); // exit HSRUN mode
while (SMC_PMSTAT == SMC_PMSTAT_HSRUN) ; // wait for !(HSRUN)
#endif
FTFL_FSTAT = FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL;
*(uint32_t *)&FTFL_FCCOB3 = 0x41070000;
FTFL_FSTAT = FTFL_FSTAT_CCIF;
while (!(FTFL_FSTAT & FTFL_FSTAT_CCIF)) ; // wait
num = *(uint32_t *)&FTFL_FCCOBB;
#if F_CPU > 120000000
SMC_PMCTRL = SMC_PMCTRL_RUNM(3); // enter HSRUN mode
while (SMC_PMSTAT != SMC_PMSTAT_HSRUN) ; // wait for HSRUN
#endif
#endif
__enable_irq();
// add extra zero to work around OS-X CDC-ACM driver bug

Loading…
Cancel
Save