USB device stack, with KL25Z fixes for USB 3.0 hosts and sleep/resume interrupt handling

Dependents:   frdm_Slider_Keyboard idd_hw2_figlax_PanType idd_hw2_appachu_finger_chording idd_hw3_AngieWangAntonioDeLimaFernandesDanielLim_BladeSymphony ... more

Fork of USBDevice by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBHAL_KL25Z.cpp Source File

USBHAL_KL25Z.cpp

00001 /* Copyright (c) 2010-2011 mbed.org, MIT License
00002 *
00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00004 * and associated documentation files (the "Software"), to deal in the Software without
00005 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
00006 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
00007 * Software is furnished to do so, subject to the following conditions:
00008 *
00009 * The above copyright notice and this permission notice shall be included in all copies or
00010 * substantial portions of the Software.
00011 *
00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00017 */
00018 
00019 #if defined(TARGET_KL25Z) | defined(TARGET_KL46Z) | defined(TARGET_K20D5M) | defined(TARGET_K64F)
00020 
00021 #include <stdarg.h>
00022 #include "USBHAL.h"
00023 
00024 // Critical section controls.  This module uses a bunch of static variables,
00025 // and much of the code that accesses the statics can be called from either
00026 // normal application context or IRQ context.  Whenever a shared variable is
00027 // accessed from code that can run in an application context, we have to
00028 // protect against interrupts by entering a critical section.  These macros
00029 // enable and disable the USB IRQ if we're running in application context.
00030 // (They do nothing if we're already in interrupt context, because the
00031 // hardware interrupt controller won't generated another of the same IRQ
00032 // that we're already handling.  We could still be interrupted by a different,
00033 // higher-priority IRQ, but our shared variables are only shared within this
00034 // module, so they won't be affected by other interrupt handlers.)
00035 static bool inIRQ;
00036 #define ENTER_CRITICAL_SECTION \
00037     if (!inIRQ) \
00038         NVIC_DisableIRQ(USB0_IRQn);
00039 #define EXIT_CRITICAL_SECTION \
00040     if (!inIRQ) \
00041         NVIC_EnableIRQ(USB0_IRQn);
00042 
00043 //#define DEBUG_WITH_PRINTF
00044 // debug printf; does a regular printf() in debug mode, nothing in
00045 // normal mode.  Note that many of our routines are called in ISR
00046 // context, so printf should really never be used here.  But in
00047 // practice we can get away with it enough that it can be helpful
00048 // as a limited debugging tool.
00049 #ifdef DEBUG_WITH_PRINTF
00050 #define printd(fmt, ...) printf(fmt, __VA_ARGS__)
00051 #else
00052 #define printd(fmt, ...)
00053 #endif
00054 
00055 // Makeshift debug instrumentation.  This is a safer and better
00056 // alternative to printf() that gathers event information in a 
00057 // circular buffer for later useoutside of interrupt context, such 
00058 // as printf() display at intervals in the main program loop.  
00059 //
00060 // Timing is critical to USB, so debug instrumentation is inherently 
00061 // problematic in that it can affect the timing and thereby change 
00062 // the behavior of what we're trying to debug.  Small timing changes
00063 // can create new errors that wouldn't be there otherwise, or even
00064 // accidentally fix the bug were trying to find (e.g., by changing
00065 // the timing enough to avoid a race condition).  To minimize these 
00066 // effects, we use a small buffer and very terse event codes - 
00067 // generally one character per event.  That makes for a cryptic 
00068 // debug log, but it results in almost zero timing effects, allowing
00069 // us to see a more faithful version of the subject program.
00070 //
00071 // Note that the buffer size isn't critical to timing, because any
00072 // printf()-type display should always occur in regular (non-ISR)
00073 // context and thus won't have any significant effect on interrupt
00074 // timing or latency.  The buffer can be expanded if longer logs
00075 // would be helpful.  However, it is important to keep the individual
00076 // event messages short (a character or two in most cases), because
00077 // it takes time to move them into the buffer.  
00078 //#define DEBUG_WITH_EVENTS
00079 #ifdef DEBUG_WITH_EVENTS
00080 const int nevents = 64;  // MUST BE A POWER OF 2
00081 char events[nevents];
00082 char ewrite = 0, eread = 0;
00083 void HAL_DEBUG_EVENT(char c)
00084 {
00085     events[ewrite] = c;
00086     ewrite = (ewrite+1) & (nevents-1);
00087     if (ewrite == eread)
00088         eread = (eread+1) & (nevents-1);
00089 }
00090 void HAL_DEBUG_EVENT(char a, char b) { 
00091     HAL_DEBUG_EVENT(a); HAL_DEBUG_EVENT(b); 
00092 }
00093 void HAL_DEBUG_EVENT(char a, char b, char c) { 
00094     HAL_DEBUG_EVENT(a); HAL_DEBUG_EVENT(b); HAL_DEBUG_EVENT(c); 
00095 }
00096 void HAL_DEBUG_EVENT(const char *s) { 
00097     while (*s) HAL_DEBUG_EVENT(*s++); 
00098 }
00099 void HAL_DEBUG_EVENTI(char c, int i) {
00100     HAL_DEBUG_EVENT(c);
00101     if (i > 1000) HAL_DEBUG_EVENT(((i / 1000) % 10) + '0');
00102     if (i > 100) HAL_DEBUG_EVENT(((i / 100) % 10) + '0');
00103     if (i > 10) HAL_DEBUG_EVENT(((i / 10) % 10) + '0');
00104     HAL_DEBUG_EVENT((i % 10) + '0');
00105 }
00106 void HAL_DEBUG_EVENTF(const char *fmt, ...) {
00107     va_list va; 
00108     va_start(va, fmt); 
00109     char buf[64]; 
00110     vsprintf(buf, fmt, va); 
00111     va_end(va); 
00112     HAL_DEBUG_EVENT(buf);
00113 }
00114 void HAL_DEBUG_PRINTEVENTS(const char *prefix)
00115 {
00116     if (prefix != 0)
00117         printf("%s ", prefix);
00118     else
00119         printf("ev: ");
00120 
00121     char buf[nevents];
00122     int i;
00123     ENTER_CRITICAL_SECTION
00124     {
00125         for (i = 0 ; eread != ewrite ; eread = (eread+1) & (nevents - 1))
00126             buf[i++] = events[eread];
00127     }
00128     EXIT_CRITICAL_SECTION
00129     printf("%.*s\r\n", i, buf);
00130 }
00131 #else
00132 #define HAL_DEBUG_EVENT(...)   void(0)
00133 #define HAL_DEBUG_EVENTf(...)  void(0)
00134 #define HAL_DEBUG_EVENTI(...)  void(0)
00135 void HAL_DEBUG_PRINTEVENTS(const char *) { }
00136 #endif
00137 
00138 
00139 // static singleton instance pointer
00140 USBHAL * USBHAL::instance;
00141 
00142 
00143 // Convert physical endpoint number to register bit
00144 #define EP(endpoint) (1<<(endpoint))
00145 
00146 // Convert physical endpoint number to logical endpoint number.
00147 // Each logical endpoint has two physical endpoints, one RX and 
00148 // one TX.  The physical endpoints are numbered in RX,TX pairs,
00149 // so the logical endpoint number is simply the physical endpoint
00150 // number divided by 2 (discarding the remainder).
00151 #define PHY_TO_LOG(endpoint)    ((endpoint)>>1)
00152 
00153 // Get a physical endpoint's direction.  IN and OUT are from
00154 // the host's perspective, so from our perspective on the device,
00155 // IN == TX and OUT == RX.  The physical endpoints are in RX,TX
00156 // pairs, so the OUT/RX is the even numbered element of a pair
00157 // and the IN/TX is the odd numbered element.
00158 #define IN_EP(endpoint)     ((endpoint) & 1U ? true : false)
00159 #define OUT_EP(endpoint)    ((endpoint) & 1U ? false : true)
00160 
00161 // BDT status flags, defined by the SIE hardware.  These are
00162 // bits packed into the 'info' byte of a BDT entry.
00163 #define BD_OWN_MASK        (1<<7)       // OWN - hardware SIE owns the BDT (TX/RX in progress)
00164 #define BD_DATA01_MASK     (1<<6)       // DATA01 - DATA0/DATA1 bit for current TX/RX on endpoint
00165 #define BD_KEEP_MASK       (1<<5)       // KEEP - hardware keeps BDT ownership after token completes
00166 #define BD_NINC_MASK       (1<<4)       // NO INCREMENT - buffer location is a FIFO, so use same address for all bytes
00167 #define BD_DTS_MASK        (1<<3)       // DATA TOGGLE SENSING - hardware SIE checks for DATA0/DATA1 match during RX/TX
00168 #define BD_STALL_MASK      (1<<2)       // STALL - SIE issues STALL handshake in reply to any host access to endpoint
00169 
00170 // Endpoint direction (from DEVICE perspective)
00171 #define TX    1
00172 #define RX    0
00173 
00174 // Buffer parity.  The hardware has a double-buffering scheme where each
00175 // physical endpoint has two associated BDT entries, labeled EVEN and ODD.
00176 // We disable the double buffering, so only the EVEN buffers are used in
00177 // this implementation.
00178 #define EVEN  0
00179 #define ODD   1
00180 
00181 // Get the BDT index for a given logical endpoint, direction, and buffer parity
00182 #define EP_BDT_IDX(logep, dir, odd) (((logep) * 4) + (2 * (dir)) + (1 *  (odd)))
00183 
00184 // Get the BDT index for a given physical endpoint and buffer parity
00185 #define PEP_BDT_IDX(phyep, odd)  (((phyep) * 2) + (1 * (odd)))
00186 
00187 // Token types reported in the BDT 'info' flags.  
00188 #define TOK_PID(idx)   ((bdt[idx].info >> 2) & 0x0F)
00189 #define SETUP_TOKEN    0x0D
00190 #define IN_TOKEN       0x09
00191 #define OUT_TOKEN      0x01
00192 
00193 // Buffer Descriptor Table (BDT) entry.  This is the hardware-defined
00194 // memory structure for the shared memory block controlling an endpoint.
00195 typedef struct BDT {
00196     uint8_t   info;       // BD[0:7]
00197     uint8_t   dummy;      // RSVD: BD[8:15]
00198     uint16_t  byte_count; // BD[16:32]
00199     uint32_t  address;    // Addr
00200 } BDT;
00201 
00202 
00203 // There are:
00204 //    * 16 bidirectional logical endpoints -> 32 physical endpoints
00205 //    * 2 BDT entries per endpoint (EVEN/ODD) -> 64 BDT entries
00206 __attribute__((__aligned__(512))) BDT bdt[NUMBER_OF_PHYSICAL_ENDPOINTS * 2];
00207 
00208 // Transfer buffers.  We allocate the transfer buffers and point the
00209 // SIE hardware to them via the BDT.  We disable hardware SIE's
00210 // double-buffering (EVEN/ODD) scheme, so we only allocate one buffer
00211 // per physical endpoint.
00212 uint8_t *endpoint_buffer[NUMBER_OF_PHYSICAL_ENDPOINTS];
00213 
00214 // Allocated size of each endpoint buffer
00215 size_t epMaxPacket[NUMBER_OF_PHYSICAL_ENDPOINTS];
00216 
00217 
00218 // SET ADDRESS mode tracking.  The address assignment has to be done in a
00219 // specific order and with specific timing defined by the USB setup protocol 
00220 // standards.  To get the sequencing right, we set a flag when we get the
00221 // address message, and then set the address in the SIE when we're at the 
00222 // right subsequent packet step in the protocol exchange.  These variables
00223 // are just a place to stash the information between the time we receive the
00224 // data and the time we're ready to update the SIE register.
00225 static uint8_t set_addr = 0;
00226 static uint8_t addr = 0;
00227 
00228 // Endpoint DATA0/DATA1 bits, packed as a bit vector.  Each endpoint's
00229 // bit is at (1 << endpoint number).  These track the current bit value
00230 // on the endpoint.  For TX endpoints, this is the bit for the LAST
00231 // packet we sent (so the next packet will be the inverse).  For RX
00232 // endpoints, this is the bit value we expect for the NEXT packet.
00233 // (Yes, it's inconsistent.)
00234 static volatile uint32_t Data1  = 0x55555555;
00235 
00236 // Endpoint read/write completion flags, packed as a bit vector.  Each 
00237 // endpoint's bit is at (1 << endpoint number).  A 1 bit signifies that
00238 // the last read or write has completed (and hasn't had its result 
00239 // consumed yet).
00240 static volatile uint32_t epComplete = 0;
00241 
00242 // Endpoint Realised flags.  We set these flags (arranged in the usual 
00243 // endpoint bit vector format) when endpoints are realised, so that
00244 // read/write operations will know if it's okay to proceed.  The
00245 // control endpoint (EP0) is always realised in both directions.
00246 static volatile uint32_t epRealised = 0x03;
00247 
00248 static uint32_t frameNumber() 
00249 {
00250     return((USB0->FRMNUML | (USB0->FRMNUMH << 8)) & 0x07FF);
00251 }
00252 
00253 uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) 
00254 {
00255     return 0;
00256 }
00257 
00258 // Enabled interrupts at startup or reset:
00259 //   TOKDN  - token done
00260 //   SOFTOK - start-of-frame token
00261 //   ERROR  - error
00262 //   SLEEP  - sleep (inactivity on bus)
00263 //   RST    - bus reset
00264 //
00265 // Note that don't enable RESUME (resume from suspend mode), per 
00266 // the hardware reference manual ("When not in suspend mode this 
00267 // interrupt must be disabled").  We also don't enable ATTACH, which
00268 // is only meaningful in host mode.
00269 #define BUS_RESET_INTERRUPTS \
00270     USB_INTEN_TOKDNEEN_MASK \
00271     | USB_INTEN_STALLEN_MASK \
00272     | USB_INTEN_SOFTOKEN_MASK \
00273     | USB_INTEN_ERROREN_MASK \
00274     | USB_INTEN_SLEEPEN_MASK \
00275     | USB_INTEN_USBRSTEN_MASK
00276 
00277 // Do a low-level reset on the USB hardware module.  This lets the 
00278 // device software initiate a hard reset.
00279 static void resetSIE(void)
00280 {
00281     // set the reset bit in the transceiver control register,
00282     // then wait for it to clear
00283     USB0->USBTRC0 |= USB_USBTRC0_USBRESET_MASK;
00284     while (USB0->USBTRC0 & USB_USBTRC0_USBRESET_MASK);
00285     
00286     // clear BDT entries
00287     for (int i = 0 ; i < sizeof(bdt)/sizeof(bdt[0]) ; ++i)
00288     {
00289         bdt[i].info = 0;
00290         bdt[i].byte_count = 0;
00291     }
00292 
00293     // Set BDT Base Register
00294     USB0->BDTPAGE1 = (uint8_t)((uint32_t)bdt>>8);
00295     USB0->BDTPAGE2 = (uint8_t)((uint32_t)bdt>>16);
00296     USB0->BDTPAGE3 = (uint8_t)((uint32_t)bdt>>24);
00297 
00298     // Clear interrupt flag
00299     USB0->ISTAT = 0xff;
00300 
00301     // Enable the initial set of interrupts
00302     USB0->INTEN = BUS_RESET_INTERRUPTS;
00303 
00304     // Disable weak pull downs, and turn off suspend mode
00305     USB0->USBCTRL = 0;
00306 
00307     // set the "reserved" bit in the transceiver control register
00308     // (hw ref: "software must set this bit to 1")
00309     USB0->USBTRC0 |= 0x40;
00310 }
00311 
00312 USBHAL::USBHAL(void) 
00313 {
00314     // Disable IRQ
00315     NVIC_DisableIRQ(USB0_IRQn);
00316 
00317 #if defined(TARGET_K64F)
00318     MPU->CESR=0;
00319 #endif
00320     // fill in callback array
00321     epCallback[0] = &USBHAL::EP1_OUT_callback;
00322     epCallback[1] = &USBHAL::EP1_IN_callback;
00323     epCallback[2] = &USBHAL::EP2_OUT_callback;
00324     epCallback[3] = &USBHAL::EP2_IN_callback;
00325     epCallback[4] = &USBHAL::EP3_OUT_callback;
00326     epCallback[5] = &USBHAL::EP3_IN_callback;
00327     epCallback[6] = &USBHAL::EP4_OUT_callback;
00328     epCallback[7] = &USBHAL::EP4_IN_callback;
00329     epCallback[8] = &USBHAL::EP5_OUT_callback;
00330     epCallback[9] = &USBHAL::EP5_IN_callback;
00331     epCallback[10] = &USBHAL::EP6_OUT_callback;
00332     epCallback[11] = &USBHAL::EP6_IN_callback;
00333     epCallback[12] = &USBHAL::EP7_OUT_callback;
00334     epCallback[13] = &USBHAL::EP7_IN_callback;
00335     epCallback[14] = &USBHAL::EP8_OUT_callback;
00336     epCallback[15] = &USBHAL::EP8_IN_callback;
00337     epCallback[16] = &USBHAL::EP9_OUT_callback;
00338     epCallback[17] = &USBHAL::EP9_IN_callback;
00339     epCallback[18] = &USBHAL::EP10_OUT_callback;
00340     epCallback[19] = &USBHAL::EP10_IN_callback;
00341     epCallback[20] = &USBHAL::EP11_OUT_callback;
00342     epCallback[21] = &USBHAL::EP11_IN_callback;
00343     epCallback[22] = &USBHAL::EP12_OUT_callback;
00344     epCallback[23] = &USBHAL::EP12_IN_callback;
00345     epCallback[24] = &USBHAL::EP13_OUT_callback;
00346     epCallback[25] = &USBHAL::EP13_IN_callback;
00347     epCallback[26] = &USBHAL::EP14_OUT_callback;
00348     epCallback[27] = &USBHAL::EP14_IN_callback;
00349     epCallback[28] = &USBHAL::EP15_OUT_callback;
00350     epCallback[29] = &USBHAL::EP15_IN_callback;
00351 
00352     // choose usb src as PLL
00353     SIM->SOPT2 |= (SIM_SOPT2_USBSRC_MASK | SIM_SOPT2_PLLFLLSEL_MASK);
00354 
00355     // enable OTG clock
00356     SIM->SCGC4 |= SIM_SCGC4_USBOTG_MASK;
00357 
00358     // Attach IRQ
00359     instance = this;
00360     NVIC_SetVector(USB0_IRQn, (uint32_t)&_usbisr);
00361     NVIC_EnableIRQ(USB0_IRQn);
00362 
00363     // USB Module Configuration
00364     // Reset USB Module
00365     resetSIE();
00366 }
00367 
00368 USBHAL::~USBHAL(void) 
00369 {
00370     // Free buffers
00371     for (int i = 0 ; i < NUMBER_OF_PHYSICAL_ENDPOINTS ; i++) 
00372     {
00373         if (endpoint_buffer[i] != NULL)
00374         {
00375             delete [] endpoint_buffer[i];
00376             endpoint_buffer[i] = NULL;
00377             epMaxPacket[i] = 0;
00378         }
00379     }
00380 }
00381 
00382 void USBHAL::connect(void) 
00383 {
00384     // enable USB
00385     USB0->CTL |= USB_CTL_USBENSOFEN_MASK;
00386     
00387     // Pull up enable
00388     USB0->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK;
00389 }
00390 
00391 void USBHAL::disconnect(void) 
00392 {
00393     // disable USB
00394     USB0->CTL &= ~USB_CTL_USBENSOFEN_MASK;
00395     
00396     // Pull up disable
00397     USB0->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK;
00398 }
00399 
00400 void USBHAL::hardReset(void)
00401 {
00402     // reset the SIE module
00403     resetSIE();
00404     
00405     // do the internal reset work
00406     internalReset();
00407 }
00408 
00409 void USBHAL::configureDevice(void) 
00410 {
00411     // not needed
00412 }
00413 
00414 void USBHAL::unconfigureDevice(void) 
00415 {
00416     // not needed
00417 }
00418 
00419 void USBHAL::setAddress(uint8_t address) 
00420 {
00421     // we don't set the address now otherwise the usb controller does not ack
00422     // we set a flag instead
00423     // see usbisr when an IN token is received
00424     set_addr = 1;
00425     addr = address;
00426  }
00427 
00428 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) 
00429 {
00430     // validate the endpoint number
00431     if (endpoint >= NUMBER_OF_PHYSICAL_ENDPOINTS)
00432         return false;
00433 
00434     // get the logical endpoint
00435     uint32_t log_endpoint = PHY_TO_LOG(endpoint);
00436     
00437     // Assume this is a bulk or interrupt endpoint.  For these, the hardware maximum
00438     // packet size is 64 bytes, and we use packet handshaking.
00439     uint32_t hwMaxPacket = 64;
00440     uint32_t handshake_flag = USB_ENDPT_EPHSHK_MASK;
00441     
00442     // If it's to be an isochronous endpoint, the hardware maximum packet size
00443     // increases to 1023 bytes, and we don't use handshaking.
00444     if (flags & ISOCHRONOUS) 
00445     {
00446         hwMaxPacket = 1023;
00447         handshake_flag = 0;
00448     }
00449 
00450     // limit the requested max packet size to the hardware limit
00451     if (maxPacket > hwMaxPacket)
00452         maxPacket = hwMaxPacket;
00453         
00454     ENTER_CRITICAL_SECTION
00455     {
00456         // if the endpoint buffer hasn't been allocated yet or was previously
00457         // allocated at a smaller size, allocate a new buffer        
00458         uint8_t *buf = endpoint_buffer[endpoint];
00459         if (buf == NULL || epMaxPacket[endpoint] < maxPacket)
00460         {
00461             // free any previous buffer
00462             if (buf != 0)
00463                 delete [] buf;
00464     
00465             // allocate at the new size
00466             endpoint_buffer[endpoint] = buf = new uint8_t[maxPacket];
00467             
00468             // set the new max packet size
00469             epMaxPacket[endpoint] = maxPacket;
00470         }
00471         
00472         // set the endpoint register flags and BDT entry
00473         if (IN_EP(endpoint)) 
00474         {
00475             // IN endpt -> device to host (TX)
00476             USB0->ENDPOINT[log_endpoint].ENDPT |= handshake_flag | USB_ENDPT_EPTXEN_MASK;  // en TX (IN) tran
00477             bdt[EP_BDT_IDX(log_endpoint, TX, EVEN)].address = (uint32_t) buf;
00478             bdt[EP_BDT_IDX(log_endpoint, TX, ODD )].address = 0;
00479         }
00480         else 
00481         {
00482             // OUT endpt -> host to device (RX)
00483             USB0->ENDPOINT[log_endpoint].ENDPT |= handshake_flag | USB_ENDPT_EPRXEN_MASK;  // en RX (OUT) tran.
00484             bdt[EP_BDT_IDX(log_endpoint, RX, EVEN)].address = (uint32_t) buf;
00485             bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].address = 0;
00486             
00487             // set up the first read
00488             bdt[EP_BDT_IDX(log_endpoint, RX, EVEN)].byte_count = maxPacket;
00489             bdt[EP_BDT_IDX(log_endpoint, RX, EVEN)].info       = BD_OWN_MASK | BD_DTS_MASK;
00490             bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].info       = 0;
00491         }
00492     
00493         // Set DATA1 on the endpoint.  For RX endpoints, we just queued up our first
00494         // read, which will always be a DATA0 packet, so the next read will use DATA1.
00495         // For TX endpoints, we always flip the bit *before* sending the packet, so
00496         // (counterintuitively) we need to set the DATA1 bit now to send DATA0 in the
00497         // next packet.  So in either case, we want DATA1 initially.
00498         Data1 |= (1 << endpoint);
00499         
00500         // mark the endpoint as realised
00501         epRealised |= (1 << endpoint);
00502     }
00503     EXIT_CRITICAL_SECTION
00504     
00505     // success
00506     return true;
00507 }
00508 
00509 // read setup packet
00510 void USBHAL::EP0setup(uint8_t *buffer) 
00511 {
00512     uint32_t sz;
00513     endpointReadResult(EP0OUT, buffer, &sz);
00514 }
00515 
00516 // Start reading the data stage of a SETUP transaction on EP0
00517 void USBHAL::EP0readStage(void) 
00518 {
00519     if (!(bdt[0].info & BD_OWN_MASK))
00520     {
00521         Data1 &= ~1UL;  // set DATA0
00522         bdt[0].byte_count = MAX_PACKET_SIZE_EP0;
00523         bdt[0].info = (BD_DTS_MASK | BD_OWN_MASK);
00524     }
00525 }
00526 
00527 // Read an OUT packet on EP0
00528 void USBHAL::EP0read(void) 
00529 {
00530     if (!(bdt[0].info & BD_OWN_MASK))
00531     {
00532         Data1 &= ~1UL;
00533         bdt[0].byte_count = MAX_PACKET_SIZE_EP0;
00534         bdt[0].info = (BD_DTS_MASK | BD_OWN_MASK);
00535     }
00536 }
00537 
00538 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) 
00539 {
00540     uint32_t sz;
00541     if (endpointReadResult(EP0OUT, buffer, &sz) == EP_COMPLETED) {
00542         return sz;
00543     }
00544     else {
00545         return 0;
00546     }
00547 }
00548 
00549 void USBHAL::EP0write(const volatile uint8_t *buffer, uint32_t size) 
00550 {
00551     endpointWrite(EP0IN, buffer, size);
00552 }
00553 
00554 void USBHAL::EP0getWriteResult(void) 
00555 {
00556 }
00557 
00558 void USBHAL::EP0stall(void) 
00559 {
00560     stallEndpoint(EP0OUT);
00561 }
00562 
00563 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) 
00564 {
00565     // We always start a new read when we fetch the result of the
00566     // previous read, so we don't have to do anything here.  Simply
00567     // indicate that the read is pending so that the caller can proceed
00568     // to check the results.
00569     return EP_PENDING;
00570 }
00571 
00572 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t *buffer, uint32_t *bytesRead) 
00573 {
00574     // validate the endpoint number and direction, and make sure it's realised
00575     if (endpoint >= NUMBER_OF_PHYSICAL_ENDPOINTS || !OUT_EP(endpoint))
00576         return EP_INVALID;
00577 
00578     // get the logical endpoint
00579     uint32_t log_endpoint = PHY_TO_LOG(endpoint);
00580     
00581     // get the mode - it's isochronous if it doesn't have the handshake flag
00582     bool iso = (USB0->ENDPOINT[log_endpoint].ENDPT & USB_ENDPT_EPHSHK_MASK) == 0;
00583     
00584     // get the BDT index
00585     int idx = EP_BDT_IDX(log_endpoint, RX, 0);
00586         
00587     // Check to see if the endpoint is ready to read
00588     if (log_endpoint == 0)
00589     {
00590         // control endpoint - just make sure we own the BDT
00591         if (bdt[idx].info & BD_OWN_MASK)
00592             return EP_PENDING;
00593     }
00594     else
00595     {
00596         // If it's not isochronous, check to see if we've received data, and
00597         // return PENDING if not.  Isochronous endpoints don't use the TOKNE 
00598         // interrupt (they use SOF instead), so the 'complete' flag doesn't
00599         // apply if it's an iso endpoint.
00600         if (!iso && !(epComplete & EP(endpoint)))
00601             return EP_PENDING;
00602     }
00603 
00604     EP_STATUS result = EP_INVALID;    
00605     ENTER_CRITICAL_SECTION
00606     {
00607         // proceed only if the endpoint has been realised
00608         if (epRealised & EP(endpoint))
00609         {
00610             // note if we have a SETUP token
00611             bool setup = (log_endpoint == 0 && TOK_PID(idx) == SETUP_TOKEN);
00612         
00613             // get the received data buffer and size
00614             uint8_t *ep_buf = endpoint_buffer[endpoint];
00615             uint32_t sz = bdt[idx].byte_count;
00616         
00617             // copy the data from the hardware receive buffer to the caller's buffer
00618             *bytesRead = sz;
00619             for (uint32_t n = 0 ; n < sz ; n++)
00620                 buffer[n] = ep_buf[n];
00621             
00622             // Figure the DATA0/DATA1 bit for the next packet received on this
00623             // endpoint.  The bit normally toggles on each packet, but it's
00624             // special for SETUP packets on endpoint 0.  The next OUT packet
00625             // after a SETUP packet with no data stage is always DATA0, even
00626             // if the SETUP packet was also DATA0.
00627             if (setup && (sz >= 7 && buffer[6] == 0)) {
00628                 // SETUP with no data stage -> next packet is always DATA0
00629                 Data1 &= ~1UL;
00630             }
00631             else {
00632                 // otherwise just toggle the last bit (assuming it matches our
00633                 // internal state - if not, we must be out of sync, so presumably
00634                 // *not* toggling our state will get us back in sync)
00635                 if (((Data1 >> endpoint) & 1) == ((bdt[idx].info >> 6) & 1))
00636                     Data1 ^= (1 << endpoint);
00637             }
00638         
00639             // set up the BDT entry to receive the next packet, and hand it to the SIE
00640             bdt[idx].byte_count = epMaxPacket[endpoint];
00641             bdt[idx].info = BD_DTS_MASK | BD_OWN_MASK | (((Data1 >> endpoint) & 1) << 6);
00642 
00643             // clear the SUSPEND TOKEN BUSY flag to allow token processing to continue
00644             USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
00645         
00646             // clear the 'completed' flag - we're now awaiting the next packet
00647             epComplete &= ~EP(endpoint);
00648             
00649             // the read is now complete
00650             result = EP_COMPLETED;
00651         }
00652     }
00653     EXIT_CRITICAL_SECTION
00654         
00655     return result;
00656 }
00657 
00658 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, const volatile uint8_t *data, uint32_t size) 
00659 {
00660     // validate the endpoint number and direction
00661     if (endpoint >= NUMBER_OF_PHYSICAL_ENDPOINTS || !IN_EP(endpoint))
00662         return EP_INVALID;
00663 
00664     // get the BDT index
00665     int idx = EP_BDT_IDX(PHY_TO_LOG(endpoint), TX, 0);
00666     
00667     EP_STATUS result = EP_INVALID;
00668     ENTER_CRITICAL_SECTION
00669     {
00670         // proceed only if the endpoint has been realised and we own the BDT
00671         if ((epRealised & EP(endpoint)) && !(bdt[idx].info & BD_OWN_MASK))
00672         {
00673             // get the endpoint buffer
00674             uint8_t *ep_buf = endpoint_buffer[endpoint];
00675         
00676             // copy the data to the hardware buffer
00677             bdt[idx].byte_count = size;
00678             for (uint32_t n = 0 ; n < size ; n++)
00679                 ep_buf[n] = data[n];
00680             
00681             // toggle DATA0/DATA1 before sending
00682             Data1 ^= (1 << endpoint);
00683     
00684             // hand the BDT to the SIE to do the send
00685             bdt[idx].info = BD_OWN_MASK | BD_DTS_MASK | (((Data1 >> endpoint) & 1) << 6);
00686 
00687             // write is now pending in the hardware
00688             result = EP_PENDING;
00689         }
00690     }
00691     EXIT_CRITICAL_SECTION
00692     
00693     return result;
00694 }
00695 
00696 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) 
00697 {
00698     // assume write is still pending
00699     EP_STATUS result = EP_PENDING;
00700     
00701     ENTER_CRITICAL_SECTION
00702     {
00703         // If the endpoint isn't realised, the result is 'invalid'.  Otherwise,
00704         // check the 'completed' flag: if set, the write is completed.
00705         if (!(epRealised & EP(endpoint)))
00706         {
00707             // endpoint isn't realised - can't read it
00708             result = EP_INVALID;
00709         }
00710         else if (epComplete & EP(endpoint)) 
00711         {
00712             // the result is COMPLETED
00713             result = EP_COMPLETED;
00714 
00715             // clear the 'completed' flag - this is consumed by fetching the result
00716             epComplete &= ~EP(endpoint);
00717         }
00718     }
00719     EXIT_CRITICAL_SECTION
00720     
00721     // return the result
00722     return result;
00723 }
00724 
00725 void USBHAL::stallEndpoint(uint8_t endpoint) 
00726 {
00727     ENTER_CRITICAL_SECTION
00728     {
00729         if (epRealised & EP(endpoint))
00730             USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT |= USB_ENDPT_EPSTALL_MASK;
00731     }
00732     EXIT_CRITICAL_SECTION
00733 }
00734 
00735 void USBHAL::unstallEndpoint(uint8_t endpoint) 
00736 {
00737     ENTER_CRITICAL_SECTION
00738     {
00739         if (epRealised & EP(endpoint))
00740         {
00741             // clear the stall bit in the endpoint register
00742             USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT &= ~USB_ENDPT_EPSTALL_MASK;
00743             
00744             // take ownership of the BDT entry
00745             int idx = PEP_BDT_IDX(endpoint, 0);
00746             bdt[idx].info &= ~(BD_OWN_MASK | BD_STALL_MASK | BD_DATA01_MASK);
00747             
00748             // if this is an RX endpoint, start a new read
00749             if (OUT_EP(endpoint))
00750             {
00751                 bdt[idx].byte_count = epMaxPacket[endpoint];
00752                 bdt[idx].info = BD_OWN_MASK | BD_DTS_MASK;
00753             }
00754     
00755             // Reset Data1 for the endpoint - we need to set the bit to 1 for 
00756             // either TX or RX, by the same logic as in realiseEndpoint()
00757             Data1 |= (1 << endpoint);
00758             
00759             // clear the 'completed' bit for the endpoint
00760             epComplete &= ~(1 << endpoint);
00761         }
00762     }
00763     EXIT_CRITICAL_SECTION
00764 }
00765 
00766 void USBHAL_KL25Z_unstall_EP0(bool force)
00767 {
00768     ENTER_CRITICAL_SECTION
00769     {
00770         if (force || (USB0->ENDPOINT[0].ENDPT & USB_ENDPT_EPSTALL_MASK))
00771         {
00772             // clear the stall bit in the endpoint register
00773             USB0->ENDPOINT[0].ENDPT &= ~USB_ENDPT_EPSTALL_MASK;
00774         
00775             // take ownership of the RX and TX BDTs
00776             bdt[EP_BDT_IDX(0, RX, EVEN)].info &= ~(BD_OWN_MASK | BD_STALL_MASK | BD_DATA01_MASK);
00777             bdt[EP_BDT_IDX(0, TX, EVEN)].info &= ~(BD_OWN_MASK | BD_STALL_MASK | BD_DATA01_MASK);
00778             bdt[EP_BDT_IDX(0, RX, EVEN)].byte_count = MAX_PACKET_SIZE_EP0;
00779             bdt[EP_BDT_IDX(0, TX, EVEN)].byte_count = MAX_PACKET_SIZE_EP0;
00780 
00781             // start a new read on EP0OUT
00782             bdt[EP_BDT_IDX(0, RX, EVEN)].info = BD_OWN_MASK | BD_DTS_MASK;
00783 
00784             // reset the DATA0/1 bit to 1 on EP0IN and EP0OUT, by the same 
00785             // logic as in realiseEndpoint()            
00786             Data1 |= 0x03;
00787         }
00788     }
00789     EXIT_CRITICAL_SECTION
00790 }
00791 
00792 bool USBHAL::getEndpointStallState(uint8_t endpoint) 
00793 {
00794     uint8_t stall = (USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT & USB_ENDPT_EPSTALL_MASK);
00795     return (stall) ? true : false;
00796 }
00797 
00798 void USBHAL::remoteWakeup(void) 
00799 {
00800     // [TODO]
00801 }
00802 
00803 // Internal reset handler.  Called when we get a Bus Reset signal
00804 // from the host, and when we initiate a reset of the SIE hardware
00805 // from the device side.
00806 void USBHAL::internalReset(void)
00807 {
00808     ENTER_CRITICAL_SECTION
00809     {
00810         int i;
00811         
00812         // set the default bus address
00813         USB0->ADDR = 0x00;
00814         addr = 0;
00815         set_addr = 0;
00816         
00817         // disable all endpoints
00818         epRealised = 0x00;
00819         for (i = 0 ; i < 16 ; i++)
00820             USB0->ENDPOINT[i].ENDPT = 0x00;
00821     
00822         // take control of all BDTs away from the SIE
00823         for (i = 0 ; i < sizeof(bdt)/sizeof(bdt[0]) ; ++i) 
00824         {
00825             bdt[i].info = 0;
00826             bdt[i].byte_count = 0;
00827         }
00828             
00829         // reset DATA0/1 state
00830         Data1 = 0x55555555;
00831     
00832         // reset endpoint completion status
00833         epComplete = 0;
00834     
00835         // reset EVEN/ODD state (and keep it permanently on EVEN -
00836         // this disables the hardware double-buffering system)
00837         USB0->CTL |= USB_CTL_ODDRST_MASK;
00838         
00839         // reset error status and enable all error interrupts
00840         USB0->ERRSTAT = 0xFF;
00841         USB0->ERREN = 0xFF;
00842         
00843         // enable our standard complement of interrupts
00844         USB0->INTEN = BUS_RESET_INTERRUPTS;
00845         
00846         // we're not suspended
00847         suspendStateChanged(0);
00848         
00849         // we're not sleeping
00850         sleepStateChanged(0);
00851     
00852         // notify upper layers of the bus reset, to reset the protocol state
00853         busReset();
00854         
00855         // realise the control endpoint (EP0) in both directions
00856         realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0);
00857         realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0);
00858     }
00859     EXIT_CRITICAL_SECTION
00860 }
00861 
00862 void USBHAL::_usbisr(void) 
00863 {
00864     inIRQ = true;
00865     instance->usbisr();
00866     inIRQ = false;
00867 }
00868 
00869 void USBHAL::usbisr(void) 
00870 {
00871     // get the interrupt status - this tells us which event(s)
00872     // triggered this interrupt
00873     uint8_t istat = USB0->ISTAT;
00874        
00875     // reset interrupt
00876     if (istat & USB_ISTAT_USBRST_MASK) 
00877     {
00878         // do the internal reset work
00879         internalReset();
00880         
00881         // resume token processing if it was suspended
00882         USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
00883         
00884         // clear the interrupt status
00885         USB0->ISTAT = USB_ISTAT_USBRST_MASK;
00886         
00887         // return immediately, ignoring any other status flags
00888         return;
00889     }
00890     
00891     // token interrupt
00892     if (istat & USB_ISTAT_TOKDNE_MASK) 
00893     {
00894         // get the endpoint information from the status register
00895         uint32_t stat = USB0->STAT;
00896         uint32_t num  = (stat >> 4) & 0x0F;
00897         uint32_t dir  = (stat >> 3) & 0x01;
00898         int endpoint = (num << 1) | dir;
00899         uint32_t ev_odd = (stat >> 2) & 0x01;
00900         
00901         // check which endpoint we're working with
00902         if (num == 0)
00903         {
00904             // Endpoint 0 requires special handling
00905             uint32_t idx = EP_BDT_IDX(num, dir, ev_odd);
00906             int pid = TOK_PID(idx);
00907             if (pid == SETUP_TOKEN)
00908             {
00909                 // SETUP packet - next IN (TX) packet must be DATA1 (confusingly,
00910                 // this means we must clear the Data1 bit, since we flip the bit
00911                 // before each send)
00912                 Data1 &= ~0x02;
00913                 
00914                 // Forcibly take ownership of the EP0IN BDT in case we have
00915                 // unfinished previous transmissions.  The protocol state machine
00916                 // assumes that we don't, so it's probably an error if this code
00917                 // actually does anything, but just in case...
00918                 bdt[EP_BDT_IDX(0, TX, EVEN)].info &= ~BD_OWN_MASK;
00919 
00920                 // handle the EP0 SETUP event in the generic protocol layer
00921                 EP0setupCallback();
00922             } 
00923             else if (pid == OUT_TOKEN)
00924             {
00925                 // OUT packet on EP0
00926                 EP0out();
00927             }
00928             else if (pid == IN_TOKEN)
00929             {
00930                 // IN packet on EP0
00931                 EP0in();
00932                 
00933                 // Special case: if the 'set address' flag is set, it means that the
00934                 // host just sent us our bus address.  We must put this into effect
00935                 // in the hardware SIE immediately after sending the reply.  We just
00936                 // did that above, so this is the time.
00937                 if (set_addr) {
00938                     USB0->ADDR = addr & 0x7F;
00939                     set_addr = 0;
00940                 }
00941             }
00942         }
00943         else
00944         {
00945             // For all other endpoints, note the read/write completion in the flags
00946             epComplete |= EP(endpoint);
00947             
00948             // call the endpoint token callback; if that handles the token, it consumes
00949             // the 'completed' status, so clear that flag again
00950             if ((instance->*(epCallback[endpoint - 2]))()) {
00951                 epComplete &= ~EP(endpoint);
00952             }
00953         }
00954 
00955         // resume token processing if suspended
00956         USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
00957 
00958         // clear the TOKDNE interrupt status bit
00959         USB0->ISTAT = USB_ISTAT_TOKDNE_MASK;
00960         return;
00961     }
00962 
00963     // SOF interrupt
00964     if (istat & USB_ISTAT_SOFTOK_MASK) 
00965     {
00966         // Read frame number and signal the SOF event to the callback
00967         SOF(frameNumber());
00968         USB0->ISTAT = USB_ISTAT_SOFTOK_MASK;
00969     }
00970 
00971     // stall interrupt
00972     if (istat & USB_ISTAT_STALL_MASK)
00973     {
00974         // if the control endpoint (EP 0) is stalled, unstall it
00975         USBHAL_KL25Z_unstall_EP0(false);
00976         
00977         // clear the busy-suspend bit to resume token processing
00978         USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
00979         
00980         // clear the interrupt status bit for STALL
00981         USB0->ISTAT = USB_ISTAT_STALL_MASK;
00982     }
00983 
00984     // Sleep interrupt.  This indicates that the USB bus has been
00985     // idle for at least 3ms (no frames transacted).  This has
00986     // several possible causes:
00987     //
00988     //  - The USB cable was unplugged
00989     //  - The host was powered off
00990     //  - The host has stopped communicating due to a software fault
00991     //  - The host has stopped communicating deliberately (e.g., due
00992     //    to user action, or due to a protocol error)
00993     //
00994     // A "sleep" event on the SIE is not to be confused with the
00995     // sleep/suspend power state on the PC.  The sleep event here
00996     // simply means that the SIE isn't seeing token traffic on the
00997     // required schedule.
00998     //
00999     // Note that the sleep event is the closest thing the KL25Z USB 
01000     // module has to a disconnect event.  There's no way to detect 
01001     // if we're physically connected to a host, so all we can really
01002     // know is that we're not transacting tokens.  USB requires token
01003     // exchange every 1ms, so if there's no token exchange for a few
01004     // milliseconds, the connection must be broken at some level.
01005     if (istat & USB_ISTAT_SLEEP_MASK) 
01006     {
01007         // tell the upper layers about the change
01008         sleepStateChanged(1);
01009 
01010         // resume token processing
01011         USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
01012 
01013         // reset the interrupt bit
01014         USB0->ISTAT = USB_ISTAT_SLEEP_MASK;
01015     }
01016 
01017     // Resume from suspend mode.
01018     //
01019     // NB: Don't confuse "suspend" with "sleep".  Suspend mode refers 
01020     // to a hardware low-power mode initiated by the device.  "Sleep"
01021     // means only that the USB connection has been idle (no tokens
01022     // transacted) for more than 3ms.  A sleep signal means that the
01023     // connection with the host was broken, either physically or 
01024     // logically; it doesn't of itself have anything to do with suspend
01025     // mode, and in particular it doesn't mean that the host has
01026     // commanded us to enter suspend mode or told us that the host
01027     // is entering a low-power state.  The higher-level device
01028     // implementation might choose to enter suspend mode on the device
01029     // in response to a lost connection, but the USB/HAL layers don't
01030     // take any such action on their own.  Note that suspend mode can
01031     // only end with explicit intervention by the host, in the form of
01032     // a USB RESUME signal, so the host has to be aware that we're
01033     // doing this sort of power management.
01034     if (istat & USB_ISTAT_RESUME_MASK) 
01035     {
01036         // note the change
01037         suspendStateChanged(0);
01038 
01039         // remove suspend mode flags
01040         USB0->USBCTRL &= ~USB_USBCTRL_SUSP_MASK;
01041         USB0->USBTRC0 &= ~USB_USBTRC0_USBRESMEN_MASK;
01042         USB0->INTEN &= ~USB_INTEN_RESUMEEN_MASK;
01043         
01044         // clear the interrupt status
01045         USB0->ISTAT = USB_ISTAT_RESUME_MASK;
01046     }
01047 
01048     // error interrupt
01049     if (istat & USB_ISTAT_ERROR_MASK) 
01050     {
01051         // reset all error status bits, and clear the SUSPEND flag to allow
01052         // token processing to continue
01053         USB0->ERRSTAT = 0xFF;
01054         USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
01055         USB0->ISTAT = USB_ISTAT_ERROR_MASK;
01056     }
01057 }
01058 
01059 #endif