more refactor to simplify musb driver
This commit is contained in:
@@ -309,6 +309,7 @@
|
|||||||
|
|
||||||
#elif TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129)
|
#elif TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129)
|
||||||
#define TUP_USBIP_MUSB
|
#define TUP_USBIP_MUSB
|
||||||
|
#define TUP_USBIP_MUSB_TI
|
||||||
#define TUP_DCD_ENDPOINT_MAX 8
|
#define TUP_DCD_ENDPOINT_MAX 8
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
@@ -474,6 +475,7 @@
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
#elif TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
|
#elif TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
|
||||||
#define TUP_USBIP_MUSB
|
#define TUP_USBIP_MUSB
|
||||||
|
#define TUP_USBIP_MUSB_ADI
|
||||||
#define TUP_DCD_ENDPOINT_MAX 12
|
#define TUP_DCD_ENDPOINT_MAX 12
|
||||||
#define TUP_RHPORT_HIGHSPEED 1
|
#define TUP_RHPORT_HIGHSPEED 1
|
||||||
|
|
||||||
|
@@ -41,10 +41,10 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\"");
|
|||||||
// Following symbols must be defined by port header
|
// Following symbols must be defined by port header
|
||||||
// - musb_dcd_int_enable/disable/clear/get_enable
|
// - musb_dcd_int_enable/disable/clear/get_enable
|
||||||
// - musb_dcd_int_handler_enter/exit
|
// - musb_dcd_int_handler_enter/exit
|
||||||
// - musb_dcd_setup_fifo/reset_fifo: Configuration of the EP's FIFO
|
// - musb_dcd_setup_fifo: Configuration of the EP's FIFO
|
||||||
#if TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129)
|
#if defined(TUP_USBIP_MUSB_TI)
|
||||||
#include "musb_ti.h"
|
#include "musb_ti.h"
|
||||||
#elif TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX78002)
|
#elif defined(TUP_USBIP_MUSB_ADI)
|
||||||
#include "musb_max32.h"
|
#include "musb_max32.h"
|
||||||
#else
|
#else
|
||||||
#error "Unsupported MCU"
|
#error "Unsupported MCU"
|
||||||
@@ -52,6 +52,8 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\"");
|
|||||||
|
|
||||||
#define MUSB_REGS(rhport) ((musb_regs_t*) MUSB_BASES[rhport])
|
#define MUSB_REGS(rhport) ((musb_regs_t*) MUSB_BASES[rhport])
|
||||||
|
|
||||||
|
#define MUSB_DEBUG 2
|
||||||
|
|
||||||
/*------------------------------------------------------------------
|
/*------------------------------------------------------------------
|
||||||
* MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
* MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
||||||
*------------------------------------------------------------------*/
|
*------------------------------------------------------------------*/
|
||||||
@@ -86,6 +88,18 @@ typedef struct
|
|||||||
*------------------------------------------------------------------*/
|
*------------------------------------------------------------------*/
|
||||||
static dcd_data_t _dcd;
|
static dcd_data_t _dcd;
|
||||||
|
|
||||||
|
TU_ATTR_ALWAYS_INLINE static inline void fifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) {
|
||||||
|
musb->index = epnum;
|
||||||
|
const uint8_t is_rx = 1 - dir_in;
|
||||||
|
|
||||||
|
#if MUSB_CFG_DYNAMIC_FIFO
|
||||||
|
musb->fifo_size[is_rx] = 0;
|
||||||
|
musb->fifo_addr[is_rx] = 0;
|
||||||
|
#elif defined(TUP_USBIP_MUSB_ADI)
|
||||||
|
// Analog have custom double buffered in csrh register, disable it
|
||||||
|
musb->indexed_csr.maxp_csr[is_rx].csrh |= MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len)
|
static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len)
|
||||||
{
|
{
|
||||||
@@ -363,13 +377,13 @@ static void process_ep0(uint8_t rhport)
|
|||||||
/* Received SETUP or DATA OUT packet */
|
/* Received SETUP or DATA OUT packet */
|
||||||
if (req == REQUEST_TYPE_INVALID) {
|
if (req == REQUEST_TYPE_INVALID) {
|
||||||
/* SETUP */
|
/* SETUP */
|
||||||
TU_ASSERT(sizeof(tusb_control_request_t) == ep_csr->rx_count,);
|
TU_ASSERT(sizeof(tusb_control_request_t) == ep_csr->count0,);
|
||||||
process_setup_packet(rhport);
|
process_setup_packet(rhport);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_dcd.pipe0.buf) {
|
if (_dcd.pipe0.buf) {
|
||||||
/* DATA OUT */
|
/* DATA OUT */
|
||||||
const unsigned vld = ep_csr->rx_count;
|
const unsigned vld = ep_csr->count0;
|
||||||
const unsigned rem = _dcd.pipe0.remaining;
|
const unsigned rem = _dcd.pipe0.remaining;
|
||||||
const unsigned len = TU_MIN(TU_MIN(rem, 64), vld);
|
const unsigned len = TU_MIN(TU_MIN(rem, 64), vld);
|
||||||
volatile void *fifo_ptr = &musb_regs->fifo[0];
|
volatile void *fifo_ptr = &musb_regs->fifo[0];
|
||||||
@@ -445,47 +459,70 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_bus_reset(uint8_t rhport)
|
// Upon BUS RESET is detected, hardware havs already done:
|
||||||
{
|
// faddr = 0, index = 0, flushes all ep fifos, clears all ep csr, enabled all ep interrupts
|
||||||
musb_regs_t* musb_regs = MUSB_REGS(rhport);
|
static void process_bus_reset(uint8_t rhport) {
|
||||||
/* When bmRequestType is REQUEST_TYPE_INVALID(0xFF),
|
musb_regs_t* musb = MUSB_REGS(rhport);
|
||||||
* a control transfer state is SETUP or STATUS stage. */
|
/* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), a control transfer state is SETUP or STATUS stage. */
|
||||||
_dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID;
|
_dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID;
|
||||||
_dcd.status_out = 0;
|
_dcd.status_out = 0;
|
||||||
/* When pipe0.buf has not NULL, DATA stage works in progress. */
|
/* When pipe0.buf has not NULL, DATA stage works in progress. */
|
||||||
_dcd.pipe0.buf = NULL;
|
_dcd.pipe0.buf = NULL;
|
||||||
|
|
||||||
musb_regs->intr_txen = 1; /* Enable only EP0 */
|
musb->intr_txen = 1; /* Enable only EP0 */
|
||||||
musb_regs->intr_rxen = 0;
|
musb->intr_rxen = 0;
|
||||||
|
|
||||||
/* Clear FIFO settings */
|
/* Clear FIFO settings */
|
||||||
for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) {
|
for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) {
|
||||||
musb_dcd_reset_fifo(rhport, i, 0);
|
fifo_reset(musb, i, 0);
|
||||||
musb_dcd_reset_fifo(rhport, i, 1);
|
fifo_reset(musb, i, 1);
|
||||||
}
|
}
|
||||||
dcd_event_bus_reset(rhport, (musb_regs->power & USB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true);
|
dcd_event_bus_reset(rhport, (musb->power & USB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------
|
/*------------------------------------------------------------------
|
||||||
* Device API
|
* Device API
|
||||||
*------------------------------------------------------------------*/
|
*------------------------------------------------------------------*/
|
||||||
|
|
||||||
void dcd_init(uint8_t rhport)
|
#if CFG_TUSB_DEBUG >= MUSB_DEBUG
|
||||||
{
|
void print_musb_info(musb_regs_t* musb_regs) {
|
||||||
|
// print version, epinfo, raminfo, config_data0, fifo_size
|
||||||
|
TU_LOG1("musb version = %u.%u\r\n", musb_regs->hwvers_bit.major, musb_regs->hwvers_bit.minor);
|
||||||
|
TU_LOG1("Number of endpoints: %u TX, %u RX\r\n", musb_regs->epinfo_bit.tx_ep_num, musb_regs->epinfo_bit.rx_ep_num);
|
||||||
|
TU_LOG1("RAM Info: %u DMA Channel, %u RAM address width\r\n", musb_regs->raminfo_bit.dma_channel, musb_regs->raminfo_bit.ram_bits);
|
||||||
|
|
||||||
|
musb_regs->index = 0;
|
||||||
|
TU_LOG1("config_data0 = 0x%x\r\n", musb_regs->indexed_csr.config_data0);
|
||||||
|
|
||||||
|
#if MUSB_CFG_DYNAMIC_FIFO
|
||||||
|
TU_LOG1("Dynamic FIFO configuration\r\n");
|
||||||
|
#else
|
||||||
|
for (uint8_t i=1; i <= musb_regs->epinfo_bit.tx_ep_num; i++) {
|
||||||
|
musb_regs->index = i;
|
||||||
|
TU_LOG1("FIFO %u Size: TX %u RX %u\r\n", i, musb_regs->indexed_csr.fifo_size_bit.tx, musb_regs->indexed_csr.fifo_size_bit.rx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void dcd_init(uint8_t rhport) {
|
||||||
musb_regs_t* musb_regs = MUSB_REGS(rhport);
|
musb_regs_t* musb_regs = MUSB_REGS(rhport);
|
||||||
musb_regs->intrusben |= USB_IE_SUSPND;
|
|
||||||
|
#if CFG_TUSB_DEBUG >= MUSB_DEBUG
|
||||||
|
print_musb_info(musb_regs);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
musb_regs->intr_usben |= USB_IE_SUSPND;
|
||||||
musb_dcd_int_clear(rhport);
|
musb_dcd_int_clear(rhport);
|
||||||
musb_dcd_phy_init(rhport);
|
musb_dcd_phy_init(rhport);
|
||||||
dcd_connect(rhport);
|
dcd_connect(rhport);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dcd_int_enable(uint8_t rhport)
|
void dcd_int_enable(uint8_t rhport) {
|
||||||
{
|
|
||||||
musb_dcd_int_enable(rhport);
|
musb_dcd_int_enable(rhport);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dcd_int_disable(uint8_t rhport)
|
void dcd_int_disable(uint8_t rhport) {
|
||||||
{
|
|
||||||
musb_dcd_int_disable(rhport);
|
musb_dcd_int_disable(rhport);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,25 +596,17 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
|
|||||||
|
|
||||||
musb_regs_t* musb_regs = MUSB_REGS(rhport);
|
musb_regs_t* musb_regs = MUSB_REGS(rhport);
|
||||||
musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn);
|
musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn);
|
||||||
if (dir_in) {
|
|
||||||
ep_csr->tx_maxp = mps;
|
const uint8_t is_rx = 1 - dir_in;
|
||||||
ep_csr->tx_csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_TXCSRH1_ISO : 0;
|
ep_csr->maxp_csr[is_rx].maxp = mps;
|
||||||
if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) {
|
ep_csr->maxp_csr[is_rx].csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0;
|
||||||
ep_csr->tx_csrl = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH;
|
|
||||||
} else {
|
uint8_t csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx);
|
||||||
ep_csr->tx_csrl = USB_TXCSRL1_CLRDT;
|
if (ep_csr->maxp_csr[is_rx].csrl & MUSB_CSRL_PACKET_READY(is_rx)) {
|
||||||
}
|
csrl |= MUSB_CSRL_FLUSH_FIFO(is_rx);
|
||||||
musb_regs->intr_txen |= TU_BIT(epn);
|
|
||||||
} else {
|
|
||||||
ep_csr->rx_maxp = mps;
|
|
||||||
ep_csr->rx_csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0;
|
|
||||||
if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) {
|
|
||||||
ep_csr->rx_csrl = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH;
|
|
||||||
} else {
|
|
||||||
ep_csr->rx_csrl = USB_RXCSRL1_CLRDT;
|
|
||||||
}
|
|
||||||
musb_regs->intr_rxen |= TU_BIT(epn);
|
|
||||||
}
|
}
|
||||||
|
ep_csr->maxp_csr[is_rx].csrl = csrl;
|
||||||
|
musb_regs->intren_ep[is_rx] |= TU_BIT(epn);
|
||||||
|
|
||||||
/* Setup FIFO */
|
/* Setup FIFO */
|
||||||
musb_dcd_setup_fifo(rhport, epn, dir_in, mps);
|
musb_dcd_setup_fifo(rhport, epn, dir_in, mps);
|
||||||
@@ -587,13 +616,13 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
|
|||||||
|
|
||||||
void dcd_edpt_close_all(uint8_t rhport)
|
void dcd_edpt_close_all(uint8_t rhport)
|
||||||
{
|
{
|
||||||
musb_regs_t* musb_regs = MUSB_REGS(rhport);
|
musb_regs_t* musb = MUSB_REGS(rhport);
|
||||||
unsigned const ie = musb_dcd_get_int_enable(rhport);
|
unsigned const ie = musb_dcd_get_int_enable(rhport);
|
||||||
musb_dcd_int_disable(rhport);
|
musb_dcd_int_disable(rhport);
|
||||||
musb_regs->intr_txen = 1; /* Enable only EP0 */
|
musb->intr_txen = 1; /* Enable only EP0 */
|
||||||
musb_regs->intr_rxen = 0;
|
musb->intr_rxen = 0;
|
||||||
for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) {
|
for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) {
|
||||||
musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, i);
|
musb_ep_csr_t* ep_csr = get_ep_csr(musb, i);
|
||||||
ep_csr->tx_maxp = 0;
|
ep_csr->tx_maxp = 0;
|
||||||
ep_csr->tx_csrh = 0;
|
ep_csr->tx_csrh = 0;
|
||||||
if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY)
|
if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY)
|
||||||
@@ -609,8 +638,8 @@ void dcd_edpt_close_all(uint8_t rhport)
|
|||||||
ep_csr->rx_csrl = USB_RXCSRL1_CLRDT;
|
ep_csr->rx_csrl = USB_RXCSRL1_CLRDT;
|
||||||
}
|
}
|
||||||
|
|
||||||
musb_dcd_reset_fifo(rhport, i, 0);
|
fifo_reset(musb, i, 0);
|
||||||
musb_dcd_reset_fifo(rhport, i, 1);
|
fifo_reset(musb, i, 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (ie) musb_dcd_int_enable(rhport);
|
if (ie) musb_dcd_int_enable(rhport);
|
||||||
@@ -620,12 +649,12 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
|
|||||||
{
|
{
|
||||||
unsigned const epn = tu_edpt_number(ep_addr);
|
unsigned const epn = tu_edpt_number(ep_addr);
|
||||||
unsigned const dir_in = tu_edpt_dir(ep_addr);
|
unsigned const dir_in = tu_edpt_dir(ep_addr);
|
||||||
musb_regs_t* musb_regs = MUSB_REGS(rhport);
|
musb_regs_t* musb = MUSB_REGS(rhport);
|
||||||
musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn);
|
musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn);
|
||||||
unsigned const ie = musb_dcd_get_int_enable(rhport);
|
unsigned const ie = musb_dcd_get_int_enable(rhport);
|
||||||
musb_dcd_int_disable(rhport);
|
musb_dcd_int_disable(rhport);
|
||||||
if (dir_in) {
|
if (dir_in) {
|
||||||
musb_regs->intr_txen &= ~TU_BIT(epn);
|
musb->intr_txen &= ~TU_BIT(epn);
|
||||||
ep_csr->tx_maxp = 0;
|
ep_csr->tx_maxp = 0;
|
||||||
ep_csr->tx_csrh = 0;
|
ep_csr->tx_csrh = 0;
|
||||||
if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) {
|
if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) {
|
||||||
@@ -634,7 +663,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
|
|||||||
ep_csr->tx_csrl = USB_TXCSRL1_CLRDT;
|
ep_csr->tx_csrl = USB_TXCSRL1_CLRDT;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
musb_regs->intr_rxen &= ~TU_BIT(epn);
|
musb->intr_rxen &= ~TU_BIT(epn);
|
||||||
ep_csr->rx_maxp = 0;
|
ep_csr->rx_maxp = 0;
|
||||||
ep_csr->rx_csrh = 0;
|
ep_csr->rx_csrh = 0;
|
||||||
if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) {
|
if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) {
|
||||||
@@ -643,7 +672,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
|
|||||||
ep_csr->rx_csrl = USB_RXCSRL1_CLRDT;
|
ep_csr->rx_csrl = USB_RXCSRL1_CLRDT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
musb_dcd_reset_fifo(rhport, epn, dir_in);
|
fifo_reset(musb, epn, dir_in);
|
||||||
if (ie) musb_dcd_int_enable(rhport);
|
if (ie) musb_dcd_int_enable(rhport);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -726,51 +755,48 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
|
|||||||
/*-------------------------------------------------------------------
|
/*-------------------------------------------------------------------
|
||||||
* ISR
|
* ISR
|
||||||
*-------------------------------------------------------------------*/
|
*-------------------------------------------------------------------*/
|
||||||
void dcd_int_handler(uint8_t rhport)
|
void dcd_int_handler(uint8_t rhport) {
|
||||||
{
|
|
||||||
uint_fast8_t is, txis, rxis;
|
|
||||||
|
|
||||||
//Part specific ISR setup/entry
|
//Part specific ISR setup/entry
|
||||||
musb_dcd_int_handler_enter(rhport);
|
musb_dcd_int_handler_enter(rhport);
|
||||||
|
|
||||||
musb_regs_t* musb_regs = MUSB_REGS(rhport);
|
musb_regs_t* musb_regs = MUSB_REGS(rhport);
|
||||||
|
uint_fast8_t intr_usb = musb_regs->intr_usb; // a read will clear this interrupt status
|
||||||
is = musb_regs->intrusb; /* read and clear interrupt status */
|
uint_fast8_t intr_tx = musb_regs->intr_tx; // a read will clear this interrupt status
|
||||||
txis = musb_regs->intr_tx; /* read and clear interrupt status */
|
uint_fast8_t intr_rx = musb_regs->intr_rx; // a read will clear this interrupt status
|
||||||
rxis = musb_regs->intr_rx; /* read and clear interrupt status */
|
|
||||||
// TU_LOG1("D%2x T%2x R%2x\r\n", is, txis, rxis);
|
// TU_LOG1("D%2x T%2x R%2x\r\n", is, txis, rxis);
|
||||||
|
|
||||||
is &= musb_regs->intrusben; /* Clear disabled interrupts */
|
intr_usb &= musb_regs->intr_usben; /* Clear disabled interrupts */
|
||||||
if (is & USB_IS_DISCON) {
|
if (intr_usb & USB_IS_DISCON) {
|
||||||
}
|
}
|
||||||
if (is & USB_IS_SOF) {
|
if (intr_usb & USB_IS_SOF) {
|
||||||
dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true);
|
dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true);
|
||||||
}
|
}
|
||||||
if (is & USB_IS_RESET) {
|
if (intr_usb & USB_IS_RESET) {
|
||||||
process_bus_reset(rhport);
|
process_bus_reset(rhport);
|
||||||
}
|
}
|
||||||
if (is & USB_IS_RESUME) {
|
if (intr_usb & USB_IS_RESUME) {
|
||||||
dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true);
|
dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true);
|
||||||
}
|
}
|
||||||
if (is & USB_IS_SUSPEND) {
|
if (intr_usb & USB_IS_SUSPEND) {
|
||||||
dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true);
|
dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
txis &= musb_regs->intr_txen; /* Clear disabled interrupts */
|
intr_tx &= musb_regs->intr_txen; /* Clear disabled interrupts */
|
||||||
if (txis & USB_TXIE_EP0) {
|
if (intr_tx & TU_BIT(0)) {
|
||||||
process_ep0(rhport);
|
process_ep0(rhport);
|
||||||
txis &= ~TU_BIT(0);
|
intr_tx &= ~TU_BIT(0);
|
||||||
}
|
}
|
||||||
while (txis) {
|
while (intr_tx) {
|
||||||
unsigned const num = __builtin_ctz(txis);
|
unsigned const num = __builtin_ctz(intr_tx);
|
||||||
process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_IN));
|
process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_IN));
|
||||||
txis &= ~TU_BIT(num);
|
intr_tx &= ~TU_BIT(num);
|
||||||
}
|
}
|
||||||
rxis &= musb_regs->intr_rxen; /* Clear disabled interrupts */
|
|
||||||
while (rxis) {
|
intr_rx &= musb_regs->intr_rxen; /* Clear disabled interrupts */
|
||||||
unsigned const num = __builtin_ctz(rxis);
|
while (intr_rx) {
|
||||||
|
unsigned const num = __builtin_ctz(intr_rx);
|
||||||
process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_OUT));
|
process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_OUT));
|
||||||
rxis &= ~TU_BIT(num);
|
intr_rx &= ~TU_BIT(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Part specific ISR exit
|
//Part specific ISR exit
|
||||||
|
@@ -34,6 +34,8 @@ extern "C" {
|
|||||||
#include "mxc_device.h"
|
#include "mxc_device.h"
|
||||||
#include "usbhs_regs.h"
|
#include "usbhs_regs.h"
|
||||||
|
|
||||||
|
#define MUSB_CFG_DYNAMIC_FIFO 0
|
||||||
|
|
||||||
const uintptr_t MUSB_BASES[] = { MXC_BASE_USBHS };
|
const uintptr_t MUSB_BASES[] = { MXC_BASE_USBHS };
|
||||||
|
|
||||||
#if CFG_TUD_ENABLED
|
#if CFG_TUD_ENABLED
|
||||||
@@ -100,40 +102,43 @@ static inline void musb_dcd_int_handler_exit(uint8_t rhport) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void musb_dcd_phy_init(uint8_t rhport) {
|
static inline void musb_dcd_phy_init(uint8_t rhport) {
|
||||||
//Interrupt for VBUS disconnect
|
(void) rhport;
|
||||||
musb_periph_inst[rhport]->mxm_int_en |= MXC_F_USBHS_MXM_INT_EN_NOVBUS;
|
mxc_usbhs_regs_t* hs_phy = MXC_USBHS;
|
||||||
|
|
||||||
|
// Interrupt for VBUS disconnect
|
||||||
|
hs_phy->mxm_int_en |= MXC_F_USBHS_MXM_INT_EN_NOVBUS;
|
||||||
|
|
||||||
musb_dcd_int_clear(rhport);
|
musb_dcd_int_clear(rhport);
|
||||||
|
|
||||||
//Unsuspend the MAC
|
// Unsuspend the MAC
|
||||||
musb_periph_inst[rhport]->mxm_suspend = 0;
|
hs_phy->mxm_suspend = 0;
|
||||||
|
|
||||||
// Configure PHY
|
// Configure PHY
|
||||||
musb_periph_inst[rhport]->m31_phy_xcfgi_31_0 = (0x1 << 3) | (0x1 << 11);
|
hs_phy->m31_phy_xcfgi_31_0 = (0x1 << 3) | (0x1 << 11);
|
||||||
musb_periph_inst[rhport]->m31_phy_xcfgi_63_32 = 0;
|
hs_phy->m31_phy_xcfgi_63_32 = 0;
|
||||||
musb_periph_inst[rhport]->m31_phy_xcfgi_95_64 = 0x1 << (72 - 64);
|
hs_phy->m31_phy_xcfgi_95_64 = 0x1 << (72 - 64);
|
||||||
musb_periph_inst[rhport]->m31_phy_xcfgi_127_96 = 0;
|
hs_phy->m31_phy_xcfgi_127_96 = 0;
|
||||||
|
|
||||||
|
|
||||||
#ifdef USBHS_M31_CLOCK_RECOVERY
|
#ifdef USBHS_M31_CLOCK_RECOVERY
|
||||||
musb_periph_inst[rhport]->m31_phy_noncry_rstb = 1;
|
hs_phy->m31_phy_noncry_rstb = 1;
|
||||||
musb_periph_inst[rhport]->m31_phy_noncry_en = 1;
|
hs_phy->m31_phy_noncry_en = 1;
|
||||||
musb_periph_inst[rhport]->m31_phy_outclksel = 0;
|
hs_phy->m31_phy_outclksel = 0;
|
||||||
musb_periph_inst[rhport]->m31_phy_coreclkin = 0;
|
hs_phy->m31_phy_coreclkin = 0;
|
||||||
musb_periph_inst[rhport]->m31_phy_xtlsel = 2; /* Select 25 MHz clock */
|
hs_phy->m31_phy_xtlsel = 2; /* Select 25 MHz clock */
|
||||||
#else
|
#else
|
||||||
musb_periph_inst[rhport]->m31_phy_noncry_rstb = 0;
|
hs_phy->m31_phy_noncry_rstb = 0;
|
||||||
musb_periph_inst[rhport]->m31_phy_noncry_en = 0;
|
hs_phy->m31_phy_noncry_en = 0;
|
||||||
musb_periph_inst[rhport]->m31_phy_outclksel = 1;
|
hs_phy->m31_phy_outclksel = 1;
|
||||||
musb_periph_inst[rhport]->m31_phy_coreclkin = 1;
|
hs_phy->m31_phy_coreclkin = 1;
|
||||||
musb_periph_inst[rhport]->m31_phy_xtlsel = 3; /* Select 30 MHz clock */
|
hs_phy->m31_phy_xtlsel = 3; /* Select 30 MHz clock */
|
||||||
#endif
|
#endif
|
||||||
musb_periph_inst[rhport]->m31_phy_pll_en = 1;
|
hs_phy->m31_phy_pll_en = 1;
|
||||||
musb_periph_inst[rhport]->m31_phy_oscouten = 1;
|
hs_phy->m31_phy_oscouten = 1;
|
||||||
|
|
||||||
/* Reset PHY */
|
/* Reset PHY */
|
||||||
musb_periph_inst[rhport]->m31_phy_ponrst = 0;
|
hs_phy->m31_phy_ponrst = 0;
|
||||||
musb_periph_inst[rhport]->m31_phy_ponrst = 1;
|
hs_phy->m31_phy_ponrst = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) {
|
static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) {
|
||||||
@@ -155,23 +160,6 @@ static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned
|
|||||||
musb_periph_inst[rhport]->index = saved_index;
|
musb_periph_inst[rhport]->index = saved_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in) {
|
|
||||||
//Most likely the caller has already grabbed the right register block. But
|
|
||||||
//as a precaution save and restore the register bank anyways
|
|
||||||
unsigned saved_index = musb_periph_inst[rhport]->index;
|
|
||||||
|
|
||||||
musb_periph_inst[rhport]->index = epnum;
|
|
||||||
|
|
||||||
//Disable double buffering
|
|
||||||
if (dir_in) {
|
|
||||||
musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS);
|
|
||||||
} else {
|
|
||||||
musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS);
|
|
||||||
}
|
|
||||||
|
|
||||||
musb_periph_inst[rhport]->index = saved_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CFG_TUD_ENABLED
|
#endif // CFG_TUD_ENABLED
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@@ -42,8 +42,10 @@
|
|||||||
#error "Unsupported MCUs"
|
#error "Unsupported MCUs"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const uintptr_t MUSB_BASES[] = { USB0_BASE };
|
#define MUSB_CFG_DYNAMIC_FIFO 1
|
||||||
|
#define MUSB_CFG_DYNAMIC_FIFO_SIZE 4096
|
||||||
|
|
||||||
|
const uintptr_t MUSB_BASES[] = { USB0_BASE };
|
||||||
|
|
||||||
// Header supports both device and host modes. Only include what's necessary
|
// Header supports both device and host modes. Only include what's necessary
|
||||||
#if CFG_TUD_ENABLED
|
#if CFG_TUD_ENABLED
|
||||||
@@ -63,36 +65,28 @@ static inline void musb_dcd_phy_init(uint8_t rhport){
|
|||||||
//Nothing to do for this part
|
//Nothing to do for this part
|
||||||
}
|
}
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE
|
TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_enable(uint8_t rhport) {
|
||||||
static inline void musb_dcd_int_enable(uint8_t rhport)
|
|
||||||
{
|
|
||||||
NVIC_EnableIRQ(musb_irqs[rhport]);
|
NVIC_EnableIRQ(musb_irqs[rhport]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE
|
TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_disable(uint8_t rhport) {
|
||||||
static inline void musb_dcd_int_disable(uint8_t rhport)
|
|
||||||
{
|
|
||||||
NVIC_DisableIRQ(musb_irqs[rhport]);
|
NVIC_DisableIRQ(musb_irqs[rhport]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE
|
TU_ATTR_ALWAYS_INLINE static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) {
|
||||||
static inline unsigned musb_dcd_get_int_enable(uint8_t rhport)
|
|
||||||
{
|
|
||||||
return NVIC_GetEnableIRQ(musb_irqs[rhport]);
|
return NVIC_GetEnableIRQ(musb_irqs[rhport]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE
|
TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_clear(uint8_t rhport) {
|
||||||
static inline void musb_dcd_int_clear(uint8_t rhport)
|
NVIC_ClearPendingIRQ(musb_irqs[rhport]);
|
||||||
{
|
|
||||||
NVIC_ClearPendingIRQ(musb_irqs[rhport]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void musb_dcd_int_handler_enter(uint8_t rhport){
|
static inline void musb_dcd_int_handler_enter(uint8_t rhport) {
|
||||||
(void)rhport;
|
(void)rhport;
|
||||||
//Nothing to do for this part
|
//Nothing to do for this part
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void musb_dcd_int_handler_exit(uint8_t rhport){
|
static inline void musb_dcd_int_handler_exit(uint8_t rhport) {
|
||||||
(void)rhport;
|
(void)rhport;
|
||||||
//Nothing to do for this part
|
//Nothing to do for this part
|
||||||
}
|
}
|
||||||
@@ -102,15 +96,13 @@ typedef struct {
|
|||||||
uint_fast16_t end; /* offset of excluding the last element */
|
uint_fast16_t end; /* offset of excluding the last element */
|
||||||
} free_block_t;
|
} free_block_t;
|
||||||
|
|
||||||
static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr)
|
static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) {
|
||||||
{
|
|
||||||
free_block_t *cur = beg;
|
free_block_t *cur = beg;
|
||||||
for (; cur < end && ((addr < cur->beg) || (cur->end <= addr)); ++cur) ;
|
for (; cur < end && ((addr < cur->beg) || (cur->end <= addr)); ++cur) ;
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size)
|
static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) {
|
||||||
{
|
|
||||||
free_block_t *p = find_containing_block(blks, blks + num, addr);
|
free_block_t *p = find_containing_block(blks, blks + num, addr);
|
||||||
TU_ASSERT(p != blks + num, -2);
|
TU_ASSERT(p != blks + num, -2);
|
||||||
if (p->beg == addr) {
|
if (p->beg == addr) {
|
||||||
@@ -150,8 +142,7 @@ static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned free_block_size(free_block_t const *blk)
|
static inline unsigned free_block_size(free_block_t const *blk) {
|
||||||
{
|
|
||||||
return blk->end - blk->beg;
|
return blk->end - blk->beg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,18 +225,6 @@ static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in)
|
|
||||||
{
|
|
||||||
musb_periph_inst[rhport]->EPIDX = epnum;
|
|
||||||
if (dir_in) {
|
|
||||||
musb_periph_inst[rhport]->TXFIFOADD = 0;
|
|
||||||
musb_periph_inst[rhport]->TXFIFOSZ = 0;
|
|
||||||
} else {
|
|
||||||
musb_periph_inst[rhport]->RXFIFOADD = 0;
|
|
||||||
musb_periph_inst[rhport]->RXFIFOSZ = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CFG_TUD_ENABLED
|
#endif // CFG_TUD_ENABLED
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user