Hi, ALL
I'm successfully migrate SW from LPC1343 to LPC1347, except FW upgrade via USB IAP.
This is my SW code that run on LPC1343 and not run on LPC1347:
#define init_msdstate() *((uint32_t *)(0x10000054)) = 0x00000000
.....
/* Disable SYSTICK timer and interrupt before calling into ISP */
SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk);
/* Initialize Storage state machine */
init_msdstate();
/*
* Set stack pointer to ROM value (reset default) This must be the last
* piece of code executed before calling ISP, because most C expressions
* and function returns will fail after the stack pointer is changed.
*/
__set_MSP( * ( (uint32_t *) 0x1FFF0000 ) );
/*
* Invoke ISP. We call "iap_entry" to invoke
* ISP because the ISP entry is done through the same
* command interface as IAP.
*/
flash_LPC13XX_IAP_ReInvokeISP();
/* Code will never return! */
......
Because I use RAM2 for USB drivers, I changed #define init_msdstate() to:
#define init_msdstate() *((uint32_t *)(0x20004054)) = 0x00000000
BUT, it still doesn't works.
Whats wrong?
解決済! 解決策の投稿を見る。
O'key. I found the problem.
I don't know why, but if I change this line
__set_MSP( * ( (uint32_t *) 0x1FFF0000 ) );
to this one
__set_MSP( * ( (uint32_t *) 0x00000000 ) );
and USB bootloader running!
BUT, if I apply optimization by size, the USB bootloader not running.
I think it is because a BUG in compiler in LPCXpresso 8.2.2 that I use.
I find WORKAROUND for this BUG, I use volatile value assigned to zero, like this:
volatile uint32_t topOfStack = 0;
__set_MSP( * ( (uint32_t *) topOfStack) );
I prefer to use _vStackTop value defined in linker script:
.....
PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_Ram);
.....
So finally, this is my ReInvokeISP function that run on LPC1347 with ANY optimization:
.....
#define init_msdstate() *((uint32_t *)(0x10000054)) = 0x00000000
extern void _vStackTop(void);
.......
void ReInvokeISP()
{
/* Disable IRQ specific interrupts */
/* DON'T use __disable_irq() */
NVIC_DisableIRQ(PIN_INT0_IRQn);
NVIC_DisableIRQ(PIN_INT1_IRQn);
NVIC_DisableIRQ(PIN_INT2_IRQn);
NVIC_DisableIRQ(PIN_INT3_IRQn);
NVIC_DisableIRQ(PIN_INT4_IRQn);
NVIC_DisableIRQ(PIN_INT5_IRQn);
NVIC_DisableIRQ(PIN_INT6_IRQn);
NVIC_DisableIRQ(PIN_INT7_IRQn);
NVIC_DisableIRQ(GINT0_IRQn);
NVIC_DisableIRQ(GINT1_IRQn);
NVIC_DisableIRQ(RIT_IRQn);
NVIC_DisableIRQ(SSP1_IRQn);
NVIC_DisableIRQ(I2C_IRQn);
NVIC_DisableIRQ(CT16B0_IRQn);
NVIC_DisableIRQ(CT16B1_IRQn);
NVIC_DisableIRQ(CT32B0_IRQn);
NVIC_DisableIRQ(CT32B1_IRQn);
NVIC_DisableIRQ(SSP0_IRQn);
NVIC_DisableIRQ(USART_IRQn);
NVIC_DisableIRQ(USB_IRQ_IRQn);
NVIC_DisableIRQ(USB_FIQ_IRQn);
NVIC_DisableIRQ(ADC_IRQn);
NVIC_DisableIRQ(BOD_IRQn);
NVIC_DisableIRQ(FMC_IRQn);
NVIC_DisableIRQ(USBWAKEUP_IRQn);
/*
* Don't use NVIC_DisableIRQ(WDT_IRQn);
* because you need WDT for MCU reset after firmware.bin replacement
*/
/* Disable SYSTICK timer and interrupt before calling into ISP */
SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk);
/* Initialize Storage state machine */
init_msdstate();
/*
* Reset main stack pointer. This must be the last piece of code
* executed before calling ISP, because most C expressions and
* function returns will fail after the stack pointer is changed.
*/
__set_MSP((uint32_t) &_vStackTop);
/*
* Invoke ISP. We call "iap_entry" to invoke
* ISP because the ISP entry is done through the same
* command interface as IAP.
*/
flash_LPC13XX_IAP_ReInvokeISP();
/* Code will never return! */
}
I attached useful drivers that can help you.
Have a good day!
O'key. I found the problem.
I don't know why, but if I change this line
__set_MSP( * ( (uint32_t *) 0x1FFF0000 ) );
to this one
__set_MSP( * ( (uint32_t *) 0x00000000 ) );
and USB bootloader running!
BUT, if I apply optimization by size, the USB bootloader not running.
I think it is because a BUG in compiler in LPCXpresso 8.2.2 that I use.
I find WORKAROUND for this BUG, I use volatile value assigned to zero, like this:
volatile uint32_t topOfStack = 0;
__set_MSP( * ( (uint32_t *) topOfStack) );
I prefer to use _vStackTop value defined in linker script:
.....
PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_Ram);
.....
So finally, this is my ReInvokeISP function that run on LPC1347 with ANY optimization:
.....
#define init_msdstate() *((uint32_t *)(0x10000054)) = 0x00000000
extern void _vStackTop(void);
.......
void ReInvokeISP()
{
/* Disable IRQ specific interrupts */
/* DON'T use __disable_irq() */
NVIC_DisableIRQ(PIN_INT0_IRQn);
NVIC_DisableIRQ(PIN_INT1_IRQn);
NVIC_DisableIRQ(PIN_INT2_IRQn);
NVIC_DisableIRQ(PIN_INT3_IRQn);
NVIC_DisableIRQ(PIN_INT4_IRQn);
NVIC_DisableIRQ(PIN_INT5_IRQn);
NVIC_DisableIRQ(PIN_INT6_IRQn);
NVIC_DisableIRQ(PIN_INT7_IRQn);
NVIC_DisableIRQ(GINT0_IRQn);
NVIC_DisableIRQ(GINT1_IRQn);
NVIC_DisableIRQ(RIT_IRQn);
NVIC_DisableIRQ(SSP1_IRQn);
NVIC_DisableIRQ(I2C_IRQn);
NVIC_DisableIRQ(CT16B0_IRQn);
NVIC_DisableIRQ(CT16B1_IRQn);
NVIC_DisableIRQ(CT32B0_IRQn);
NVIC_DisableIRQ(CT32B1_IRQn);
NVIC_DisableIRQ(SSP0_IRQn);
NVIC_DisableIRQ(USART_IRQn);
NVIC_DisableIRQ(USB_IRQ_IRQn);
NVIC_DisableIRQ(USB_FIQ_IRQn);
NVIC_DisableIRQ(ADC_IRQn);
NVIC_DisableIRQ(BOD_IRQn);
NVIC_DisableIRQ(FMC_IRQn);
NVIC_DisableIRQ(USBWAKEUP_IRQn);
/*
* Don't use NVIC_DisableIRQ(WDT_IRQn);
* because you need WDT for MCU reset after firmware.bin replacement
*/
/* Disable SYSTICK timer and interrupt before calling into ISP */
SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk);
/* Initialize Storage state machine */
init_msdstate();
/*
* Reset main stack pointer. This must be the last piece of code
* executed before calling ISP, because most C expressions and
* function returns will fail after the stack pointer is changed.
*/
__set_MSP((uint32_t) &_vStackTop);
/*
* Invoke ISP. We call "iap_entry" to invoke
* ISP because the ISP entry is done through the same
* command interface as IAP.
*/
flash_LPC13XX_IAP_ReInvokeISP();
/* Code will never return! */
}
I attached useful drivers that can help you.
Have a good day!
Hi Denys Yurchenko ,
#define init_msdstate() *((uint32_t *)(0x20004054)) = 0x00000000 cause this issue, and I'd like to share some suggestion about this issue.
1. Whether you had tried assign the storage state machine in RAM1.
2. Whether you can assure USBSRAM bit has became 1.
Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
1. Yes, I tried use RAM1 instead RAM2. The same result, not working.
2. What is USBSRAM?
Hi Denys Yurchenko ,
Thanks for your reply.
I was wondering if you can introduce the demo code in details, and it will help me to figure out the root cause of issue.
Regrading to the USBSRAM bit, it is used to enable or disable the USB SRAM block which has been indicated in the Table 19 in reference manual.
Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------