Skip to content

Instantly share code, notes, and snippets.

@raasoft
Last active June 4, 2018 12:30
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 raasoft/85f6e683c9b8cb8f57e86aef429b059b to your computer and use it in GitHub Desktop.
Save raasoft/85f6e683c9b8cb8f57e86aef429b059b to your computer and use it in GitHub Desktop.
Reading HEX files
typedef enum { CREATION, FILLING, EARLY_STOP, FORCE_SEND_CONFIGURATION_MEMORY, ELABORATION_READ_PM, WAIT }
StateMachine_t;
StateMachine_t stm = CREATION;
typedef struct {
uint32_t startingAddress;
uint16_t validDataUntil;
uint16_t maxNumberOfWords;
PageType_t type;
MemoryWord word[PM33F_PAGE_SIZE_IN_WORDS];
MemoryWord wordFromREAD_PM[PM33F_PAGE_SIZE_IN_WORDS];
} MemoryPage;
MemoryPage page;
typedef struct {
uint32_t address;
uint8_t byte[PM33F_WORD_SIZE_IN_BYTE]; //0 LSB, 2 MSB
} MemoryWord;
SendHexFile(fMappa);
void SendHexFile(FILE * pFile)
{
while( (!feof(pFile)) && (RichiestaAttiva != RicREAD_PM) && (!readyToSend) ) //Reads until a newline or 'sizeof(Buffer)' character read
{
long ByteCount;
long Address;
long RecordType;
long CharCount;
fgets(Buffer, sizeof(Buffer), pFile);
sscanf(Buffer+1, "%2x%4x%2x", &ByteCount, &Address, &RecordType); //Discard the colon (Buffer+1) and format everything
switch (RecordType) //Data Record
{
case 0: //Data Record
Address = (Address + ExtAddr + ExtSegAddr) / 2; //Real address on device is half of the one written in the .hex
if (ByteCount < 4 || ByteCount % 4 != 0)
{
return;
}
for(CharCount = 0; CharCount < ByteCount*2; CharCount += 8, Address += PM33F_ADDRESS_INCREMENT)
{
if(!readyToSend)
{
sscanf(&(Buffer[9 + CharCount]), "%2hx%2hx%2hx", &(appoggio.byte[0]),&(appoggio.byte[1]),&(appoggio.byte[2]));
appoggio.address = Address;
RunSTM(&stm, appoggio, &page);
if(RichiestaAttiva == RicREAD_PM)
{
Invia_RichiestaCAN(RichiestaAttiva);
DELAY(2000);
RunSTM(&stm, appoggio, &page);
}
}
}
break;
case 1: //End of Data Record
break;
case 2: // Extended Segment Address Record
sscanf(Buffer+9, "%4x", &ExtAddr);
ExtSegAddr = ExtSegAddr << 4;
break;
case 4: // Extended Linear Address Record
sscanf(Buffer+9, "%4x", &ExtAddr);
ExtAddr = ExtAddr << 16;
break;
default:
return ;
break;
}
}
if(feof(pFile))
{
if(stm != CREATION)
{
stm = FORCE_SEND_CONFIGURATION_MEMORY;
RunSTM(&stm, appoggio, &page);
}
}
}
void RunSTM(StateMachine_t * stm_ptr, MemoryWord word, MemoryPage * page_ptr)
{
StateMachine_t stm = *stm_ptr;
long weAreDoneWithThisWord = 0;
long pageOldWordNo = 0;
long pageNewWordNo = 0;
long instrOldUntil = 0;
while (weAreDoneWithThisWord == 0)
{
switch (stm)
{
case CREATION:
//Skip creation until 0x1C00??!??!?
weAreDoneWithThisWord = 1;
if (word.address < 0x001C00U)
{
break;
}
page_ptr->startingAddress = word.address;
page_ptr->validDataUntil = 0;
page_ptr->word[page_ptr->validDataUntil] = word;
if (word.address < 0xF80000)
{
page_ptr->type = PROGRAM_MEMORY;
page_ptr->maxNumberOfWords = PM33F_PAGE_SIZE_IN_WORDS;
}
else
{
page_ptr->type = CONFIGURATION_MEMORY;
page_ptr->maxNumberOfWords = PM33F_CONF_PAGE_SIZE_IN_WORDS;
long i;
MemoryWord w1;
w1.byte[2] = 0x01; w1.byte[1] = 0xCD; w1.byte[0] = 0xCD;
for (i = 0; i < PM33F_CONF_PAGE_SIZE_IN_WORDS; i++)
{
page_ptr->word[i] = w1;
page_ptr->word[i].address = 0xF80000 | i*2;
}
page_ptr->word[(word.address & 0x00000F)/2] = word;
}
stm = FILLING;
break;
case FILLING:
if ((word.address - page_ptr->word[page_ptr->validDataUntil].address) == PM33F_ADDRESS_INCREMENT || page_ptr->type == CONFIGURATION_MEMORY)
{
page_ptr->validDataUntil++;
if (page_ptr->type == CONFIGURATION_MEMORY) {
page_ptr->word[(word.address & 0x0000FF)/2] = word;
} else {
page_ptr->word[page_ptr->validDataUntil] = word;
}
if (page_ptr->validDataUntil == page_ptr->maxNumberOfWords - 1) {
readyToSend = 1;
stm = CREATION;
}
weAreDoneWithThisWord = 1;
}
else
{
stm = EARLY_STOP;
weAreDoneWithThisWord = 0;
}
break;
case EARLY_STOP:
weAreDoneWithThisWord = 1;
stm = ELABORATION_READ_PM;
readyToSend = 0;
SetDati[RicREAD_PM].ByteRichiesta[2] = 0x00;
SetDati[RicREAD_PM].ByteRichiesta[3] = (page_ptr->startingAddress) & 0xFF;
SetDati[RicREAD_PM].ByteRichiesta[4] = (page_ptr->startingAddress >> 8) & 0xFF;
SetDati[RicREAD_PM].ByteRichiesta[5] = (page_ptr->startingAddress >> 16) & 0xFF;
RichiestaAttiva = RicREAD_PM;
break;
case FORCE_SEND_CONFIGURATION_MEMORY:
readyToSend = 1;
weAreDoneWithThisWord = 1;
DELAY(500);
break;
case WAIT:
break;
case ELABORATION_READ_PM:
RichiestaAttiva = RicWRITE_PM;
// trasformo il buffer di ricezione READ_PM in una struttura
// consona all'uso delle funzioni sviluppate di seguito
long cnt;
unsigned short cntA = 0;
for(cnt = 2, Valore = 0; cnt < MAX_BYTE_FROM_READ_PM;)
{
page_ptr->wordFromREAD_PM[Valore/3].byte[Valore % 3] = BancataRX[cnt]; Valore++;
page_ptr->wordFromREAD_PM[Valore/3].byte[Valore % 3] = BancataRX[cnt + 1]; Valore++;
page_ptr->wordFromREAD_PM[Valore/3].byte[Valore % 3] = BancataRX[cnt + 2]; Valore++;
page_ptr->wordFromREAD_PM[Valore/3].byte[Valore % 3] = BancataRX[cnt + 3]; Valore++;
cntA++;
cnt+=8;
}
pageOldWordNo = page_ptr->word[page_ptr->validDataUntil].address / PM33F_PAGE_INCREMENT;
pageNewWordNo = word.address / PM33F_PAGE_INCREMENT;
if (pageNewWordNo == pageOldWordNo)
{
//FAST-FORWARD
long i;
long addr;
instrOldUntil = (word.address - page_ptr->word[page_ptr->validDataUntil].address)/PM33F_ADDRESS_INCREMENT - 1;
for (i = 0, addr = page_ptr->word[page_ptr->validDataUntil].address + PM33F_ADDRESS_INCREMENT; i < instrOldUntil; i++, addr += PM33F_ADDRESS_INCREMENT)
{
page_ptr->validDataUntil++; // from 0 to 511
page_ptr->word[page_ptr->validDataUntil] = page_ptr->wordFromREAD_PM[page_ptr->validDataUntil];
page_ptr->word[page_ptr->validDataUntil].address = addr;
}
stm = FILLING;
weAreDoneWithThisWord = 0; //We will need this afterwards to fill the remaining part
readyToSend = 0;
}
else
{
instrOldUntil = ((pageOldWordNo+1) * PM33F_PAGE_INCREMENT - (page_ptr->word[page_ptr->validDataUntil].address))/2 - 1;
long i; long addr;
for (i = 0, addr = page_ptr->word[page_ptr->validDataUntil].address + PM33F_ADDRESS_INCREMENT; i < instrOldUntil; i++, addr += PM33F_ADDRESS_INCREMENT)
{
page_ptr->validDataUntil++; // from 0 to 511
page_ptr->word[page_ptr->validDataUntil] = page_ptr->wordFromREAD_PM[page_ptr->validDataUntil];
page_ptr->word[page_ptr->validDataUntil].address = addr;
}
readyToSend = 1;
stm = CREATION;
weAreDoneWithThisWord = 1;
}
break;
}
}
*stm_ptr = stm;
}
void SendHexFile(FILE * pFile)
{
char Buffer[BUFFER_SIZE];
int ExtAddr = 0;
int ExtSegAddr = 0;
StateMachine_t stm = CREATION;
MemoryPage page;
MemoryWord appoggio;
while(fgets(Buffer, sizeof(Buffer), pFile) != NULL) //Reads until a newline or 'sizeof(Buffer)' character read
{
int ByteCount;
int Address;
int RecordType;
sscanf((Buffer+7), "%2x", &RecordType);
switch (RecordType) //Data Record
{
case 0: //Data Record
sscanf((Buffer+3), "%4x", &Address);
Address = (Address + ExtAddr + ExtSegAddr) / 2; //Real address on device is half of the one written in the .hex
sscanf((Buffer+1), "%2x", &ByteCount);
if (ByteCount < 4 || ByteCount % 4 != 0)
{
return;
}
for(int CharCount = 0; CharCount < ByteCount*2; CharCount += 8, Address += PM33F_ADDRESS_INCREMENT)
{
sscanf(&(Buffer[9 + CharCount]), "%2hx%2hx%2hx", &(appoggio.byte[0]),&(appoggio.byte[1]),&(appoggio.byte[2]));
appoggio.address = Address;
RunSTM(&stm, appoggio, &page);
}
break;
case 1: //End of Data Record
break;
case 2: // Extended Segment Address Record
sscanf(Buffer+9, "%4x", &ExtAddr);
ExtSegAddr = ExtSegAddr << 4;
break;
case 4: // Extended Linear Address Record
sscanf(Buffer+9, "%4x", &ExtAddr);
ExtAddr = ExtAddr << 16;
break;
default:
return ;
break;
}
}
if (stm != CREATION) {
stm = FORCE_SEND_CONFIGURATION_MEMORY;
RunSTM(&stm, appoggio, &page);
}
return;
}
void RunSTM(StateMachine_t * stm_ptr, MemoryWord word, MemoryPage * page_ptr)
{
StateMachine_t stm = *stm_ptr;
int readyToSend = 0;
int weAreDoneWithThisWord = 0;
while (weAreDoneWithThisWord == 0)
{
switch (stm)
{
case CREATION:
//Skip creation until 0x1C00??!??!?
weAreDoneWithThisWord = 1;
if (word.address < 0x001C00U)
{
break;
}
page_ptr->startingAddress = word.address;
page_ptr->validDataUntil = 0;
page_ptr->word[page_ptr->validDataUntil] = word;
if (word.address < 0xF80000)
{
page_ptr->type = PROGRAM_MEMORY;
page_ptr->maxNumberOfWords = PM33F_PAGE_SIZE_IN_WORDS;
}
else
{
page_ptr->type = CONFIGURATION_MEMORY;
page_ptr->maxNumberOfWords = PM33F_CONF_PAGE_SIZE_IN_WORDS;
int i;
MemoryWord w1;
w1.byte[2] = 0x01; w1.byte[1] = 0xCD; w1.byte[0] = 0xCD;
for (i = 0; i < PM33F_CONF_PAGE_SIZE_IN_WORDS; i++)
{
page_ptr->word[i] = w1;
page_ptr->word[i].address = 0xF80000 | i*2;
}
page_ptr->word[(word.address & 0x00000F)/2] = word;
}
stm = FILLING;
break;
case FILLING:
if ((word.address - page_ptr->word[page_ptr->validDataUntil].address) == PM33F_ADDRESS_INCREMENT || page_ptr->type == CONFIGURATION_MEMORY)
{
page_ptr->validDataUntil++;
if (page_ptr->type == CONFIGURATION_MEMORY) {
page_ptr->word[(word.address & 0x0000FF)/2] = word;
} else {
page_ptr->word[page_ptr->validDataUntil] = word;
}
if (page_ptr->validDataUntil == page_ptr->maxNumberOfWords - 1) {
readyToSend = 1;
stm = CREATION;
}
weAreDoneWithThisWord = 1;
}
else
{
stm = EARLY_STOP;
weAreDoneWithThisWord = 0;
}
break
case EARLY_STOP:
readyToSend = 1;
stm = CREATION;
weAreDoneWithThisWord = 0;
//implementare comando 0x02 ==> lettura
break;
case FORCE_SEND_CONFIGURATION_MEMORY:
//to be checked
readyToSend = 1;
weAreDoneWithThisWord = 1;
break;
}
if (readyToSend == 1)
{
unsigned short CountA = 1;
unsigned short Valore;
if (page_ptr->type == PROGRAM_MEMORY)
{
SetDati[RicWRITE_PM].ByteRichiesta[2] = 0x00;
SetDati[RicWRITE_PM].ByteRichiesta[3] = (page_ptr->startingAddress) & 0xFF;
SetDati[RicWRITE_PM].ByteRichiesta[4] = (page_ptr->startingAddress >> 8) & 0xFF;
SetDati[RicWRITE_PM].ByteRichiesta[5] = (page_ptr->startingAddress >> 16) & 0xFF;
SetDati[RicWRITE_PM].ByteRichiesta[6] = 0x00;
Invia_RichiestaCAN(RicWRITE_PM);
//comando 0x03 ==> scrittura
for(Count = 1 , Valore = 0; Count <= PageSize_X_CountPage; Count++)
{
SetDati[RicWRITE_PM].ByteRichiesta[CountA + 1] = Count;
SetDati[RicWRITE_PM].ByteRichiesta[CountA + 2] = page_ptr -> word[Valore/3].byte[Valore % 3]; Valore++;
SetDati[RicWRITE_PM].ByteRichiesta[CountA + 3] = page_ptr -> word[Valore/3].byte[Valore % 3]; Valore++;
SetDati[RicWRITE_PM].ByteRichiesta[CountA + 4] = page_ptr -> word[Valore/3].byte[Valore % 3]; Valore++;
SetDati[RicWRITE_PM].ByteRichiesta[CountA + 5] = page_ptr -> word[Valore/3].byte[Valore % 3]; Valore++;
Invia_RichiestaCAN(RicWRITE_PM);
}
}
else
{
DELAY(100);
for(Count = 1 ; Count <= PM33F_CONF_PAGE_SIZE_IN_WORDS; Count++)
{
SetDati[RicWrite_CM].ByteRichiesta[CountA + 1] = Count;
SetDati[RicWrite_CM].ByteRichiesta[CountA + 2] = page_ptr -> word[Count-1].byte[2];
SetDati[RicWrite_CM].ByteRichiesta[CountA + 3] = page_ptr -> word[Count-1].byte[0];
SetDati[RicWrite_CM].ByteRichiesta[CountA + 4] = page_ptr -> word[Count-1].byte[1];
Invia_RichiestaCAN(RicWrite_CM);
}
}
readyToSend = 0;
}
}
*stm_ptr = stm;
return;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment