Archive
Archive for May, 2013
dsPIC EEPROM read/write
May 3, 2013
1 comment
This code provides a simple example of reading and writing to EEPROM on a dsPIC30F4011 using a couple of functions adapted from http://www.microchip.com/forums/fb.ashx?m=417425.
/* * David Dorran 03/05/13 Adapted from http://www.microchip.com/forums/fb.ashx?m=417425 to use offsets rather than explicit address locations. * Additional Notes: Tested on dspic30f4011 **********************************************************************/ #include <p30f4011.h> #include <libpic30.h> #include <stdio.h> #define ERASE_WORD 0x4044 #define WRITE_WORD 0x4004 #define ADDRESS_HI 0x007F #define EEPROM_LOW_START_ADDRESS 0xFC00 #define TRUE 1 // Configuration settings _FOSC(CSW_FSCM_OFF & FRC_PLL16); // Fosc=16x7.5MHz, Fcy=30MHz _FWDT(WDT_OFF); // Watchdog timer off _FBORPOR(MCLR_DIS); // Disable reset pin void Eeprom_WriteWord(unsigned short pushAddressOffset, unsigned short value); unsigned short Eeprom_ReadWord(unsigned short pushAddressOffset); int main(void) { unsigned short value; // Setup UART for debugging U1BRG = 48; // 38400 baud @ 30 MIPS U1MODEbits.UARTEN = 1; // Enable UART Eeprom_WriteWord(8, 0x2345 ); //write the wordlength value 0x2345 to the 8th available EEPROM memory location Eeprom_WriteWord(13, 0x4612 ); Eeprom_WriteWord(84, 0xf123 ); value = Eeprom_ReadWord(13); //Read the vword stored in the 13th available EEPROM memory location (should be 0x4612) printf("\nRead value = %x\n", value); while(1); } unsigned short Eeprom_ReadWord(unsigned short pushAddressOffset) { unsigned short ushResult; register int eedata_addr; register int eedata_val; unsigned short pushAddress; pushAddressOffset = pushAddressOffset*2; //word offset , byte addressable so multiply by 2 pushAddress = pushAddressOffset + EEPROM_LOW_START_ADDRESS; TBLPAG = ADDRESS_HI; // __builtin_tblpage() eedata_addr = (unsigned short)pushAddress; // __builtin_tbloffset() __asm__("TBLRDL [%[addr]], %[val]" : [val]"=r"(eedata_val) : [addr]"r"(eedata_addr)); ushResult = eedata_val; return (ushResult); } void Eeprom_WriteWord(unsigned short pushAddressOffset, unsigned short value) { unsigned short pushAddress; pushAddressOffset = pushAddressOffset*2; //word offset , byte addressable so multiply by 2 pushAddress = pushAddressOffset + EEPROM_LOW_START_ADDRESS; TBLPAG = ADDRESS_HI; NVMADRU = ADDRESS_HI; // Write address of word to be erased into NVMADRU, NVMADR registers. NVMADR = (unsigned short) pushAddress; NVMCON = ERASE_WORD; // Setup NVMCON register to erase one EEPROM word. //PROTECT_CODE_FROM_INTERRUPTS_START // Disable interrupts while the KEY sequence is written NVMKEY = 0x55; // Write the KEY sequence step1 NVMKEY = 0xAA; // step2 NVMCONbits.WR = TRUE; // Start the erase cycle //PROTECT_CODE_FROM_INTERRUPTS_STOP // Enable interrupts while (NVMCONbits.WR == TRUE); // wait for the EEPROMS NVMCON = WRITE_WORD; // Setup NVMCON register to write one EEPROM word. { register int eedata_addr; register int eedata_val; eedata_addr = (unsigned short)pushAddress; // write low word of address eedata_val = value; // write data __asm__ volatile ("TBLWTL %[val], [%[addr]]" : [val]"+r"(eedata_val) : [addr]"r"(eedata_addr)); } NVMCON = WRITE_WORD; //PROTECT_CODE_FROM_INTERRUPTS_START // Disable interrupts while the KEY sequence is written NVMKEY = 0x55; // Write the KEY sequence step1 NVMKEY = 0xAA; // step2 NVMCONbits.WR = TRUE; // Start the erase cycle //PROTECT_CODE_FROM_INTERRUPTS_STOP // Enable interrupts while (NVMCONbits.WR == TRUE); // wait for the word to be written // no proper watchdog protection in the 2 while loops // no proper check if bytes are written correctly by re-reading them }
Categories: Uncategorized