Problem erasing flash sectors.

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problem erasing flash sectors.

Jump to solution
473 Views
john71
Senior Contributor I

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?

0 Kudos
1 Solution
459 Views
john71
Senior Contributor I

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.

View solution in original post

0 Kudos
1 Reply
460 Views
john71
Senior Contributor I

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.

0 Kudos