Problem with ReinvokeISP on LPC54618

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Problem with ReinvokeISP on LPC54618

ソリューションへジャンプ
2,371件の閲覧回数
mattyoung
Contributor III

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. 

 

0 件の賞賛
返信
1 解決策
2,348件の閲覧回数
mattyoung
Contributor III

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: 

https://community.nxp.com/t5/LPC-Microcontrollers-Knowledge/LPC54XXX-How-To-Use-USB-Port-To-Update-F...

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.

元の投稿で解決策を見る

0 件の賞賛
返信
6 返答(返信)
2,358件の閲覧回数
ZhangJennie
NXP TechSupport
NXP TechSupport

HI 

For LPC546xx, we can use both USB1 and USB0 to ReInvoke ISP.

ZhangJennie_0-1633685179967.png

 

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

2,137件の閲覧回数
NVazquez
Contributor IV

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".

 

0 件の賞賛
返信
2,131件の閲覧回数
mattyoung
Contributor III

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();

2,125件の閲覧回数
NVazquez
Contributor IV

Thank you Matt for the quick response. This definitely helps!

0 件の賞賛
返信
2,355件の閲覧回数
mattyoung
Contributor III

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

0 件の賞賛
返信
2,349件の閲覧回数
mattyoung
Contributor III

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: 

https://community.nxp.com/t5/LPC-Microcontrollers-Knowledge/LPC54XXX-How-To-Use-USB-Port-To-Update-F...

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.

0 件の賞賛
返信