mirror of
https://github.com/hathach/tinyusb.git
synced 2025-02-07 05:54:11 +08:00
add tuh_max3421_reg_read(), tuh_max3421_reg_read() for application usage
added max3241 for feather m4 and tested
This commit is contained in:
parent
cbd3e0bc0b
commit
1f71625a32
@ -31,6 +31,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define _PINNUM(port, pin) ((port)*32 + (pin))
|
||||||
|
|
||||||
// LED
|
// LED
|
||||||
#define LED_PIN 23
|
#define LED_PIN 23
|
||||||
#define LED_STATE_ON 1
|
#define LED_STATE_ON 1
|
||||||
@ -43,6 +45,21 @@
|
|||||||
#define UART_TX_PIN (32 + 17)
|
#define UART_TX_PIN (32 + 17)
|
||||||
#define UART_RX_PIN (32 + 16)
|
#define UART_RX_PIN (32 + 16)
|
||||||
|
|
||||||
|
// SPI for USB host shield
|
||||||
|
#define MAX3421_SERCOM_ID 1 // SERCOM2
|
||||||
|
#define MAX3421_SERCOM_FUNCTION 2 // function C
|
||||||
|
|
||||||
|
#define MAX3421_SCK_PIN _PINNUM(0, 17)
|
||||||
|
#define MAX3421_MOSI_PIN _PINNUM(1, 23)
|
||||||
|
#define MAX3421_MISO_PIN _PINNUM(1, 22)
|
||||||
|
#define MAX3421_TX_PAD 2 // MOSI = PAD_3, SCK = PAD_1
|
||||||
|
#define MAX3421_RX_PAD 2 // MISO = PAD_2
|
||||||
|
|
||||||
|
#define MAX3421_CS_PIN 21 // D11
|
||||||
|
|
||||||
|
#define MAX3421_INTR_PIN 20 // D10
|
||||||
|
#define MAX3421_INTR_EIC_ID 4 // EIC4
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -76,12 +76,18 @@ void USB_3_Handler(void) {
|
|||||||
// Implementation
|
// Implementation
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
|
#if CFG_TUH_ENABLED && CFG_TUH_MAX3421
|
||||||
|
|
||||||
|
// API to read MAX3421's register. Implemented by TinyUSB
|
||||||
|
extern uint8_t tuh_max3421_reg_read(uint8_t rhport, uint8_t reg, bool in_isr);
|
||||||
|
|
||||||
|
// API to write MAX3421's register. Implemented by TinyUSB
|
||||||
|
extern bool tuh_max3421_reg_write(uint8_t rhport, uint8_t reg, uint8_t data, bool in_isr);
|
||||||
|
|
||||||
#define MAX3421_SERCOM TU_XSTRCAT(SERCOM, MAX3421_SERCOM_ID)
|
#define MAX3421_SERCOM TU_XSTRCAT(SERCOM, MAX3421_SERCOM_ID)
|
||||||
#define MAX3421_EIC_Handler TU_XSTRCAT3(EIC_, MAX3421_INTR_EIC_ID, _Handler)
|
#define MAX3421_EIC_Handler TU_XSTRCAT3(EIC_, MAX3421_INTR_EIC_ID, _Handler)
|
||||||
|
|
||||||
static void max3421_init(void);
|
static void max3421_init(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void board_init(void) {
|
void board_init(void) {
|
||||||
@ -136,11 +142,23 @@ void board_init(void) {
|
|||||||
gpio_set_pin_function(PIN_PA24, PINMUX_PA24H_USB_DM);
|
gpio_set_pin_function(PIN_PA24, PINMUX_PA24H_USB_DM);
|
||||||
gpio_set_pin_function(PIN_PA25, PINMUX_PA25H_USB_DP);
|
gpio_set_pin_function(PIN_PA25, PINMUX_PA25H_USB_DP);
|
||||||
|
|
||||||
#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
|
#if CFG_TUH_ENABLED && CFG_TUH_MAX3421
|
||||||
max3421_init();
|
max3421_init();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void board_init_after_tusb(void) {
|
||||||
|
#if CFG_TUH_ENABLED && CFG_TUH_MAX3421
|
||||||
|
// FeatherWing MAX3421E use MAX3421E's GPIO0 for VBUS enable
|
||||||
|
enum {
|
||||||
|
IOPINS1_ADDR = 20u << 3, // 0xA0
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t rhport = 1;
|
||||||
|
tuh_max3421_reg_write(rhport, IOPINS1_ADDR, 0x01, false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Board porting API
|
// Board porting API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
@ -182,7 +200,7 @@ uint32_t board_millis(void) {
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// API: SPI transfer with MAX3421E, must be implemented by application
|
// API: SPI transfer with MAX3421E, must be implemented by application
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
|
#if CFG_TUH_ENABLED && CFG_TUH_MAX3421
|
||||||
|
|
||||||
static void max3421_init(void) {
|
static void max3421_init(void) {
|
||||||
//------------- SPI Init -------------//
|
//------------- SPI Init -------------//
|
||||||
@ -262,7 +280,7 @@ static void max3421_init(void) {
|
|||||||
|
|
||||||
// Enable the SPI module
|
// Enable the SPI module
|
||||||
sercom->SPI.CTRLA.bit.ENABLE = 1;
|
sercom->SPI.CTRLA.bit.ENABLE = 1;
|
||||||
while (sercom->SPI.SYNCBUSY.bit.ENABLE);
|
while (sercom->SPI.SYNCBUSY.bit.ENABLE) {}
|
||||||
|
|
||||||
//------------- External Interrupt -------------//
|
//------------- External Interrupt -------------//
|
||||||
|
|
||||||
|
@ -54,6 +54,12 @@ enum {
|
|||||||
CPUCTL_ADDR = 16u << 3, // 0x80
|
CPUCTL_ADDR = 16u << 3, // 0x80
|
||||||
PINCTL_ADDR = 17u << 3, // 0x88
|
PINCTL_ADDR = 17u << 3, // 0x88
|
||||||
REVISION_ADDR = 18u << 3, // 0x90
|
REVISION_ADDR = 18u << 3, // 0x90
|
||||||
|
// 19 is not used
|
||||||
|
IOPINS1_ADDR = 20u << 3, // 0xA0
|
||||||
|
IOPINS2_ADDR = 21u << 3, // 0xA8
|
||||||
|
GPINIRQ_ADDR = 22u << 3, // 0xB0
|
||||||
|
GPINIEN_ADDR = 23u << 3, // 0xB8
|
||||||
|
GPINPOL_ADDR = 24u << 3, // 0xC0
|
||||||
HIRQ_ADDR = 25u << 3, // 0xC8
|
HIRQ_ADDR = 25u << 3, // 0xC8
|
||||||
HIEN_ADDR = 26u << 3, // 0xD0
|
HIEN_ADDR = 26u << 3, // 0xD0
|
||||||
MODE_ADDR = 27u << 3, // 0xD8
|
MODE_ADDR = 27u << 3, // 0xD8
|
||||||
@ -207,7 +213,9 @@ typedef struct {
|
|||||||
static max3421_data_t _hcd_data;
|
static max3421_data_t _hcd_data;
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// API: SPI transfer with MAX3421E, must be implemented by application
|
// API: SPI transfer with MAX3421E
|
||||||
|
// - spi_cs_api(), spi_xfer_api(), int_api(): must be implemented by application
|
||||||
|
// - reg_read(), reg_write(): is implemented by this driver, can be used by application
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// API to control MAX3421 SPI CS
|
// API to control MAX3421 SPI CS
|
||||||
@ -220,11 +228,18 @@ extern bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint
|
|||||||
// API to enable/disable MAX3421 INTR pin interrupt
|
// API to enable/disable MAX3421 INTR pin interrupt
|
||||||
extern void tuh_max3421_int_api(uint8_t rhport, bool enabled);
|
extern void tuh_max3421_int_api(uint8_t rhport, bool enabled);
|
||||||
|
|
||||||
|
// API to read MAX3421's register. Implemented by TinyUSB
|
||||||
|
uint8_t tuh_max3421_reg_read(uint8_t rhport, uint8_t reg, bool in_isr);
|
||||||
|
|
||||||
|
// API to write MAX3421's register. Implemented by TinyUSB
|
||||||
|
bool tuh_max3421_reg_write(uint8_t rhport, uint8_t reg, uint8_t data, bool in_isr);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// SPI Helper
|
// SPI Commands and Helper
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
static void handle_connect_irq(uint8_t rhport, bool in_isr);
|
|
||||||
static inline void hirq_write(uint8_t rhport, uint8_t data, bool in_isr);
|
#define reg_read tuh_max3421_reg_read
|
||||||
|
#define reg_write tuh_max3421_reg_write
|
||||||
|
|
||||||
static void max3421_spi_lock(uint8_t rhport, bool in_isr) {
|
static void max3421_spi_lock(uint8_t rhport, bool in_isr) {
|
||||||
// disable interrupt and mutex lock (for pre-emptive RTOS) if not in_isr
|
// disable interrupt and mutex lock (for pre-emptive RTOS) if not in_isr
|
||||||
@ -248,6 +263,32 @@ static void max3421_spi_unlock(uint8_t rhport, bool in_isr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t tuh_max3421_reg_read(uint8_t rhport, uint8_t reg, bool in_isr) {
|
||||||
|
uint8_t tx_buf[2] = {reg, 0};
|
||||||
|
uint8_t rx_buf[2] = {0, 0};
|
||||||
|
|
||||||
|
max3421_spi_lock(rhport, in_isr);
|
||||||
|
bool ret = tuh_max3421_spi_xfer_api(rhport, tx_buf, rx_buf, 2);
|
||||||
|
max3421_spi_unlock(rhport, in_isr);
|
||||||
|
|
||||||
|
_hcd_data.hirq = rx_buf[0];
|
||||||
|
return ret ? rx_buf[1] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tuh_max3421_reg_write(uint8_t rhport, uint8_t reg, uint8_t data, bool in_isr) {
|
||||||
|
uint8_t tx_buf[2] = {reg | CMDBYTE_WRITE, data};
|
||||||
|
uint8_t rx_buf[2] = {0, 0};
|
||||||
|
|
||||||
|
max3421_spi_lock(rhport, in_isr);
|
||||||
|
bool ret = tuh_max3421_spi_xfer_api(rhport, tx_buf, rx_buf, 2);
|
||||||
|
max3421_spi_unlock(rhport, in_isr);
|
||||||
|
|
||||||
|
// HIRQ register since we are in full-duplex mode
|
||||||
|
_hcd_data.hirq = rx_buf[0];
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void fifo_write(uint8_t rhport, uint8_t reg, uint8_t const * buffer, uint16_t len, bool in_isr) {
|
static void fifo_write(uint8_t rhport, uint8_t reg, uint8_t const * buffer, uint16_t len, bool in_isr) {
|
||||||
uint8_t hirq;
|
uint8_t hirq;
|
||||||
reg |= CMDBYTE_WRITE;
|
reg |= CMDBYTE_WRITE;
|
||||||
@ -275,34 +316,7 @@ static void fifo_read(uint8_t rhport, uint8_t * buffer, uint16_t len, bool in_is
|
|||||||
max3421_spi_unlock(rhport, in_isr);
|
max3421_spi_unlock(rhport, in_isr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reg_write(uint8_t rhport, uint8_t reg, uint8_t data, bool in_isr) {
|
//------------- register write helper -------------//
|
||||||
uint8_t tx_buf[2] = {reg | CMDBYTE_WRITE, data};
|
|
||||||
uint8_t rx_buf[2] = {0, 0};
|
|
||||||
|
|
||||||
max3421_spi_lock(rhport, in_isr);
|
|
||||||
|
|
||||||
tuh_max3421_spi_xfer_api(rhport, tx_buf, rx_buf, 2);
|
|
||||||
|
|
||||||
max3421_spi_unlock(rhport, in_isr);
|
|
||||||
|
|
||||||
// HIRQ register since we are in full-duplex mode
|
|
||||||
_hcd_data.hirq = rx_buf[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t reg_read(uint8_t rhport, uint8_t reg, bool in_isr) {
|
|
||||||
uint8_t tx_buf[2] = {reg, 0};
|
|
||||||
uint8_t rx_buf[2] = {0, 0};
|
|
||||||
|
|
||||||
max3421_spi_lock(rhport, in_isr);
|
|
||||||
|
|
||||||
bool ret = tuh_max3421_spi_xfer_api(rhport, tx_buf, rx_buf, 2);
|
|
||||||
|
|
||||||
max3421_spi_unlock(rhport, in_isr);
|
|
||||||
|
|
||||||
_hcd_data.hirq = rx_buf[0];
|
|
||||||
return ret ? rx_buf[1] : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void hirq_write(uint8_t rhport, uint8_t data, bool in_isr) {
|
static inline void hirq_write(uint8_t rhport, uint8_t data, bool in_isr) {
|
||||||
reg_write(rhport, HIRQ_ADDR, data, in_isr);
|
reg_write(rhport, HIRQ_ADDR, data, in_isr);
|
||||||
// HIRQ write 1 is clear
|
// HIRQ write 1 is clear
|
||||||
|
Loading…
x
Reference in New Issue
Block a user