summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2023-11-20 21:31:06 +0700
committerhathach <[email protected]>2023-11-20 21:31:06 +0700
commit1f71625a32a77d5fe243f71f9e8be03c9bbc41d1 (patch)
tree7712c11853d422af79d1d37c065498016fdcfc53
parentcbd3e0bc0b5cbcc29f9a8e487d560c67a9bb1d2e (diff)
add tuh_max3421_reg_read(), tuh_max3421_reg_read() for application usage
added max3241 for feather m4 and tested
-rw-r--r--hw/bsp/samd51/boards/feather_m4_express/board.h17
-rw-r--r--hw/bsp/samd51/family.c28
-rw-r--r--src/portable/analog/max3421/hcd_max3421.c78
3 files changed, 86 insertions, 37 deletions
diff --git a/hw/bsp/samd51/boards/feather_m4_express/board.h b/hw/bsp/samd51/boards/feather_m4_express/board.h
index 4629643fd..474163c06 100644
--- a/hw/bsp/samd51/boards/feather_m4_express/board.h
+++ b/hw/bsp/samd51/boards/feather_m4_express/board.h
@@ -31,6 +31,8 @@
extern "C" {
#endif
+#define _PINNUM(port, pin) ((port)*32 + (pin))
+
// LED
#define LED_PIN 23
#define LED_STATE_ON 1
@@ -43,6 +45,21 @@
#define UART_TX_PIN (32 + 17)
#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
}
#endif
diff --git a/hw/bsp/samd51/family.c b/hw/bsp/samd51/family.c
index bca18e1a2..2a2aee982 100644
--- a/hw/bsp/samd51/family.c
+++ b/hw/bsp/samd51/family.c
@@ -76,12 +76,18 @@ void USB_3_Handler(void) {
// 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_EIC_Handler TU_XSTRCAT3(EIC_, MAX3421_INTR_EIC_ID, _Handler)
static void max3421_init(void);
-
#endif
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_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();
#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
//--------------------------------------------------------------------+
@@ -182,7 +200,7 @@ uint32_t board_millis(void) {
//--------------------------------------------------------------------+
// 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) {
//------------- SPI Init -------------//
@@ -262,7 +280,7 @@ static void max3421_init(void) {
// Enable the SPI module
sercom->SPI.CTRLA.bit.ENABLE = 1;
- while (sercom->SPI.SYNCBUSY.bit.ENABLE);
+ while (sercom->SPI.SYNCBUSY.bit.ENABLE) {}
//------------- External Interrupt -------------//
diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c
index 65f87f7c6..2abd74d51 100644
--- a/src/portable/analog/max3421/hcd_max3421.c
+++ b/src/portable/analog/max3421/hcd_max3421.c
@@ -54,6 +54,12 @@ enum {
CPUCTL_ADDR = 16u << 3, // 0x80
PINCTL_ADDR = 17u << 3, // 0x88
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
HIEN_ADDR = 26u << 3, // 0xD0
MODE_ADDR = 27u << 3, // 0xD8
@@ -207,7 +213,9 @@ typedef struct {
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
@@ -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
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) {
// disable interrupt and mutex lock (for pre-emptive RTOS) if not in_isr
@@ -248,61 +263,60 @@ static void max3421_spi_unlock(uint8_t rhport, 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;
- reg |= CMDBYTE_WRITE;
+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);
-
- tuh_max3421_spi_xfer_api(rhport, &reg, &hirq, 1);
- _hcd_data.hirq = hirq;
- tuh_max3421_spi_xfer_api(rhport, buffer, NULL, len);
-
+ 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 void fifo_read(uint8_t rhport, uint8_t * buffer, uint16_t len, bool in_isr) {
- uint8_t hirq;
- uint8_t const reg = RCVVFIFO_ADDR;
+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);
- tuh_max3421_spi_xfer_api(rhport, &reg, &hirq, 1);
- _hcd_data.hirq = hirq;
- tuh_max3421_spi_xfer_api(rhport, NULL, buffer, len);
+ // HIRQ register since we are in full-duplex mode
+ _hcd_data.hirq = rx_buf[0];
- max3421_spi_unlock(rhport, in_isr);
+ return ret;
}
-static void 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};
+static void fifo_write(uint8_t rhport, uint8_t reg, uint8_t const * buffer, uint16_t len, bool in_isr) {
+ uint8_t hirq;
+ reg |= CMDBYTE_WRITE;
max3421_spi_lock(rhport, in_isr);
- tuh_max3421_spi_xfer_api(rhport, tx_buf, rx_buf, 2);
+ tuh_max3421_spi_xfer_api(rhport, &reg, &hirq, 1);
+ _hcd_data.hirq = hirq;
+ tuh_max3421_spi_xfer_api(rhport, buffer, NULL, len);
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};
+static void fifo_read(uint8_t rhport, uint8_t * buffer, uint16_t len, bool in_isr) {
+ uint8_t hirq;
+ uint8_t const reg = RCVVFIFO_ADDR;
max3421_spi_lock(rhport, in_isr);
- bool ret = tuh_max3421_spi_xfer_api(rhport, tx_buf, rx_buf, 2);
+ tuh_max3421_spi_xfer_api(rhport, &reg, &hirq, 1);
+ _hcd_data.hirq = hirq;
+ tuh_max3421_spi_xfer_api(rhport, NULL, buffer, len);
max3421_spi_unlock(rhport, in_isr);
-
- _hcd_data.hirq = rx_buf[0];
- return ret ? rx_buf[1] : 0;
}
+//------------- register write helper -------------//
static inline void hirq_write(uint8_t rhport, uint8_t data, bool in_isr) {
reg_write(rhport, HIRQ_ADDR, data, in_isr);
// HIRQ write 1 is clear