Hello,
I would like to be able to update firmware over USB without requiring the user to press the ISPx switch. I understand reinvokeISP allows you to do this, but I am unable to get it to work. Can you help?
My code includes this:
uint32_t status = 0;
IAP_ReinvokeISP(8, &status); // Argument 8 is USB0
I am using the fsl_iap.c /.h driver from SDK 2.10 which includes this function:
void IAP_ReinvokeISP(uint8_t ispType, uint32_t *status)
{
uint32_t command[5] = {0x00U};
uint32_t result[5] = {0x00U};
uint8_t ispParameterArray[8];
command[0] = (uint32_t)kIapCmd_IAP_ReinvokeISP;
(void)memset(ispParameterArray, 0, sizeof(uint8_t) * 8U);
ispParameterArray[1] = ispType;
ispParameterArray[7] = ispParameterArray[0] ^ ispParameterArray[1] ^ ispParameterArray[2] ^ ispParameterArray[3] ^
ispParameterArray[4] ^ ispParameterArray[5] ^ ispParameterArray[6];
command[1] = (uint32_t)ispParameterArray;
iap_entry(command, result);
*status = (uint32_t)translate_iap_status(result[0]);
}
The result is the program passes through this with no effect (a file explore doesn't open on Windows like it does when I do a power cycle and press the appropriate ISP_x button).
I have also tried ispType 0 (Auto-Detect). In this case the program locks up in iap_entry().
I am using using the LPCXpresso546xx rev C demo board.
Related question: Can I use Reinvoke_ISP on USB1? Our own board design only has a connector for USB1, not USB0. I went back to the dev board to test if it would work on USB0, but not working there either.
Thank you.
解決済! 解決策の投稿を見る。
Update: I now have it working! Thanks.
I found the Chip_IAP_ReinvokeISP code in an attachment to a related knowledge base, that happens to be from you also:
This is the code I needed:
/* Reinvoke ISP */
uint32_t Chip_IAP_ReinvokeISP( uint32_t *invoke_ptr )
{
uint32_t command[5], result[4];
command[0] = IAP_REINVOKE_ISP_CMD;
command[1] = (uint32_t)invoke_ptr;
iap_entry(command, result);
return result[0];
}
Additional notes:
I Changed: isp_mode[0] = 0xAA; /* 0xAA as DFU, otherwise, it's a MSC */
To: isp_mode[0] = 0xFF; /* 0xAA as DFU, otherwise, it's a MSC */
The reason is I’m familiar with MSC in that it opens a window on the PC to work with and drop the new file in. I understand DFU requires a utility program on the PC in order to update firmware.
USB1 vs USB0: It works for me with USB1 (MSC), but while I had it hooked up I tried to get it to work on USB0 also as an experiment. What is the value to enter for that? Is ‘SL_USBHS’ for USB1 and ‘SL_USBFS’ for USB0?
isp_mode[1] = SL_USBFS;
I tried the above and connected to USB0, but it didn’t work.
HI
For LPC546xx, we can use both USB1 and USB0 to ReInvoke ISP.
Config isp_mode[1] to select the USB port. I ever tested below code on my side on LPC54628 demo board. It works. Please try it on your side as well. See how it works.
typedef enum {
SL_AUTO = 0, /* AUTO */
SL_I2C0 = 1, /* I2C0 */
SL_SPI0 = 4, /*!< SPI0 */
SL_UART0 = 6, /*!< UART0 */
SL_USBFS = 8, /*!< USB FS */
SL_USBHS = 9, /*!< USB HS */
SL_CAN0 = 10, /*!< CAN0 */
} SL_IFSEL_T;
uint32_t error_code;
uint8_t xor_value = 0, isp_mode[8];
memset( isp_mode, 0, sizeof(isp_mode) );
isp_mode[0] = 0xAA; /* 0xAA as DFU, otherwise, it's a MSC */
isp_mode[1] = SL_USBHS;
for ( i = 0; i < 8; i++ ) {
xor_value ^= isp_mode[i];
}
isp_mode[7] = xor_value;
error_code = Chip_IAP_ReinvokeISP((uint32_t *)isp_mode);
err_check(error_code);
Have a nice day
Jun Zhang
where can we add this part of the code?
typedef enum {
SL_AUTO = 0, /* AUTO */
SL_I2C0 = 1, /* I2C0 */
SL_SPI0 = 4, /*!< SPI0 */
SL_UART0 = 6, /*!< UART0 */
SL_USBFS = 8, /*!< USB FS */
SL_USBHS = 9, /*!< USB HS */
SL_CAN0 = 10, /*!< CAN0 */
} SL_IFSEL_T;
uint32_t error_code;
uint8_t xor_value = 0, isp_mode[8];
memset( isp_mode, 0, sizeof(isp_mode) );
isp_mode[0] = 0xAA; /* 0xAA as DFU, otherwise, it's a MSC */
isp_mode[1] = SL_USBHS;
for ( i = 0; i < 8; i++ ) {
xor_value ^= isp_mode[i];
}
isp_mode[7] = xor_value;
error_code = Chip_IAP_ReinvokeISP((uint32_t *)isp_mode);
err_check(error_code);
Also I get an error 'IAP_REINVOKE_ISP_CMD' undeclared (first use in this function) fsl_iap.c".
Hi Nhule,
I'm not NXP support, but I can show my code that worked:
//************************************************************************************
// ReinvokeISP
// This enters ISP mode for updating firmware on USB1, MSC mode
//************************************************************************************
void ReinvokeISP_USB(void)
{
uint8_t xor_value = 0, isp_mode[8];
uint8_t i;
memset( isp_mode, 0, sizeof(isp_mode) );
isp_mode[0] = 0xFF; /* 0xAA as DFU, otherwise, it's a MSC */
isp_mode[1] = 9; //9 for USB1 (8 for USB0??)
for ( i = 0; i < 8; i++ ) {
xor_value ^= isp_mode[i];
}
isp_mode[7] = xor_value;
(void)Chip_IAP_ReinvokeISP((uint32_t *)isp_mode);
}
//************************************************************************************
// Chip_IAP_ReinvokeISP
//************************************************************************************
uint32_t Chip_IAP_ReinvokeISP( uint32_t *invoke_ptr )
{
uint32_t command[5], result[4];
command[0] = IAP_REINVOKE_ISP_CMD; //57 is command for Reinvoke ISP
command[1] = (uint32_t)invoke_ptr;
iap_entry(command, result);
return result[0];
}
Also this earlier:
#define IAP_REINVOKE_ISP_CMD 57 /*!< Reinvoke ISP */
And run this when I want it to happen:
ReinvokeISP_USB();
Thank you Matt for the quick response. This definitely helps!
Hello Jun Zhang,
Thank you for the response. Could you tell me the function to use for: Chip_IAP_ReinvokeISP((uint32_t *)isp_mode)
I searched and did not find it in my SDK version 2.10
Thanks,
Matt
Update: I now have it working! Thanks.
I found the Chip_IAP_ReinvokeISP code in an attachment to a related knowledge base, that happens to be from you also:
This is the code I needed:
/* Reinvoke ISP */
uint32_t Chip_IAP_ReinvokeISP( uint32_t *invoke_ptr )
{
uint32_t command[5], result[4];
command[0] = IAP_REINVOKE_ISP_CMD;
command[1] = (uint32_t)invoke_ptr;
iap_entry(command, result);
return result[0];
}
Additional notes:
I Changed: isp_mode[0] = 0xAA; /* 0xAA as DFU, otherwise, it's a MSC */
To: isp_mode[0] = 0xFF; /* 0xAA as DFU, otherwise, it's a MSC */
The reason is I’m familiar with MSC in that it opens a window on the PC to work with and drop the new file in. I understand DFU requires a utility program on the PC in order to update firmware.
USB1 vs USB0: It works for me with USB1 (MSC), but while I had it hooked up I tried to get it to work on USB0 also as an experiment. What is the value to enter for that? Is ‘SL_USBHS’ for USB1 and ‘SL_USBFS’ for USB0?
isp_mode[1] = SL_USBFS;
I tried the above and connected to USB0, but it didn’t work.