Last active
June 4, 2018 12:30
-
-
Save raasoft/85f6e683c9b8cb8f57e86aef429b059b to your computer and use it in GitHub Desktop.
Reading HEX files
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
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; | |
} |
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
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