diff --git a/SConscript b/SConscript new file mode 100644 index 000000000..b5043f437 --- /dev/null +++ b/SConscript @@ -0,0 +1,11 @@ +# RT-Thread building script for bridge + +import os +from building import * + +objs = [] +cwd = GetCurrentDir() + +objs = objs + SConscript(cwd + '/lib/rt-thread/SConscript') + +Return('objs') diff --git a/lib/rt-thread/SConscript b/lib/rt-thread/SConscript new file mode 100644 index 000000000..14fbf5549 --- /dev/null +++ b/lib/rt-thread/SConscript @@ -0,0 +1,42 @@ +import rtconfig +from building import * + +cwd = GetCurrentDir() +src = Split(""" +../../src/tusb.c +../../src/common/tusb_fifo.c +../../src/device/usbd.c +../../src/device/usbd_control.c +./tusb_rt_thread_port.c +""") +path = [cwd, cwd + "/../../src"] + +# BSP +if GetDepend(["SOC_FAMILY_STM32"]): + src += ["../../src/portable/synopsys/dwc2/dcd_dwc2.c", + "../../src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c"] + +if GetDepend(["SOC_NRF52840"]): + src += ["../../src/portable/nordic/nrf5x/dcd_nrf5x.c"] + +if GetDepend(["SOC_FAMILY_RENESAS"]): + src += ["../../src/portable/renesas/rusb2/dcd_rusb2.c", + "../../src/portable/renesas/rusb2/rusb2_common.c"] + +# Device class +if GetDepend(["PKG_TINYUSB_DEVICE_CDC"]): + src += ["../../src/class/cdc/cdc_device.c"] + +if GetDepend(["PKG_TINYUSB_DEVICE_MSC"]): + src += ["../../src/class/msc/msc_device.c", "port/msc_device_port.c"] + +LOCAL_CFLAGS = '' + +if rtconfig.PLATFORM == 'gcc' or rtconfig.PLATFORM == 'armclang': # GCC or Keil AC6 + LOCAL_CFLAGS += ' -std=c99' +elif rtconfig.PLATFORM == 'armcc': # Keil AC5 + LOCAL_CFLAGS += ' --c99 --gnu' + +group = DefineGroup('TinyUSB', src, depend = ['PKG_USING_TINYUSB'], CPPPATH = path, LOCAL_CFLAGS = LOCAL_CFLAGS) + +Return('group') diff --git a/lib/rt-thread/port/msc_device_port.c b/lib/rt-thread/port/msc_device_port.c new file mode 100644 index 000000000..6af3c4f61 --- /dev/null +++ b/lib/rt-thread/port/msc_device_port.c @@ -0,0 +1,171 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ +#ifdef __RTTHREAD__ +#include +#include + +#include +#include + +static bool ejected = false; +static rt_device_t flash_device; +static struct rt_device_blk_geometry blk_geom; + +#ifdef __CC_ARM +uint16_t __builtin_bswap16(uint16_t x) +{ + return (x << 8) | (x >> 8); +} +#endif + +void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) +{ + (void) lun; + + const char vid[] = PKG_TINYUSB_DEVICE_MSC_VID; + const char pid[] = PKG_TINYUSB_DEVICE_MSC_PID; + const char rev[] = PKG_TINYUSB_DEVICE_MSC_REV; + + memcpy(vendor_id, vid, strlen(vid)); + memcpy(product_id, pid, strlen(pid)); + memcpy(product_rev, rev, strlen(rev)); +} + +bool tud_msc_test_unit_ready_cb(uint8_t lun) +{ + (void) lun; + + if (ejected) + { + tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00); + return false; + } + + if (flash_device == NULL) + { + flash_device = rt_device_find(PKG_TINYUSB_DEVICE_MSC_NAME); + } + if (flash_device != NULL) + { + static uint8_t open_flg = 0; + if (!open_flg) + { + open_flg = 1; + rt_device_open(flash_device, 0); + } + + rt_device_control(flash_device, RT_DEVICE_CTRL_BLK_GETGEOME, &blk_geom); + return true; + } + + return false; +} + +void tud_msc_capacity_cb(uint8_t lun, uint32_t *block_count, uint16_t *block_size) +{ + (void) lun; + + *block_count = blk_geom.sector_count; + *block_size = blk_geom.bytes_per_sector; +} + +bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) +{ + (void) lun; + (void) power_condition; + + if (load_eject) + { + if (start) + { + ejected = false; + } else { + // unload disk storage + ejected = true; + } + } + + return true; +} + +int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize) +{ + (void) lun; + (void) offset; + (void) bufsize; + + return (int32_t) rt_device_read(flash_device, (rt_off_t) lba, buffer, 1) * blk_geom.bytes_per_sector; +} + +int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize) +{ + (void) lun; + (void) offset; + (void) bufsize; + + return (int32_t) rt_device_write(flash_device, (rt_off_t) lba, buffer, 1) * blk_geom.bytes_per_sector; +} + +int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, uint16_t bufsize) +{ + void const *response = NULL; + uint16_t resplen = 0; + + // most scsi handled is input + bool in_xfer = true; + + switch (scsi_cmd[0]) + { + case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: + // Host is about to read/write etc ... better not to disconnect disk + resplen = 0; + break; + + default: + // Set Sense = Invalid Command Operation + tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); + + // negative means error -> tinyusb could stall and/or response with failed status + resplen = -1; + break; + } + + // return resplen must not larger than bufsize + if (resplen > bufsize) resplen = bufsize; + + if (response && (resplen > 0)) + { + if (in_xfer) + { + memcpy(buffer, response, resplen); + } else { + // SCSI output + } + } + + return resplen; +} +#endif /*__RTTHREAD__*/ diff --git a/lib/rt-thread/tusb_config.h b/lib/rt-thread/tusb_config.h new file mode 100644 index 000000000..8b145f3f7 --- /dev/null +++ b/lib/rt-thread/tusb_config.h @@ -0,0 +1,147 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __RTTHREAD__ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +#if defined(SOC_SERIES_STM32F0) +#define CFG_TUSB_MCU OPT_MCU_STM32F0 +#elif defined(SOC_SERIES_STM32F1) +#define CFG_TUSB_MCU OPT_MCU_STM32F1 +#elif defined(SOC_SERIES_STM32F2) +#define CFG_TUSB_MCU OPT_MCU_STM32F2 +#elif defined(SOC_SERIES_STM32F3) +#define CFG_TUSB_MCU OPT_MCU_STM32F3 +#elif defined(SOC_SERIES_STM32F4) +#define CFG_TUSB_MCU OPT_MCU_STM32F4 +#elif defined(SOC_SERIES_STM32F7) +#define CFG_TUSB_MCU OPT_MCU_STM32F7 +#elif defined(SOC_SERIES_STM32H7) +#define CFG_TUSB_MCU OPT_MCU_STM32H7 +#elif defined(SOC_SERIES_STM32L0) +#define CFG_TUSB_MCU OPT_MCU_STM32L0 +#elif defined(SOC_SERIES_STM32L1) +#define CFG_TUSB_MCU OPT_MCU_STM32L1 +#elif defined(SOC_SERIES_STM32L4) +#define CFG_TUSB_MCU OPT_MCU_STM32L4 +#elif defined(SOC_NRF52840) +#define CFG_TUSB_MCU OPT_MCU_NRF5X +#elif defined(SOC_HPM6000) +#define CFG_TUSB_MCU OPT_MCU_HPM +#elif defined(SOC_RP2040) +#define CFG_TUSB_MCU OPT_MCU_RP2040 +#elif defined(SOC_FAMILY_RENESAS) +#define CFG_TUSB_MCU OPT_MCU_RAXXX +#else +#error "Not support for current MCU" +#endif + +#define CFG_TUSB_OS OPT_OS_RTTHREAD + +//-------------------------------------------------------------------- +// DEBUG CONFIGURATION +//-------------------------------------------------------------------- +#ifdef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG_PRINTF rt_kprintf +#endif /* CFG_TUSB_DEBUG */ + +#ifndef BOARD_DEVICE_RHPORT_NUM +#define BOARD_DEVICE_RHPORT_NUM PKG_TINYUSB_RHPORT_NUM +#endif + +#ifndef BOARD_DEVICE_RHPORT_SPEED +#define BOARD_DEVICE_RHPORT_SPEED PKG_TINYUSB_DEVICE_PORT_SPEED +#endif + +#if BOARD_DEVICE_RHPORT_NUM == 0 +#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#elif BOARD_DEVICE_RHPORT_NUM == 1 +#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#else + #error "Incorrect RHPort configuration" +#endif + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION rt_section(PKG_TINYUSB_MEM_SECTION) +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN rt_align(PKG_TINYUSB_MEM_ALIGN) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE PKG_TINYUSB_EDPT0_SIZE +#endif + +// CDC FIFO size of TX and RX +#define CFG_TUD_CDC_RX_BUFSIZE PKG_TINYUSB_DEVICE_CDC_RX_BUFSIZE +#define CFG_TUD_CDC_TX_BUFSIZE PKG_TINYUSB_DEVICE_CDC_TX_BUFSIZE + +#define CFG_TUD_MSC_EP_BUFSIZE PKG_TINYUSB_DEVICE_MSC_EP_BUFSIZE + +#define CFG_TUD_HID_EP_BUFSIZE PKG_TINYUSB_DEVICE_HID_EP_BUFSIZE + +#ifndef PKG_TINYUSB_DEVICE_CDC_STRING +#define PKG_TINYUSB_DEVICE_CDC_STRING "" +#endif + +#ifndef PKG_TINYUSB_DEVICE_MSC_STRING +#define PKG_TINYUSB_DEVICE_MSC_STRING "" +#endif + +#ifndef PKG_TINYUSB_DEVICE_HID_STRING +#define PKG_TINYUSB_DEVICE_HID_STRING "" +#endif + + +#ifdef __cplusplus +} +#endif +#endif /*__RTTHREAD__*/ + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/lib/rt-thread/tusb_rt_thread_port.c b/lib/rt-thread/tusb_rt_thread_port.c new file mode 100644 index 000000000..d33e3ac60 --- /dev/null +++ b/lib/rt-thread/tusb_rt_thread_port.c @@ -0,0 +1,81 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ +#ifdef __RTTHREAD__ +#include + +#define DBG_TAG "TinyUSB" +#define DBG_LVL DBG_INFO +#include +#include + +#ifndef RT_USING_HEAP +/* if there is not enable heap, we should use static thread and stack. */ +static rt_uint8_t tusb_stack[PKG_TINYUSB_STACK_SIZE]; +static struct rt_thread tusb_thread; +#endif /* RT_USING_HEAP */ + +extern int tusb_board_init(void); + +static void tusb_thread_entry(void *parameter) +{ + (void) parameter; + while (1) + { + tud_task(); + } +} + +static int init_tinyusb(void) +{ + rt_thread_t tid; + + tusb_board_init(); + tusb_init(); + +#ifdef RT_USING_HEAP + tid = rt_thread_create("tusb", tusb_thread_entry, RT_NULL, + PKG_TINYUSB_STACK_SIZE, + PKG_TINYUSB_THREAD_PRIORITY, 10); + if (tid == RT_NULL) +#else + rt_err_t result; + + tid = &tusb_thread; + result = rt_thread_init(tid, "tusb", tusb_thread_entry, RT_NULL, + tusb_stack, sizeof(tusb_stack), 4, 10); + if (result != RT_EOK) +#endif /* RT_USING_HEAP */ + { + LOG_E("Fail to create TinyUSB thread"); + return -1; + } + + rt_thread_startup(tid); + + return 0; +} +INIT_APP_EXPORT(init_tinyusb); +#endif /*__RTTHREAD__*/