mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-31 05:52:55 +08:00
add hard fault handler to bsp.c
rename class_install_subtask to class_open_subtask add class_close for unmount adding code for usbh_device_unplugged_isr & invoke it in hcd_isr
This commit is contained in:
parent
63765b37c7
commit
97c9001d40
@ -50,3 +50,89 @@ void check_failed(uint8_t *file, uint32_t line)
|
||||
(void) file;
|
||||
(void) line;
|
||||
}
|
||||
|
||||
/**
|
||||
* HardFault_HandlerAsm:
|
||||
* Alternative Hard Fault handler to help debug the reason for a fault.
|
||||
* To use, edit the vector table to reference this function in the HardFault vector
|
||||
* This code is suitable for Cortex-M3 and Cortex-M0 cores
|
||||
*/
|
||||
|
||||
// Use the 'naked' attribute so that C stacking is not used.
|
||||
__attribute__((naked))
|
||||
void HardFault_HandlerAsm(void){
|
||||
/*
|
||||
* Get the appropriate stack pointer, depending on our mode,
|
||||
* and use it as the parameter to the C handler. This function
|
||||
* will never return
|
||||
*/
|
||||
|
||||
__asm( ".syntax unified\n"
|
||||
"MOVS R0, #4 \n"
|
||||
"MOV R1, LR \n"
|
||||
"TST R0, R1 \n"
|
||||
"BEQ _MSP \n"
|
||||
"MRS R0, PSP \n"
|
||||
"B HardFault_HandlerC \n"
|
||||
"_MSP: \n"
|
||||
"MRS R0, MSP \n"
|
||||
"B HardFault_HandlerC \n"
|
||||
".syntax divided\n") ;
|
||||
}
|
||||
|
||||
/**
|
||||
* HardFaultHandler_C:
|
||||
* This is called from the HardFault_HandlerAsm with a pointer the Fault stack
|
||||
* as the parameter. We can then read the values from the stack and place them
|
||||
* into local variables for ease of reading.
|
||||
* We then read the various Fault Status and Address Registers to help decode
|
||||
* cause of the fault.
|
||||
* The function ends with a BKPT instruction to force control back into the debugger
|
||||
*/
|
||||
void HardFault_HandlerC(unsigned long *hardfault_args){
|
||||
volatile unsigned long stacked_r0 ;
|
||||
volatile unsigned long stacked_r1 ;
|
||||
volatile unsigned long stacked_r2 ;
|
||||
volatile unsigned long stacked_r3 ;
|
||||
volatile unsigned long stacked_r12 ;
|
||||
volatile unsigned long stacked_lr ;
|
||||
volatile unsigned long stacked_pc ;
|
||||
volatile unsigned long stacked_psr ;
|
||||
volatile unsigned long _CFSR ;
|
||||
volatile unsigned long _HFSR ;
|
||||
volatile unsigned long _DFSR ;
|
||||
volatile unsigned long _AFSR ;
|
||||
volatile unsigned long _BFAR ;
|
||||
volatile unsigned long _MMAR ;
|
||||
|
||||
stacked_r0 = ((unsigned long)hardfault_args[0]) ;
|
||||
stacked_r1 = ((unsigned long)hardfault_args[1]) ;
|
||||
stacked_r2 = ((unsigned long)hardfault_args[2]) ;
|
||||
stacked_r3 = ((unsigned long)hardfault_args[3]) ;
|
||||
stacked_r12 = ((unsigned long)hardfault_args[4]) ;
|
||||
stacked_lr = ((unsigned long)hardfault_args[5]) ;
|
||||
stacked_pc = ((unsigned long)hardfault_args[6]) ;
|
||||
stacked_psr = ((unsigned long)hardfault_args[7]) ;
|
||||
|
||||
// Configurable Fault Status Register
|
||||
// Consists of MMSR, BFSR and UFSR
|
||||
_CFSR = (*((volatile unsigned long *)(0xE000ED28))) ;
|
||||
|
||||
// Hard Fault Status Register
|
||||
_HFSR = (*((volatile unsigned long *)(0xE000ED2C))) ;
|
||||
|
||||
// Debug Fault Status Register
|
||||
_DFSR = (*((volatile unsigned long *)(0xE000ED30))) ;
|
||||
|
||||
// Auxiliary Fault Status Register
|
||||
_AFSR = (*((volatile unsigned long *)(0xE000ED3C))) ;
|
||||
|
||||
// Read the Fault Address Registers. These may not contain valid values.
|
||||
// Check BFARVALID/MMARVALID to see if they are valid values
|
||||
// MemManage Fault Address Register
|
||||
_MMAR = (*((volatile unsigned long *)(0xE000ED34))) ;
|
||||
// Bus Fault Address Register
|
||||
_BFAR = (*((volatile unsigned long *)(0xE000ED38))) ;
|
||||
|
||||
__asm("BKPT #0\n") ; // Break into the debugger
|
||||
}
|
||||
|
@ -97,3 +97,13 @@ void test_isr_device_connect_slowspeed(void)
|
||||
//------------- Code Under Test -------------//
|
||||
hcd_isr(hostid);
|
||||
}
|
||||
|
||||
void test_isr_device_disconnect(void)
|
||||
{
|
||||
ehci_controller_device_unplug(hostid);
|
||||
usbh_device_unplugged_isr_Expect(hostid);
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
hcd_isr(hostid);
|
||||
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ void test_enum_failed_get_full_config_desc(void)
|
||||
|
||||
void class_install_expect(void)
|
||||
{
|
||||
hidh_install_subtask_StubWithCallback(hidh_install_stub);
|
||||
hidh_open_subtask_StubWithCallback(hidh_install_stub);
|
||||
}
|
||||
|
||||
void test_enum_parse_config_desc(void)
|
||||
|
@ -156,3 +156,22 @@ void test_usbh_init_ok(void)
|
||||
TEST_ASSERT_EQUAL_MEMORY(device_info_zero, usbh_device_info_pool, sizeof(usbh_device_info_t)*(TUSB_CFG_HOST_DEVICE_MAX+1));
|
||||
|
||||
}
|
||||
|
||||
void class_close_expect(void)
|
||||
{
|
||||
hidh_close_Expect(1);
|
||||
}
|
||||
|
||||
void test_usbh_device_unplugged_isr(void)
|
||||
{
|
||||
usbh_device_info_pool[1].status = TUSB_DEVICE_STATUS_READY;
|
||||
usbh_device_info_pool[1].core_id = 0;
|
||||
usbh_device_info_pool[1].hub_addr = 0;
|
||||
usbh_device_info_pool[1].hub_port = 0;
|
||||
|
||||
class_close_expect();
|
||||
|
||||
usbh_device_unplugged_isr(0);
|
||||
|
||||
TEST_ASSERT_EQUAL(TUSB_DEVICE_STATUS_REMOVING, usbh_device_info_pool[1].status);
|
||||
}
|
||||
|
@ -86,3 +86,12 @@ void ehci_controller_device_plug(uint8_t hostid, tusb_speed_t speed)
|
||||
regs->portsc_bit.current_connect_status = 1;
|
||||
regs->portsc_bit.nxp_port_speed = speed;
|
||||
}
|
||||
|
||||
void ehci_controller_device_unplug(uint8_t hostid)
|
||||
{
|
||||
ehci_registers_t* const regs = get_operational_register(hostid);
|
||||
|
||||
regs->usb_sts_bit.port_change_detect = 1;
|
||||
regs->portsc_bit.connect_status_change = 1;
|
||||
regs->portsc_bit.current_connect_status = 0;
|
||||
}
|
||||
|
@ -57,6 +57,7 @@
|
||||
|
||||
void ehci_controller_run(uint8_t hostid);
|
||||
void ehci_controller_device_plug(uint8_t hostid, tusb_speed_t speed);
|
||||
void ehci_controller_device_unplug(uint8_t hostid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -88,8 +88,9 @@ tusb_error_t hidh_keyboard_install(uint8_t dev_addr, uint8_t const *descriptor)
|
||||
// CLASS DRIVER FUNCTION (all declared with WEAK)
|
||||
//--------------------------------------------------------------------+
|
||||
void hidh_init(void) ATTR_WEAK;
|
||||
tusb_error_t hidh_install_subtask(uint8_t dev_addr, uint8_t const *descriptor, uint16_t *p_length) ATTR_WEAK ATTR_WARN_UNUSED_RESULT;
|
||||
tusb_error_t hidh_open_subtask(uint8_t dev_addr, uint8_t const *descriptor, uint16_t *p_length) ATTR_WEAK ATTR_WARN_UNUSED_RESULT;
|
||||
void hidh_isr(pipe_handle_t pipe_hdl) ATTR_WEAK;
|
||||
void hidh_close(uint8_t dev_addr) ATTR_WEAK;
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -69,9 +69,9 @@
|
||||
#ifdef _TINY_USB_SOURCE_FILE_
|
||||
|
||||
void msch_init(void) ATTR_WEAK;
|
||||
tusb_error_t msch_install_subtask(uint8_t dev_addr, uint8_t const *descriptor, uint16_t *p_length) ATTR_WEAK ATTR_WARN_UNUSED_RESULT;
|
||||
tusb_error_t msch_open_subtask(uint8_t dev_addr, uint8_t const *descriptor, uint16_t *p_length) ATTR_WEAK ATTR_WARN_UNUSED_RESULT;
|
||||
void msch_isr(pipe_handle_t pipe_hdl) ATTR_WEAK;
|
||||
|
||||
void msch_close(uint8_t dev_addr) ATTR_WEAK;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -175,7 +175,7 @@ void port_connect_status_isr(uint8_t hostid)
|
||||
usbh_device_plugged_isr(hostid, regs->portsc_bit.nxp_port_speed); // NXP specific port speed
|
||||
}else // device unplugged
|
||||
{
|
||||
// usbh_device_
|
||||
usbh_device_unplugged_isr(hostid);
|
||||
}
|
||||
|
||||
}
|
||||
@ -578,6 +578,7 @@ static inline ehci_qtd_t* get_control_qtds(uint8_t dev_addr)
|
||||
|
||||
static void init_qhd(ehci_qhd_t *p_qhd, uint8_t dev_addr, uint16_t max_packet_size, uint8_t endpoint_addr, uint8_t xfer_type)
|
||||
{
|
||||
// address 0 uses async head, which always on the list --> cannot be cleared (ehci halted otherwise)
|
||||
if (dev_addr != 0)
|
||||
{
|
||||
memclr_(p_qhd, sizeof(ehci_qhd_t));
|
||||
|
@ -65,14 +65,16 @@ class_driver_t const usbh_class_drivers[TUSB_CLASS_MAX_CONSEC_NUMBER] =
|
||||
{
|
||||
[TUSB_CLASS_HID] = {
|
||||
.init = hidh_init,
|
||||
.install_subtask = hidh_install_subtask,
|
||||
.isr = hidh_isr
|
||||
.open_subtask = hidh_open_subtask,
|
||||
.isr = hidh_isr,
|
||||
.close = hidh_close
|
||||
},
|
||||
|
||||
[TUSB_CLASS_MSC] = {
|
||||
.init = msch_init,
|
||||
.install_subtask = msch_install_subtask,
|
||||
.isr = msch_isr
|
||||
.open_subtask = msch_open_subtask,
|
||||
.isr = msch_isr,
|
||||
.close = msch_close
|
||||
}
|
||||
};
|
||||
|
||||
@ -190,7 +192,23 @@ void usbh_device_plugged_isr(uint8_t hostid, tusb_speed_t speed)
|
||||
|
||||
void usbh_device_unplugged_isr(uint8_t hostid)
|
||||
{
|
||||
uint8_t dev_addr=1;
|
||||
while ( dev_addr <= TUSB_CFG_HOST_DEVICE_MAX && ! (usbh_device_info_pool[dev_addr].core_id == hostid &&
|
||||
usbh_device_info_pool[dev_addr].hub_addr == 0 &&
|
||||
usbh_device_info_pool[dev_addr].hub_port ==0))
|
||||
{
|
||||
dev_addr++;
|
||||
}
|
||||
|
||||
ASSERT(dev_addr <= TUSB_CFG_HOST_DEVICE_MAX, (void) 0 );
|
||||
|
||||
for (uint8_t class_code = 1; class_code < TUSB_CLASS_MAX_CONSEC_NUMBER; class_code++)
|
||||
{
|
||||
if (usbh_class_drivers[class_code].close)
|
||||
usbh_class_drivers[class_code].close(dev_addr);
|
||||
}
|
||||
|
||||
usbh_device_info_pool[dev_addr].status = TUSB_DEVICE_STATUS_REMOVING;
|
||||
}
|
||||
|
||||
|
||||
@ -260,6 +278,8 @@ OSAL_TASK_DECLARE(usbh_enumeration_task)
|
||||
usbh_device_info_pool[new_addr].status = TUSB_DEVICE_STATUS_ADDRESSED;
|
||||
hcd_pipe_control_close(0);
|
||||
|
||||
// hcd_port_reset( usbh_device_info_pool[new_addr].core_id ); TODO verified
|
||||
|
||||
// open control pipe for new address
|
||||
TASK_ASSERT_STATUS ( usbh_pipe_control_open(new_addr, ((tusb_descriptor_device_t*) enum_data_buffer)->bMaxPacketSize0 ) );
|
||||
|
||||
@ -335,11 +355,11 @@ OSAL_TASK_DECLARE(usbh_enumeration_task)
|
||||
TASK_ASSERT( false ); // corrupted data, abort enumeration
|
||||
} else if ( class_code < TUSB_CLASS_MAX_CONSEC_NUMBER)
|
||||
{
|
||||
if ( usbh_class_drivers[class_code].install_subtask )
|
||||
if ( usbh_class_drivers[class_code].open_subtask )
|
||||
{
|
||||
uint16_t length;
|
||||
OSAL_SUBTASK_INVOKED_AND_WAIT ( // parameters in task/sub_task must be static storage (static or global)
|
||||
usbh_class_drivers[ ((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass ].install_subtask(new_addr, p_desc, &length) );
|
||||
usbh_class_drivers[ ((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass ].open_subtask(new_addr, p_desc, &length) );
|
||||
p_desc += length;
|
||||
}
|
||||
} else // unsupported class (not enable or yet implemented)
|
||||
@ -366,6 +386,7 @@ OSAL_TASK_DECLARE(usbh_enumeration_task)
|
||||
)
|
||||
);
|
||||
|
||||
usbh_device_info_pool[new_addr].status = TUSB_DEVICE_STATUS_READY;
|
||||
tusbh_device_mount_succeed_cb(new_addr);
|
||||
|
||||
// TODO invoke mounted callback
|
||||
|
@ -151,8 +151,9 @@ typedef uint8_t tusbh_device_status_t;
|
||||
|
||||
typedef struct {
|
||||
void (* const init) (void);
|
||||
tusb_error_t (* const install_subtask)(uint8_t, uint8_t const *, uint16_t*);
|
||||
tusb_error_t (* const open_subtask)(uint8_t, uint8_t const *, uint16_t*);
|
||||
void (* const isr) (pipe_handle_t);
|
||||
void (* const close) (uint8_t)
|
||||
} class_driver_t;
|
||||
//--------------------------------------------------------------------+
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
|
Loading…
x
Reference in New Issue
Block a user