diff options
| author | hathach <[email protected]> | 2012-11-28 11:53:23 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2012-11-28 11:53:23 +0700 |
| commit | 851f5bfd06c837626ddf06f1c326970763d07010 (patch) | |
| tree | f8d2b65856ef7d9eb6e0f9ffd8e67ec0c46789f7 /tinyusb | |
| parent | a5eecb40555d5053393dd3d0916fa63bfa9a6b18 (diff) | |
make keyboard device work with lpc1347
Diffstat (limited to 'tinyusb')
| -rw-r--r-- | tinyusb/class/hid.c | 337 | ||||
| -rw-r--r-- | tinyusb/class/hid.h | 142 | ||||
| -rw-r--r-- | tinyusb/common/common.h | 2 | ||||
| -rw-r--r-- | tinyusb/common/fifo.c | 212 | ||||
| -rw-r--r-- | tinyusb/common/fifo.h | 76 | ||||
| -rw-r--r-- | tinyusb/device/dcd.c | 99 | ||||
| -rw-r--r-- | tinyusb/tusb_cfg.h | 4 |
7 files changed, 860 insertions, 12 deletions
diff --git a/tinyusb/class/hid.c b/tinyusb/class/hid.c new file mode 100644 index 000000000..21871d284 --- /dev/null +++ b/tinyusb/class/hid.c @@ -0,0 +1,337 @@ +/* + * hid.c + * + * Created on: Nov 27, 2012 + * Author: hathach ([email protected]) + */ + +/* + * Software License Agreement (BSD License) + * Copyright (c) 2012, hathach ([email protected]) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the tiny usb stack. + */ + +#include "hid.h" +//#include "../systick/systick.h" + +#ifdef CLASS_HID + +#ifdef CFG_CLASS_HID_KEYBOARD +USB_HID_KeyboardReport_t hid_keyboard_report; +volatile static bool bKeyChanged = false; +#endif + +#ifdef CFG_USB_HID_MOUSE +USB_HID_MouseReport_t hid_mouse_report; +volatile static bool bMouseChanged = false; +#endif + +/**************************************************************************/ +/*! + @brief Handler for HID_GetReport in the USB ROM driver +*/ +/**************************************************************************/ +ErrorCode_t HID_GetReport( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t* plength) +{ + USB_HID_CTRL_T* pHidCtrl = (USB_HID_CTRL_T*) hHid; + + /* ReportID = SetupPacket.wValue.WB.L; */ + if (pSetup->wValue.WB.H == HID_REPORT_INPUT) + return (ERR_USBD_STALL); /* Not Supported */ + + switch (pHidCtrl->protocol) + { + #ifdef CFG_CLASS_HID_KEYBOARD + case HID_PROTOCOL_KEYBOARD: + *pBuffer = (uint8_t*) &hid_keyboard_report; + *plength = sizeof(USB_HID_KeyboardReport_t); + + if (!bKeyChanged) + { + memset(pBuffer, 0, *plength); + } + bKeyChanged = false; + break; + #endif + + #ifdef CFG_USB_HID_MOUSE + case HID_PROTOCOL_MOUSE: + *pBuffer = (uint8_t*) &hid_mouse_report; + *plength = sizeof(USB_HID_MouseReport_t); + + if (!bMouseChanged) + { + memset(pBuffer, 0, *plength); + } + bMouseChanged = false; + break; + #endif + + default: + break; + } + + return (LPC_OK); +} + +/**************************************************************************/ +/*! + @brief Handler for HIS_SetReport in the USB ROM driver +*/ +/**************************************************************************/ +ErrorCode_t HID_SetReport( USBD_HANDLE_T hHid, USB_SETUP_PACKET* pSetup, uint8_t** pBuffer, uint16_t length) +{ + /* we will reuse standard EP0Buf */ + if (length == 0) + return LPC_OK; + + /* ReportID = SetupPacket.wValue.WB.L; */ + if (pSetup->wValue.WB.H != HID_REPORT_OUTPUT) + return (ERR_USBD_STALL); /* Not Supported */ + + return (LPC_OK); +} + +/**************************************************************************/ +/*! + @brief HID endpoint in handler for the USB ROM driver +*/ +/**************************************************************************/ +ErrorCode_t HID_EpIn_Hdlr (USBD_HANDLE_T hUsb, void* data, uint32_t event) +{ + if (USB_EVT_IN == event) + { + USB_HID_CTRL_T* pHidCtrl = (USB_HID_CTRL_T*)data; + switch(pHidCtrl->protocol) + { + #ifdef CFG_CLASS_HID_KEYBOARD + case HID_PROTOCOL_KEYBOARD: + if (!bKeyChanged) + { + memset(&hid_keyboard_report, 0, sizeof(USB_HID_KeyboardReport_t)); + } + USBD_API->hw->WriteEP(hUsb, pHidCtrl->epin_adr, (uint8_t*) &hid_keyboard_report, sizeof(USB_HID_KeyboardReport_t)); + bKeyChanged = false; + break; + #endif + + #ifdef CFG_USB_HID_MOUSE + case HID_PROTOCOL_MOUSE: + if (!bMouseChanged) + { + memset(&hid_mouse_report, 0, sizeof(USB_HID_MouseReport_t)); + } + USBD_API->hw->WriteEP(hUsb, pHidCtrl->epin_adr, (uint8_t*) &hid_mouse_report, sizeof(USB_HID_MouseReport_t)); + bMouseChanged = false; + break; + #endif + + default: + break; + } + } + + return LPC_OK; +} + +/**************************************************************************/ +/*! + @brief HID endpoint out handler for the USB ROM driver +*/ +/**************************************************************************/ +ErrorCode_t HID_EpOut_Hdlr (USBD_HANDLE_T hUsb, void* data, uint32_t event) +{ + if (USB_EVT_OUT == event) + { + // not used yet + // uint8_t outreport[8]; + // USB_HID_CTRL_T* pHidCtrl = (USB_HID_CTRL_T*)data; + // USBD_API->hw->ReadEP(hUsb, pHidCtrl->epout_adr, outreport); + } + return LPC_OK; +} + +/**************************************************************************/ +/*! + @brief Initialises USB HID using the ROM based drivers +*/ +/**************************************************************************/ +ErrorCode_t usb_hid_init(USBD_HANDLE_T hUsb, USB_INTERFACE_DESCRIPTOR const *const pIntfDesc, uint8_t const * const pHIDReportDesc, uint32_t ReportDescLength, uint32_t* mem_base, uint32_t* mem_size) +{ + USB_HID_REPORT_T reports_data = + { + .desc = (uint8_t*) pHIDReportDesc, + .len = ReportDescLength, + .idle_time = 0, + }; + + USBD_HID_INIT_PARAM_T hid_param = + { + .mem_base = *mem_base, + .mem_size = *mem_size, + + .intf_desc = (uint8_t*)pIntfDesc, + .report_data = &reports_data, + .max_reports = 1, + + /* user defined functions */ + .HID_GetReport = HID_GetReport, + .HID_SetReport = HID_SetReport, + .HID_EpIn_Hdlr = HID_EpIn_Hdlr, + .HID_EpOut_Hdlr = HID_EpOut_Hdlr + }; + + ASSERT( (pIntfDesc != NULL) && (pIntfDesc->bInterfaceClass == USB_DEVICE_CLASS_HUMAN_INTERFACE), ERR_FAILED); + + ASSERT_STATUS( USBD_API->hid->init(hUsb, &hid_param) ); + + /* update memory variables */ + *mem_base = hid_param.mem_base; + *mem_size = hid_param.mem_size; + + return LPC_OK; +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +ErrorCode_t usb_hid_configured(USBD_HANDLE_T hUsb) +{ + #ifdef CFG_CLASS_HID_KEYBOARD + USBD_API->hw->WriteEP(hUsb , HID_KEYBOARD_EP_IN , (uint8_t* ) &hid_keyboard_report , sizeof(USB_HID_KeyboardReport_t) ); // initial packet for IN endpoint , will not work if omitted + #endif + + #ifdef CFG_USB_HID_MOUSE + USBD_API->hw->WriteEP(hUsb , HID_MOUSE_EP_IN , (uint8_t* ) &hid_mouse_report , sizeof(USB_HID_MouseReport_t) ); // initial packet for IN endpoint, will not work if omitted + #endif + + return LPC_OK; +} + +#ifdef CFG_CLASS_HID_KEYBOARD +/**************************************************************************/ +/*! + @brief Send the supplied key codes out via HID USB keyboard emulation + + @param[in] modifier + KB modifier code bits (see USB_HID_KB_KEYMODIFIER_CODE) + @param[in] keycodes + A buffer containing up to six keycodes + @param[in] numkey + The number of keys to send (max 6) + + @note Note that for HID KBs, letter codes are not case sensitive. To + create an upper-case letter, you need to include the correct + KB modifier code(s), for ex: (1 << HID_KEYMODIFIER_LEFTSHIFT) + + @section EXAMPLE + + @code + + // Send an unmodified 'a' character + if (usb_isConfigured()) + { + uint8_t keys[6] = {HID_USAGE_KEYBOARD_aA}; + usb_hid_keyboard_sendKeys(0x00, keys, 1); + } + + // Send Windows + 'e' (shortcut for 'explorer.exe') + if (usb_isConfigured()) + { + uint8_t keys[6] = {HID_USAGE_KEYBOARD_aA + 'e' - 'a'}; + usb_hid_keyboard_sendKeys((1<<HID_KEYMODIFIER_LEFTGUI), keys, 1); + } + + @endcode +*/ +/**************************************************************************/ +ErrorCode_t usb_hid_keyboard_sendKeys(uint8_t modifier, uint8_t keycodes[], uint8_t numkey) +{ + uint32_t start_time = systickGetSecondsActive(); + while (bKeyChanged) // TODO blocking while previous key has yet sent - can use fifo to improve this + { + ASSERT_MESSAGE(systickGetSecondsActive() - start_time < 5, ERR_FAILED, "HID Keyboard Timeout"); + } + ASSERT(keycodes && numkey && numkey <=6, ERR_FAILED); + + hid_keyboard_report.Modifier = modifier; + memset(hid_keyboard_report.KeyCode, 0, 6); + memcpy(hid_keyboard_report.KeyCode, keycodes, numkey); + + bKeyChanged = true; + + return LPC_OK; +} +#endif + +#ifdef CFG_USB_HID_MOUSE +/**************************************************************************/ +/*! + @brief Send the supplied mouse event out via HID USB mouse emulation + + @param[in] buttons + Indicate which button(s) are being pressed (see + USB_HID_MOUSE_BUTTON_CODE) + @param[in] x + Position adjustment on the X scale + @param[in] y + Position adjustment on the Y scale + + @section EXAMPLE + + @code + + if (usb_isConfigured()) + { + // Move the mouse +10 in the X direction and + 10 in the Y direction + usb_hid_mouse_send(0x00, 10, 10); + } + + @endcode +*/ +/**************************************************************************/ +ErrorCode_t usb_hid_mouse_send(uint8_t buttons, int8_t x, int8_t y) +{ + uint32_t start_time = systickGetSecondsActive(); + while (bMouseChanged) // TODO Block while previous key hasn't been sent - can use fifo to improve this + { + ASSERT_MESSAGE(systickGetSecondsActive() - start_time < 5, ERR_FAILED, "HID Mouse Timeout"); + } + + hid_mouse_report.Button = buttons; + hid_mouse_report.X = x; + hid_mouse_report.Y = y; + + bMouseChanged = true; + + return LPC_OK; +} +#endif + +#endif diff --git a/tinyusb/class/hid.h b/tinyusb/class/hid.h new file mode 100644 index 000000000..8ba5eea77 --- /dev/null +++ b/tinyusb/class/hid.h @@ -0,0 +1,142 @@ +/* + * hid.h + * + * Created on: Nov 27, 2012 + * Author: hathach ([email protected]) + */ + +/* + * Software License Agreement (BSD License) + * Copyright (c) 2012, hathach ([email protected]) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the tiny usb stack. + */ + +#ifndef _TUSB_HID_H_ +#define _TUSB_HID_H_ + +#ifdef __cplusplus + extern "C" { +#endif + + // TODO refractor +#include "common/common.h" +#include "device/dcd.h" + +ErrorCode_t usb_hid_init(USBD_HANDLE_T hUsb, USB_INTERFACE_DESCRIPTOR const *const pIntfDesc, uint8_t const * const pHIDReportDesc, uint32_t ReportDescLength, uint32_t* mem_base, uint32_t* mem_size); +ErrorCode_t usb_hid_configured(USBD_HANDLE_T hUsb); + +ErrorCode_t usb_hid_keyboard_sendKeys(uint8_t modifier, uint8_t keycodes[], uint8_t numkey); +ErrorCode_t usb_hid_mouse_send(uint8_t buttons, int8_t x, int8_t y); + +/** \brief Standard HID Boot Protocol Mouse Report. + * + * Type define for a standard Boot Protocol Mouse report + */ +typedef PRE_PACK struct +{ + uint8_t Button; /**< Button mask for currently pressed buttons in the mouse. */ + int8_t X; /**< Current delta X movement of the mouse. */ + int8_t Y; /**< Current delta Y movement on the mouse. */ +} POST_PACK USB_HID_MouseReport_t; + +/** \brief Standard HID Boot Protocol Keyboard Report. + * + * Type define for a standard Boot Protocol Keyboard report + */ +typedef PRE_PACK struct +{ + uint8_t Modifier; /**< Keyboard modifier byte, indicating pressed modifier keys (a combination of HID_KEYBOARD_MODIFER_* masks). */ + uint8_t Reserved; /**< Reserved for OEM use, always set to 0. */ + uint8_t KeyCode[6]; /**< Key codes of the currently pressed keys. */ +} POST_PACK USB_HID_KeyboardReport_t; + +/* Button codes for HID mouse */ +enum USB_HID_MOUSE_BUTTON_CODE +{ + HID_MOUSEBUTTON_RIGHT = 0, + HID_MOUSEBUTTON_LEFT = 1, + HID_MOUSEBUTTON_MIDDLE = 2 +}; + +/* KB modifier codes for HID KB */ +enum USB_HID_KB_KEYMODIFIER_CODE +{ + HID_KEYMODIFIER_LEFTCTRL = 0, + HID_KEYMODIFIER_LEFTSHIFT, + HID_KEYMODIFIER_LEFTALT, + HID_KEYMODIFIER_LEFTGUI, + HID_KEYMODIFIER_RIGHTCTRL, + HID_KEYMODIFIER_RIGHTSHIFT, + HID_KEYMODIFIER_RIGHTALT, + HID_KEYMODIFIER_RIGHTGUI +}; + +enum USB_HID_LOCAL_CODE +{ + HID_Local_NotSupported = 0, + HID_Local_Arabic, + HID_Local_Belgian, + HID_Local_Canadian_Bilingual, + HID_Local_Canadian_French, + HID_Local_Czech_Republic, + HID_Local_Danish, + HID_Local_Finnish, + HID_Local_French, + HID_Local_German, + HID_Local_Greek, + HID_Local_Hebrew, + HID_Local_Hungary, + HID_Local_International, + HID_Local_Italian, + HID_Local_Japan_Katakana, + HID_Local_Korean, + HID_Local_Latin_American, + HID_Local_Netherlands_Dutch, + HID_Local_Norwegian, + HID_Local_Persian_Farsi, + HID_Local_Poland, + HID_Local_Portuguese, + HID_Local_Russia, + HID_Local_Slovakia, + HID_Local_Spanish, + HID_Local_Swedish, + HID_Local_Swiss_French, + HID_Local_Swiss_German, + HID_Local_Switzerland, + HID_Local_Taiwan, + HID_Local_Turkish_Q, + HID_Local_UK, + HID_Local_US, + HID_Local_Yugoslavia, + HID_Local_Turkish_F +}; + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_HID_H__ */ diff --git a/tinyusb/common/common.h b/tinyusb/common/common.h index de87ca1a8..1405b7605 100644 --- a/tinyusb/common/common.h +++ b/tinyusb/common/common.h @@ -51,7 +51,7 @@ #include "errors.h" //#if ( defined CFG_PRINTF_UART || defined CFG_PRINTF_USBCDC || defined CFG_PRINTF_DEBUG ) -#if 1 +#if 1 // TODO refractor ASSERT #define PRINTF_LOCATION(mess) printf("Assert: %s at line %d: %s\n", __func__, __LINE__, mess) #else #define PRINTF_LOCATION(mess) diff --git a/tinyusb/common/fifo.c b/tinyusb/common/fifo.c new file mode 100644 index 000000000..1a8d3cce5 --- /dev/null +++ b/tinyusb/common/fifo.c @@ -0,0 +1,212 @@ +/* + * fifo.c + * + * Created on: Nov 27, 2012 + * Author: hathach ([email protected]) + */ + +/* + * Software License Agreement (BSD License) + * Copyright (c) 2012, hathach ([email protected]) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the tiny usb stack. + */ + +#include "fifo.h" + +/**************************************************************************/ +/*! + @brief Disables the IRQ specified in the FIFO's 'irq' field + to prevent reads/write issues with interrupts + + @param[in] f + Pointer to the FIFO that should be protected +*/ +/**************************************************************************/ +static inline void mutex_lock (fifo_t* f) +{ + if (f->irq > 0) + NVIC_DisableIRQ(f->irq); +} + +/**************************************************************************/ +/*! + @brief Re-enables the IRQ specified in the FIFO's 'irq' field + + @param[in] f + Pointer to the FIFO that should be protected +*/ +/**************************************************************************/ +static inline void mutex_unlock (fifo_t* f) +{ + if (f->irq > 0) + NVIC_EnableIRQ(f->irq); +} + +/**************************************************************************/ +/*! + @brief Initialises the FIFO buffer + + @param[in] f + Pointer to the fifo_t object to intiialize + @param[in] buffer + Pointer to the buffer's location in memory + @param[in] size + The buffer size in bytes + @param[in] overwritable + Set to TRUE is the FIFO is overwritable when the FIFO + is full (the first element will be overwritten) + @param[in] irq + The IRQ number to disable for MUTEX protection. + Set the -1 if not required. +*/ +/**************************************************************************/ +void fifo_init(fifo_t* f, uint8_t* buffer, uint16_t size, bool overwritable, IRQn_Type irq) +{ + f->buf = buffer; + f->size = size; + f->rd_ptr = f->wr_ptr = f->len = 0; + f->overwritable = overwritable; + f->irq = irq; +} + +/**************************************************************************/ +/*! + @brief Read one byte out of the RX buffer. + + This function will return the byte located at the array index of the + read pointer, and then increment the read pointer index. If the read + pointer exceeds the maximum buffer size, it will roll over to zero. + + @param[in] f + Pointer to the FIFO buffer to manipulate + @param[in] data + Pointer to the place holder for data read from the buffer + + @returns TRUE if the queue is not empty +*/ +/**************************************************************************/ +bool fifo_read(fifo_t* f, uint8_t *data) +{ + if (fifo_isEmpty(f)) + return false; + + mutex_lock(f); + + *data = f->buf[f->rd_ptr]; + f->rd_ptr = (f->rd_ptr + 1) % f->size; + f->len--; + + mutex_unlock(f); + + return true; +} + +/**************************************************************************/ +/*! + @brief Read a byte array from FIFO + + @param[in] f + Pointer to the FIFO buffer to manipulate + @param[in] rx + Pointer to the place holder for data read from the buffer + @param[in] maxlen + The maximum number of bytes to read from the FIFO + + @returns The actual number of bytes read from the FIFO + */ +/**************************************************************************/ +uint16_t fifo_readArray(fifo_t* f, uint8_t* rx, uint16_t maxlen) +{ + uint16_t len = 0; + + while ( len < maxlen && fifo_read(f, rx) ) + { + len++; + rx++; + } + + return len; +} + +/**************************************************************************/ +/*! + @brief Write one byte into the RX buffer. + + This function will write one byte into the array index specified by + the write pointer and increment the write index. If the write index + exceeds the max buffer size, then it will roll over to zero. + + @param[in] f + Pointer to the FIFO buffer to manipulate + @param[in] data + The byte to add to the FIFO + + @returns TRUE if the data was written to the FIFO (overwrittable + FIFO will always return TRUE) +*/ +/**************************************************************************/ +bool fifo_write(fifo_t* f, uint8_t data) +{ + if ( fifo_isFull(f) && f->overwritable == false) + return false; + + mutex_lock(f); + + f->buf[f->wr_ptr] = data; + f->wr_ptr = (f->wr_ptr + 1) % f->size; + + if (fifo_isFull(f)) + { + f->rd_ptr = f->wr_ptr; // keep the full state (rd == wr && len = size) + }else + { + f->len++; + } + + mutex_unlock(f); + + return true; +} + +/**************************************************************************/ +/*! + @brief Clear the fifo read and write pointers and set length to zero + + @param[in] f + Pointer to the FIFO buffer to manipulate +*/ +/**************************************************************************/ +void fifo_clear(fifo_t *f) +{ + mutex_lock(f); + + f->rd_ptr = 0; + f->wr_ptr = 0; + f->len = 0; + + mutex_unlock(f); +} diff --git a/tinyusb/common/fifo.h b/tinyusb/common/fifo.h new file mode 100644 index 000000000..1019c8bde --- /dev/null +++ b/tinyusb/common/fifo.h @@ -0,0 +1,76 @@ +/* + * fifo.h + * + * Created on: Nov 27, 2012 + * Author: hathach ([email protected]) + */ + +/* + * Software License Agreement (BSD License) + * Copyright (c) 2012, hathach ([email protected]) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the tiny usb stack. + */ + +#ifndef _TUSB_FIFO_H_ +#define _TUSB_FIFO_H_ + +#include "common/common.h" + +/* ToDo: Describe each field in fifo_t */ +typedef struct _fifo_t +{ + uint8_t* buf; + uint16_t size; + volatile uint16_t len; + volatile uint16_t wr_ptr; + volatile uint16_t rd_ptr; + bool overwritable; + IRQn_Type irq; +} fifo_t; + +void fifo_init(fifo_t* f, uint8_t* buffer, uint16_t size, bool overwritable, IRQn_Type irq); +bool fifo_write(fifo_t* f, uint8_t data); +bool fifo_read(fifo_t* f, uint8_t *data); +uint16_t fifo_readArray(fifo_t* f, uint8_t * rx, uint16_t maxlen); +void fifo_clear(fifo_t*); + +static inline bool fifo_isEmpty(fifo_t* f) +{ + return (f->len == 0); +} + +static inline bool fifo_isFull(fifo_t* f) +{ + return (f->len == f->size); +} + +static inline uint16_t fifo_getLength(fifo_t* f) +{ + return f->len; +} + +#endif /* _TUSB_FIFO_H_ */ diff --git a/tinyusb/device/dcd.c b/tinyusb/device/dcd.c index 4ae826597..11f920b13 100644 --- a/tinyusb/device/dcd.c +++ b/tinyusb/device/dcd.c @@ -40,20 +40,58 @@ // TODO refractor later #include "descriptors.h" +#define USB_ROM_SIZE (1024*2) +uint8_t usb_RomDriver_buffer[USB_ROM_SIZE]ALIGNED(2048) /*__BSS(RAM2)*/; +USBD_HANDLE_T g_hUsb; +volatile static bool isConfigured = false; +/**************************************************************************/ +/*! + @brief Handler for the USB Configure Event +*/ +/**************************************************************************/ +ErrorCode_t USB_Configure_Event (USBD_HANDLE_T hUsb) +{ + USB_CORE_CTRL_T* pCtrl = (USB_CORE_CTRL_T*)hUsb; + if (pCtrl->config_value) + { + #if defined(CLASS_HID) + ASSERT_STATUS( usb_hid_configured(hUsb) ); + #endif + + #ifdef CFG_USB_CDC + ASSERT_STATUS( usb_cdc_configured(hUsb) ); + #endif + } + + isConfigured = true; + + return LPC_OK; +} + +/**************************************************************************/ +/*! + @brief Handler for the USB Reset Event +*/ +/**************************************************************************/ +ErrorCode_t USB_Reset_Event (USBD_HANDLE_T hUsb) +{ + isConfigured = false; + return LPC_OK; +} void dcd_init() { - /* ROM DRIVER INIT */ + /* ROM DRIVER INIT */ USBD_API_INIT_PARAM_T usb_param = { -// .usb_reg_base = LPC_USB_BASE, -// .max_num_ep = USB_MAX_EP_NUM, -// .mem_base = (uint32_t) usb_RomDriver_buffer, -// .mem_size = USB_ROM_SIZE, //USBD_API->hw->GetMemSize() -// -// .USB_Configure_Event = USB_Configure_Event, -// .USB_Reset_Event = USB_Reset_Event + .usb_reg_base = LPC_USB_BASE, + .max_num_ep = USB_MAX_EP_NUM, + .mem_base = (uint32_t) usb_RomDriver_buffer, + .mem_size = USB_ROM_SIZE, //USBD_API->hw->GetMemSize() + + .USB_Configure_Event = USB_Configure_Event, + .USB_Reset_Event = USB_Reset_Event }; USB_CORE_DESCS_T DeviceDes = @@ -65,7 +103,50 @@ void dcd_init() .device_qualifier = NULL }; - USBD_HANDLE_T g_hUsb; /* Start USB hardware initialisation */ ASSERT_STATUS(USBD_API->hw->Init(&g_hUsb, &DeviceDes, &usb_param)); + + /* Initialise the class driver(s) */ + #ifdef CFG_USB_CDC + ASSERT_STATUS( usb_cdc_init(g_hUsb, &USB_FsConfigDescriptor.CDC_CCI_Interface, + &USB_FsConfigDescriptor.CDC_DCI_Interface, &usb_param.mem_base, &usb_param.mem_size) ); + #endif + + #ifdef CFG_CLASS_HID_KEYBOARD + ASSERT_STATUS( usb_hid_init(g_hUsb , &USB_FsConfigDescriptor.HID_KeyboardInterface , + HID_KeyboardReportDescriptor, USB_FsConfigDescriptor.HID_KeyboardHID.DescriptorList[0].wDescriptorLength, + &usb_param.mem_base , &usb_param.mem_size) ); + #endif + + #ifdef CFG_USB_HID_MOUSE + ASSERT_STATUS( usb_hid_init(g_hUsb , &USB_FsConfigDescriptor.HID_MouseInterface , + HID_MouseReportDescriptor, USB_FsConfigDescriptor.HID_MouseHID.DescriptorList[0].wDescriptorLength, + &usb_param.mem_base , &usb_param.mem_size) ); + #endif + + /* Enable the USB interrupt */ + NVIC_EnableIRQ(USB_IRQ_IRQn); + + /* Perform USB soft connect */ + USBD_API->hw->Connect(g_hUsb, 1); +} + +/**************************************************************************/ +/*! + @brief Indicates whether USB is configured or not +*/ +/**************************************************************************/ +bool usb_isConfigured(void) +{ + return isConfigured; +} + +/**************************************************************************/ +/*! + @brief Redirect the USB IRQ handler to the ROM handler +*/ +/**************************************************************************/ +void USB_IRQHandler(void) +{ + USBD_API->hw->ISR(g_hUsb); } diff --git a/tinyusb/tusb_cfg.h b/tinyusb/tusb_cfg.h index deeb8e425..7331d904f 100644 --- a/tinyusb/tusb_cfg.h +++ b/tinyusb/tusb_cfg.h @@ -47,9 +47,9 @@ #define CFG_TUSB_HOST #define CFG_TUSB_DEVICE -#define CFG_USB_HID_KEYBOARD +#define CFG_CLASS_HID_KEYBOARD -#define CLASS_HID (defined CFG_USB_HID_KEYBOARD) +#define CLASS_HID (defined CFG_CLASS_HID_KEYBOARD) // TODO APP |
