Last active
January 14, 2018 00:34
-
-
Save cv007/ef4c71befc9fffeec106baac3d9c2848 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//rom user id addresses | |
#define ROM_ROW_SIZE 32 | |
#define ROM_ID 0x8000 | |
#define ROM_ID0 0x8000 | |
#define ROM_ID1 0x8001 | |
#define ROM_ID2 0x8002 | |
#define ROM_ID3 0x8003 | |
#define ROM_MY_ADDRESS ROM_ID0 | |
/*------------------------------------------------------------------------------ | |
- read byte from flash, config, or eeprom | |
- flash 0x0000-FLASH_SIZE, config 0x8000+, eeprom 0xF000-0xF0FF | |
- return 16bit read value (only 14bits of flash, upper 2 bits are 0) | |
- eeprom read returns 16bits, but only 8bits valid (upper 8 should be 0) | |
------------------------------------------------------------------------------*/ | |
uint16_t rom_read( uint16_t waddr ) | |
{ | |
NVMADRH = waddr>>8; //set address | |
NVMADRL = waddr; | |
NVMREGS = 0; //assume flash space | |
if( waddr & 0x8000 ) NVMREGS = 1;//else config space if waddr bit15 set | |
RD = 1; //start read | |
NVMREGS = 0; | |
return NVMDATH<<8 | NVMDATL; | |
} | |
/*------------------------------------------------------------------------------ | |
- unlock sequence for nvm | |
- irq's off while writing | |
------------------------------------------------------------------------------*/ | |
void rom_unlock() | |
{ | |
while( WR == 1 ); //in case eeprom still writing | |
//unlock | |
uint8_t gie_save = GIE; //save irq status | |
GIE = 0; //irq off | |
WREN = 1; //program/erase enable | |
NVMCON2 = 0x55; //unlock | |
NVMCON2 = 0xAA; | |
WR = 1; //write | |
//cpu stops here | |
WREN = 0; //program/erase disable | |
if( gie_save ) GIE = 1; //restore irq status | |
//done | |
} | |
/*------------------------------------------------------------------------------ | |
- write word to flash, user id, or eeprom | |
- if address >= 0x8000 user id space, if >= 0xF000 eeprom | |
- if flash or user id, assumes row erase is already done | |
------------------------------------------------------------------------------*/ | |
void rom_write_word( uint16_t waddr, uint16_t wdata ) | |
{ | |
NVMADRH = waddr>>8; //set address | |
NVMADRL = waddr; | |
NVMDATH = wdata>>8; //and data | |
NVMDATL = wdata; | |
if( waddr & 0x8000 ) NVMREGS = 1;//config/eeprom space | |
rom_unlock(); | |
NVMREGS = 0; | |
} | |
/*------------------------------------------------------------------------------ | |
- erase rom row | |
- irq's off while writing | |
------------------------------------------------------------------------------*/ | |
void rom_erase_row( uint16_t waddr ) | |
{ | |
FREE = 1; //erase flag (is only set in this function) | |
rom_write_word( waddr, 0 ); | |
FREE = 0; //leave everything as before | |
} | |
/*------------------------------------------------------------------------------ | |
- write data to latch | |
------------------------------------------------------------------------------*/ | |
void rom_write_latch( uint16_t waddr, uint16_t wdata ) | |
{ | |
LWLO = 1; //load word to latch only | |
rom_write_word( waddr, wdata ); | |
LWLO = 0; //leave everything as before | |
} | |
/*------------------------------------------------------------------------------ | |
- write to user id location addr (0x8000-0x8003) | |
- preserve other id locations in this row | |
------------------------------------------------------------------------------*/ | |
void rom_write_id( uint16_t addr, uint16_t wdat ) | |
{ | |
//return if invalid address | |
if( addr < ROM_ID0 || addr > ROM_ID3 ) return; | |
//preserve other id's directly into latches | |
for( uint16_t i = ROM_ID0; i <= ROM_ID3; i++ ){ | |
if( i == addr ) continue; //skip writing to latch for our target addr | |
rom_write_latch( i, rom_read( i ) ); | |
} | |
//erase row (latches not affected by erase) | |
rom_erase_row( ROM_ID ); | |
//now write our new address data, programming the whole row from latches | |
rom_write_word( addr, wdat ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment