initial check in based on SVN revision 575
This commit is contained in:
415
source/eeprom.c
Normal file
415
source/eeprom.c
Normal file
@@ -0,0 +1,415 @@
|
||||
/*
|
||||
* eeprom.c
|
||||
*
|
||||
* Created on: Jun 10, 2022
|
||||
* Author: Keith.Lloyd
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "fsl_spi.h"
|
||||
#include <fsl_clock.h>
|
||||
#include <fsl_ctimer.h>
|
||||
|
||||
#include "m95512.h"
|
||||
#include "spi.h"
|
||||
#include "timer.h"
|
||||
#include "System/system.h"
|
||||
#include "bootloader.h"
|
||||
#include "frq.h"
|
||||
#include "eeprom.h"
|
||||
#include "Fonts/translate.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#define EE_BUFFER_SIZE (8) //size of buffer for send/receive 4-byte words
|
||||
#define EE_BYTES_PER_WORD (4)
|
||||
|
||||
#define EE_HEADER_NUM_BYTES (3) //number of bytes in m95512 header - instruction, addrH, addrL
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
extern SYSTEM_DATA_t sys;
|
||||
extern spi_transfer_t SPI0_xfer;
|
||||
extern uint8_t frequency;
|
||||
extern TIMER_t tmr;
|
||||
/*******************************************************************************
|
||||
* Static Function Declarations
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Static Functions
|
||||
******************************************************************************/
|
||||
|
||||
static bool EE_Busy(void)
|
||||
{
|
||||
uint8_t sr;
|
||||
M95512_ReadStatus(&sr);
|
||||
return sr & EE_SR_WIP;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Public Functions
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* Load data from EEPROM
|
||||
*/
|
||||
void EE_LoadData(void)
|
||||
{
|
||||
//Check for blank EEPROM
|
||||
EE_ReadBytes(EE_SYS_MFG, sys.manufacturer, SYS_INFO_LENGTH);
|
||||
if(sys.manufacturer[0] == 0xff)
|
||||
{
|
||||
SYS_LoadFactoryDefaults();
|
||||
EE_SaveData();
|
||||
}
|
||||
|
||||
//System Data
|
||||
EE_ReadBytes(EE_SYS_MFG, sys.manufacturer, SYS_INFO_LENGTH);
|
||||
EE_ReadBytes(EE_SYS_MODEL_NUMBER, sys.modelNumber, SYS_INFO_LENGTH);
|
||||
EE_ReadBytes(EE_SYS_MODEL_NAME, sys.modelName, SYS_INFO_LENGTH);
|
||||
EE_ReadBytes(EE_SYS_SERIAL, sys.serialNumber, SYS_INFO_LENGTH);
|
||||
EE_ReadBytes(EE_SYS_MFG_DATE, sys.mfgDate, SYS_INFO_LENGTH);
|
||||
|
||||
EE_ReadMemoryUINT32(BL_VERSION_EEPROM_ADDR, &sys.bootloaderVersion);
|
||||
|
||||
EE_ReadMemoryUINT32(EE_DATA_LANGUAGE, &sys.language);
|
||||
if(sys.language > NUM_TRANSLATION_STRINGS)
|
||||
sys.language = LANG_ENGLISH;
|
||||
|
||||
EE_ReadBytes(EE_DATA_FREQUENCY, &frequency, 1); //1 byte only
|
||||
|
||||
EE_ReadBytes(EE_DATA_TIMER, &tmr.autoShutdown, 1); //timer 1 byte only
|
||||
if(tmr.autoShutdown >= SD_NUM)
|
||||
tmr.autoShutdown = SD_1_HR;
|
||||
|
||||
if(frequency > FREQ_MAX_NUM)
|
||||
frequency = 1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool EE_LoadFrequencies(void)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
//Load frequencies
|
||||
uint32_t tempNumFreqs = EE_ReadUINT32(EE_FREQ_NUM);
|
||||
if((tempNumFreqs > FREQ_MAX_NUM) || (tempNumFreqs == 0)) //Error check numFreqs
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(uint32_t i = 0; i < tempNumFreqs; i++)
|
||||
{
|
||||
uint32_t packedFreq = EE_ReadUINT32(EE_FREQ_START + EE_BYTES_PER_WORD * i);
|
||||
FREQ_AddPackedFrequency(packedFreq);
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save data to EEPROM
|
||||
*/
|
||||
void EE_SaveData(void)
|
||||
{
|
||||
EE_WriteBytes(EE_SYS_MFG, sys.manufacturer, SYS_INFO_LENGTH);
|
||||
EE_WriteBytes(EE_SYS_MODEL_NUMBER, sys.modelNumber, SYS_INFO_LENGTH);
|
||||
EE_WriteBytes(EE_SYS_MODEL_NAME, sys.modelName, SYS_INFO_LENGTH);
|
||||
EE_WriteBytes(EE_SYS_SERIAL, sys.serialNumber, SYS_INFO_LENGTH);
|
||||
EE_WriteBytes(EE_SYS_MFG_DATE, sys.mfgDate, SYS_INFO_LENGTH);
|
||||
|
||||
EE_WriteUINT32(EE_DATA_LANGUAGE, sys.language);
|
||||
|
||||
EE_WriteBytes(EE_DATA_FREQUENCY, &frequency, 1);
|
||||
|
||||
EE_WriteBytes(EE_DATA_TIMER, &tmr.autoShutdown, 1); // Save Power down timer status
|
||||
|
||||
//Save Frequencies
|
||||
uint32_t numFreqs = FREQ_GetNumFrequencies();
|
||||
EE_WriteUINT32(EE_FREQ_NUM, numFreqs);
|
||||
for(uint32_t i = 0; i < numFreqs; i++)
|
||||
{
|
||||
EE_WriteUINT32(EE_FREQ_START + EE_BYTES_PER_WORD * i, FREQ_GetPackedFrequency(i));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Erase ALL EEPROM data except for bootloader data
|
||||
* Write 0xff to all
|
||||
*/
|
||||
void EE_EraseAllData(void)
|
||||
{
|
||||
for(uint32_t i = EE_PAGE_SYS; i < EE_PAGE_DATA; i++) //EE_DATA_END; i++)
|
||||
{
|
||||
EE_WriteUINT32(i, 0xffffffff);
|
||||
}
|
||||
}
|
||||
|
||||
void EE_Test(void)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
uint32_t TEST_START_ADDR = 256;
|
||||
uint32_t numWords = 64;
|
||||
|
||||
uint32_t writeData[numWords]; //write to EEPROM
|
||||
uint32_t readData[numWords]; //read from EEPROM
|
||||
|
||||
static uint32_t numGood = 0;
|
||||
static uint32_t numBad = 0;
|
||||
|
||||
//Init writeData
|
||||
for(uint32_t i = 0; i < numWords; i++)
|
||||
{
|
||||
writeData[i] = i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Write data to EEPROM
|
||||
for(uint32_t i = 0; i < numWords; i++)
|
||||
{
|
||||
data = i;
|
||||
EE_WriteMemoryUINT32(TEST_START_ADDR + i*EE_BYTES_PER_WORD, &writeData[i]);
|
||||
}
|
||||
|
||||
|
||||
//Read back
|
||||
memset(readData, 0, sizeof(readData));
|
||||
|
||||
for(uint32_t i = 0; i < numWords; i++)
|
||||
{
|
||||
EE_ReadMemoryUINT32(TEST_START_ADDR + i*EE_BYTES_PER_WORD, &readData[i]);
|
||||
}
|
||||
|
||||
//COMPARE DATA
|
||||
if(0 == memcmp(writeData, readData, numWords))
|
||||
{
|
||||
numGood++;
|
||||
}
|
||||
else
|
||||
{
|
||||
numBad++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//Write zeros to EEPROM
|
||||
for(uint32_t i = 0; i < numWords; i++)
|
||||
{
|
||||
data = 0;
|
||||
EE_WriteMemoryUINT32(TEST_START_ADDR + i*EE_BYTES_PER_WORD, &data);
|
||||
}
|
||||
|
||||
//Read back
|
||||
memset(readData, 0, sizeof(readData));
|
||||
|
||||
for(uint32_t i = 0; i < numWords; i++)
|
||||
{
|
||||
EE_ReadMemoryUINT32(TEST_START_ADDR + i*EE_BYTES_PER_WORD, &readData[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void EE_TestBytes(void)
|
||||
{
|
||||
uint32_t data = 0;
|
||||
uint32_t TEST_START_ADDR = 256;
|
||||
uint32_t numBytes = 128;
|
||||
|
||||
uint8_t writeData[numBytes]; //write to EEPROM
|
||||
uint8_t readData[numBytes]; //read from EEPROM
|
||||
|
||||
static uint32_t numGood = 0;
|
||||
static uint32_t numBad = 0;
|
||||
|
||||
//Init writeData
|
||||
for(uint32_t i = 0; i < numBytes; i++)
|
||||
{
|
||||
writeData[i] = i;
|
||||
}
|
||||
|
||||
//Write data to EEPROM
|
||||
EE_WriteBytes(TEST_START_ADDR, writeData, numBytes);
|
||||
|
||||
|
||||
//Read back
|
||||
memset(readData, 0, numBytes);
|
||||
|
||||
EE_ReadBytes(TEST_START_ADDR, readData, numBytes);
|
||||
|
||||
//COMPARE DATA
|
||||
if(0 == memcmp(writeData, readData, numBytes))
|
||||
{
|
||||
numGood++;
|
||||
}
|
||||
else
|
||||
{
|
||||
numBad++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//Write zeros to EEPROM
|
||||
memset(writeData, 0, sizeof(writeData));
|
||||
EE_WriteBytes(TEST_START_ADDR, writeData, numBytes);
|
||||
|
||||
//Read back
|
||||
memset(readData, 0, sizeof(readData));
|
||||
EE_ReadBytes(TEST_START_ADDR, readData, numBytes);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void EE_WriteMemoryUINT32(uint16_t address, uint32_t *pdata)
|
||||
{
|
||||
TMR_Stop(); //Stop the timer to prevent interrupts from breaking EEPROM comms
|
||||
uint32_t data;
|
||||
uint8_t srcBuff[EE_BUFFER_SIZE];
|
||||
|
||||
M95512_WriteEnable();
|
||||
|
||||
data = *pdata;
|
||||
srcBuff[0] = WRITE_MEM_ARRAY;
|
||||
srcBuff[1] = address >> 8;
|
||||
srcBuff[2] = address;
|
||||
srcBuff[3] = (data & 0xff000000) >> 24;
|
||||
srcBuff[4] = (data & 0x00ff0000) >> 16;
|
||||
srcBuff[5] = (data & 0x0000ff00) >> 8;
|
||||
srcBuff[6] = (data & 0x000000ff);
|
||||
SPI0_SendBytes(srcBuff, 7, E2PROM);
|
||||
|
||||
//Wait for EEPROM WIP flag low
|
||||
while(EE_Busy());
|
||||
|
||||
TMR_Start();
|
||||
}
|
||||
|
||||
void EE_ReadMemoryUINT32(uint16_t address, uint32_t *pdata)
|
||||
{
|
||||
TMR_Stop(); //Stop the timer to prevent interrupts from breaking EEPROM comms
|
||||
|
||||
uint32_t data;
|
||||
uint8_t srcBuff[EE_BUFFER_SIZE];
|
||||
memset(srcBuff, 0, EE_BUFFER_SIZE); //Zero out srcBuff[]. byte 3 was 1???
|
||||
|
||||
srcBuff[0] = READ_MEM_ARRAY;
|
||||
srcBuff[1] = address >> 8; //ADDR high
|
||||
srcBuff[2] = address; //ADDR low
|
||||
SPI0_SendBytes(srcBuff, 7, E2PROM);
|
||||
|
||||
for(uint16_t i = 3; i < 7; i++){
|
||||
data <<= 8;
|
||||
data += SPI0_xfer.rxData[i];
|
||||
}
|
||||
*pdata = data;
|
||||
|
||||
TMR_Start();
|
||||
}
|
||||
|
||||
void EE_WriteUINT32(uint16_t address, uint32_t data)
|
||||
{
|
||||
TMR_Stop(); //Stop the timer to prevent interrupts from breaking EEPROM comms
|
||||
uint8_t srcBuff[EE_BUFFER_SIZE];
|
||||
|
||||
M95512_WriteEnable();
|
||||
|
||||
srcBuff[0] = WRITE_MEM_ARRAY;
|
||||
srcBuff[1] = address >> 8;
|
||||
srcBuff[2] = address;
|
||||
srcBuff[3] = (data & 0xff000000) >> 24;
|
||||
srcBuff[4] = (data & 0x00ff0000) >> 16;
|
||||
srcBuff[5] = (data & 0x0000ff00) >> 8;
|
||||
srcBuff[6] = (data & 0x000000ff);
|
||||
SPI0_SendBytes(srcBuff, 7, E2PROM);
|
||||
|
||||
//Wait for EEPROM WIP flag low
|
||||
while(EE_Busy());
|
||||
|
||||
TMR_Start();
|
||||
}
|
||||
|
||||
uint32_t EE_ReadUINT32(uint16_t address)
|
||||
{
|
||||
TMR_Stop(); //Stop the timer to prevent interrupts from breaking EEPROM comms
|
||||
|
||||
uint32_t data;
|
||||
uint8_t srcBuff[EE_BUFFER_SIZE];
|
||||
memset(srcBuff, 0, EE_BUFFER_SIZE); //Zero out srcBuff[]. byte 3 was 1???
|
||||
|
||||
srcBuff[0] = READ_MEM_ARRAY;
|
||||
srcBuff[1] = address >> 8; //ADDR high
|
||||
srcBuff[2] = address; //ADDR low
|
||||
SPI0_SendBytes(srcBuff, 7, E2PROM);
|
||||
|
||||
for(uint16_t i = 3; i < 7; i++){
|
||||
data <<= 8;
|
||||
data += SPI0_xfer.rxData[i];
|
||||
}
|
||||
|
||||
TMR_Start();
|
||||
return data;
|
||||
}
|
||||
|
||||
/* Write bytes to EEPROM
|
||||
* CAUTION: avoid writing across a 128 byte page boundary! This will cause rollover per the datasheet section 6.6
|
||||
*/
|
||||
void EE_WriteBytes(uint16_t address, uint8_t *pdata, uint16_t numBytes)
|
||||
{
|
||||
|
||||
if((address % EE_PAGE_SIZE) + numBytes > EE_PAGE_SIZE) //Prevent writing across page boundary
|
||||
{
|
||||
//while(1); //Use for debugging
|
||||
return;
|
||||
}
|
||||
|
||||
TMR_Stop(); //Stop the timer to prevent interrupts from breaking EEPROM comms
|
||||
|
||||
uint8_t srcBuff[SPI_XFER_BUFFER_SIZE + EE_HEADER_NUM_BYTES]; //temporary buffer for data
|
||||
|
||||
M95512_WriteEnable();
|
||||
|
||||
srcBuff[0] = WRITE_MEM_ARRAY;
|
||||
srcBuff[1] = address >> 8;
|
||||
srcBuff[2] = address;
|
||||
memcpy(&srcBuff[3], pdata, numBytes); //copy pData to srcBuf
|
||||
SPI0_SendBytes(srcBuff, numBytes + EE_HEADER_NUM_BYTES, E2PROM);
|
||||
|
||||
//Wait for EEPROM WIP flag low
|
||||
while(EE_Busy());
|
||||
|
||||
TMR_Start();
|
||||
}
|
||||
|
||||
/* Read bytes from EEPROM
|
||||
*
|
||||
*/
|
||||
void EE_ReadBytes(uint16_t address, uint8_t *pdata, uint16_t numBytes)
|
||||
{
|
||||
TMR_Stop(); //Stop the timer to prevent interrupts from breaking EEPROM comms
|
||||
|
||||
uint8_t srcBuff[SPI_XFER_BUFFER_SIZE + EE_HEADER_NUM_BYTES];
|
||||
memset(srcBuff, 0, SPI_XFER_BUFFER_SIZE); //Zero out srcBuff[]. byte 3 was 1???
|
||||
|
||||
srcBuff[0] = READ_MEM_ARRAY;
|
||||
srcBuff[1] = address >> 8; //ADDR high
|
||||
srcBuff[2] = address; //ADDR low
|
||||
SPI0_SendBytes(srcBuff, numBytes + EE_HEADER_NUM_BYTES, E2PROM);
|
||||
|
||||
memcpy(pdata, &SPI0_xfer.rxData[3], numBytes); //copy received data to pdata
|
||||
|
||||
TMR_Start();
|
||||
}
|
||||
Reference in New Issue
Block a user