forked from PAWPAW-Mirror/lib_xua
DFU now uses absolute address for DFU persistent flag (similar to role-change) to try and improve resilience to code/tools changes.
This commit is contained in:
@@ -10,6 +10,28 @@
|
|||||||
|
|
||||||
#include <dfu_interface.h>
|
#include <dfu_interface.h>
|
||||||
|
|
||||||
|
#if defined(ARCH_X200) && (ARCH_X200 == 1)
|
||||||
|
/* Note range 0x7FFC8 - 0x7FFFF guarenteed to be untouched by tools */
|
||||||
|
#define FLAG_ADDRESS 0x7ffc4
|
||||||
|
#else
|
||||||
|
/* Note range 0x1FFC8 - 0x1FFFF guarenteed to be untouched by tools */
|
||||||
|
#define FLAG_ADDRESS 0x1ffc4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Store Flag to fixed address */
|
||||||
|
static void SetDFUFlag(unsigned x)
|
||||||
|
{
|
||||||
|
asm volatile("stw %0, %1[0]" :: "r"(x), "r"(FLAG_ADDRESS));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load flag from fixed address */
|
||||||
|
static unsigned GetDFUFlag()
|
||||||
|
{
|
||||||
|
unsigned x;
|
||||||
|
asm volatile("ldw %0, %1[0]" : "=r"(x) : "r"(FLAG_ADDRESS));
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
static int g_DFU_state = STATE_APP_IDLE;
|
static int g_DFU_state = STATE_APP_IDLE;
|
||||||
static int DFU_status = DFU_OK;
|
static int DFU_status = DFU_OK;
|
||||||
static timer DFUTimer;
|
static timer DFUTimer;
|
||||||
@@ -19,8 +41,6 @@ static int DFU_flash_connected = 0;
|
|||||||
|
|
||||||
static unsigned int subPagesLeft = 0;
|
static unsigned int subPagesLeft = 0;
|
||||||
|
|
||||||
extern int DFU_reset_override;
|
|
||||||
|
|
||||||
extern void DFUCustomFlashEnable();
|
extern void DFUCustomFlashEnable();
|
||||||
extern void DFUCustomFlashDisable();
|
extern void DFUCustomFlashDisable();
|
||||||
|
|
||||||
@@ -32,13 +52,6 @@ void DFUDelay(unsigned d)
|
|||||||
tmr when timerafter(s + d) :> void;
|
tmr when timerafter(s + d) :> void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void temp()
|
|
||||||
{
|
|
||||||
asm(".linkset DFU_reset_override, _edp.bss");
|
|
||||||
asm(".globl DFU_reset_override");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return non-zero on error */
|
/* Return non-zero on error */
|
||||||
static int DFU_OpenFlash()
|
static int DFU_OpenFlash()
|
||||||
{
|
{
|
||||||
@@ -321,8 +334,12 @@ int DFUReportResetState(chanend ?c_user_cmd)
|
|||||||
{
|
{
|
||||||
unsigned int inDFU = 0;
|
unsigned int inDFU = 0;
|
||||||
unsigned int currentTime = 0;
|
unsigned int currentTime = 0;
|
||||||
|
|
||||||
|
unsigned flag;
|
||||||
|
flag = GetDFUFlag();
|
||||||
|
|
||||||
if (DFU_reset_override == 0x11042011)
|
//if (DFU_reset_override == 0x11042011)
|
||||||
|
if (flag == 0x11042011)
|
||||||
{
|
{
|
||||||
unsigned int cmd_data[16];
|
unsigned int cmd_data[16];
|
||||||
inDFU = 1;
|
inDFU = 1;
|
||||||
@@ -412,7 +429,7 @@ void DFUHandler(server interface i_dfu i, chanend ?c_user_cmd)
|
|||||||
select
|
select
|
||||||
{
|
{
|
||||||
case i.HandleDfuRequest(USB_SetupPacket_t &sp, unsigned data_buffer[], unsigned data_buffer_length, unsigned dfuState)
|
case i.HandleDfuRequest(USB_SetupPacket_t &sp, unsigned data_buffer[], unsigned data_buffer_length, unsigned dfuState)
|
||||||
-> {unsigned reset_device_after_ack, int return_data_len, unsigned dfu_reset_override, unsigned returnVal, unsigned newDfuState}:
|
-> {unsigned reset_device_after_ack, int return_data_len, int dfu_reset_override, int returnVal, unsigned newDfuState}:
|
||||||
|
|
||||||
reset_device_after_ack = 0;
|
reset_device_after_ack = 0;
|
||||||
return_data_len = 0;
|
return_data_len = 0;
|
||||||
@@ -519,8 +536,9 @@ int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, USB_SetupPacket_t &sp, ch
|
|||||||
unsigned int data_buffer_len = 0;
|
unsigned int data_buffer_len = 0;
|
||||||
unsigned int data_buffer[17];
|
unsigned int data_buffer[17];
|
||||||
unsigned int reset_device_after_ack = 0;
|
unsigned int reset_device_after_ack = 0;
|
||||||
unsigned int returnVal = 0;
|
int returnVal = 0;
|
||||||
unsigned int dfuState = g_DFU_state;
|
unsigned int dfuState = g_DFU_state;
|
||||||
|
int dfuResetOverride;
|
||||||
|
|
||||||
if(sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_H2D)
|
if(sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_H2D)
|
||||||
{
|
{
|
||||||
@@ -530,21 +548,23 @@ int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, USB_SetupPacket_t &sp, ch
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Interface used here such that the handler can be on another tile */
|
/* Interface used here such that the handler can be on another tile */
|
||||||
{reset_device_after_ack, return_data_len, DFU_reset_override, returnVal, dfuState} = i.HandleDfuRequest(sp, data_buffer, data_buffer_len, g_DFU_state);
|
{reset_device_after_ack, return_data_len, dfuResetOverride, returnVal, dfuState} = i.HandleDfuRequest(sp, data_buffer, data_buffer_len, g_DFU_state);
|
||||||
|
|
||||||
|
SetDFUFlag(dfuResetOverride);
|
||||||
|
|
||||||
/* Update our version of dfuState */
|
/* Update our version of dfuState */
|
||||||
g_DFU_state = dfuState;
|
g_DFU_state = dfuState;
|
||||||
|
|
||||||
/* Check if the request was handled */
|
/* Check if the request was handled */
|
||||||
if(!returnVal)
|
if(returnVal == 0)
|
||||||
{
|
{
|
||||||
if (sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_D2H && sp.wLength != 0)
|
if (sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_D2H && sp.wLength != 0)
|
||||||
{
|
{
|
||||||
XUD_DoGetRequest(ep0_out, ep0_in, (data_buffer, unsigned char[]), return_data_len, return_data_len);
|
returnVal = XUD_DoGetRequest(ep0_out, ep0_in, (data_buffer, unsigned char[]), return_data_len, return_data_len);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
XUD_DoSetRequestStatus(ep0_in);
|
returnVal = XUD_DoSetRequestStatus(ep0_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If device reset requested, handle after command acknowledgement
|
// If device reset requested, handle after command acknowledgement
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
interface i_dfu
|
interface i_dfu
|
||||||
{
|
{
|
||||||
{unsigned, int, unsigned, unsigned, unsigned} HandleDfuRequest(USB_SetupPacket_t &sp, unsigned data_buffer[], unsigned data_buffer_length, unsigned dfuState);
|
{unsigned, int, int, int, unsigned} HandleDfuRequest(USB_SetupPacket_t &sp, unsigned data_buffer[], unsigned data_buffer_length, unsigned dfuState);
|
||||||
void finish();
|
void finish();
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -575,14 +575,11 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
|
|||||||
/* This will return 1 if reset requested */
|
/* This will return 1 if reset requested */
|
||||||
result = DFUDeviceRequests(ep0_out, &ep0_in, &sp, null, g_interfaceAlt[sp.wIndex], dfuInterface, &reset);
|
result = DFUDeviceRequests(ep0_out, &ep0_in, &sp, null, g_interfaceAlt[sp.wIndex], dfuInterface, &reset);
|
||||||
|
|
||||||
if(reset && result == XUD_RES_OKAY)
|
if(reset)
|
||||||
{
|
{
|
||||||
DFUDelay(50000000);
|
DFUDelay(50000000);
|
||||||
device_reboot(c_audioControl);
|
device_reboot(c_audioControl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO we should not make the assumption that all DFU requests are handled */
|
|
||||||
//result = 0;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Check for: - Audio CONTROL interface request - always 0, note we check for DFU first
|
/* Check for: - Audio CONTROL interface request - always 0, note we check for DFU first
|
||||||
|
|||||||
@@ -69,4 +69,6 @@ void device_reboot(chanend spare)
|
|||||||
asm("freer res[%0]"::"r"(spare));
|
asm("freer res[%0]"::"r"(spare));
|
||||||
#endif
|
#endif
|
||||||
device_reboot_aux();
|
device_reboot_aux();
|
||||||
|
|
||||||
|
while(1);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user