I use the Kinetis CPU MK10F12.
I'm trying to create the PC side bootloader application for a standard bootloader.
unsigned char FC_Communication( void )
{
uint8_t i,rd_buff[100]={0}; //uiReadData=0,
uint8_t *pAddress;
ADDRESS_TYPE * pTempAddress;
//byte status;
static byte isFirstTime = 1;
uint8 tempde=0;
// if(UART_S1_RDRF_MASK != UART_getchar_present(TERM_PORT))
// {
// return 0;
// }
// read data from UART -----> We are reading the data through the interrupt UART_OnRxChar to uiReadData (Global parameter).
status = UART_RecvChar(&uiReadData);
if((status == ERR_RXEMPTY )&&(g_ucFC_State != 0)) // if we don't get nothing in status & this is not first state return.
return 0; // was: return 2
//uiReadData = UART_getchar(TERM_PORT);
switch( g_ucFC_State )
{
case FC_STATE_NULL:
{
if( uiReadData == FC_CMD_ACK )
{
UART_Send(0xFC);
//UART_putchar( TERM_PORT,0xfc );
g_ucFC_State = FC_STATE_WORKING;
}
else
{
return 0;
}
}
break;
case FC_STATE_WORKING:
{
switch( uiReadData )
{
case FC_CMD_IDENT:
{
//UART_SendChar(0xC9);
if(!isFirstTime) // To prevent sending all the time the strings to the host.
{
return 1;
}
UART_Send(m_MCU_Info.Version);
UART_Send(m_MCU_Info.Sdid>>8);
UART_Send(m_MCU_Info.Sdid);
pTempAddress = (ADDRESS_TYPE *)&m_MCU_Info.BlocksCnt;
for(i=0;i<7;i++)
{
UART_Send(pTempAddress[i].Bytes.hh);
WAIT1_Waitus(10);
UART_Send(pTempAddress[i].Bytes.hl);
WAIT1_Waitus(10);
UART_Send(pTempAddress[i].Bytes.lh);
WAIT1_Waitus(10);
UART_Send(pTempAddress[i].Bytes.ll);
WAIT1_Waitus(10);
}
i = 0;
do
{
//UART_putchar( TERM_PORT,m_MCU_Info.IdString[i]);
UART_Send(m_MCU_Info.IdString[i]);
}while(m_MCU_Info.IdString[i++]);
isFirstTime = 0;
}
break;
case FC_CMD_ERASE:
{
g_ucFC_State = FC_STATE_EREASE;
}
break;
case FC_CMD_WRITE:
{
g_ucFC_State = FC_STATE_WRITE_ADDRESS;
}
break;
case FC_CMD_READ:
{
g_ucFC_State = FC_STATE_READ;
}
break;
case FC_CMD_QUIT:
{
SCB_VTOR = RELOCATION_VERTOR_ADDR;
JumpToUserApplication(RELOCATION_VERTOR_ADDR);
// SCB_VTOR = 0x1ffffc00;
// JumpToUserApplication(0x1ffffc00);
}
break;
default:
//UART_putchar( TERM_PORT,0xfc );
break;
}
m_uiRecCount = 0;
idx = 0;
}
break;
case FC_STATE_EREASE:
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// for(i=0;i<100;i++)
// {
// rd_buff[i] = uiReadData;
// }
//idx = 0;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
m_pRecFrame[m_uiRecCount++] = uiReadData;
if( m_uiRecCount >= sizeof(uint32_t) )
{
// erase
LONG_Convert(&m_RecFrame.uiAddress);
if(!Flash_EraseSector(m_RecFrame.uiAddress))
{
UART_Send(FC_CMD_ACK);
//UART_putchar( TERM_PORT,FC_CMD_ACK );
}
else
{
UART_Send(FC_CMD_NACK);
//UART_putchar( TERM_PORT,FC_CMD_NACK );
}
g_ucFC_State = FC_STATE_WORKING;
}
}
break;
case FC_STATE_WRITE_ADDRESS:
{
m_pRecFrame[m_uiRecCount++] = uiReadData;
if( m_uiRecCount >= sizeof(uint32_t) )
{
g_ucFC_State = FC_STATE_WRITE_LEN;
}
}
break;
case FC_STATE_WRITE_LEN:
{
m_pRecFrame[m_uiRecCount++] = uiReadData;
g_ucFC_State = FC_STATE_WRITE_DATA;
}
break;
case FC_STATE_WRITE_DATA:
{
m_pRecFrame[m_uiRecCount++] = uiReadData;
if( m_uiRecCount > (m_RecFrame.Length + sizeof(uint32_t) ))
{
LONG_Convert(&m_RecFrame.uiAddress);
Memcpy_Byte((uint8_t *)&m_ucDataBuff[0],(uint8_t *)&m_RecFrame.DataBuff[0],m_RecFrame.Length);
uiNumberCount ++;
if( !Flash_Write(m_RecFrame.uiAddress,
(uint8_t *)&m_ucDataBuff[0],m_RecFrame.Length) )
{
UART_Send(FC_CMD_ACK);
//UART_putchar( TERM_PORT,FC_CMD_ACK );
}
else
{
UART_Send(FC_CMD_NACK);
//UART_putchar( TERM_PORT,FC_CMD_NACK );
}
g_ucFC_State = FC_STATE_WORKING;
}
}
break;
case FC_STATE_READ:
{
m_pRecFrame[m_uiRecCount++] = uiReadData;
if( m_uiRecCount > sizeof(uint32_t) )
{
LONG_Convert(&m_RecFrame.uiAddress);
pAddress = (uint8_t *)m_RecFrame.uiAddress;
for( i=0;i<m_RecFrame.Length;i++)
{
UART_Send(pAddress[i]);
//UART_putchar( TERM_PORT,pAddress[i] );
}
g_ucFC_State = FC_STATE_WORKING;
}
}
break;
default:
break;
}
return 1;
}
With a supplied win_hc08sprg.exe it works OK. But I need to modify it to burn bin files instead of srec.
So I create my own application.
First I erase the pages needed for the main program. I send erase opcode (0x45) + address.
First send FC_CMD_ERASE + 4000 - I get FC_CMD_ACK - page erased successfully.
Second send - FC_CMD_ERASE + 5000 (page size 0x1000) - I get an exception
PE_ISR(Cpu_Interrupt)
{
/* This code can be changed using the CPU component property "Build Options / Unhandled int code" */
PE_DEBUGHALT();
}
at if(!Flash_EraseSector(m_RecFrame.uiAddress)).
I was trying some patterns to find the problem but can't bit it.
-------------------------------------------------------------------
FC_CMD_ERASE 4000 - FC_CMD_ACK
FC_CMD_ERASE 4000 - PE_ISR(Cpu_Interrupt).
--------------------------------------------------------------------
FC_CMD_ERASE 5000 - FC_CMD_ACK
FC_CMD_ERASE 5000 - FC_CMD_ACK
FC_CMD_ERASE 4000 - PE_ISR(Cpu_Interrupt)
--------------------------------------------------------------------
FC_CMD_ERASE 5000 - FC_CMD_ACK
FC_CMD_ERASE 5000 - FC_CMD_ACK
FC_CMD_ERASE 5000 - FC_CMD_ACK
FC_CMD_ERASE 4000 - FC_CMD_ACK
FC_CMD_ERASE 4000 - PE_ISR(Cpu_Interrupt).
--------------------------------------------------------------------
What is wrong with my algorithm?
Solved! Go to Solution.
Well...
I generated a bin file of the bootloader program - it's 16820 bytes.
and
case FC_CMD_QUIT:
{
SCB_VTOR = RELOCATION_VERTOR_ADDR;
JumpToUserApplication(RELOCATION_VERTOR_ADDR);
}
break;
where RELOCATION_VERTOR_ADDR = 0x04000 (16384 bytes)
What do I miss?
OMG!!!
The original bootloader size was 9K. After modification it's 17K. So I should change - RELOCATION_VERTOR_ADDR = 0x05000.
Well...
I generated a bin file of the bootloader program - it's 16820 bytes.
and
case FC_CMD_QUIT:
{
SCB_VTOR = RELOCATION_VERTOR_ADDR;
JumpToUserApplication(RELOCATION_VERTOR_ADDR);
}
break;
where RELOCATION_VERTOR_ADDR = 0x04000 (16384 bytes)
What do I miss?
OMG!!!
The original bootloader size was 9K. After modification it's 17K. So I should change - RELOCATION_VERTOR_ADDR = 0x05000.