diff --git a/examples/device/device_virtual_com/src/cdc_device_app.c b/examples/device/device_virtual_com/src/cdc_device_app.c new file mode 100644 index 000000000..cbc4f4ffe --- /dev/null +++ b/examples/device/device_virtual_com/src/cdc_device_app.c @@ -0,0 +1,166 @@ +/**************************************************************************/ +/*! + @file cdc_device_app.c + @author hathach (tinyusb.org) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2013, hathach (tinyusb.org) + 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. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''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 COPYRIGHT HOLDER 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 tinyusb stack. +*/ +/**************************************************************************/ + +#include "cdc_device_app.h" + +#if TUSB_CFG_DEVICE_CDC + +#include "common/fifo.h" // TODO refractor +#include "app_os_prio.h" + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +enum { SERIAL_BUFFER_SIZE = 64 }; + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ +static osal_semaphore_t sem_hdl; + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +TUSB_CFG_ATTR_USBRAM static uint8_t serial_rx_buffer[SERIAL_BUFFER_SIZE]; +TUSB_CFG_ATTR_USBRAM static uint8_t serial_tx_buffer[SERIAL_BUFFER_SIZE]; + +FIFO_DEF(fifo_serial, SERIAL_BUFFER_SIZE, uint8_t, true); + +//--------------------------------------------------------------------+ +// tinyusb callbacks +//--------------------------------------------------------------------+ +void cdc_serial_app_mount(uint8_t coreid) +{ + osal_semaphore_reset(sem_hdl); + + tud_cdc_receive(coreid, serial_rx_buffer, SERIAL_BUFFER_SIZE, true); +} + +void cdc_serial_app_umount(uint8_t coreid) +{ + +} + +void tud_cdc_xfer_cb(uint8_t coreid, tusb_event_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes) +{ + switch ( pipe_id ) + { + case CDC_PIPE_DATA_OUT: + switch(event) + { + case TUSB_EVENT_XFER_COMPLETE: + for(uint8_t i=0; i +#include +#include + +#include "bsp/board.h" +#include "tusb.h" + +#include "cdc_device_app.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ +void print_greeting(void); + +#if TUSB_CFG_OS == TUSB_OS_NONE +// like a real RTOS, this function is a main loop invoking each task in application and never return +void os_none_start_scheduler(void) +{ + while (1) + { + tusb_task_runner(); + led_blinking_task(NULL); + cdc_serial_app_task(NULL); + } +} +#endif + +int main(void) +{ + board_init(); + print_greeting(); + + tusb_init(); + + //------------- application task init -------------// + led_blinking_init(); + cdc_serial_app_init(); + + while (1) + { + tusb_task_runner(); + + led_blinking_task(NULL); + cdc_serial_app_task(NULL); + } + + return 0; +} + +//--------------------------------------------------------------------+ +// tinyusb callbacks +//--------------------------------------------------------------------+ +void tud_mount_cb(uint8_t coreid) +{ + cdc_serial_app_mount(coreid); +} + +void tud_umount_cb(uint8_t coreid) +{ + cdc_serial_app_umount(coreid); +} + +//--------------------------------------------------------------------+ +// HELPER FUNCTION +//--------------------------------------------------------------------+ +void print_greeting(void) +{ + char const * const rtos_name[] = + { + [TUSB_OS_NONE] = "None", + [TUSB_OS_FREERTOS] = "FreeRTOS", + }; + + printf("\n\ +--------------------------------------------------------------------\n\ +- Device Demo (a tinyusb example)\n\ +- if you find any bugs or get any questions, feel free to file an\n\ +- issue at https://github.com/hathach/tinyusb\n\ +--------------------------------------------------------------------\n\n" + ); + + puts("This DEVICE demo is configured to support:"); + printf(" - RTOS = %s\n", rtos_name[TUSB_CFG_OS]); + if (TUSB_CFG_DEVICE_HID_MOUSE ) puts(" - HID Mouse"); + if (TUSB_CFG_DEVICE_HID_KEYBOARD ) puts(" - HID Keyboard"); + if (TUSB_CFG_DEVICE_MSC ) puts(" - Mass Storage"); + if (TUSB_CFG_DEVICE_CDC ) puts(" - Communication Device Class"); +} diff --git a/examples/device/device_virtual_com/src/tusb_config.h b/examples/device/device_virtual_com/src/tusb_config.h new file mode 100644 index 000000000..37f2ae04a --- /dev/null +++ b/examples/device/device_virtual_com/src/tusb_config.h @@ -0,0 +1,121 @@ +/**************************************************************************/ +/*! + @file tusb_config.h + @author hathach (tinyusb.org) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2013, hathach (tinyusb.org) + 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. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''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 COPYRIGHT HOLDER 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 tinyusb stack. +*/ +/**************************************************************************/ + +#ifndef _TUSB_TUSB_CONFIG_H_ +#define _TUSB_TUSB_CONFIG_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// CONTROLLER CONFIGURATION +//--------------------------------------------------------------------+ +//#define TUSB_CFG_MCU will be passed from IDE/command line for easy board/mcu switching + +#define TUSB_CFG_CONTROLLER_0_MODE (TUSB_MODE_DEVICE) +//#define TUSB_CFG_CONTROLLER_1_MODE (TUSB_MODE_DEVICE) + +//--------------------------------------------------------------------+ +// DEVICE CONFIGURATION +//--------------------------------------------------------------------+ +#define TUSB_CFG_DEVICE_CONTROL_ENDOINT_SIZE 64 + +//------------- CLASS -------------// +#define TUSB_CFG_DEVICE_HID_KEYBOARD 0 +#define TUSB_CFG_DEVICE_HID_MOUSE 0 +#define TUSB_CFG_DEVICE_HID_GENERIC 0 // not supported yet +#define TUSB_CFG_DEVICE_MSC 0 +#define TUSB_CFG_DEVICE_CDC 1 + +//--------------------------------------------------------------------+ +// COMMON CONFIGURATION +//--------------------------------------------------------------------+ +#define TUSB_CFG_DEBUG 2 + +//#define TUSB_CFG_OS TUSB_OS_NONE // be passed from IDE/command line for easy project switching +//#define TUSB_CFG_OS_TASK_PRIO 0 // be passed from IDE/command line for easy project switching +#define TUSB_CFG_TICKS_HZ 1000 + +//#define TUSB_CFG_OS TUSB_OS_NONE + +//--------------------------------------------------------------------+ +// USB RAM PLACEMENT +//--------------------------------------------------------------------+ +#ifdef __CODE_RED // compiled with lpcxpresso + + #if (TUSB_CFG_MCU == MCU_LPC11UXX) || (TUSB_CFG_MCU == MCU_LPC13UXX) + #define TUSB_CFG_ATTR_USBRAM ATTR_SECTION(.data.$RAM2) ATTR_ALIGNED(64) // lp11u & lp13u requires data to be 64 byte aligned + #elif TUSB_CFG_MCU == MCU_LPC175X_6X + #define TUSB_CFG_ATTR_USBRAM // LPC17xx USB DMA can access all + #elif (TUSB_CFG_MCU == MCU_LPC43XX) + #define TUSB_CFG_ATTR_USBRAM ATTR_SECTION(.data.$RAM3) + #endif + +#elif defined __CC_ARM // Compiled with Keil armcc, USBRAM_SECTION is defined in scatter files + + #if (TUSB_CFG_MCU == MCU_LPC11UXX) || (TUSB_CFG_MCU == MCU_LPC13UXX) + #define TUSB_CFG_ATTR_USBRAM ATTR_SECTION(USBRAM_SECTION) ATTR_ALIGNED(64) // lp11u & lp13u requires data to be 64 byte aligned + #elif (TUSB_CFG_MCU == MCU_LPC175X_6X) + #define TUSB_CFG_ATTR_USBRAM // LPC17xx USB DMA can access all address + #elif (TUSB_CFG_MCU == MCU_LPC43XX) + #define TUSB_CFG_ATTR_USBRAM // Use keil tool configure to have AHB SRAM as default memory + #endif + +#elif defined __ICCARM__ // compiled with IAR + + #if (TUSB_CFG_MCU == MCU_LPC11UXX) || (TUSB_CFG_MCU == MCU_LPC13UXX) + #define TUSB_CFG_ATTR_USBRAM _Pragma("location=\"USB_PACKET_MEMORY\"") ATTR_ALIGNED(64) + #elif (TUSB_CFG_MCU == MCU_LPC175X_6X) + #define TUSB_CFG_ATTR_USBRAM + #elif (TUSB_CFG_MCU == MCU_LPC43XX) + #define TUSB_CFG_ATTR_USBRAM _Pragma("location=\".ahb_sram1\"") + #endif + +#else + + #error compiler not specified + +#endif + + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_TUSB_CONFIG_H_ */ diff --git a/examples/device/device_virtual_com/src/tusb_descriptors.c b/examples/device/device_virtual_com/src/tusb_descriptors.c new file mode 100644 index 000000000..82d9d1fbe --- /dev/null +++ b/examples/device/device_virtual_com/src/tusb_descriptors.c @@ -0,0 +1,475 @@ +/**************************************************************************/ +/*! + @file tusb_descriptors.c + @author hathach (tinyusb.org) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2013, hathach (tinyusb.org) + 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. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''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 COPYRIGHT HOLDER 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 tinyusb stack. +*/ +/**************************************************************************/ + +#include "tusb_descriptors.h" + +//--------------------------------------------------------------------+ +// Keyboard Report Descriptor +//--------------------------------------------------------------------+ +#if TUSB_CFG_DEVICE_HID_KEYBOARD +uint8_t const desc_keyboard_report[] = { + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ), + HID_USAGE ( HID_USAGE_DESKTOP_KEYBOARD ), + HID_COLLECTION ( HID_COLLECTION_APPLICATION ), + HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ), + HID_USAGE_MIN ( 224 ), + HID_USAGE_MAX ( 231 ), + HID_LOGICAL_MIN ( 0 ), + HID_LOGICAL_MAX ( 1 ), + + HID_REPORT_SIZE ( 1 ), + HID_REPORT_COUNT ( 8 ), /* 8 bits */ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ), /* maskable modifier key */ + + HID_REPORT_SIZE ( 8 ), + HID_REPORT_COUNT ( 1 ), + HID_INPUT ( HID_CONSTANT ), /* reserved */ + + HID_USAGE_PAGE ( HID_USAGE_PAGE_LED ), + HID_USAGE_MIN ( 1 ), + HID_USAGE_MAX ( 5 ), + HID_REPORT_COUNT ( 5 ), + HID_REPORT_SIZE ( 1 ), + HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ), /* 5-bit Led report */ + + HID_REPORT_SIZE ( 3 ), /* led padding */ + HID_REPORT_COUNT ( 1 ), + HID_OUTPUT ( HID_CONSTANT ), + + HID_USAGE_PAGE (HID_USAGE_PAGE_KEYBOARD), + HID_USAGE_MIN ( 0 ), + HID_USAGE_MAX ( 101 ), + HID_LOGICAL_MIN ( 0 ), + HID_LOGICAL_MAX ( 101 ), + + HID_REPORT_SIZE ( 8 ), + HID_REPORT_COUNT ( 6 ), + HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ), /* keycodes array 6 items */ + HID_COLLECTION_END +}; +#endif + +//--------------------------------------------------------------------+ +// Mouse Report Descriptor +//--------------------------------------------------------------------+ +#if TUSB_CFG_DEVICE_HID_MOUSE +uint8_t const desc_mouse_report[] = { + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ), + HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ), + HID_COLLECTION ( HID_COLLECTION_APPLICATION ), + HID_USAGE (HID_USAGE_DESKTOP_POINTER), + + HID_COLLECTION ( HID_COLLECTION_PHYSICAL ), + HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ), + HID_USAGE_MIN ( 1 ), + HID_USAGE_MAX ( 3 ), + HID_LOGICAL_MIN ( 0 ), + HID_LOGICAL_MAX ( 1 ), + + HID_REPORT_SIZE ( 1 ), + HID_REPORT_COUNT ( 3 ), /* Left, Right and Middle mouse*/ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ), + + HID_REPORT_SIZE ( 5 ), + HID_REPORT_COUNT ( 1 ), + HID_INPUT ( HID_CONSTANT ), /* 5 bit padding followed 3 bit buttons */ + + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ), + HID_USAGE ( HID_USAGE_DESKTOP_X ), + HID_USAGE ( HID_USAGE_DESKTOP_Y ), + HID_LOGICAL_MIN ( 0x81 ), /* -127 */ + HID_LOGICAL_MAX ( 0x7f ), /* 127 */ + + HID_REPORT_SIZE ( 8 ), + HID_REPORT_COUNT ( 2 ), /* X, Y position */ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), /* relative values */ + + HID_USAGE ( HID_USAGE_DESKTOP_WHEEL ), /* mouse scroll */ + HID_LOGICAL_MIN ( 0x81 ), /* -127 */ + HID_LOGICAL_MAX ( 0x7f ), /* 127 */ + HID_REPORT_COUNT( 1 ), + HID_REPORT_SIZE ( 8 ), /* 8-bit value */ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), /* relative values */ + + HID_COLLECTION_END, + + HID_COLLECTION_END +}; +#endif + +//--------------------------------------------------------------------+ +// USB DEVICE DESCRIPTOR +//--------------------------------------------------------------------+ +tusb_descriptor_device_t const desc_device = +{ + .bLength = sizeof(tusb_descriptor_device_t), + .bDescriptorType = TUSB_DESC_TYPE_DEVICE, + .bcdUSB = 0x0200, + #if TUSB_CFG_DEVICE_CDC + // Use Interface Association Descriptor (IAD) for CDC + // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + #else + .bDeviceClass = 0x00, + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, + #endif + + .bMaxPacketSize0 = TUSB_CFG_DEVICE_CONTROL_ENDOINT_SIZE, + + .idVendor = CFG_VENDORID, + .idProduct = CFG_PRODUCTID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01 // TODO multiple configurations +}; + +//--------------------------------------------------------------------+ +// USB COFNIGURATION DESCRIPTOR +//--------------------------------------------------------------------+ +app_descriptor_configuration_t const desc_configuration = +{ + .configuration = + { + .bLength = sizeof(tusb_descriptor_configuration_t), + .bDescriptorType = TUSB_DESC_TYPE_CONFIGURATION, + + .wTotalLength = sizeof(app_descriptor_configuration_t), + .bNumInterfaces = TOTAL_INTEFACES, + + .bConfigurationValue = 1, + .iConfiguration = 0x00, + .bmAttributes = TUSB_DESC_CONFIG_ATT_BUS_POWER, + .bMaxPower = TUSB_DESC_CONFIG_POWER_MA(500) + }, + + #if TUSB_CFG_DEVICE_CDC + // IAD points to CDC Interfaces + .cdc_iad = + { + .bLength = sizeof(tusb_descriptor_interface_association_t), + .bDescriptorType = TUSB_DESC_TYPE_INTERFACE_ASSOCIATION, + + .bFirstInterface = INTERFACE_NO_CDC, + .bInterfaceCount = 2, + + .bFunctionClass = TUSB_CLASS_CDC, + .bFunctionSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, + .bFunctionProtocol = CDC_COMM_PROTOCOL_ATCOMMAND, + .iFunction = 0 + }, + + //------------- CDC Communication Interface -------------// + .cdc_comm_interface = + { + .bLength = sizeof(tusb_descriptor_interface_t), + .bDescriptorType = TUSB_DESC_TYPE_INTERFACE, + .bInterfaceNumber = INTERFACE_NO_CDC, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = TUSB_CLASS_CDC, + .bInterfaceSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, + .bInterfaceProtocol = CDC_COMM_PROTOCOL_ATCOMMAND, + .iInterface = 0x00 + }, + + .cdc_header = + { + .bLength = sizeof(cdc_desc_func_header_t), + .bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC, + .bDescriptorSubType = CDC_FUNC_DESC_HEADER, + .bcdCDC = 0x0120 + }, + + .cdc_call = + { + .bLength = sizeof(cdc_desc_func_call_management_t), + .bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC, + .bDescriptorSubType = CDC_FUNC_DESC_CALL_MANAGEMENT, + .bmCapabilities = { 0 }, + .bDataInterface = INTERFACE_NO_CDC+1, + }, + + .cdc_acm = + { + .bLength = sizeof(cdc_desc_func_abstract_control_management_t), + .bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC, + .bDescriptorSubType = CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, + .bmCapabilities = { // 0x02 + .support_line_request = 1, + } + }, + + .cdc_union = + { + .bLength = sizeof(cdc_desc_func_union_t), // plus number of + .bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC, + .bDescriptorSubType = CDC_FUNC_DESC_UNION, + .bControlInterface = INTERFACE_NO_CDC, + .bSubordinateInterface = INTERFACE_NO_CDC+1, + }, + + .cdc_endpoint_notification = + { + .bLength = sizeof(tusb_descriptor_endpoint_t), + .bDescriptorType = TUSB_DESC_TYPE_ENDPOINT, + .bEndpointAddress = CDC_EDPT_NOTIFICATION_ADDR, + .bmAttributes = { .xfer = TUSB_XFER_INTERRUPT }, + .wMaxPacketSize = { .size = 0x08 }, + .bInterval = 0x10 + }, + + //------------- CDC Data Interface -------------// + .cdc_data_interface = + { + .bLength = sizeof(tusb_descriptor_interface_t), + .bDescriptorType = TUSB_DESC_TYPE_INTERFACE, + .bInterfaceNumber = INTERFACE_NO_CDC+1, + .bAlternateSetting = 0x00, + .bNumEndpoints = 2, + .bInterfaceClass = TUSB_CLASS_CDC_DATA, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = 0x04 + }, + + .cdc_endpoint_out = + { + .bLength = sizeof(tusb_descriptor_endpoint_t), + .bDescriptorType = TUSB_DESC_TYPE_ENDPOINT, + .bEndpointAddress = CDC_EDPT_DATA_OUT_ADDR, + .bmAttributes = { .xfer = TUSB_XFER_BULK }, + .wMaxPacketSize = { .size = CDC_EDPT_DATA_PACKETSIZE }, + .bInterval = 0 + }, + + .cdc_endpoint_in = + { + .bLength = sizeof(tusb_descriptor_endpoint_t), + .bDescriptorType = TUSB_DESC_TYPE_ENDPOINT, + .bEndpointAddress = CDC_EDPT_DATA_IN_ADDR, + .bmAttributes = { .xfer = TUSB_XFER_BULK }, + .wMaxPacketSize = { .size = CDC_EDPT_DATA_PACKETSIZE }, + .bInterval = 0 + }, + #endif + + //------------- HID Keyboard -------------// + #if TUSB_CFG_DEVICE_HID_KEYBOARD + .keyboard_interface = + { + .bLength = sizeof(tusb_descriptor_interface_t), + .bDescriptorType = TUSB_DESC_TYPE_INTERFACE, + .bInterfaceNumber = INTERFACE_NO_HID_KEYBOARD, + .bAlternateSetting = 0x00, + .bNumEndpoints = 1, + .bInterfaceClass = TUSB_CLASS_HID, + .bInterfaceSubClass = HID_SUBCLASS_BOOT, + .bInterfaceProtocol = HID_PROTOCOL_KEYBOARD, + .iInterface = 0x05 + }, + + .keyboard_hid = + { + .bLength = sizeof(tusb_hid_descriptor_hid_t), + .bDescriptorType = HID_DESC_TYPE_HID, + .bcdHID = 0x0111, + .bCountryCode = HID_Local_NotSupported, + .bNumDescriptors = 1, + .bReportType = HID_DESC_TYPE_REPORT, + .wReportLength = sizeof(desc_keyboard_report) + }, + + .keyboard_endpoint = + { + .bLength = sizeof(tusb_descriptor_endpoint_t), + .bDescriptorType = TUSB_DESC_TYPE_ENDPOINT, + .bEndpointAddress = HID_KEYBOARD_EDPT_ADDR, + .bmAttributes = { .xfer = TUSB_XFER_INTERRUPT }, + .wMaxPacketSize = { .size = HID_KEYBOARD_EDPT_PACKETSIZE }, + .bInterval = 0x0A + }, + #endif + + //------------- HID Mouse -------------// + #if TUSB_CFG_DEVICE_HID_MOUSE + .mouse_interface = + { + .bLength = sizeof(tusb_descriptor_interface_t), + .bDescriptorType = TUSB_DESC_TYPE_INTERFACE, + .bInterfaceNumber = INTERFACE_NO_HID_MOUSE, + .bAlternateSetting = 0x00, + .bNumEndpoints = 1, + .bInterfaceClass = TUSB_CLASS_HID, + .bInterfaceSubClass = HID_SUBCLASS_BOOT, + .bInterfaceProtocol = HID_PROTOCOL_MOUSE, + .iInterface = 0x06 + }, + + .mouse_hid = + { + .bLength = sizeof(tusb_hid_descriptor_hid_t), + .bDescriptorType = HID_DESC_TYPE_HID, + .bcdHID = 0x0111, + .bCountryCode = HID_Local_NotSupported, + .bNumDescriptors = 1, + .bReportType = HID_DESC_TYPE_REPORT, + .wReportLength = sizeof(desc_mouse_report) + }, + + .mouse_endpoint = + { + .bLength = sizeof(tusb_descriptor_endpoint_t), + .bDescriptorType = TUSB_DESC_TYPE_ENDPOINT, + .bEndpointAddress = HID_MOUSE_EDPT_ADDR, // TODO + .bmAttributes = { .xfer = TUSB_XFER_INTERRUPT }, + .wMaxPacketSize = { .size = HID_MOUSE_EDPT_PACKETSIZE }, + .bInterval = 0x0A + }, + #endif + + //------------- Mass Storage -------------// + #if TUSB_CFG_DEVICE_MSC + .msc_interface = + { + .bLength = sizeof(tusb_descriptor_interface_t), + .bDescriptorType = TUSB_DESC_TYPE_INTERFACE, + .bInterfaceNumber = INTERFACE_NO_MSC, + .bAlternateSetting = 0x00, + .bNumEndpoints = 2, + .bInterfaceClass = TUSB_CLASS_MSC, + .bInterfaceSubClass = MSC_SUBCLASS_SCSI, + .bInterfaceProtocol = MSC_PROTOCOL_BOT, + .iInterface = 0x07 + }, + + .msc_endpoint_in = + { + .bLength = sizeof(tusb_descriptor_endpoint_t), + .bDescriptorType = TUSB_DESC_TYPE_ENDPOINT, + .bEndpointAddress = MSC_EDPT_IN_ADDR, + .bmAttributes = { .xfer = TUSB_XFER_BULK }, + .wMaxPacketSize = { .size = MSC_EDPT_PACKETSIZE }, + .bInterval = 1 + }, + + .msc_endpoint_out = + { + .bLength = sizeof(tusb_descriptor_endpoint_t), + .bDescriptorType = TUSB_DESC_TYPE_ENDPOINT, + .bEndpointAddress = MSC_EDPT_OUT_ADDR, + .bmAttributes = { .xfer = TUSB_XFER_BULK }, + .wMaxPacketSize = { .size = MSC_EDPT_PACKETSIZE }, + .bInterval = 1 + }, + #endif +}; + +//--------------------------------------------------------------------+ +// STRING DESCRIPTORS +//--------------------------------------------------------------------+ +#define STRING_LEN_UNICODE(n) (2 + (2*(n))) // also includes 2 byte header +#define ENDIAN_BE16_FROM( high, low) ENDIAN_BE16(high << 8 | low) + +// array of pointer to string descriptors +uint16_t const * const string_descriptor_arr [] = +{ + [0] = (uint16_t []) { // supported language + ENDIAN_BE16_FROM( STRING_LEN_UNICODE(1), TUSB_DESC_TYPE_STRING ), + 0x0409 // English + }, + + [1] = (uint16_t []) { // manufacturer + ENDIAN_BE16_FROM( STRING_LEN_UNICODE(11), TUSB_DESC_TYPE_STRING), + 't', 'i', 'n', 'y', 'u', 's', 'b', '.', 'o', 'r', 'g' // len = 11 + }, + + [2] = (uint16_t []) { // product + ENDIAN_BE16_FROM( STRING_LEN_UNICODE(14), TUSB_DESC_TYPE_STRING), + 't', 'i', 'n', 'y', 'u', 's', 'b', ' ', 'd', 'e', 'v', 'i', 'c', 'e' // len = 14 + }, + + [3] = (uint16_t []) { // serials + ENDIAN_BE16_FROM( STRING_LEN_UNICODE(4), TUSB_DESC_TYPE_STRING), + '1', '2', '3', '4' // len = 4 + }, + + [4] = (uint16_t []) { // CDC Interface + ENDIAN_BE16_FROM( STRING_LEN_UNICODE(3), TUSB_DESC_TYPE_STRING), + 'c', 'd', 'c' // len = 3 + }, + + [5] = (uint16_t []) { // Keyboard Interface + ENDIAN_BE16_FROM( STRING_LEN_UNICODE(5), TUSB_DESC_TYPE_STRING), + 'm', 'o', 'u', 's', 'e' // len = 5 + }, + + [6] = (uint16_t []) { // Keyboard Interface + ENDIAN_BE16_FROM( STRING_LEN_UNICODE(8), TUSB_DESC_TYPE_STRING), + 'k', 'e', 'y', 'b', 'o', 'a', 'r', 'd' // len = 8 + }, + + [7] = (uint16_t []) { // MSC Interface + ENDIAN_BE16_FROM( STRING_LEN_UNICODE(3), TUSB_DESC_TYPE_STRING), + 'm', 's', 'c' // len = 3 + } +}; + +//--------------------------------------------------------------------+ +// TINYUSB Descriptors Pointer (this variable is required by the stack) +//--------------------------------------------------------------------+ +tusbd_descriptor_pointer_t tusbd_descriptor_pointers = +{ + .p_device = (uint8_t const * ) &desc_device, + .p_configuration = (uint8_t const * ) &desc_configuration, + .p_string_arr = (uint8_t const **) string_descriptor_arr, + + #if TUSB_CFG_DEVICE_HID_KEYBOARD + .p_hid_keyboard_report = (uint8_t const *) desc_keyboard_report, + #endif + + #if TUSB_CFG_DEVICE_HID_MOUSE + .p_hid_mouse_report = (uint8_t const *) desc_mouse_report, + #endif +}; diff --git a/examples/device/device_virtual_com/src/tusb_descriptors.h b/examples/device/device_virtual_com/src/tusb_descriptors.h new file mode 100644 index 000000000..322af0392 --- /dev/null +++ b/examples/device/device_virtual_com/src/tusb_descriptors.h @@ -0,0 +1,178 @@ +/**************************************************************************/ +/*! + @file tusb_descriptors.h + @author hathach (tinyusb.org) + + @section LICENSE + + Software License Agreement (BSD License) + + Copyright (c) 2013, hathach (tinyusb.org) + 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. Neither the name of the copyright holders nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''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 COPYRIGHT HOLDER 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 tinyusb stack. +*/ +/**************************************************************************/ + +#ifndef _TUSB_DESCRIPTORS_H_ +#define _TUSB_DESCRIPTORS_H_ + +#include "tusb.h" + +//--------------------------------------------------------------------+ +// Descriptors Value (calculated by enabled Classes) +//--------------------------------------------------------------------+ +#define CFG_VENDORID 0xCAFE +//#define CFG_PRODUCTID 0x4567 // use auto product id to prevent conflict with pc's driver + +// each combination of interfaces need to have a unique productid, as windows will bind & remember device driver after the first plug. +// Auto ProductID layout's Bitmap: (MSB) MassStorage | Generic | Mouse | Key | CDC (LSB) +#ifndef CFG_PRODUCTID + #define PRODUCTID_BITMAP(interface, n) ( (TUSB_CFG_DEVICE_##interface) << (n) ) + #define CFG_PRODUCTID (0x4000 | ( PRODUCTID_BITMAP(CDC, 0) | PRODUCTID_BITMAP(HID_KEYBOARD, 1) | \ + PRODUCTID_BITMAP(HID_MOUSE, 2) | PRODUCTID_BITMAP(HID_GENERIC, 3) | \ + PRODUCTID_BITMAP(MSC, 4) ) ) +#endif + +#define INTERFACE_NO_CDC 0 +#define INTERFACE_NO_HID_KEYBOARD (INTERFACE_NO_CDC + 2*(TUSB_CFG_DEVICE_CDC ? 1 : 0) ) +#define INTERFACE_NO_HID_MOUSE (INTERFACE_NO_HID_KEYBOARD + TUSB_CFG_DEVICE_HID_KEYBOARD ) +#define INTERFACE_NO_HID_GENERIC (INTERFACE_NO_HID_MOUSE + TUSB_CFG_DEVICE_HID_MOUSE ) +#define INTERFACE_NO_MSC (INTERFACE_NO_HID_GENERIC + TUSB_CFG_DEVICE_HID_GENERIC ) + +#define TOTAL_INTEFACES (2*TUSB_CFG_DEVICE_CDC + TUSB_CFG_DEVICE_HID_KEYBOARD + TUSB_CFG_DEVICE_HID_MOUSE + \ + TUSB_CFG_DEVICE_HID_GENERIC + TUSB_CFG_DEVICE_MSC) + +#if (TUSB_CFG_MCU == MCU_LPC11UXX || TUSB_CFG_MCU == MCU_LPC13UXX) && (TOTAL_INTEFACES > 4) + #error These MCUs do not have enough number of endpoints for the current configuration +#endif + +//--------------------------------------------------------------------+ +// Endpoints Address & Max Packet Size +//--------------------------------------------------------------------+ +#define EDPT_IN(x) (0x80 | (x)) +#define EDPT_OUT(x) (x) + +#if TUSB_CFG_MCU == MCU_LPC175X_6X // MCUs's endpoint number has a fixed type + + //------------- CDC -------------// + #define CDC_EDPT_NOTIFICATION_ADDR EDPT_IN (1) + #define CDC_EDPT_NOTIFICATION_PACKETSIZE 64 + + #define CDC_EDPT_DATA_OUT_ADDR EDPT_OUT(2) + #define CDC_EDPT_DATA_IN_ADDR EDPT_IN (2) + #define CDC_EDPT_DATA_PACKETSIZE 64 + + //------------- HID Keyboard -------------// + #define HID_KEYBOARD_EDPT_ADDR EDPT_IN (4) + #define HID_KEYBOARD_EDPT_PACKETSIZE 8 + + //------------- HID Mouse -------------// + #define HID_MOUSE_EDPT_ADDR EDPT_IN (7) + #define HID_MOUSE_EDPT_PACKETSIZE 8 + + //------------- HID Generic -------------// + + //------------- Mass Storage -------------// + #define MSC_EDPT_OUT_ADDR EDPT_OUT(5) + #define MSC_EDPT_IN_ADDR EDPT_IN (5) + +#else + + //------------- CDC -------------// + #define CDC_EDPT_NOTIFICATION_ADDR EDPT_IN (INTERFACE_NO_CDC+1) + #define CDC_EDPT_NOTIFICATION_PACKETSIZE 64 + + #define CDC_EDPT_DATA_OUT_ADDR EDPT_OUT(INTERFACE_NO_CDC+2) + #define CDC_EDPT_DATA_IN_ADDR EDPT_IN (INTERFACE_NO_CDC+2) + #define CDC_EDPT_DATA_PACKETSIZE 64 + + //------------- HID Keyboard -------------// + #define HID_KEYBOARD_EDPT_ADDR EDPT_IN (INTERFACE_NO_HID_KEYBOARD+1) + #define HID_KEYBOARD_EDPT_PACKETSIZE 8 + + //------------- HID Mouse -------------// + #define HID_MOUSE_EDPT_ADDR EDPT_IN (INTERFACE_NO_HID_MOUSE+1) + #define HID_MOUSE_EDPT_PACKETSIZE 8 + + //------------- HID Generic -------------// + + //------------- Mass Storage -------------// + #define MSC_EDPT_OUT_ADDR EDPT_OUT(INTERFACE_NO_MSC+1) + #define MSC_EDPT_IN_ADDR EDPT_IN (INTERFACE_NO_MSC+1) + +#endif + +#define MSC_EDPT_PACKETSIZE (TUSB_CFG_MCU == MCU_LPC43XX ? 512 : 64) + +//--------------------------------------------------------------------+ +// CONFIGURATION DESCRIPTOR +//--------------------------------------------------------------------+ +typedef struct ATTR_PACKED +{ + tusb_descriptor_configuration_t configuration; + + //------------- CDC -------------// +#if TUSB_CFG_DEVICE_CDC + tusb_descriptor_interface_association_t cdc_iad; + + //CDC Control Interface + tusb_descriptor_interface_t cdc_comm_interface; + cdc_desc_func_header_t cdc_header; + cdc_desc_func_call_management_t cdc_call; + cdc_desc_func_abstract_control_management_t cdc_acm; + cdc_desc_func_union_t cdc_union; + tusb_descriptor_endpoint_t cdc_endpoint_notification; + + //CDC Data Interface + tusb_descriptor_interface_t cdc_data_interface; + tusb_descriptor_endpoint_t cdc_endpoint_out; + tusb_descriptor_endpoint_t cdc_endpoint_in; +#endif + + //------------- HID Keyboard -------------// +#if TUSB_CFG_DEVICE_HID_KEYBOARD + tusb_descriptor_interface_t keyboard_interface; + tusb_hid_descriptor_hid_t keyboard_hid; + tusb_descriptor_endpoint_t keyboard_endpoint; +#endif + +//------------- HID Mouse -------------// +#if TUSB_CFG_DEVICE_HID_MOUSE + tusb_descriptor_interface_t mouse_interface; + tusb_hid_descriptor_hid_t mouse_hid; + tusb_descriptor_endpoint_t mouse_endpoint; +#endif + +//------------- Mass Storage -------------// +#if TUSB_CFG_DEVICE_MSC + tusb_descriptor_interface_t msc_interface; + tusb_descriptor_endpoint_t msc_endpoint_in; + tusb_descriptor_endpoint_t msc_endpoint_out; +#endif + +} app_descriptor_configuration_t; + +#endif diff --git a/examples/device/device_virtual_com/xpresso/.cproject b/examples/device/device_virtual_com/xpresso/.cproject new file mode 100644 index 000000000..5a4b9d17c --- /dev/null +++ b/examples/device/device_virtual_com/xpresso/.cproject @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <?xml version="1.0" encoding="UTF-8"?> +<TargetConfig> +<Properties property_0="None" property_2="LPC18x7_43x7_2x512_BootA.cfx" property_3="NXP" property_4="LPC4357" property_count="5" version="70200"/> +<infoList vendor="NXP"><info chip="LPC4357" flash_driver="LPC18x7_43x7_2x512_BootA.cfx" match_id="0x0" name="LPC4357" resetscript="LPC18LPC43InternalFLASHBootResetscript.scp" stub="crt_emu_lpc18_43_nxp"><chip><name>LPC4357</name> +<family>LPC43xx</family> +<vendor>NXP (formerly Philips)</vendor> +<reset board="None" core="Real" sys="Real"/> +<clock changeable="TRUE" freq="20MHz" is_accurate="TRUE"/> +<memory can_program="true" id="Flash" is_ro="true" type="Flash"/> +<memory id="RAM" type="RAM"/> +<memory id="Periph" is_volatile="true" type="Peripheral"/> +<memoryInstance derived_from="Flash" edited="true" id="MFlashA512" location="0x1a000000" size="0x80000"/> +<memoryInstance derived_from="Flash" edited="true" id="MFlashB512" location="0x1b000000" size="0x80000"/> +<memoryInstance derived_from="RAM" edited="true" id="RamLoc32" location="0x10000000" size="0x8000"/> +<memoryInstance derived_from="RAM" edited="true" id="RamLoc40" location="0x10080000" size="0xa000"/> +<memoryInstance derived_from="RAM" edited="true" id="RamAHB32" location="0x20000000" size="0x8000"/> +<memoryInstance derived_from="RAM" edited="true" id="RamAHB16" location="0x20008000" size="0x4000"/> +<memoryInstance derived_from="RAM" edited="true" id="RamAHB_ETB16" location="0x2000c000" size="0x4000"/> +<prog_flash blocksz="0x2000" location="0x1a000000" maxprgbuff="0x400" progwithcode="TRUE" size="0x10000"/> +<prog_flash blocksz="0x10000" location="0x1a010000" maxprgbuff="0x400" progwithcode="TRUE" size="0x70000"/> +<prog_flash blocksz="0x2000" location="0x1b000000" maxprgbuff="0x400" progwithcode="TRUE" size="0x10000"/> +<prog_flash blocksz="0x10000" location="0x1b010000" maxprgbuff="0x400" progwithcode="TRUE" size="0x70000"/> +<peripheralInstance derived_from="V7M_MPU" id="MPU" location="0xe000ed90"/> +<peripheralInstance derived_from="V7M_NVIC" id="NVIC" location="0xe000e000"/> +<peripheralInstance derived_from="V7M_DCR" id="DCR" location="0xe000edf0"/> +<peripheralInstance derived_from="V7M_ITM" id="ITM" location="0xe0000000"/> +<peripheralInstance derived_from="SCT" id="SCT" location="0x40000000"/> +<peripheralInstance derived_from="GPDMA" id="GPDMA" location="0x40002000"/> +<peripheralInstance derived_from="SPIFI" id="SPIFI" location="0x40003000"/> +<peripheralInstance derived_from="SDMMC" id="SDMMC" location="0x40004000"/> +<peripheralInstance derived_from="EMC" id="EMC" location="0x40005000"/> +<peripheralInstance derived_from="USB0" id="USB0" location="0x40006000"/> +<peripheralInstance derived_from="USB1" id="USB1" location="0x40007000"/> +<peripheralInstance derived_from="LCD" id="LCD" location="0x40008000"/> +<peripheralInstance derived_from="EEPROM" id="EEPROM" location="0x4000e000"/> +<peripheralInstance derived_from="ETHERNET" id="ETHERNET" location="0x40010000"/> +<peripheralInstance derived_from="ATIMER" id="ATIMER" location="0x40040000"/> +<peripheralInstance derived_from="REGFILE" id="REGFILE" location="0x40041000"/> +<peripheralInstance derived_from="PMC" id="PMC" location="0x40042000"/> +<peripheralInstance derived_from="CREG" id="CREG" location="0x40043000"/> +<peripheralInstance derived_from="EVENTROUTER" id="EVENTROUTER" location="0x40044000"/> +<peripheralInstance derived_from="RTC" id="RTC" location="0x40046000"/> +<peripheralInstance derived_from="CGU" id="CGU" location="0x40050000"/> +<peripheralInstance derived_from="CCU1" id="CCU1" location="0x40051000"/> +<peripheralInstance derived_from="CCU2" id="CCU2" location="0x40052000"/> +<peripheralInstance derived_from="RGU" id="RGU" location="0x40053000"/> +<peripheralInstance derived_from="WWDT" id="WWDT" location="0x40080000"/> +<peripheralInstance derived_from="USART0" id="USART0" location="0x40081000"/> +<peripheralInstance derived_from="USART2" id="USART2" location="0x400c1000"/> +<peripheralInstance derived_from="USART3" id="USART3" location="0x400c2000"/> +<peripheralInstance derived_from="UART1" id="UART1" location="0x40082000"/> +<peripheralInstance derived_from="SSP0" id="SSP0" location="0x40083000"/> +<peripheralInstance derived_from="SSP1" id="SSP1" location="0x400c5000"/> +<peripheralInstance derived_from="TIMER0" id="TIMER0" location="0x40084000"/> +<peripheralInstance derived_from="TIMER1" id="TIMER1" location="0x40085000"/> +<peripheralInstance derived_from="TIMER2" id="TIMER2" location="0x400c3000"/> +<peripheralInstance derived_from="TIMER3" id="TIMER3" location="0x400c4000"/> +<peripheralInstance derived_from="SCU" id="SCU" location="0x40086000"/> +<peripheralInstance derived_from="GPIO-PIN-INT" id="GPIO-PIN-INT" location="0x40087000"/> +<peripheralInstance derived_from="GPIO-GROUP-INT0" id="GPIO-GROUP-INT0" location="0x40088000"/> +<peripheralInstance derived_from="GPIO-GROUP-INT1" id="GPIO-GROUP-INT1" location="0x40089000"/> +<peripheralInstance derived_from="MCPWM" id="MCPWM" location="0x400a0000"/> +<peripheralInstance derived_from="I2C0" id="I2C0" location="0x400a1000"/> +<peripheralInstance derived_from="I2C1" id="I2C1" location="0x400e0000"/> +<peripheralInstance derived_from="I2S0" id="I2S0" location="0x400a2000"/> +<peripheralInstance derived_from="I2S1" id="I2S1" location="0x400a3000"/> +<peripheralInstance derived_from="C-CAN1" id="C-CAN1" location="0x400a4000"/> +<peripheralInstance derived_from="RITIMER" id="RITIMER" location="0x400c0000"/> +<peripheralInstance derived_from="QEI" id="QEI" location="0x400c6000"/> +<peripheralInstance derived_from="GIMA" id="GIMA" location="0x400c7000"/> +<peripheralInstance derived_from="DAC" id="DAC" location="0x400e1000"/> +<peripheralInstance derived_from="C-CAN0" id="C-CAN0" location="0x400e2000"/> +<peripheralInstance derived_from="ADC0" id="ADC0" location="0x400e3000"/> +<peripheralInstance derived_from="ADC1" id="ADC1" location="0x400e4000"/> +<peripheralInstance derived_from="GPIO-PORT" id="GPIO-PORT" location="0x400f4000"/> +<peripheralInstance derived_from="SPI" id="SPI" location="0x40100000"/> +<peripheralInstance derived_from="SGPIO" id="SGPIO" location="0x40101000"/> +</chip> +<processor><name gcc_name="cortex-m4">Cortex-M4</name> +<family>Cortex-M</family> +</processor> +<link href="nxp_lpc43xx_peripheral.xme" show="embed" type="simple"/> +</info> +</infoList> +</TargetConfig> + + + + + + + + + + + MCB4357 + + + diff --git a/examples/device/device_virtual_com/xpresso/.project b/examples/device/device_virtual_com/xpresso/.project new file mode 100644 index 000000000..ecd387b48 --- /dev/null +++ b/examples/device/device_virtual_com/xpresso/.project @@ -0,0 +1,43 @@ + + + device_virtual_com + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + hw + 2 + PARENT-4-PROJECT_LOC/hw + + + src + 2 + PARENT-1-PROJECT_LOC/src + + + tinyusb + 2 + PARENT-4-PROJECT_LOC/tinyusb + + + diff --git a/examples/obsolete/device/device_os_none/.project b/examples/obsolete/device/device_os_none/.project index 13f40a9a9..040ba75e7 100644 --- a/examples/obsolete/device/device_os_none/.project +++ b/examples/obsolete/device/device_os_none/.project @@ -83,7 +83,7 @@ hw 2 - PARENT-3-PROJECT_LOC/hw + PARENT-4-PROJECT_LOC/hw src @@ -93,7 +93,7 @@ tinyusb 2 - PARENT-3-PROJECT_LOC/tinyusb + PARENT-4-PROJECT_LOC/tinyusb diff --git a/hw/bsp/ea4357/startup/xpresso/cr_startup_lpc43xx.c b/hw/bsp/ea4357/startup/xpresso/cr_startup_lpc43xx.c index d692c94e7..a5f06006a 100644 --- a/hw/bsp/ea4357/startup/xpresso/cr_startup_lpc43xx.c +++ b/hw/bsp/ea4357/startup/xpresso/cr_startup_lpc43xx.c @@ -1,32 +1,34 @@ //***************************************************************************** -// +--+ -// | ++----+ -// +-++ | -// | | -// +-+--+ | -// | +--+--+ -// +----+ Copyright (c) 2011-12 Code Red Technologies Ltd. -// -// LPC43xx Microcontroller Startup code for use with Red Suite -// -// Version : 120430 -// -// Software License Agreement -// -// The software is owned by Code Red Technologies and/or its suppliers, and is -// protected under applicable copyright laws. All rights are reserved. Any -// use in violation of the foregoing restrictions may subject the user to criminal -// sanctions under applicable laws, as well as to civil liability for the breach -// of the terms and conditions of this license. -// -// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED -// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. -// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT -// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH -// CODE RED TECHNOLOGIES LTD. +// LPC43xx (Cortex-M4) Microcontroller Startup code for use with LPCXpresso IDE // +// Version : 150706 //***************************************************************************** +// +// Copyright(C) NXP Semiconductors, 2013-2015 +// All rights reserved. +// +// Software that is described herein is for illustrative purposes only +// which provides customers with programming information regarding the +// LPC products. This software is supplied "AS IS" without any warranties of +// any kind, and NXP Semiconductors and its licensor disclaim any and +// all warranties, express or implied, including all implied warranties of +// merchantability, fitness for a particular purpose and non-infringement of +// intellectual property rights. NXP Semiconductors assumes no responsibility +// or liability for the use of the software, conveys no license or rights under any +// patent, copyright, mask work right, or any other intellectual property rights in +// or to any products. NXP Semiconductors reserves the right to make changes +// in the software without notification. NXP Semiconductors also makes no +// representation or warranty that such application will be suitable for the +// specified use without further testing or modification. +// +// Permission to use, copy, modify, and distribute this software and its +// documentation is hereby granted, under NXP Semiconductors' and its +// licensor's relevant copyrights in the software, without fee, provided that it +// is used in conjunction with NXP Semiconductors microcontrollers. This +// copyright, permission, and disclaimer notice must appear in all copies of +// this code. +//***************************************************************************** + #if defined (__cplusplus) #ifdef __REDLIB__ #error Redlib does not support C++ @@ -37,7 +39,7 @@ // //***************************************************************************** extern "C" { - extern void __libc_init_array(void); + extern void __libc_init_array(void); } #endif #endif @@ -45,17 +47,17 @@ extern "C" { #define WEAK __attribute__ ((weak)) #define ALIAS(f) __attribute__ ((weak, alias (#f))) -// Code Red - if CMSIS is being used, then SystemInit() routine -// will be called by startup code rather than in application's main() -#if defined (__USE_CMSIS) -#include "LPC43xx.h" -#endif - //***************************************************************************** #if defined (__cplusplus) extern "C" { #endif +//***************************************************************************** +#if defined (__USE_CMSIS) || defined (__USE_LPCOPEN) +// Declaration of external SystemInit function +extern void SystemInit(void); +#endif + //***************************************************************************** // // Forward declaration of the default handlers. These are aliased. @@ -63,7 +65,7 @@ extern "C" { // automatically take precedence over these weak definitions // //***************************************************************************** - void ResetISR(void); +void ResetISR(void); WEAK void NMI_Handler(void); WEAK void HardFault_Handler(void); WEAK void MemManage_Handler(void); @@ -84,9 +86,12 @@ WEAK void IntDefaultHandler(void); // //***************************************************************************** void DAC_IRQHandler(void) ALIAS(IntDefaultHandler); +#if defined (__USE_LPCOPEN) +void M0APP_IRQHandler(void) ALIAS(IntDefaultHandler); +#else void M0CORE_IRQHandler(void) ALIAS(IntDefaultHandler); +#endif void DMA_IRQHandler(void) ALIAS(IntDefaultHandler); -void EZH_IRQHandler(void) ALIAS(IntDefaultHandler); void FLASH_EEPROM_IRQHandler(void) ALIAS(IntDefaultHandler); void ETH_IRQHandler(void) ALIAS(IntDefaultHandler); void SDIO_IRQHandler(void) ALIAS(IntDefaultHandler); @@ -102,7 +107,7 @@ void TIMER3_IRQHandler(void) ALIAS(IntDefaultHandler); void MCPWM_IRQHandler(void) ALIAS(IntDefaultHandler); void ADC0_IRQHandler(void) ALIAS(IntDefaultHandler); void I2C0_IRQHandler(void) ALIAS(IntDefaultHandler); -void SPI_IRQHandler (void) ALIAS(IntDefaultHandler); +void SPI_IRQHandler(void) ALIAS(IntDefaultHandler); void I2C1_IRQHandler(void) ALIAS(IntDefaultHandler); void ADC1_IRQHandler(void) ALIAS(IntDefaultHandler); void SSP0_IRQHandler(void) ALIAS(IntDefaultHandler); @@ -127,15 +132,18 @@ void GINT0_IRQHandler(void) ALIAS(IntDefaultHandler); void GINT1_IRQHandler(void) ALIAS(IntDefaultHandler); void EVRT_IRQHandler(void) ALIAS(IntDefaultHandler); void CAN1_IRQHandler(void) ALIAS(IntDefaultHandler); +#if defined (__USE_LPCOPEN) +void ADCHS_IRQHandler(void) ALIAS(IntDefaultHandler); +#else void VADC_IRQHandler(void) ALIAS(IntDefaultHandler); +#endif void ATIMER_IRQHandler(void) ALIAS(IntDefaultHandler); void RTC_IRQHandler(void) ALIAS(IntDefaultHandler); void WDT_IRQHandler(void) ALIAS(IntDefaultHandler); -void M0s_IRQHandler(void) ALIAS(IntDefaultHandler); +void M0SUB_IRQHandler(void) ALIAS(IntDefaultHandler); void CAN0_IRQHandler(void) ALIAS(IntDefaultHandler); void QEI_IRQHandler(void) ALIAS(IntDefaultHandler); - //***************************************************************************** // // The entry point for the application. @@ -154,6 +162,13 @@ extern int main(void); //***************************************************************************** extern void _vStackTop(void); +//***************************************************************************** +// +// External declaration for LPC MCU vector table checksum from Linker Script +// +//***************************************************************************** +WEAK extern void __valid_user_code_checksum(); + //***************************************************************************** #if defined (__cplusplus) } // extern "C" @@ -165,81 +180,90 @@ extern void _vStackTop(void); // //***************************************************************************** extern void (* const g_pfnVectors[])(void); -__attribute__ ((section(".isr_vector"))) +__attribute__ ((used,section(".isr_vector"))) void (* const g_pfnVectors[])(void) = { - // Core Level - CM4 - &_vStackTop, // The initial stack pointer - ResetISR, // The reset handler - NMI_Handler, // The NMI handler - HardFault_Handler, // The hard fault handler - MemManage_Handler, // The MPU fault handler - BusFault_Handler, // The bus fault handler - UsageFault_Handler, // The usage fault handler - 0, // Reserved - 0, // Reserved - 0, // Reserved - 0, // Reserved - SVC_Handler, // SVCall handler - DebugMon_Handler, // Debug monitor handler - 0, // Reserved - PendSV_Handler, // The PendSV handler - SysTick_Handler, // The SysTick handler + // Core Level - CM4 + &_vStackTop, // The initial stack pointer + ResetISR, // The reset handler + NMI_Handler, // The NMI handler + HardFault_Handler, // The hard fault handler + MemManage_Handler, // The MPU fault handler + BusFault_Handler, // The bus fault handler + UsageFault_Handler, // The usage fault handler + __valid_user_code_checksum, // LPC MCU Checksum + 0, // Reserved + 0, // Reserved + 0, // Reserved + SVC_Handler, // SVCall handler + DebugMon_Handler, // Debug monitor handler + 0, // Reserved + PendSV_Handler, // The PendSV handler + SysTick_Handler, // The SysTick handler + + // Chip Level - LPC43 (M4) + DAC_IRQHandler, // 16 +#if defined (__USE_LPCOPEN) + M0APP_IRQHandler, // 17 CortexM4/M0 (LPC43XX ONLY) +#else + M0CORE_IRQHandler, // 17 +#endif + DMA_IRQHandler, // 18 + 0, // 19 + FLASH_EEPROM_IRQHandler, // 20 ORed flash Bank A, flash Bank B, EEPROM interrupts + ETH_IRQHandler, // 21 + SDIO_IRQHandler, // 22 + LCD_IRQHandler, // 23 + USB0_IRQHandler, // 24 + USB1_IRQHandler, // 25 + SCT_IRQHandler, // 26 + RIT_IRQHandler, // 27 + TIMER0_IRQHandler, // 28 + TIMER1_IRQHandler, // 29 + TIMER2_IRQHandler, // 30 + TIMER3_IRQHandler, // 31 + MCPWM_IRQHandler, // 32 + ADC0_IRQHandler, // 33 + I2C0_IRQHandler, // 34 + I2C1_IRQHandler, // 35 + SPI_IRQHandler, // 36 + ADC1_IRQHandler, // 37 + SSP0_IRQHandler, // 38 + SSP1_IRQHandler, // 39 + UART0_IRQHandler, // 40 + UART1_IRQHandler, // 41 + UART2_IRQHandler, // 42 + UART3_IRQHandler, // 43 + I2S0_IRQHandler, // 44 + I2S1_IRQHandler, // 45 + SPIFI_IRQHandler, // 46 + SGPIO_IRQHandler, // 47 + GPIO0_IRQHandler, // 48 + GPIO1_IRQHandler, // 49 + GPIO2_IRQHandler, // 50 + GPIO3_IRQHandler, // 51 + GPIO4_IRQHandler, // 52 + GPIO5_IRQHandler, // 53 + GPIO6_IRQHandler, // 54 + GPIO7_IRQHandler, // 55 + GINT0_IRQHandler, // 56 + GINT1_IRQHandler, // 57 + EVRT_IRQHandler, // 58 + CAN1_IRQHandler, // 59 + 0, // 60 +#if defined (__USE_LPCOPEN) + ADCHS_IRQHandler, // 61 ADCHS combined interrupt +#else + VADC_IRQHandler, // 61 +#endif + ATIMER_IRQHandler, // 62 + RTC_IRQHandler, // 63 + 0, // 64 + WDT_IRQHandler, // 65 + M0SUB_IRQHandler, // 66 + CAN0_IRQHandler, // 67 + QEI_IRQHandler, // 68 +}; - // Chip Level - LPC43 - DAC_IRQHandler, // 16 - M0CORE_IRQHandler, // 17 - DMA_IRQHandler, // 18 - EZH_IRQHandler, // 19 - FLASH_EEPROM_IRQHandler, // 20 - ETH_IRQHandler, // 21 - SDIO_IRQHandler, // 22 - LCD_IRQHandler, // 23 - USB0_IRQHandler, // 24 - USB1_IRQHandler, // 25 - SCT_IRQHandler, // 26 - RIT_IRQHandler, // 27 - TIMER0_IRQHandler, // 28 - TIMER1_IRQHandler, // 29 - TIMER2_IRQHandler, // 30 - TIMER3_IRQHandler, // 31 - MCPWM_IRQHandler, // 32 - ADC0_IRQHandler, // 33 - I2C0_IRQHandler, // 34 - I2C1_IRQHandler, // 35 - SPI_IRQHandler, // 36 - ADC1_IRQHandler, // 37 - SSP0_IRQHandler, // 38 - SSP1_IRQHandler, // 39 - UART0_IRQHandler, // 40 - UART1_IRQHandler, // 41 - UART2_IRQHandler, // 42 - UART3_IRQHandler, // 43 - I2S0_IRQHandler, // 44 - I2S1_IRQHandler, // 45 - SPIFI_IRQHandler, // 46 - SGPIO_IRQHandler, // 47 - GPIO0_IRQHandler, // 48 - GPIO1_IRQHandler, // 49 - GPIO2_IRQHandler, // 50 - GPIO3_IRQHandler, // 51 - GPIO4_IRQHandler, // 52 - GPIO5_IRQHandler, // 53 - GPIO6_IRQHandler, // 54 - GPIO7_IRQHandler, // 55 - GINT0_IRQHandler, // 56 - GINT1_IRQHandler, // 57 - EVRT_IRQHandler, // 58 - CAN1_IRQHandler, // 59 - 0, // 60 - VADC_IRQHandler, // 61 - ATIMER_IRQHandler, // 62 - RTC_IRQHandler, // 63 - 0, // 64 - WDT_IRQHandler, // 65 - M0s_IRQHandler, // 66 - CAN0_IRQHandler, // 67 - QEI_IRQHandler, // 68 - }; //***************************************************************************** // Functions to carry out the initialization of RW and BSS data sections. These @@ -247,21 +271,22 @@ void (* const g_pfnVectors[])(void) = { // ResetISR() function in order to cope with MCUs with multiple banks of // memory. //***************************************************************************** -__attribute__ ((section(".after_vectors"))) + __attribute__((section(".after_vectors" +))) void data_init(unsigned int romstart, unsigned int start, unsigned int len) { - unsigned int *pulDest = (unsigned int*) start; - unsigned int *pulSrc = (unsigned int*) romstart; - unsigned int loop; - for (loop = 0; loop < len; loop = loop + 4) - *pulDest++ = *pulSrc++; + unsigned int *pulDest = (unsigned int*) start; + unsigned int *pulSrc = (unsigned int*) romstart; + unsigned int loop; + for (loop = 0; loop < len; loop = loop + 4) + *pulDest++ = *pulSrc++; } __attribute__ ((section(".after_vectors"))) void bss_init(unsigned int start, unsigned int len) { - unsigned int *pulDest = (unsigned int*) start; - unsigned int loop; - for (loop = 0; loop < len; loop = loop + 4) - *pulDest++ = 0; + unsigned int *pulDest = (unsigned int*) start; + unsigned int loop; + for (loop = 0; loop < len; loop = loop + 4) + *pulDest++ = 0; } //***************************************************************************** @@ -282,8 +307,7 @@ extern unsigned int __bss_section_table_end; // library. // //***************************************************************************** -void -ResetISR(void) { +void ResetISR(void) { // ************************************************************* // The following conditional block of code manually resets as @@ -298,123 +322,128 @@ ResetISR(void) { // #ifndef DONT_RESET_ON_RESTART - // Disable interrupts - __asm volatile ("cpsid i"); - // equivalent to CMSIS '__disable_irq()' function + // Disable interrupts + __asm volatile ("cpsid i"); + // equivalent to CMSIS '__disable_irq()' function - unsigned int *RESET_CONTROL = (unsigned int *) 0x40053100; - // LPC_RGU->RESET_CTRL0 @ 0x40053100 - // LPC_RGU->RESET_CTRL1 @ 0x40053104 - // Note that we do not use the CMSIS register access mechanism, - // as there is no guarantee that the project has been configured - // to use CMSIS. + unsigned int *RESET_CONTROL = (unsigned int *) 0x40053100; + // LPC_RGU->RESET_CTRL0 @ 0x40053100 + // LPC_RGU->RESET_CTRL1 @ 0x40053104 + // Note that we do not use the CMSIS register access mechanism, + // as there is no guarantee that the project has been configured + // to use CMSIS. - // Write to LPC_RGU->RESET_CTRL0 - *(RESET_CONTROL+0) = 0x10DF0000; - // GPIO_RST|AES_RST|ETHERNET_RST|SDIO_RST|DMA_RST| - // USB1_RST|USB0_RST|LCD_RST + // Write to LPC_RGU->RESET_CTRL0 + *(RESET_CONTROL + 0) = 0x10DF1000; + // GPIO_RST|AES_RST|ETHERNET_RST|SDIO_RST|DMA_RST| + // USB1_RST|USB0_RST|LCD_RST|M0_SUB_RST - // Write to LPC_RGU->RESET_CTRL1 - *(RESET_CONTROL+1) = 0x01DFF7FF; - // M0APP_RST|CAN0_RST|CAN1_RST|I2S_RST|SSP1_RST|SSP0_RST| - // I2C1_RST|I2C0_RST|UART3_RST|UART1_RST|UART1_RST|UART0_RST| - // DAC_RST|ADC1_RST|ADC0_RST|QEI_RST|MOTOCONPWM_RST|SCT_RST| - // RITIMER_RST|TIMER3_RST|TIMER2_RST|TIMER1_RST|TIMER0_RST + // Write to LPC_RGU->RESET_CTRL1 + *(RESET_CONTROL + 1) = 0x01DFF7FF; + // M0APP_RST|CAN0_RST|CAN1_RST|I2S_RST|SSP1_RST|SSP0_RST| + // I2C1_RST|I2C0_RST|UART3_RST|UART1_RST|UART1_RST|UART0_RST| + // DAC_RST|ADC1_RST|ADC0_RST|QEI_RST|MOTOCONPWM_RST|SCT_RST| + // RITIMER_RST|TIMER3_RST|TIMER2_RST|TIMER1_RST|TIMER0_RST - // Clear all pending interrupts in the NVIC - volatile unsigned int *NVIC_ICPR = (unsigned int *) 0xE000E280; - unsigned int irqpendloop; - for (irqpendloop = 0; irqpendloop < 8; irqpendloop++) { - *(NVIC_ICPR+irqpendloop)= 0xFFFFFFFF; - } + // Clear all pending interrupts in the NVIC + volatile unsigned int *NVIC_ICPR = (unsigned int *) 0xE000E280; + unsigned int irqpendloop; + for (irqpendloop = 0; irqpendloop < 8; irqpendloop++) { + *(NVIC_ICPR + irqpendloop) = 0xFFFFFFFF; + } - // Reenable interrupts - __asm volatile ("cpsie i"); - // equivalent to CMSIS '__enable_irq()' function + // Reenable interrupts + __asm volatile ("cpsie i"); + // equivalent to CMSIS '__enable_irq()' function #endif // ifndef DONT_RESET_ON_RESTART // ************************************************************* +#if defined (__USE_LPCOPEN) + SystemInit(); +#endif // // Copy the data sections from flash to SRAM. // - unsigned int LoadAddr, ExeAddr, SectionLen; - unsigned int *SectionTableAddr; + unsigned int LoadAddr, ExeAddr, SectionLen; + unsigned int *SectionTableAddr; - // Load base address of Global Section Table - SectionTableAddr = &__data_section_table; + // Load base address of Global Section Table + SectionTableAddr = &__data_section_table; // Copy the data sections from flash to SRAM. - while (SectionTableAddr < &__data_section_table_end) { - LoadAddr = *SectionTableAddr++; - ExeAddr = *SectionTableAddr++; - SectionLen = *SectionTableAddr++; - data_init(LoadAddr, ExeAddr, SectionLen); - } - // At this point, SectionTableAddr = &__bss_section_table; - // Zero fill the bss segment - while (SectionTableAddr < &__bss_section_table_end) { - ExeAddr = *SectionTableAddr++; - SectionLen = *SectionTableAddr++; - bss_init(ExeAddr, SectionLen); - } + while (SectionTableAddr < &__data_section_table_end) { + LoadAddr = *SectionTableAddr++; + ExeAddr = *SectionTableAddr++; + SectionLen = *SectionTableAddr++; + data_init(LoadAddr, ExeAddr, SectionLen); + } + // At this point, SectionTableAddr = &__bss_section_table; + // Zero fill the bss segment + while (SectionTableAddr < &__bss_section_table_end) { + ExeAddr = *SectionTableAddr++; + SectionLen = *SectionTableAddr++; + bss_init(ExeAddr, SectionLen); + } +#if !defined (__USE_LPCOPEN) +// LPCOpen init code deals with FP and VTOR initialisation #if defined (__VFP_FP__) && !defined (__SOFTFP__) -/* - * Code to enable the Cortex-M4 FPU only included - * if appropriate build options have been selected. - * Code taken from Section 7.1, Cortex-M4 TRM (DDI0439C) - */ - // CPACR is located at address 0xE000ED88 - asm("LDR.W R0, =0xE000ED88"); - // Read CPACR - asm("LDR R1, [R0]"); - // Set bits 20-23 to enable CP10 and CP11 coprocessors - asm(" ORR R1, R1, #(0xF << 20)"); - // Write back the modified value to the CPACR - asm("STR R1, [R0]"); + /* + * Code to enable the Cortex-M4 FPU only included + * if appropriate build options have been selected. + * Code taken from Section 7.1, Cortex-M4 TRM (DDI0439C) + */ + // CPACR is located at address 0xE000ED88 + asm("LDR.W R0, =0xE000ED88"); + // Read CPACR + asm("LDR R1, [R0]"); + // Set bits 20-23 to enable CP10 and CP11 coprocessors + asm(" ORR R1, R1, #(0xF << 20)"); + // Write back the modified value to the CPACR + asm("STR R1, [R0]"); #endif // (__VFP_FP__) && !(__SOFTFP__) - - // ****************************** - // Check to see if we are running the code from a non-zero + // ****************************** + // Check to see if we are running the code from a non-zero // address (eg RAM, external flash), in which case we need // to modify the VTOR register to tell the CPU that the // vector table is located at a non-0x0 address. - // Note that we do not use the CMSIS register access mechanism, - // as there is no guarantee that the project has been configured - // to use CMSIS. - unsigned int * pSCB_VTOR = (unsigned int *) 0xE000ED08; - if ((unsigned int *)g_pfnVectors!=(unsigned int *) 0x00000000) { - // CMSIS : SCB->VTOR =
- *pSCB_VTOR = (unsigned int)g_pfnVectors; - } + // Note that we do not use the CMSIS register access mechanism, + // as there is no guarantee that the project has been configured + // to use CMSIS. + unsigned int * pSCB_VTOR = (unsigned int *) 0xE000ED08; + if ((unsigned int *) g_pfnVectors != (unsigned int *) 0x00000000) { + // CMSIS : SCB->VTOR =
+ *pSCB_VTOR = (unsigned int) g_pfnVectors; + } +#endif -#ifdef __USE_CMSIS - SystemInit(); +#if defined (__USE_CMSIS) + SystemInit(); #endif #if defined (__cplusplus) - // - // Call C++ library initialisation - // - __libc_init_array(); + // + // Call C++ library initialisation + // + __libc_init_array(); #endif #if defined (__REDLIB__) - // Call the Redlib library, which in turn calls main() - __main() ; + // Call the Redlib library, which in turn calls main() + __main(); #else - main(); + main(); #endif - // - // main() shouldn't return, but if it does, we'll just enter an infinite loop - // - while (1) { - ; - } + // + // main() shouldn't return, but if it does, we'll just enter an infinite loop + // + while (1) { + ; + } } //***************************************************************************** @@ -422,66 +451,48 @@ ResetISR(void) { // handler routines in your application code. //***************************************************************************** __attribute__ ((section(".after_vectors"))) -void NMI_Handler(void) -{ - while(1) - { +void NMI_Handler(void) { + while (1) { } } __attribute__ ((section(".after_vectors"))) -void HardFault_Handler(void) -{ - while(1) - { +void HardFault_Handler(void) { + while (1) { } } __attribute__ ((section(".after_vectors"))) -void MemManage_Handler(void) -{ - while(1) - { +void MemManage_Handler(void) { + while (1) { } } __attribute__ ((section(".after_vectors"))) -void BusFault_Handler(void) -{ - while(1) - { +void BusFault_Handler(void) { + while (1) { } } __attribute__ ((section(".after_vectors"))) -void UsageFault_Handler(void) -{ - while(1) - { +void UsageFault_Handler(void) { + while (1) { } } __attribute__ ((section(".after_vectors"))) -void SVC_Handler(void) -{ - while(1) - { +void SVC_Handler(void) { + while (1) { } } __attribute__ ((section(".after_vectors"))) -void DebugMon_Handler(void) -{ - while(1) - { +void DebugMon_Handler(void) { + while (1) { } } __attribute__ ((section(".after_vectors"))) -void PendSV_Handler(void) -{ - while(1) - { +void PendSV_Handler(void) { + while (1) { } } __attribute__ ((section(".after_vectors"))) -void SysTick_Handler(void) -{ - while(1) - { +void SysTick_Handler(void) { + while (1) { } } @@ -492,9 +503,7 @@ void SysTick_Handler(void) // //***************************************************************************** __attribute__ ((section(".after_vectors"))) -void IntDefaultHandler(void) -{ - while(1) - { +void IntDefaultHandler(void) { + while (1) { } } diff --git a/hw/mcu/nxp/lpc43xx/CMSIS_LPC43xx_DriverLib/src/sdio.c b/hw/mcu/nxp/lpc43xx/CMSIS_LPC43xx_DriverLib/src/sdio.c deleted file mode 100644 index a184458f6..000000000 --- a/hw/mcu/nxp/lpc43xx/CMSIS_LPC43xx_DriverLib/src/sdio.c +++ /dev/null @@ -1,1220 +0,0 @@ -/****************************************************************************************************//** - * @file sdio.c - * - * @status EXPERIMENTAL - * - * @brief LPC18xx_43xx SD/MMC/SDIO controller driver - * - * @version V1.0 - * @date 02. November 2011 - * - * Software that is described herein is for illustrative purposes only -* which provides customers with programming information regarding the -* products. This software is supplied "AS IS" without any warranties. -* NXP Semiconductors assumes no responsibility or liability for the -* use of the software, conveys no license or title under any patent, -* copyright, or mask work right to the product. NXP Semiconductors -* reserves the right to make changes in the software without -* notification. NXP Semiconductors also make no representation or -* warranty that such application will be suitable for the specified -* use without further testing or modification. -* Permission to use, copy, modify, and distribute this software and its -* documentation is hereby granted, under NXP Semiconductors’ -* relevant copyright in the software, without fee, provided that it -* is used in conjunction with NXP Semiconductors microcontrollers. This -* copyright, permission, and disclaimer notice must appear in all copies of -* this code. -*******************************************************************************************************/ - -#include -#include "LPC43xx.h" /* LPC18xx definitions */ -#include "system_LPC43xx.h" -#include "lpc_sdmmc.h" -#include "sdio.h" - -/* Global instance of the current card */ -static MCI_CARD_INFO_T g_card_info; - -#ifdef USE_DMADESC_DBUFF -/* Array of DMA descriptors used for double buffered mode. Must be enough to - transfer up to 64KBytes in a single DMA session. */ -static LPC_SDMMC_DMA_Type mci_dma_dd[1 + (0x10000 / (2 * MCI_DMADES1_MAXTR))]; -#else -/* Array of DMA descriptors used for chained mode. Must be enough to transfer - up to 64KBytes in a single DMA session. */ -static LPC_SDMMC_DMA_Type mci_dma_dd[1 + (0x10000 / MCI_DMADES1_MAXTR)]; -#endif - -/* This must be defined outside the driver and is the rate of the base - clock going into the SDIO IP */ -uint32_t sdio_clk_rate; - -extern void timer_wait_us(void *t, int us); -extern void timer_wait_ms(void *t, int ms); - -int sdio_execute_command(MCI_CARD_INFO_T* pdev, - uint32_t cmd, - uint32_t arg, - uint32_t wait_status); - -/*********************************************************************** - * MCI driver private functions - **********************************************************************/ - -/***************************************************************************** -** Function name: sdio_enable_clock -** -** Descriptions: Enables the SDIO controller clock -** -** parameters: None -** -** Returned value: None -** -*****************************************************************************/ -static void sdio_enable_clock(void) -{ - /* Enable SD MMC clock */ - LPC_CCU1->CLK_M4_SDIO_CFG = 1; -} - -/***************************************************************************** -** Function name: sdio_disable_clock -** -** Descriptions: Disables the SDIO controller clock -** -** parameters: None -** -** Returned value: None -** -*****************************************************************************/ -static void sdio_disable_clock(void) -{ - /* Disable SD MMC clock */ - LPC_CCU1->CLK_M4_SDIO_CFG = 0; -} - -/***************************************************************************** -** Function name: sdio_disable_clock -** -** Descriptions: Return clock running status -** -** parameters: None -** -** Returned value: !0 if the clock is enabled, otherwise 0 -** -*****************************************************************************/ -int sdio_is_clock_enabled(void) -{ - return (LPC_CCU1->CLK_M4_SDIO_CFG & 0x1); -} - -/********************************************************************** - ** Function name: wait_for_program_finish - ** - ** Description: Wait for card program to finish - ** - ** Parameters: pdev : None - ** - ** Returned value: None - **********************************************************************/ - static void wait_for_program_finish(void) -{ - while (sdio_get_state() == SDMMC_PRG_ST); - while (sdio_get_state() != SDMMC_TRAN_ST); -} - -/***************************************************************************** -** Function name: sdio_dma_setup -** -** Descriptions: Setup DMA descriptors -** -** parameters: addr : Address of buffer (source or destination) -** size: size of buffer in bytes (64K max) -** -** Returned value: None -** -*****************************************************************************/ -void sdio_dma_setup(uint32_t addr, uint32_t size) -{ - int i = 0; - uint32_t ctrl, maxs; -#ifdef USE_DMADESC_DBUFF - uint32_t maxs2; -#endif - - /* Reset DMA */ - LPC_SDMMC->CTRL |= MCI_CTRL_DMA_RESET | MCI_CTRL_FIFO_RESET; - while (LPC_SDMMC->CTRL & MCI_CTRL_DMA_RESET); - -#ifdef USE_DMADESC_DBUFF - /* Build a descriptor list using the double buffered DMA method */ - while (size > 0) { - /* Limit size of the transfer to maximum buffer size * 2*/ - maxs = size; - if (maxs > (MCI_DMADES1_MAXTR * 2)) - maxs = (MCI_DMADES1_MAXTR * 2); - size -= maxs; - - /* Setup buffer sizes */ - if (maxs > MCI_DMADES1_MAXTR) { - maxs2 = maxs - MCI_DMADES1_MAXTR; - maxs = MCI_DMADES1_MAXTR; - } - else - maxs2 = 0; - - /* Set buffer sizes */ - mci_dma_dd[i].des1 = MCI_DMADES1_BS1(maxs) | MCI_DMADES1_BS2(maxs2); - - /* Setup buffer address (double buffered) */ - mci_dma_dd[i].des2 = addr + (i * (MCI_DMADES1_MAXTR * 2)); - mci_dma_dd[i].des3 = mci_dma_dd[i].des2 + maxs; - - /* Setup basic control */ - ctrl = MCI_DMADES0_OWN; // | MCI_DMADES0_DIC; - if (i == 0) - ctrl |= MCI_DMADES0_FS; /* First DMA buffer */ - - /* No more data? Then this is the last descriptor */ - if (!size) - ctrl |= MCI_DMADES0_LD; - else - ctrl |= MCI_DMADES0_DIC; - - mci_dma_dd[i].des0 = ctrl; - - i++; - } - - mci_dma_dd[i].des0 = MCI_DMADES0_OWN | MCI_DMADES0_LD; - mci_dma_dd[i].des1 = 0; - mci_dma_dd[i].des2 = 0; - mci_dma_dd[i].des3 = 0; - -#else - /* Build a descriptor list using the chained DMA method */ - i = 0; - while (size > 0) { - /* Limit size of the transfer to maximum buffer size */ - maxs = size; - if (maxs > MCI_DMADES1_MAXTR) - maxs = MCI_DMADES1_MAXTR; - size -= maxs; - - /* Set buffer size */ - mci_dma_dd[i].des1 = MCI_DMADES1_BS1(maxs); - - /* Setup buffer address (chained) */ - mci_dma_dd[i].des2 = addr + (i * MCI_DMADES1_MAXTR); - - /* Setup basic control */ - ctrl = MCI_DMADES0_OWN | MCI_DMADES0_CH; - if (i == 0) - ctrl |= MCI_DMADES0_FS; /* First DMA buffer */ - - /* No more data? Then this is the last descriptor */ - if (!size) - ctrl |= MCI_DMADES0_LD; - else - ctrl |= MCI_DMADES0_DIC; - - /* Another descriptor is needed */ - mci_dma_dd[i].des3 = (uint32_t) &mci_dma_dd[i + 1]; - mci_dma_dd[i].des0 = ctrl; - - i++; - } -#endif - - /* Set DMA derscriptor base address */ - LPC_SDMMC->DBADDR = (uint32_t) &mci_dma_dd[0]; -} - -/***************************************************************************** -** Function name: prv_card_acquired -** -** Descriptions: Checks whether card is acquired properly or not -** -** parameters: pdev: Pointer to card info structure -** -** Returned value: !0 if card has been acquired, otherwise 0 -** -*****************************************************************************/ -static int prv_card_acquired(MCI_CARD_INFO_T* pdev) -{ - return (pdev->cid[0] != 0); -} - -/***************************************************************************** -** Function name: prv_get_bits -** -** Descriptions: Helper function to get a bit field withing multi-word -** buffer. Used to get fields with-in CSD & EXT-CSD -** structures. -** -** parameters: start: Start position of the bit field -** end : Start position of the bit field -** data : Pointer to buffer -** -** Returned value: The bit field value of the selected range -** -*****************************************************************************/ -static uint32_t prv_get_bits(int start, int end, uint32_t* data) -{ - uint32_t v; - uint32_t i = end >> 5; - uint32_t j = start & 0x1f; - - if (i == (start >> 5)) - v = (data[i] >> j); - else - v = ((data[i] << (32 - j)) | (data[start >> 5] >> j)); - - return (v & ((1 << (end - start + 1)) - 1)); -} - -/***************************************************************************** -** Function name: prv_clear_all -** -** Descriptions: Clears the FIFOs, response and data, and the interrupt -** status -** -** parameters: None -** -** Returned value: None -** -*****************************************************************************/ -static void prv_clear_all(void) -{ - /* reset all blocks */ - LPC_SDMMC->CTRL |= MCI_CTRL_FIFO_RESET; - - /* wait till resets clear */ - while (LPC_SDMMC->CTRL & MCI_CTRL_FIFO_RESET); - - /* Clear interrupt status */ - LPC_SDMMC->RINTSTS = 0xFFFFFFFF; -} - -/***************************************************************************** -** Function name: prv_send_cmd -** -** Descriptions: Function to send command to Card interface unit (CIU) -** -** parameters: cmd : Command with all flags set. -** arg : Argument for the command -** -** Returned value: TRUE on times-out, otherwise FALSE -** -*****************************************************************************/ -static int prv_send_cmd(uint32_t cmd, uint32_t arg) -{ - volatile int tmo = 50; - volatile int delay; - - /* set command arg reg*/ - LPC_SDMMC->CMDARG = arg; - LPC_SDMMC->CMD = MCI_CMD_START | cmd; - - /* poll untill command is accepted by the CIU */ - while (--tmo && (LPC_SDMMC->CMD & MCI_CMD_START)) - { - if (tmo & 1) - delay = 50; - else - delay = 18000; - - while (--delay > 1); - } - - return (tmo < 1) ? 1 : 0; -} - -/***************************************************************************** -** Function name: prv_set_clock -** -** Descriptions: Function to set speed of the clock going to card -** -** parameters: speed : Clock speed -** -** Returned value: TRUE on times-out, otherwise FALSE -** -*****************************************************************************/ -static void prv_set_clock(uint32_t speed) -{ - /* compute SD/MMC clock dividers */ - uint32_t div; - - div = ((sdio_clk_rate / speed) + 2) >> 1; - - if ((div == LPC_SDMMC->CLKDIV) && LPC_SDMMC->CLKENA) - return; /* requested speed is already set */ - - /* disable clock */ - LPC_SDMMC->CLKENA = 0; - - /* User divider 0 */ - LPC_SDMMC->CLKSRC = MCI_CLKSRC_CLKDIV0; - - /* inform CIU */ - prv_send_cmd(MCI_CMD_UPD_CLK | MCI_CMD_PRV_DAT_WAIT, 0); - - /* set divider 0 to desired value */ - LPC_SDMMC->CLKDIV = MCI_CLOCK_DIVIDER(0, div); - /* inform CIU */ - prv_send_cmd(MCI_CMD_UPD_CLK | MCI_CMD_PRV_DAT_WAIT, 0); - - /* enable clock */ - LPC_SDMMC->CLKENA = MCI_CLKEN_ENABLE(0); - /* inform CIU */ - prv_send_cmd(MCI_CMD_UPD_CLK | MCI_CMD_PRV_DAT_WAIT, 0); -} - -/***************************************************************************** -** Function name: prv_pull_response -** -** Descriptions: Function to retrieve command response -** -** parameters: pdev: Pointer to card info structure -** length : the length of the expected response, in bits -** -** Returned value: None -** -*****************************************************************************/ -static void prv_pull_response(MCI_CARD_INFO_T* pdev, int length) -{ - /* on this chip response is not a fifo so read all 4 regs */ - pdev->response[0] = LPC_SDMMC->RESP0; - pdev->response[1] = LPC_SDMMC->RESP1; - pdev->response[2] = LPC_SDMMC->RESP2; - pdev->response[3] = LPC_SDMMC->RESP3; -} - -/***************************************************************************** -** Function name: prv_wait_for_completion -** -** Descriptions: Polls for command completion -** -** parameters: pdev : Pointer to card info structure -** bit : Status bits to poll for command completion. -** -** Returned value: 0 on success, or failure condition (-1) -** -*****************************************************************************/ -static uint32_t prv_wait_for_completion(MCI_CARD_INFO_T* pdev, uint32_t bits) -{ - uint32_t status = 0; - int tmo_count = US_TIMEOUT; - - /* also check error conditions */ - bits |= MCI_INT_EBE | MCI_INT_SBE | MCI_INT_HLE - | MCI_INT_RTO | MCI_INT_RCRC | MCI_INT_RESP_ERR; - - if (bits & MCI_INT_DATA_OVER) - bits |= MCI_INT_FRUN | MCI_INT_HTO | MCI_INT_DTO - | MCI_INT_DCRC; - - if (pdev->wait_func == 0) - { - /* do busy polling when wait_func is not set*/ - do - { - timer_wait_us(0, 1); - status = LPC_SDMMC->RINTSTS; - - if (--tmo_count < 1) - { - break; - } - } - while ((status & bits) == 0); - /* set time out flag for driver timeout also */ - status |= ((tmo_count < 1) ? MCI_INT_RTO : 0); - } - else - { - /* call wait function set by application */ - status = pdev->wait_func(pdev, bits); - } - - return status; -} - -/***************************************************************************** -** Function name: prv_process_csd -** -** Descriptions: Function to process the CSD & EXT-CSD of the card -** -** parameters: pdev: Pointer to card info structure -** -** Returned value: None -** -*****************************************************************************/ -static void prv_process_csd(MCI_CARD_INFO_T* pdev) -{ - int status = 0; - int c_size = 0; - int c_size_mult = 0; - int mult = 0; - - /* compute block length based on CSD response */ - pdev->block_len = 1 << prv_get_bits(80, 83, pdev->csd); - - if ((pdev->card_type & CARD_TYPE_HC) && - (pdev->card_type & CARD_TYPE_SD)) - { - /* See section 5.3.3 CSD Register (CSD Version 2.0) of SD2.0 spec - an explanation for the calculation of these values - */ - c_size = prv_get_bits(48, 63, (uint32_t*)pdev->csd) + 1; - pdev->blocknr = c_size << 10; /* 512 byte blocks */ - } - else - { - /* See section 5.3 of the 4.1 revision of the MMC specs for - an explanation for the calculation of these values - */ - c_size = prv_get_bits(62, 73, (uint32_t*)pdev->csd); - c_size_mult = prv_get_bits(47, 49, (uint32_t*)pdev->csd); //csd_c_size_mult (); - mult = 1 << (c_size_mult + 2); - pdev->blocknr = (c_size + 1) * mult; - /* adjust blocknr to 512/block */ - if (pdev->block_len > MMC_SECTOR_SIZE) - pdev->blocknr = pdev->blocknr * (pdev->block_len >> 9); - - /* get extended CSD for newer MMC cards CSD spec >= 4.0*/ - if (((pdev->card_type & CARD_TYPE_SD) == 0) && - (prv_get_bits(122, 125, (uint32_t*)pdev->csd) >= 4)) - { - /* put card in trans state */ - status = sdio_execute_command(pdev, CMD_SELECT_CARD, pdev->rca << 16, 0); - /* set block size and byte count */ - LPC_SDMMC->BLKSIZ = MMC_SECTOR_SIZE; - LPC_SDMMC->BYTCNT = MMC_SECTOR_SIZE; - /* send EXT_CSD command */ - sdio_dma_setup((uint32_t) pdev->ext_csd, MMC_SECTOR_SIZE); - status = sdio_execute_command(pdev, CMD_SEND_EXT_CSD, 0, 0 - | MCI_INT_DATA_OVER); - if ((status & MCI_INT_ERROR) == 0) - { - /* check EXT_CSD_VER is greater than 1.1 */ - if ((pdev->ext_csd[48] & 0xFF) > 1) - pdev->blocknr = pdev->ext_csd[53]; /* bytes 212:215 represent sec count */ - - /* switch to 52MHz clock if card type is set to 1 or else set to 26MHz */ - if ((pdev->ext_csd[49] & 0xFF) == 1) - { - /* for type 1 MMC cards high speed is 52MHz */ - pdev->speed = MMC_HIGH_BUS_MAX_CLOCK; - } - else - { - /* for type 0 MMC cards high speed is 26MHz */ - pdev->speed = MMC_LOW_BUS_MAX_CLOCK; - } - } - } - } - - pdev->device_size = pdev->blocknr << 9; /* blocknr * 512 */ -} - -/***************************************************************************** -** Function name: prv_set_trans_state -** -** Descriptions: Puts current selected card in trans state -** -** parameters: pdev: Pointer to card info structure -** -** Returned value: 0 on success, or error code (-1) -** -*****************************************************************************/ -static int prv_set_trans_state(MCI_CARD_INFO_T* pdev) -{ - uint32_t status; - - /* get current state of the card */ - status = sdio_execute_command(pdev, CMD_SEND_STATUS, pdev->rca << 16, 0); - if (status & MCI_INT_RTO) - { - /* unable to get the card state. So return immediatly. */ - return -1; - } - /* check card state in response */ - status = R1_CURRENT_STATE(pdev->response[0]); - switch (status) - { - case SDMMC_STBY_ST: - /* put card in 'Trans' state */ - status = sdio_execute_command(pdev, CMD_SELECT_CARD, pdev->rca << 16, 0); - if (status != 0) - { - /* unable to put the card in Trans state. So return immediatly. */ - return -1; - } - break; - case SDMMC_TRAN_ST: - /*do nothing */ - break; - default: - /* card shouldn't be in other states so return */ - return -1; - } - -#if SDIO_BUS_WIDTH > 1 - if (pdev->card_type & CARD_TYPE_SD) - { - sdio_execute_command(pdev, CMD_SD_SET_WIDTH, 2, 0); /* SD, 4 bit width */ - /* if positive response */ - LPC_SDMMC->CTYPE = MCI_CTYPE_4BIT(0); - } -#if SDIO_BUS_WIDTH > 4 -#error 8-bit mode not supported yet! -#endif -#endif - /* set block length */ - LPC_SDMMC->BLKSIZ = MMC_SECTOR_SIZE; - status = sdio_execute_command(pdev, CMD_SET_BLOCKLEN, MMC_SECTOR_SIZE, 0); - - return 0; -} - -/*********************************************************************** - * MCI driver public functions - **********************************************************************/ - - /***************************************************************************** -** Function name: sdio_execute_command -** -** Descriptions: Function to execute a command -** -** parameters: pdev: Pointer to card info structure -** cmd : Command with all flags set. -** arg : Argument for the command -** wait_status : Status bits to poll for command completion. -** -** Returned value: 0 on success, or error code (-1) -** -*****************************************************************************/ -int sdio_execute_command(MCI_CARD_INFO_T* pdev, - uint32_t cmd, - uint32_t arg, - uint32_t wait_status) -{ - /* if APP command there are 2 stages */ - int step = (cmd & CMD_BIT_APP) ? 2 : 1; - int status = 0; - uint32_t cmd_reg = 0; - - if (!wait_status) - wait_status = (cmd & CMD_MASK_RESP) ? MCI_INT_CMD_DONE : MCI_INT_DATA_OVER; - - /* Clear the interrupts & FIFOs*/ - if (cmd & CMD_BIT_DATA) - prv_clear_all(); - - while (step) - { - prv_set_clock((cmd & CMD_BIT_LS) ? SD_MMC_ENUM_CLOCK : pdev->speed); - - /* Clear the interrupts */ - LPC_SDMMC->RINTSTS = 0xFFFFFFFF; - - switch (step) - { - case 1: /* Execute command */ - cmd_reg = ((cmd & CMD_MASK_CMD) >> CMD_SHIFT_CMD) - | ((cmd & CMD_BIT_INIT) ? MCI_CMD_INIT : 0) - | ((cmd & CMD_BIT_DATA) ? (MCI_CMD_DAT_EXP | MCI_CMD_PRV_DAT_WAIT) : 0) - | (((cmd & CMD_MASK_RESP) == CMD_RESP_R2) ? MCI_CMD_RESP_LONG : 0) - | ((cmd & CMD_MASK_RESP) ? MCI_CMD_RESP_EXP : 0) - | ((cmd & CMD_BIT_WRITE) ? MCI_CMD_DAT_WR : 0) - | ((cmd & CMD_BIT_STREAM) ? MCI_CMD_STRM_MODE : 0) - | ((cmd & CMD_BIT_BUSY) ? MCI_CMD_STOP : 0) - | ((cmd & CMD_BIT_AUTO_STOP) ? MCI_CMD_SEND_STOP : 0) - | MCI_CMD_START - ; - /* wait for previos data finsh for select/deselect commands */ - if (((cmd & CMD_MASK_CMD) >> CMD_SHIFT_CMD) == MMC_SELECT_CARD) - { - cmd_reg |= MCI_CMD_PRV_DAT_WAIT; - } - - /* wait for command to be accepted by CIU */ - if (prv_send_cmd(cmd_reg, arg) == 0) - --step; - break; - - case 0: - return 0; - - case 2: /* APP prefix */ - cmd_reg = MMC_APP_CMD - | MCI_CMD_RESP_EXP /* Response is status */ - | ((cmd & CMD_BIT_INIT) ? MCI_CMD_INIT : 0) - | MCI_CMD_START - ; - if (prv_send_cmd(cmd_reg, pdev->rca << 16) == 0) - --step; - break; - } - - /* wait for command response*/ - status = prv_wait_for_completion(pdev, wait_status); - - /* We return an error if there is a timeout, even if we've fetched - a response */ - if (status & MCI_INT_ERROR) - return status; - - if (status & MCI_INT_CMD_DONE) - { - switch (cmd & CMD_MASK_RESP) - { - case 0: - break; - case CMD_RESP_R1: - case CMD_RESP_R3: - prv_pull_response(pdev, 48); - break; - case CMD_RESP_R2: - prv_pull_response(pdev, 136); - break; - } - } - } - return 0; -} - - /***************************************************************************** -** Function name: sdio_acquire -** -** Descriptions: Function to enumerate the SD/MMC/SDHC/MMC+ cards -** -** parameters: None -** -** Returned value: 1 if a card is acquired, otherwise 0 -** -*****************************************************************************/ -int sdio_acquire(void) -{ - MCI_CARD_INFO_T* pdev = &g_card_info; - int status; - int tries = 0; - uint32_t ocr = OCR_VOLTAGE_RANGE_MSK; - uint32_t r; - int state = 0; - uint32_t command = 0; - /* preserve wait_func and irq callback*/ - MCI_CMD_WAIT_FUNC_T temp = pdev->wait_func; - MCI_IRQ_CB_FUNC_T tempirq = pdev->irq_callback; - - /* clear card struct */ - memset(pdev, 0, sizeof(MCI_CARD_INFO_T)); - /* restore wait_func */ - pdev->wait_func = temp; - pdev->irq_callback = tempirq; - - /* clear card type */ - LPC_SDMMC->CTYPE = 0; - - /* set high speed for the card as 20MHz */ - pdev->speed = MMC_MAX_CLOCK; - - status = sdio_execute_command(pdev, CMD_IDLE, 0, MCI_INT_CMD_DONE); - - while (state < 100) - { - switch (state) - { - case 0: /* Setup for SD */ - /* check if it is SDHC card */ - status = sdio_execute_command(pdev, CMD_SD_SEND_IF_COND, SD_SEND_IF_ARG, 0); - if (!(status & MCI_INT_RTO)) - { - - /* check response has same echo pattern */ - if ((pdev->response[0] & SD_SEND_IF_ECHO_MSK) == SD_SEND_IF_RESP) - /* it is SD 2.0 card so indicate we are SDHC capable*/ - ocr |= OCR_HC_CCS; - } - - ++state; - command = CMD_SD_OP_COND; - tries = INIT_OP_RETRIES; - /* assume SD card */ - pdev->card_type |= CARD_TYPE_SD; - /* for SD cards high speed is 25MHz */ - pdev->speed = SD_MAX_CLOCK; - - break; - - case 10: /* Setup for MMC */ - /* start fresh for MMC crds */ - pdev->card_type &= ~CARD_TYPE_SD; - status = sdio_execute_command(pdev, CMD_IDLE, 0, MCI_INT_CMD_DONE); - command = CMD_MMC_OP_COND; - tries = INIT_OP_RETRIES; - ocr |= OCR_HC_CCS; - ++state; - /* for MMC cards high speed is 20MHz */ - pdev->speed = MMC_MAX_CLOCK; - break; - - case 1: - case 11: - status = sdio_execute_command(pdev, command, 0, 0); - if (status & MCI_INT_RTO) - state += 9; /* Mode unavailable */ - else - ++state; - break; - - case 2: /* Initial OCR check */ - case 12: - ocr = pdev->response[0] | (ocr & OCR_HC_CCS); - if (ocr & OCR_ALL_READY) - ++state; - else - state += 2; - break; - - case 3: /* Initial wait for OCR clear */ - case 13: - while ((ocr & OCR_ALL_READY) && --tries > 0) - { - timer_wait_ms(0, MS_ACQUIRE_DELAY); - status = sdio_execute_command(pdev, command, 0, 0); - ocr = pdev->response[0] | (ocr & OCR_HC_CCS); - } - if (ocr & OCR_ALL_READY) - state += 7; - else - ++state; - break; - - case 14: - /* for MMC cards set high capacity bit */ - ocr |= OCR_HC_CCS; - case 4: /* Assign OCR */ - tries = SET_OP_RETRIES; - ocr &= OCR_VOLTAGE_RANGE_MSK | OCR_HC_CCS; /* Mask for the bits we care about */ - do - { - timer_wait_ms(0, MS_ACQUIRE_DELAY); - status = sdio_execute_command(pdev, command, ocr, 0); - r = pdev->response[0]; - } - while (!(r & OCR_ALL_READY) && --tries > 0); - if (r & OCR_ALL_READY) - { - /* is it high capacity card */ - pdev->card_type |= (r & OCR_HC_CCS); - ++state; - } - else - state += 6; - - break; - - case 5: /* CID polling */ - case 15: - status = sdio_execute_command(pdev, CMD_ALL_SEND_CID, 0, 0); - memcpy(pdev->cid, pdev->response, 16); - ++state; - break; - - case 6: /* RCA send, for SD get RCA */ - status = sdio_execute_command(pdev, CMD_SD_SEND_RCA, 0, 0); - pdev->rca = (pdev->response[0]) >> 16; - ++state; - break; - case 16: /* RCA assignment for MMC set to 1 */ - pdev->rca = 1; - status = sdio_execute_command(pdev, CMD_MMC_SET_RCA, pdev->rca << 16, 0); - ++state; - break; - - case 7: - case 17: - status = sdio_execute_command(pdev, CMD_SEND_CSD, pdev->rca << 16, 0); - memcpy(pdev->csd, pdev->response, 16); - state = 100; - break; - - default: - state += 100; /* break from while loop */ - break; - } - } - - /* Compute card size, block size and no. of blocks - based on CSD response recived. */ - if (prv_card_acquired(pdev)) - prv_process_csd(pdev); - - return prv_card_acquired(&g_card_info); -} - - /***************************************************************************** -** Function name: sdio_init -** -** Descriptions: Initializes the MCI card controller -** -** parameters: waitfunc : Pointer to wait function to be used during for poll -** command status. -** irqfunc : Pointer to IRQ status callback -** -** Returned value: None -** -*****************************************************************************/ -void sdio_init(MCI_CMD_WAIT_FUNC_T waitfunc, - MCI_IRQ_CB_FUNC_T irqfunc) -{ - volatile uint32_t i; - - /* enable SD/MMC clock */ - sdio_enable_clock(); - - /* Software reset */ - LPC_SDMMC->BMOD = MCI_BMOD_SWR; - - /* reset all blocks */ - LPC_SDMMC->CTRL = MCI_CTRL_RESET | MCI_CTRL_FIFO_RESET - | MCI_CTRL_DMA_RESET; - while (LPC_SDMMC->CTRL & - (MCI_CTRL_RESET | MCI_CTRL_FIFO_RESET | MCI_CTRL_DMA_RESET)); - - /* Internal DMA setup for control register */ -#ifdef SDIO_USE_POLLING - LPC_SDMMC->CTRL = MCI_CTRL_USE_INT_DMAC; -#else - LPC_SDMMC->CTRL = MCI_CTRL_USE_INT_DMAC | MCI_CTRL_INT_ENABLE; -#endif - /* Clear the interrupts for the host controller */ - LPC_SDMMC->RINTSTS = 0xFFFFFFFF; - - /* Put in max timeout */ - LPC_SDMMC->TMOUT = 0xFFFFFFFF; - - /* FIFO threshold settings for DMA, DMA burst of 4, - FIFO watermark at 16 */ - LPC_SDMMC->FIFOTH = (0x1 << 28) | (0xF << 16) | (0x10 << 0); - - /* Enable DMA, burst size of 4, fixed burst */ - LPC_SDMMC->BMOD = MCI_BMOD_DE | MCI_BMOD_PBL4 | MCI_BMOD_DSL(4); - - /* disable clock to CIU (needs latch) */ - LPC_SDMMC->CLKENA = 0; - LPC_SDMMC->CLKSRC = 0; - - /* clear mmc structure*/ - memset(&g_card_info, 0, sizeof(MCI_CARD_INFO_T)); - /* set the wait_func if passed */ - g_card_info.wait_func = waitfunc; - g_card_info.irq_callback = irqfunc; - - /* If not in polling mode, enable SDIO IRQ */ -#ifndef SDIO_USE_POLLING - NVIC_EnableIRQ(SDIO_IRQn); -#endif -} - -/***************************************************************************** -** Function name: sdio_card_detect -** -** Descriptions: Detect if an SD card is inserted -** -** parameters: None -** -** Returned value: 1 if a card is detected, otherwise 0 -** -*****************************************************************************/ -int sdio_card_detect(void) -{ - /* No card = high state in regsiter */ - if (LPC_SDMMC->CDETECT & 1) - return 0; - - return 1; -} - -/***************************************************************************** -** Function name: sdio_card_wp_on -** -** Descriptions: Detect if write protect is enabled -** -** parameters: None -** -** Returned value: Returns 1 if card is write protected, otherwise 0 -** -*****************************************************************************/ -int sdio_card_wp_on(void) -{ - if (LPC_SDMMC->WRTPRT & 1) - return 1; - - return 0; -} - -/***************************************************************************** -** Function name: sdio_power_on -** -** Descriptions: Enable slot power -** -** Returned value: None -** -*****************************************************************************/ -void sdio_power_on(void) -{ - sdio_power_onoff(0); - -} - -/***************************************************************************** -** Function name: sdio_power_off -** -** Descriptions: Enable slot power -** -** Returned value: None -** -*****************************************************************************/ -void sdio_power_off(void) -{ - sdio_power_onoff(1); - -} - -/***************************************************************************** -** Function name: sdio_power_onoff -** -** Descriptions: Enable or disable slot power -** -** parameters: enable: !0 to enable, or 0 to disable -** -** Returned value: None -** -*****************************************************************************/ -void sdio_power_onoff(int enable) -{ - if (enable) - LPC_SDMMC->PWREN = 1; - else - LPC_SDMMC->PWREN = 0; -} - -/***************************************************************************** -** Function name: sdio_get_state -** -** Descriptions: Get card's current state (idle, transfer, program, etc.) -** -** parameters: None -** -** Returned value: Current transfer state (0 - -** -*****************************************************************************/ - -/* Get card's current state (idle, transfer, program, etc.) */ -int sdio_get_state(void) -{ - uint32_t status; - - /* get current state of the card */ - status = sdio_execute_command(&g_card_info, CMD_SEND_STATUS, g_card_info.rca << 16, 0); - if (status & MCI_INT_RTO) - { - /* unable to get the card state. So return immediatly. */ - return -1; - } - /* check card state in response */ - return (int) R1_CURRENT_STATE(g_card_info.response[0]); -} - -/***************************************************************************** -** Function name: sdio_deinit -** -** Descriptions: Close the MCI -** -** parameters: None -** -** Returned value: None -** -*****************************************************************************/ -void sdio_deinit(void) -{ - /* Place card in idle state */ - if (prv_card_acquired(&g_card_info) == 0) - sdio_execute_command(&g_card_info, CMD_IDLE, 0, MCI_INT_CMD_DONE); - - /* clear mmc structure*/ - memset(&g_card_info, 0, sizeof(MCI_CARD_INFO_T)); - sdio_disable_clock(); -} - -/***************************************************************************** -** Function name: sdio_read_blocks -** -** Descriptions: Performs the read of data from the SD/MMC card -** -** parameters: buffer: Pointer to data buffer to copy to -** start_block: Start block number -** end_block: End block number -** -** Returned value: Bytes read, or 0 on error -** -*****************************************************************************/ -int sdio_read_blocks(void* buffer, - int start_block, - int end_block) -{ - MCI_CARD_INFO_T* pdev = &g_card_info; - int cbRead = (end_block - start_block + 1) << 9; /*(end_block - start_block) * 512 */ - int status = 0; - int index; - - /* if card is not acquired return immediately */ - if ((prv_card_acquired(pdev) == 0) - || (end_block < start_block) /* check block index in range */ - || (start_block < 0) - || (end_block > pdev->blocknr) - ) - { - return 0; - } - /* put card in trans state */ - if (prv_set_trans_state(pdev) != 0) - return 0; - - /* set number of bytes to read */ - LPC_SDMMC->BYTCNT = cbRead; - - /* if high capacity card use block indexing */ - if (pdev->card_type & CARD_TYPE_HC) - index = start_block; - else - index = start_block << 9; - - sdio_dma_setup((uint32_t) buffer, cbRead); - - /* check how many blocks to read */ - if (end_block == start_block) - { - status = sdio_execute_command(pdev, CMD_READ_SINGLE, index, - 0 | MCI_INT_DATA_OVER); - } - else - { - /* do read multiple */ - status = sdio_execute_command(pdev, CMD_READ_MULTIPLE, index, - 0 | MCI_INT_DATA_OVER); - } - - if (status != 0) - cbRead = 0; /* return error if command fails */ - - wait_for_program_finish(); - - return cbRead; -} - -/***************************************************************************** -** Function name: sdio_write_blocks -** -** Descriptions: Performs write of data to the SD/MMC card -** -** parameters: buffer: Pointer to data buffer to copy to -** start_block: Start block number -** end_block: End block number -** -** Returned value: Number of bytes actually written, or 0 on error -** -*****************************************************************************/ -int sdio_write_blocks(void* buffer, - int start_block, - int end_block) -{ - MCI_CARD_INFO_T* pdev = &g_card_info; - /*(end_block - start_block) * 512 */ - int cbWrote = (end_block - start_block + 1) << 9; - int status; - int index; - - /* if card is not acquired return immediately */ - if ((prv_card_acquired(pdev) == 0) - || (end_block < start_block) /* check block index in range */ - || (start_block < 0) - || (end_block > pdev->blocknr) - ) - { - return 0; - } - - wait_for_program_finish(); - - /* put card in trans state */ - if (prv_set_trans_state(pdev) != 0) - return 0; - - /* set number of bytes to write */ - LPC_SDMMC->BYTCNT = cbWrote; - - /* if high capacity card use block indexing */ - if (pdev->card_type & CARD_TYPE_HC) - index = start_block; - else - index = start_block << 9; - - sdio_dma_setup((uint32_t) buffer, cbWrote); - - wait_for_program_finish(); - - /* check how many blocks to write */ - if (end_block == start_block) - { - status = sdio_execute_command(pdev, CMD_WRITE_SINGLE, index, - 0 | MCI_INT_DATA_OVER); - } - else - { - /* do write multiple */ - status = sdio_execute_command(pdev, CMD_WRITE_MULTIPLE, index, - 0 | MCI_INT_DATA_OVER); - } - - if (status != 0) - cbWrote = 0; - - wait_for_program_finish(); - - return cbWrote; -} - -/********************************************************************** - ** Function name: SDIO_IRQHandler - ** - ** Description: SDIO controller interrupt handler - ** - ** Parameters: None - ** - ** Returned value: None - **********************************************************************/ -void SDIO_IRQHandler(void) -{ - if (g_card_info.irq_callback) - g_card_info.irq_callback(&g_card_info, LPC_SDMMC->RINTSTS); -} - -/********************************************************************** - ** Function name: sdio_get_device_size - ** - ** Description: Return the capacity of the SD card in bytes - ** - ** Parameters: None - ** - ** Returned value: Device capacity in bytes - **********************************************************************/ -int sdio_get_device_size(void) -{ - return g_card_info.device_size; -} - diff --git a/tinyusb/tusb_option.h b/tinyusb/tusb_option.h index 9e2a4576e..377d3756e 100644 --- a/tinyusb/tusb_option.h +++ b/tinyusb/tusb_option.h @@ -119,6 +119,9 @@ #error TUSB_CFG_ATTR_USBRAM is not defined, please help me know how to place data in accessible RAM for usb controller #endif +#ifndef TUSB_OS_NONE +#define TUSB_CFG_OS TUSB_OS_NONE +#endif #if (TUSB_CFG_OS != TUSB_OS_NONE) && !defined (TUSB_CFG_OS_TASK_PRIO) #error TUSB_CFG_OS_TASK_PRIO need to be defined (hint: use the highest if possible)