Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: F401RE-USBHostMIDI_RecieveExample
Fork of F401RE-USBHost by
Diff: USBHALHost.cpp
- Revision:
- 3:a3872f7593e2
- Parent:
- 2:0cdac6bcc534
- Child:
- 4:21d651ad6987
diff -r 0cdac6bcc534 -r a3872f7593e2 USBHALHost.cpp
--- a/USBHALHost.cpp Thu Jan 23 08:32:54 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,285 +0,0 @@
-// Simple USBHost for FRDM-KL46Z
-#include "USBHALHost.h"
-#include <algorithm>
-
-template <bool>struct CtAssert;
-template <>struct CtAssert<true> {};
-#define CTASSERT(A) CtAssert<A>();
-
-
-#ifdef _USB_DBG
-#define USB_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");} while(0);
-#define USB_DBG_HEX(A,B) debug_hex(A,B)
-void debug_hex(uint8_t* buf, int size);
-#else
-#define USB_DBG(...) while(0)
-#define USB_DBG_HEX(A,B) while(0)
-#endif
-
-#define USB_TEST_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
-#define USB_TEST_ASSERT_FALSE(A) USB_TEST_ASSERT(!(A))
-
-#define BD_OWN_MASK (1<<7)
-#define BD_DATA01_MASK (1<<6)
-#define BD_KEEP_MASK (1<<5)
-#define BD_NINC_MASK (1<<4)
-#define BD_DTS_MASK (1<<3)
-#define BD_STALL_MASK (1<<2)
-
-#define TX 1
-#define RX 0
-
-#define EP0_BDT_IDX(dir, odd) (((2 * dir) + (1 * odd)))
-
-#define SETUP_TOKEN 0x0D
-#define IN_TOKEN 0x09
-#define OUT_TOKEN 0x01
-
-// for each endpt: 8 bytes
-struct BDT {
- uint8_t info; // BD[0:7]
- uint8_t dummy; // RSVD: BD[8:15]
- uint16_t byte_count; // BD[16:32]
- uint32_t address; // Addr
- void setBuffer(uint8_t* buf, int size) {
- address = (uint32_t)buf;
- byte_count = size;
- }
- uint8_t getStatus() {
- return (info>>2)&0x0f;
- }
-};
-
-__attribute__((__aligned__(512))) BDT bdt[64];
-
-USBHALHost* USBHALHost::instHost;
-
-USBHALHost::USBHALHost() {
- instHost = this;
- memset(rx_data01, DATA1, sizeof(rx_data01));
- memset(tx_data01, DATA1, sizeof(tx_data01));
-}
-
-void USBHALHost::init() {
- // Disable IRQ
- NVIC_DisableIRQ(USB0_IRQn);
-
- // choose usb src as PLL
- SIM->SOPT2 |= (SIM_SOPT2_USBSRC_MASK | SIM_SOPT2_PLLFLLSEL_MASK);
-
- // enable OTG clock
- SIM->SCGC4 |= SIM_SCGC4_USBOTG_MASK;
-
- // USB Module Configuration
- // Reset USB Module
- USB0->USBTRC0 |= USB_USBTRC0_USBRESET_MASK;
- while(USB0->USBTRC0 & USB_USBTRC0_USBRESET_MASK);
-
- // Clear interrupt flag
- USB0->ISTAT = 0xff;
-
- // Set BDT Base Register
- USB0->BDTPAGE1=(uint8_t)((uint32_t)bdt>>8);
- USB0->BDTPAGE2=(uint8_t)((uint32_t)bdt>>16);
- USB0->BDTPAGE3=(uint8_t)((uint32_t)bdt>>24);
-
- // Set SOF threshold
- USB0->SOFTHLD = USB_SOFTHLD_CNT(1);
-
- // pulldown D+ and D-
- USB0->USBCTRL = USB_USBCTRL_PDE_MASK;
-
- USB0->USBTRC0 |= 0x40;
-
- // Host mode
- USB0->CTL |= USB_CTL_HOSTMODEEN_MASK;
- // Desable SOF packet generation
- USB0->CTL &= ~USB_CTL_USBENSOFEN_MASK;
-
- NVIC_SetVector(USB0_IRQn, (uint32_t)_usbisr);
- NVIC_EnableIRQ(USB0_IRQn);
-
- wait_attach();
-
- for(int retry = 2; retry > 0; retry--) {
- // Enable RESET
- USB0->CTL |= USB_CTL_RESET_MASK;
- wait_ms(500);
- USB0->CTL &= ~USB_CTL_RESET_MASK;
-
- // Enable SOF
- USB0->CTL |= USB_CTL_USBENSOFEN_MASK;
- wait_ms(100);
-
- // token transfer initialize
- tx_ptr = ODD;
- rx_ptr = ODD;
- USB0->INTEN |= USB_INTEN_TOKDNEEN_MASK;
-
- if (enumeration()) {
- break;
- }
- USB_DBG("retry=%d", retry);
- USB_TEST_ASSERT(retry > 1);
- }
-}
-
-void USBHALHost::wait_attach() {
- attach_done = false;
- USB0->INTEN = USB_INTEN_ATTACHEN_MASK;
- while(!attach_done);
- wait_ms(100);
- USB_TEST_ASSERT_FALSE(USB0->CTL & USB_CTL_SE0_MASK);
- lowSpeed = (USB0->CTL & USB_CTL_JSTATE_MASK) ? false : true;
- if (lowSpeed) { // low speed
- USB0->ENDPOINT[0].ENDPT |= USB_ENDPT_HOSTWOHUB_MASK;
- }
- USB_DBG("lowSpeed=%d", lowSpeed);
-}
-
-void USBHALHost::setAddr(int _addr) {
- USB0->ADDR = (lowSpeed ? USB_ADDR_LSEN_MASK : 0x00) | USB_ADDR_ADDR(_addr);
-}
-
-void USBHALHost::setEndpoint(bool use_retry) {
- USB0->ENDPOINT[0].ENDPT = (lowSpeed ? USB_ENDPT_HOSTWOHUB_MASK : 0x00)|
- USB_ENDPT_EPCTLDIS_MASK|
- (use_retry ? 0x00 : USB_ENDPT_RETRYDIS_MASK)|
- USB_ENDPT_EPRXEN_MASK|
- USB_ENDPT_EPTXEN_MASK|
- USB_ENDPT_EPHSHK_MASK;
-}
-
-int USBHALHost::token_setup(SETUP_PACKET* setup, uint16_t wLength) {
- int retry = 0;
- do {
- token_ready();
- USB0->ENDPOINT[0].ENDPT = (lowSpeed ? USB_ENDPT_HOSTWOHUB_MASK : 0x00) |
- USB_ENDPT_RETRYDIS_MASK|
- USB_ENDPT_EPRXEN_MASK|
- USB_ENDPT_EPTXEN_MASK|
- USB_ENDPT_EPHSHK_MASK;
- CTASSERT(sizeof(SETUP_PACKET) == 8);
- setup->wLength = wLength;
- int idx = EP0_BDT_IDX(TX, tx_ptr);
- bdt[idx].setBuffer((uint8_t*)setup, sizeof(SETUP_PACKET));
- bdt[idx].info = BD_OWN_MASK |
- BD_DTS_MASK; // always data0
- token_done = false;
- USB0->TOKEN = USB_TOKEN_TOKENPID(SETUP_TOKEN)|USB_TOKEN_TOKENENDPT(0);
- while(!token_done);
- LastStatus = bdt[idx].getStatus();
- if (LastStatus == ACK) {
- if (retry > 0) {
- USB_DBG("retry=%d %02x", retry, prev_LastStatus);
- }
- return ACK;
- }
- wait_ms(1);
- prev_LastStatus = LastStatus;
- //USB_DBG("retry=%d %02x", retry, prev_LastStatus);
- }while(retry++ < 10);
- return LastStatus;
-}
-
-int USBHALHost::token_in(uint8_t ep, uint8_t* data, int size, int retryLimit) {
- USB_TEST_ASSERT(ep < sizeof(rx_data01));
- for(int retry = 0;; retry++) {
- token_ready();
- int idx = EP0_BDT_IDX(RX, rx_ptr);
- bdt[idx].setBuffer(data, size);
- bdt[idx].info = BD_OWN_MASK|
- BD_DTS_MASK|
- ((rx_data01[ep] == DATA1) ? BD_DATA01_MASK : 0);
- token_done = false;
- USB0->TOKEN = USB_TOKEN_TOKENPID(IN_TOKEN)|USB_TOKEN_TOKENENDPT(ep);
- while(!token_done);
- LastStatus = bdt[idx].getStatus();
- int len = bdt[idx].byte_count;
- if (LastStatus == DATA0 || LastStatus == DATA1) {
- rx_data01[ep] = LastStatus == DATA0 ? DATA1 : DATA0;
- if (retry > 0) {
- USB_DBG("len=%d retry=%d %02x", len, retry, prev_LastStatus);
- }
- return len;
- }
- if (++retry >= retryLimit) {
- return -1;
- }
- wait_ms(100);
- prev_LastStatus = LastStatus;
- }
-}
-
-int USBHALHost::token_out(uint8_t ep, const uint8_t* data, int size) {
- USB_TEST_ASSERT(ep < sizeof(tx_data01));
- int retry = 0;
- do {
- token_ready();
- int idx = EP0_BDT_IDX(TX, tx_ptr);
- bdt[idx].info = BD_OWN_MASK|
- BD_DTS_MASK|
- ((tx_data01[ep] == DATA1) ? BD_DATA01_MASK : 0);
- bdt[idx].setBuffer((uint8_t*)data, size);
- token_done = false;
- USB0->TOKEN = USB_TOKEN_TOKENPID(OUT_TOKEN)|USB_TOKEN_TOKENENDPT(ep);
- while(!token_done);
- LastStatus = bdt[idx].getStatus();
- if (LastStatus == ACK) {
- tx_data01[ep] = (tx_data01[ep] == DATA0) ? DATA1 : DATA0;
- if (retry > 0) {
- USB_DBG("retry=%d %02x", retry, prev_LastStatus);
- }
- return bdt[idx].byte_count;
- }
- wait_ms(10);
- prev_LastStatus = LastStatus;
- } while(retry++ < 10);
- return -1;
-}
-
-void USBHALHost::token_ready() {
- while(USB0->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) { // TOKEN_BUSY ?
- wait_ms(1);
- }
- USB0->ISTAT |= USB_ISTAT_SOFTOK_MASK; // Clear SOF
- while (!(USB0->ISTAT & USB_ISTAT_SOFTOK_MASK));
- USB0->SOFTHLD = 0; // this is needed as without this you can get errors
- USB0->ISTAT |= USB_ISTAT_SOFTOK_MASK; // clear SOF
-}
-
-void USBHALHost::_usbisr(void) {
- if (instHost) {
- instHost->UsbIrqhandler();
- }
-}
-
-void USBHALHost::UsbIrqhandler() {
- uint8_t istat = USB0->ISTAT;
- if (istat & USB_ISTAT_TOKDNE_MASK) {
- uint8_t stat = USB0->STAT;
- ODD_EVEN next_ptr = (stat & USB_STAT_ODD_MASK) ? ODD : EVEN;
- if (stat & USB_STAT_TX_MASK) {
- tx_ptr = next_ptr;
- } else {
- rx_ptr = next_ptr;
- }
- token_done = true;
- }
- if (istat & USB_ISTAT_ATTACH_MASK) {
- USB0->INTEN &= ~USB_INTEN_ATTACHEN_MASK;
- attach_done = true;
- }
- USB0->ISTAT = istat; // clear
-}
-
-void debug_hex(uint8_t* buf, int size) {
- for(int i = 0; i < size; i++) {
- fprintf(stderr, "%02x ", buf[i]);
- if (i%16 == 15) {
- fprintf(stderr, "\r\n");
- }
- }
- fprintf(stderr, "\r\n");
-}
-
