Skip to content

Instantly share code, notes, and snippets.

@cv007
Last active January 14, 2018 00:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cv007/ef4c71befc9fffeec106baac3d9c2848 to your computer and use it in GitHub Desktop.
Save cv007/ef4c71befc9fffeec106baac3d9c2848 to your computer and use it in GitHub Desktop.
//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