📄 sbl_main.c
字号:
/*****************************************************************************
* sbl_main.c: SBL_MAIN API file for NXP LPC210x Family Microprocessors
*
* Copyright(C) 2006, NXP Semiconductor
* All rights reserved.
*
* History
* 2005.10.01 ver 1.00 Prelimnary version, first Release
******************************************************************************/
#include "LPC210x.H"
#include "irq.h"
#include "i2c_sbl.h"
#include "i2c.h"
#include "sbl_iap.h"
#include "sbl_main.h"
#include "sbl_config.h"
unsigned int i2c_data_buf[(I2C_BUF_SIZE/4)];
unsigned int data_block_cnt;
/*****************************************************************************
** Function name: sbl_entry
** Description: Entry point for In-Application Programming
** Parameter: None
** Returned value: None
*****************************************************************************/
void sbl_entry(void)
{
/* Disable Interrupts before IAP process begins */
uninstall_irq(I2C0_INT);
VICIntEnClr = 1 << I2C0_INT;
uninstall_irq(UART1_INT);
VICIntEnClr = 1 << UART1_INT;
/* Loads the IAP Code and the RW component of the IAP Code */
load_overlay(2);
/* Starts the firmware upgrade process */
start_fw_upgrade(60000);
} // sbl_entry
#pragma arm section code = "START_FW_UPGRADE" // This section of code is placed in the sector 3 of the flash
/*****************************************************************************
** Function name: run_user_code
** Description: This function returns control back to the user code
** after IAP is completed.
** Parameter: None
** Returned value: None
*****************************************************************************/
void run_user_code(void)
{
void (*user_entry)(void);
user_entry = (void (*)(void))USER_CODE_START_ADDRESS;
user_entry();
} // run_user_code
/*****************************************************************************
** Function name: start_fw_upgrade
** Description: This function returns control back to the user code
** after IAP is completed.
** Parameter: None
** Returned value: None
*****************************************************************************/
void start_fw_upgrade(unsigned int cclk)
{
data_block_cnt = 0;
i2c_sbl_init();
while (1)
{
upgrade_fw(cclk);
}
} // start_fw_upgrade
/*****************************************************************************
** Function name: upgrade_fw
** Description: slave_receive() is called in the forever loop.
** This function waits for the code to be downloaded via I2C and
** programmed into the flash.
**
** There are three cases that slave_transmit() will
** be called:
** (1) Checksum don't match during the slave_receive()
** (2) Flash program failure during the flash programming
** (3) Flash program success.
**
** On the master side, it will send master_transmit()
** first to upload the code, once it finishes, it will
** call master_receive() to get the status. There will be
** two cases:
** (1) Checksum failure, CHECKSUM_BAD state, status
** 0xFF-0xFF-0xFF will be returned immediately.
** (2) Programming in progress, I2C interface on the slave
** will be disabled, so, on the master side, device address
** will be NACK all the time until programming is finished.
**
** Once the master receives a ACK, it should receive three
** bytes, 0x00-0x00-0x00 indicates programming is successful,
** 0xFF-0xFF-0xFF is failure.
**
** Once all the blocks have been downloaded on the slave side,
** master will send "end-of_program" flag:
** - DEV_ADDR, CMD(0x02) and parameter (0x00-0x00)
** Once the slave sees this sequence of data, is goes to
** DONE state to execute the program.
** Parameter: cclk, not use for now
** Returned value: None
*****************************************************************************/
void upgrade_fw(unsigned int cclk)
{
unsigned char rc;
rc = slave_receive((unsigned char *)i2c_data_buf);
switch (rc)
{
case DATA_OK:
I2C0CONSET &= ~I2CONSET_I2EN;
/* Data block Count is obtained from slave_receive(). */
if ( data_block_cnt == 0x0000 )
{
/* For debugging only, block number is 1 based,
if it's a 0, all the blocks have been sent, it should go
to DONE state, not here. */
while(1); /* Fatal error */
}
data_block_cnt--; // Offset by one adjustment for programming
rc = write_flash(cclk, i2c_data_buf, data_block_cnt);
i2c0_ready();
if (rc == CMD_SUCCESS)
{
slave_transmit( 0x00 ); // Programming successful
}
else
{
slave_transmit( 0xFF ); // Programming failure
}
break;
case CHECKSUM_BAD:
slave_transmit( 0xFF );
break;
case DONE: // Command 0x02, parameters: '0x00', '0x00'
run_user_code();
break;
default: // do nothing
break;
}
} // upgrade_fw
#pragma arm section code
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -