mirror of
https://github.com/hathach/tinyusb.git
synced 2025-04-17 17:42:43 +00:00
Merge pull request #1094 from kasjer/kasjer/da146xx-vbus-handling
dcd_da146xx: Add VBUS handling
This commit is contained in:
commit
3e569f8e79
@ -53,6 +53,9 @@ void UnhandledIRQ(void)
|
||||
while(1);
|
||||
}
|
||||
|
||||
// DA146xx driver function that must be called whenever VBUS changes.
|
||||
extern void tusb_vbus_changed(bool present);
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
// LED
|
||||
@ -70,7 +73,10 @@ void board_init(void)
|
||||
// 1ms tick timer
|
||||
SysTick_Config(SystemCoreClock / 1000);
|
||||
|
||||
NVIC_SetPriority(USB_IRQn, 2);
|
||||
#if TUSB_OPT_DEVICE_ENABLED
|
||||
// This board is USB powered there is no need to monitor
|
||||
// VBUS line. Notify driver that VBUS is present.
|
||||
tusb_vbus_changed(true);
|
||||
|
||||
/* Setup USB IRQ */
|
||||
NVIC_SetPriority(USB_IRQn, 2);
|
||||
@ -81,6 +87,7 @@ void board_init(void)
|
||||
|
||||
mcu_gpio_set_pin_function(14, MCU_GPIO_MODE_INPUT, MCU_GPIO_FUNC_USB);
|
||||
mcu_gpio_set_pin_function(15, MCU_GPIO_MODE_INPUT, MCU_GPIO_FUNC_USB);
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
|
@ -36,6 +36,21 @@ void USB_IRQHandler(void)
|
||||
tud_int_handler(0);
|
||||
}
|
||||
|
||||
#if TUSB_OPT_DEVICE_ENABLED
|
||||
// DA146xx driver function that must be called whenever VBUS changes
|
||||
extern void tusb_vbus_changed(bool present);
|
||||
|
||||
// VBUS change interrupt handler
|
||||
void VBUS_IRQHandler(void)
|
||||
{
|
||||
bool present = (CRG_TOP->ANA_STATUS_REG & CRG_TOP_ANA_STATUS_REG_VBUS_AVAILABLE_Msk) != 0;
|
||||
// Clear VBUS interrupt
|
||||
CRG_TOP->VBUS_IRQ_CLEAR_REG = 1;
|
||||
|
||||
tusb_vbus_changed(present);
|
||||
}
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO TYPEDEF CONSTANT ENUM
|
||||
//--------------------------------------------------------------------+
|
||||
@ -70,7 +85,15 @@ void board_init(void)
|
||||
// 1ms tick timer
|
||||
SysTick_Config(SystemCoreClock / 1000);
|
||||
|
||||
NVIC_SetPriority(USB_IRQn, 2);
|
||||
#if TUSB_OPT_DEVICE_ENABLED
|
||||
// Setup interrupt for both connect and disconnect
|
||||
CRG_TOP->VBUS_IRQ_MASK_REG = CRG_TOP_VBUS_IRQ_MASK_REG_VBUS_IRQ_EN_FALL_Msk |
|
||||
CRG_TOP_VBUS_IRQ_MASK_REG_VBUS_IRQ_EN_RISE_Msk;
|
||||
NVIC_SetPriority(VBUS_IRQn, 2);
|
||||
// Trigger interrupt at the start to inform driver about VBUS state at start
|
||||
// otherwise it could go unnoticed.
|
||||
NVIC_SetPendingIRQ(VBUS_IRQn);
|
||||
NVIC_EnableIRQ(VBUS_IRQn);
|
||||
|
||||
/* Setup USB IRQ */
|
||||
NVIC_SetPriority(USB_IRQn, 2);
|
||||
@ -81,6 +104,7 @@ void board_init(void)
|
||||
|
||||
mcu_gpio_set_pin_function(14, MCU_GPIO_MODE_INPUT, MCU_GPIO_FUNC_USB);
|
||||
mcu_gpio_set_pin_function(15, MCU_GPIO_MODE_INPUT, MCU_GPIO_FUNC_USB);
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
|
@ -217,6 +217,7 @@ typedef struct {
|
||||
static struct
|
||||
{
|
||||
bool vbus_present;
|
||||
bool init_called;
|
||||
bool in_reset;
|
||||
xfer_ctl_t xfer_status[EP_MAX][2];
|
||||
// Endpoints that use DMA, one for each direction
|
||||
@ -224,6 +225,7 @@ static struct
|
||||
} _dcd =
|
||||
{
|
||||
.vbus_present = false,
|
||||
.init_called = false,
|
||||
.xfer_status =
|
||||
{
|
||||
{ { .regs = EP_REGS(USB_EPC0_REG) }, { .regs = EP_REGS(USB_EPC0_REG) } },
|
||||
@ -735,19 +737,13 @@ static void handle_ep0_nak(void)
|
||||
*------------------------------------------------------------------*/
|
||||
void dcd_init(uint8_t rhport)
|
||||
{
|
||||
USB->USB_MCTRL_REG = USB_USB_MCTRL_REG_USBEN_Msk;
|
||||
USB->USB_NFSR_REG = 0;
|
||||
USB->USB_FAR_REG = 0x80;
|
||||
USB->USB_NFSR_REG = NFSR_NODE_RESET;
|
||||
USB->USB_TXMSK_REG = 0;
|
||||
USB->USB_RXMSK_REG = 0;
|
||||
(void) rhport;
|
||||
|
||||
USB->USB_MAMSK_REG = USB_USB_MAMSK_REG_USB_M_INTR_Msk |
|
||||
USB_USB_MAMSK_REG_USB_M_ALT_Msk |
|
||||
USB_USB_MAMSK_REG_USB_M_WARN_Msk;
|
||||
USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESET_Msk;
|
||||
|
||||
dcd_connect(rhport);
|
||||
_dcd.init_called = true;
|
||||
if (_dcd.vbus_present)
|
||||
{
|
||||
dcd_connect(rhport);
|
||||
}
|
||||
}
|
||||
|
||||
void dcd_int_enable(uint8_t rhport)
|
||||
@ -783,10 +779,25 @@ void dcd_connect(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
|
||||
REG_SET_BIT(USB_MCTRL_REG, USB_NAT);
|
||||
if (GET_BIT(USB->USB_MCTRL_REG, USB_USB_MCTRL_REG_USB_NAT) == 0)
|
||||
{
|
||||
USB->USB_MCTRL_REG = USB_USB_MCTRL_REG_USBEN_Msk;
|
||||
USB->USB_NFSR_REG = 0;
|
||||
USB->USB_FAR_REG = 0x80;
|
||||
USB->USB_NFSR_REG = NFSR_NODE_RESET;
|
||||
USB->USB_TXMSK_REG = 0;
|
||||
USB->USB_RXMSK_REG = 0;
|
||||
|
||||
// Select chosen DMA to be triggered by USB.
|
||||
DMA->DMA_REQ_MUX_REG = (DMA->DMA_REQ_MUX_REG & ~DA146XX_DMA_USB_MUX_MASK) | DA146XX_DMA_USB_MUX;
|
||||
USB->USB_MAMSK_REG = USB_USB_MAMSK_REG_USB_M_INTR_Msk |
|
||||
USB_USB_MAMSK_REG_USB_M_ALT_Msk |
|
||||
USB_USB_MAMSK_REG_USB_M_WARN_Msk;
|
||||
USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESET_Msk;
|
||||
|
||||
REG_SET_BIT(USB_MCTRL_REG, USB_NAT);
|
||||
|
||||
// Select chosen DMA to be triggered by USB.
|
||||
DMA->DMA_REQ_MUX_REG = (DMA->DMA_REQ_MUX_REG & ~DA146XX_DMA_USB_MUX_MASK) | DA146XX_DMA_USB_MUX;
|
||||
}
|
||||
}
|
||||
|
||||
void dcd_disconnect(uint8_t rhport)
|
||||
@ -796,6 +807,30 @@ void dcd_disconnect(uint8_t rhport)
|
||||
REG_CLR_BIT(USB_MCTRL_REG, USB_NAT);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void)
|
||||
{
|
||||
return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0;
|
||||
}
|
||||
|
||||
void tusb_vbus_changed(bool present)
|
||||
{
|
||||
if (present && !_dcd.vbus_present)
|
||||
{
|
||||
_dcd.vbus_present = true;
|
||||
// If power event happened before USB started, delay dcd_connect
|
||||
// until dcd_init is called.
|
||||
if (_dcd.init_called)
|
||||
{
|
||||
dcd_connect(0);
|
||||
}
|
||||
}
|
||||
else if (!present && _dcd.vbus_present)
|
||||
{
|
||||
_dcd.vbus_present = false;
|
||||
USB->USB_MCTRL_REG = 0;
|
||||
dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, is_in_isr());
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* DCD Endpoint port
|
||||
|
Loading…
x
Reference in New Issue
Block a user