From 30c8f68930880903fe6210fc8247d9350c630d95 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 Dec 2013 12:26:37 +0700 Subject: [PATCH] able to get connect status change interrupt occured --- .../boards/lpcxpresso/board_lpcxpresso1769.c | 4 + demos/device/device_os_none/.cproject | 24 ++++-- demos/device/device_os_none/tusb_config.h | 2 +- tests/lpc18xx_43xx/project.yml | 2 +- tinyusb/class/msc_device.c | 4 +- tinyusb/hal/hal_lpc175x_6x.c | 33 ++++--- tinyusb/host/ohci/ohci.c | 86 +++++++++++++++++++ 7 files changed, 133 insertions(+), 22 deletions(-) diff --git a/demos/bsp/boards/lpcxpresso/board_lpcxpresso1769.c b/demos/bsp/boards/lpcxpresso/board_lpcxpresso1769.c index f08ae8b85..2fd46cc7f 100644 --- a/demos/bsp/boards/lpcxpresso/board_lpcxpresso1769.c +++ b/demos/bsp/boards/lpcxpresso/board_lpcxpresso1769.c @@ -50,6 +50,7 @@ void board_init(void) // Leds Init GPIO_SetDir(CFG_LED_PORT, BIT_(CFG_LED_PIN), 1); +#if MODE_DEVICE_SUPPORTED //------------- USB Device -------------// // VBUS sense is wrongly connected to P0_5 (instead of P1_30). So we need to always pull P1_30 to high // so that USB device block can work. However, Device Controller (thus tinyusb) cannot able to determine @@ -58,6 +59,9 @@ void board_init(void) .Portnum = 1, .Pinnum = 30, .Funcnum = 2, .Pinmode = PINSEL_PINMODE_PULLUP} ); + //P0_21 instead of P2_9 as USB connect +#endif + #if CFG_UART_ENABLE //------------- UART init -------------// diff --git a/demos/device/device_os_none/.cproject b/demos/device/device_os_none/.cproject index 8f9b80204..38fca4563 100644 --- a/demos/device/device_os_none/.cproject +++ b/demos/device/device_os_none/.cproject @@ -1,5 +1,7 @@ - + + + @@ -32,6 +34,7 @@ @@ -121,6 +125,7 @@ @@ -209,6 +215,7 @@ @@ -302,6 +310,7 @@ @@ -391,6 +401,7 @@ @@ -460,11 +472,8 @@ <?xml version="1.0" encoding="UTF-8"?> <TargetConfig> -<Properties property_0="" property_2="LPC175x_6x_512.cfx" property_3="NXP" property_4="LPC1769" property_count="5" version="60100"/> -<infoList vendor="NXP"> -<info chip="LPC1769" flash_driver="LPC175x_6x_512.cfx" match_id="0x26113F37" name="LPC1769" package="lpc17_lqfp100.xml" stub="crt_emu_cm3_nxp"> -<chip> -<name>LPC1769</name> +<Properties property_0="" property_2="LPC175x_6x_512.cfx" property_3="NXP" property_4="LPC1769" property_count="5" version="1"/> +<infoList vendor="NXP"><info chip="LPC1769" flash_driver="LPC175x_6x_512.cfx" match_id="0x26113F37" name="LPC1769" package="lpc17_lqfp100.xml" stub="crt_emu_cm3_nxp"><chip><name>LPC1769</name> <family>LPC17xx</family> <vendor>NXP (formerly Philips)</vendor> <reset board="None" core="Real" sys="Real"/> @@ -526,8 +535,7 @@ <peripheralInstance derived_from="LPC17_MCPWM" determined="infoFile" enable="SYSCTL.PCONP.PCMCPWM&amp;0x1" id="MCPWM" location="0x400B8000"/> <peripheralInstance derived_from="LPC17_FMC" determined="infoFile" id="FMC" location="0x40084000"/> </chip> -<processor> -<name gcc_name="cortex-m3">Cortex-M3</name> +<processor><name gcc_name="cortex-m3">Cortex-M3</name> <family>Cortex-M</family> </processor> <link href="nxp_lpcxxxx_peripheral.xme" show="embed" type="simple"/> diff --git a/demos/device/device_os_none/tusb_config.h b/demos/device/device_os_none/tusb_config.h index 71a14acd0..527103091 100644 --- a/demos/device/device_os_none/tusb_config.h +++ b/demos/device/device_os_none/tusb_config.h @@ -88,7 +88,7 @@ #define TUSB_CFG_DEVICE_HID_KEYBOARD 0 #define TUSB_CFG_DEVICE_HID_MOUSE 0 #define TUSB_CFG_DEVICE_HID_GENERIC 0 -#define TUSB_CFG_DEVICE_MSC 0 +#define TUSB_CFG_DEVICE_MSC 1 #define TUSB_CFG_DEVICE_CDC 1 diff --git a/tests/lpc18xx_43xx/project.yml b/tests/lpc18xx_43xx/project.yml index 56d7a3b48..4493b690d 100644 --- a/tests/lpc18xx_43xx/project.yml +++ b/tests/lpc18xx_43xx/project.yml @@ -33,7 +33,7 @@ :source: - ../../tinyusb/** - +:../../demos/bsp/lpc43xx/** - - +:../../demos/device/keyboard/* + #- +:../../demos/device/keyboard/* - -:../../demos/ - ../../vendor/freertos/freertos/Source/* - ../../vendor/freertos/freertos/Source/portable/MSVC-MingW/* diff --git a/tinyusb/class/msc_device.c b/tinyusb/class/msc_device.c index 52c2e5de8..ae1e61618 100644 --- a/tinyusb/class/msc_device.c +++ b/tinyusb/class/msc_device.c @@ -122,11 +122,11 @@ tusb_error_t mscd_control_request_subtask(uint8_t coreid, tusb_control_request_t switch(p_request->bRequest) { case MSC_REQUEST_RESET: - dcd_pipe_control_xfer(coreid, TUSB_DIR_HOST_TO_DEV, NULL, 0); + dcd_pipe_control_xfer(coreid, TUSB_DIR_HOST_TO_DEV, NULL, 0, false); break; case MSC_REQUEST_GET_MAX_LUN: - dcd_pipe_control_xfer(coreid, TUSB_DIR_DEV_TO_HOST, &p_msc->max_lun, 1); + dcd_pipe_control_xfer(coreid, TUSB_DIR_DEV_TO_HOST, &p_msc->max_lun, 1, false); break; default: diff --git a/tinyusb/hal/hal_lpc175x_6x.c b/tinyusb/hal/hal_lpc175x_6x.c index 60b66a5e4..5398e9307 100644 --- a/tinyusb/hal/hal_lpc175x_6x.c +++ b/tinyusb/hal/hal_lpc175x_6x.c @@ -51,18 +51,30 @@ //--------------------------------------------------------------------+ tusb_error_t hal_init(void) { - LPC_SC->PCONP |= CLKPWR_PCONP_PCUSB; /* USB PCLK -> enable USB Per.*/ + enum { + USBCLK_DEVCIE = 0x12, // AHB + Device + USBCLK_HOST = 0x19 // AHB + Host + OTG (!) + }; + + LPC_SC->PCONP |= CLKPWR_PCONP_PCUSB; // enable USB Peripherals //------------- user manual 11.13 usb device controller initialization -------------// - LPC_PINCON->PINSEL1 &= ~((3<<26)|(3<<28)); /* P0.29 D+, P0.30 D- */ - LPC_PINCON->PINSEL1 |= ((1<<26)|(1<<28)); /* PINSEL1 26.27, 28.29 = 01 */ + LPC_PINCON->PINSEL1 = bit_set_range(LPC_PINCON->PINSEL1, 26, 27, BIN8(01)); // P0.29 as D+ + LPC_PINCON->PINSEL1 = bit_set_range(LPC_PINCON->PINSEL1, 28, 29, BIN8(01)); // P0.30 as D- -// LPC_PINCON->PINSEL3 &= ~(3<<6); TODO HOST -// LPC_PINCON->PINSEL3 |= (2<<6); +#if MODE_HOST_SUPPORTED + LPC_PINCON->PINSEL3 = bit_set_range(LPC_PINCON->PINSEL3, 12, 23, BIN8(10)); // P1.22 as USB_PWRD +// PINSEL_ConfigPin( &(PINSEL_CFG_Type) { .Portnum = 1, .Pinnum = 22, +// .Funcnum = 2, .Pinmode = PINSEL_PINMODE_PULLUP} ); + LPC_PINCON->PINSEL3 = bit_set_range(LPC_PINCON->PINSEL3, 6, 7, BIN8(10)); // P1.19 as USB_PPWR - //------------- Device -------------// - LPC_PINCON->PINSEL4 &= ~(3 << 18); - LPC_PINCON->PINSEL4 |= (1 << 18); // P2_9 as USB Connect + LPC_USB->USBClkCtrl = USBCLK_HOST; + while ((LPC_USB->USBClkSt & USBCLK_HOST) != USBCLK_HOST); + LPC_USB->OTGStCtrl = 0x3; +#endif + +#if MODE_DEVICE_SUPPORTED + LPC_PINCON->PINSEL4 = bit_set_range(LPC_PINCON->PINSEL4, 18, 19, BIN8(01)); // P2_9 as USB Connect // P1_30 as VBUS, ignore if it is already in VBUS mode if ( !(!BIT_TEST_(LPC_PINCON->PINSEL3, 28) && BIT_TEST_(LPC_PINCON->PINSEL3, 29)) ) @@ -74,8 +86,9 @@ tusb_error_t hal_init(void) .Funcnum = 2, .Pinmode = PINSEL_PINMODE_PULLDOWN} ); } - LPC_USB->USBClkCtrl = 0x12; /* Dev, PortSel, AHB clock enable */ - while ((LPC_USB->USBClkSt & 0x12) != 0x12); + LPC_USB->USBClkCtrl = USBCLK_DEVCIE; + while ((LPC_USB->USBClkSt & USBCLK_DEVCIE) != USBCLK_DEVCIE); +#endif return TUSB_ERROR_NONE; } diff --git a/tinyusb/host/ohci/ohci.c b/tinyusb/host/ohci/ohci.c index 61cc9e737..d0257a7ce 100644 --- a/tinyusb/host/ohci/ohci.c +++ b/tinyusb/host/ohci/ohci.c @@ -55,6 +55,47 @@ //--------------------------------------------------------------------+ #define OHCI_REG ((ohci_registers_t *) LPC_USB_BASE) +enum { + OHCI_CONTROL_FUNCSTATE_RESET = 0, + OHCI_CONTROL_FUNCSTATE_RESUME, + OHCI_CONTROL_FUNCSTATE_OPERATIONAL, + OHCI_CONTROL_FUNCSTATE_SUSPEND +}; + +enum { + OHCI_CONTROL_CONTROL_BULK_RATIO = 3, + OHCI_CONTROL_LIST_PERIODIC_ENABLE_MASK = BIT_(2), + OHCI_CONTROL_LIST_ISOCHRONOUS_ENABLE_MASK = BIT_(3), + OHCI_CONTROL_LIST_CONTROL_ENABLE_MASK = BIT_(4), + OHCI_CONTROL_LIST_BULK_ENABLE_MASK = BIT_(5), +}; + +enum { + OHCI_FMINTERVAL_FI = 0x2EDF, // 7.3.1 nominal (reset) value + OHCI_FMINTERVAL_FSMPS = (6*(OHCI_FMINTERVAL_FI-210)) / 7, // 5.4 calculated based on maximum overhead + bit stuffing +}; + +enum { + OHCI_PERIODIC_START = 0x3E67 +}; + +enum { + OHCI_INT_SCHEDULING_OVERUN_MASK = BIT_(0), + OHCI_INT_WRITEBACK_DONEHEAD_MASK = BIT_(1), + OHCI_INT_SOF_MASK = BIT_(2), + OHCI_INT_RESUME_DETECTED_MASK = BIT_(3), + OHCI_INT_UNRECOVERABLE_ERROR_MASK = BIT_(4), + OHCI_INT_FRAME_OVERFLOW_MASK = BIT_(5), + OHCI_INT_RHPORT_STATUS_CHANGE_MASK = BIT_(6), + + OHCI_INT_OWNERSHIP_CHANGE_MASK = BIT_(30), + OHCI_INT_MASTER_ENABLE_MASK = BIT_(31), + + OHCI_INT_ALL_MASK = OHCI_INT_SCHEDULING_OVERUN_MASK | OHCI_INT_WRITEBACK_DONEHEAD_MASK | OHCI_INT_SOF_MASK | + OHCI_INT_RESUME_DETECTED_MASK | OHCI_INT_UNRECOVERABLE_ERROR_MASK | OHCI_INT_FRAME_OVERFLOW_MASK | + OHCI_INT_RHPORT_STATUS_CHANGE_MASK | OHCI_INT_OWNERSHIP_CHANGE_MASK | OHCI_INT_MASTER_ENABLE_MASK +}; + //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ @@ -63,12 +104,39 @@ ohci_data_t ohci_data TUSB_CFG_ATTR_USBRAM; //--------------------------------------------------------------------+ // USBH-HCD API //--------------------------------------------------------------------+ +// Initialization according to 5.1.1.4 tusb_error_t hcd_init(void) { //------------- Data Structure init -------------// memclr_(&ohci_data, sizeof(ohci_data_t)); + ohci_data.control[0].ed.skip = 1; + // reset controller + OHCI_REG->command_status_bit.controller_reset = 1; + while( OHCI_REG->command_status_bit.controller_reset ) {} // should not take longer than 10 us + // TODO peridoic list build + // TODO assign control, bulk head + + //------------- init ohci registers -------------// + OHCI_REG->control_bit.hc_functional_state = OHCI_CONTROL_FUNCSTATE_OPERATIONAL; // move HC to operational state TODO use this to suspend (save power) + + OHCI_REG->frame_interval = (OHCI_FMINTERVAL_FSMPS << 16) | OHCI_FMINTERVAL_FI; + OHCI_REG->periodic_start = (OHCI_FMINTERVAL_FI * 9) / 10; // Periodic start is 90% of frame interval + + OHCI_REG->control_head_ed = (uint32_t) &ohci_data.control[0].ed; + OHCI_REG->hcca = (uint32_t) &ohci_data.hcca; + + OHCI_REG->control |= OHCI_CONTROL_CONTROL_BULK_RATIO | OHCI_CONTROL_LIST_CONTROL_ENABLE_MASK | + 0 /*OHCI_CONTROL_LIST_BULK_ENABLE_MASK*/; // TODO periodic enable + + OHCI_REG->rh_status_bit.local_power_status_change = 1; // set global power for ports + + OHCI_REG->interrupt_disable = OHCI_INT_ALL_MASK; + OHCI_REG->interrupt_status = OHCI_REG->interrupt_status; // clear current set bits + OHCI_REG->interrupt_enable = OHCI_INT_WRITEBACK_DONEHEAD_MASK | OHCI_INT_RESUME_DETECTED_MASK | + OHCI_INT_UNRECOVERABLE_ERROR_MASK | OHCI_INT_FRAME_OVERFLOW_MASK | OHCI_INT_RHPORT_STATUS_CHANGE_MASK | + OHCI_INT_MASTER_ENABLE_MASK; return TUSB_ERROR_NONE; } @@ -174,7 +242,25 @@ tusb_error_t hcd_pipe_clear_stall(pipe_handle_t pipe_hdl) //--------------------------------------------------------------------+ void hcd_isr(uint8_t hostid) { + uint32_t int_status = OHCI_REG->interrupt_status & OHCI_REG->interrupt_enable; + OHCI_REG->interrupt_status = int_status; // Acknowledge handled interrupt + if (int_status == 0) return; + + if ( int_status & OHCI_INT_RHPORT_STATUS_CHANGE_MASK ) + { + // TODO dual port is not yet supported + if ( OHCI_REG->rhport_status_bit[0].connect_status_change ) + { + if ( OHCI_REG->rhport_status_bit[0].current_connect_status ) + { + usbh_hcd_rhport_plugged_isr(0); + }else + { + usbh_hcd_rhport_unplugged_isr(0); + } + } + } } //--------------------------------------------------------------------+ // HELPER