diff --git a/companion/src/firmwares/opentx/simulator/opentxsimulator.cpp b/companion/src/firmwares/opentx/simulator/opentxsimulator.cpp index 49421aa71..abe90c2fe 100644 --- a/companion/src/firmwares/opentx/simulator/opentxsimulator.cpp +++ b/companion/src/firmwares/opentx/simulator/opentxsimulator.cpp @@ -233,7 +233,7 @@ namespace NAMESPACE { #include "radio/src/targets/taranis/pulses_driver.cpp" #include "radio/src/targets/taranis/rtc_driver.cpp" #include "radio/src/targets/taranis/trainer_driver.cpp" -#include "radio/src/targets/taranis/uart3_driver.cpp" +#include "radio/src/targets/taranis/serial2_driver.cpp" #elif defined(PCBSKY9X) #include "radio/src/targets/sky9x/board_sky9x.cpp" #include "radio/src/targets/sky9x/telemetry_driver.cpp" @@ -244,7 +244,7 @@ namespace NAMESPACE { #include "radio/src/targets/sky9x/sdcard_driver.cpp" #include "radio/src/targets/sky9x/coproc_driver.cpp" #include "radio/src/targets/sky9x/haptic_driver.cpp" -#include "radio/src/targets/sky9x/second_serial_driver.cpp" +#include "radio/src/targets/sky9x/serial2_driver.cpp" #include "radio/src/targets/sky9x/pulses_driver.cpp" #elif defined(PCBGRUVIN9X) #include "radio/src/targets/gruvin9x/board_gruvin9x.cpp" diff --git a/radio/src/Makefile b/radio/src/Makefile index 82eddef95..541c3ae8d 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -268,6 +268,10 @@ SHUTDOWN_CONFIRMATION = NO # Values = YES, NO DEBUG = NO +# Activate Command Line Interpreter +# Values = NO, YES +CLI = NO + # Activate writing of SPORT telemetry received data to sport.log file # Values = YES, NO SPORT_FILE_LOG = NO @@ -301,9 +305,10 @@ LUA = NO MENUS_LOCK = NO # USB options in the main image -# Values = JOYSTICK, MASSSTORAGE +# Values = JOYSTICK, MASSSTORAGE, SERIAL # JOYSTICK: The TX will appear as a joystick # MASSSTORAGE: The TX will appear as a drive +# SERIAL: The TX will appear as a serial port USB = JOYSTICK # Mixers monitor view added to Channels monitor one @@ -805,7 +810,7 @@ ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO)) EEPROMSRC = eeprom_common.cpp eeprom_raw.cpp eeprom_conversions.cpp PULSESSRC = pulses/pulses_arm.cpp pulses/ppm_arm.cpp pulses/pxx_arm.cpp pulses/dsm2_arm.cpp CPPSRC += tasks_arm.cpp audio_arm.cpp haptic.cpp gui/$(GUIDIRECTORY)/view_about.cpp gui/$(GUIDIRECTORY)/view_text.cpp telemetry/telemetry.cpp - CPPSRC += targets/sky9x/telemetry_driver.cpp targets/sky9x/second_serial_driver.cpp targets/sky9x/pwr_driver.cpp targets/sky9x/adc_driver.cpp targets/sky9x/eeprom_driver.cpp targets/sky9x/pulses_driver.cpp targets/sky9x/keys_driver.cpp targets/sky9x/audio_driver.cpp targets/sky9x/buzzer_driver.cpp targets/sky9x/haptic_driver.cpp targets/sky9x/sdcard_driver.cpp targets/sky9x/massstorage.cpp + CPPSRC += targets/sky9x/telemetry_driver.cpp targets/sky9x/serial2_driver.cpp targets/sky9x/pwr_driver.cpp targets/sky9x/adc_driver.cpp targets/sky9x/eeprom_driver.cpp targets/sky9x/pulses_driver.cpp targets/sky9x/keys_driver.cpp targets/sky9x/audio_driver.cpp targets/sky9x/buzzer_driver.cpp targets/sky9x/haptic_driver.cpp targets/sky9x/sdcard_driver.cpp targets/sky9x/massstorage.cpp CPPSRC += loadboot.cpp debug.cpp BITMAPS += bitmaps/9X/splash.lbm bitmaps/9X/asterisk.lbm bitmaps/9X/about.lbm ifeq ($(SDCARD), YES) @@ -919,8 +924,11 @@ ifeq ($(PCB), TARANIS) LDSCRIPT = targets/taranis/stm32f2_flash.ld endif STM32USBPATH = $(THIRDPARTY)/STM32_USB-Host-Device_Lib_V2.1.0/Libraries - INCDIRS += $(STM32USBPATH)/STM32_USB_OTG_Driver/inc $(STM32USBPATH)/STM32_USB_Device_Library/Core/inc - INCDIRS += $(STM32USBPATH)/STM32_USB_Device_Library/Class/msc/inc $(STM32USBPATH)/STM32_USB_Device_Library/Class/hid/inc + INCDIRS += $(STM32USBPATH)/STM32_USB_OTG_Driver/inc + INCDIRS += $(STM32USBPATH)/STM32_USB_Device_Library/Core/inc + INCDIRS += $(STM32USBPATH)/STM32_USB_Device_Library/Class/msc/inc + INCDIRS += $(STM32USBPATH)/STM32_USB_Device_Library/Class/hid/inc + INCDIRS += $(STM32USBPATH)/STM32_USB_Device_Library/Class/cdc/inc GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_hardware.cpp BOARDSRC = main_arm.cpp targets/taranis/board_taranis.cpp EXTRABOARDSRC += targets/taranis/configure_pins.cpp targets/taranis/lcd_driver.cpp targets/taranis/flash_driver.cpp targets/taranis/i2c_driver.cpp targets/taranis/aspi.c targets/taranis/delays.c @@ -929,8 +937,8 @@ ifeq ($(PCB), TARANIS) EEPROMSRC = eeprom_common.cpp eeprom_rlc.cpp eeprom_conversions.cpp PULSESSRC = pulses/pulses_arm.cpp pulses/ppm_arm.cpp pulses/pxx_arm.cpp CPPSRC += tasks_arm.cpp audio_arm.cpp sbus.cpp telemetry/telemetry.cpp - CPPSRC += targets/taranis/pulses_driver.cpp targets/taranis/keys_driver.cpp targets/taranis/adc_driver.cpp targets/taranis/trainer_driver.cpp targets/taranis/audio_driver.cpp targets/taranis/uart3_driver.cpp targets/taranis/telemetry_driver.cpp - CPPSRC += bmp.cpp gui/$(GUIDIRECTORY)/view_channels.cpp gui/$(GUIDIRECTORY)/view_about.cpp gui/$(GUIDIRECTORY)/view_text.cpp debug.cpp + CPPSRC += targets/taranis/pulses_driver.cpp targets/taranis/keys_driver.cpp targets/taranis/adc_driver.cpp targets/taranis/trainer_driver.cpp targets/taranis/audio_driver.cpp targets/taranis/serial2_driver.cpp targets/taranis/telemetry_driver.cpp + CPPSRC += bmp.cpp gui/$(GUIDIRECTORY)/view_channels.cpp gui/$(GUIDIRECTORY)/view_about.cpp gui/$(GUIDIRECTORY)/view_text.cpp debug.cpp serial.cpp CPPSRC += loadboot.cpp ifeq ($(PCBREV), REV9E) CPPSRC += targets/taranis/top_lcd_driver.cpp @@ -972,6 +980,10 @@ ifeq ($(PCB), TARANIS) ifeq ($(USB), JOYSTICK) CPPDEFS += -DUSB_JOYSTICK SRC += targets/taranis/usbd_hid_joystick.c + else ifeq ($(USB), SERIAL) + CPPDEFS += -DUSB_SERIAL + SRC += $(STM32USBPATH)/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c + EXTRABOARDSRC += targets/taranis/usbd_cdc.cpp else CPPDEFS += -DUSB_MASS_STORAGE SRC += $(STM32USBPATH)/STM32_USB_Device_Library/Class/msc/src/usbd_msc_data.c @@ -1247,10 +1259,10 @@ ifeq ($(EXT), JETI) endif ifeq ($(EXT), MAVLINK) - CPPDEFS += -DMAVLINK - INCDIRS += thirdparty - CPPSRC += telemetry/mavlink.cpp gui/$(GUIDIRECTORY)/view_mavlink.cpp serial.cpp - EEPROM_VARIANT += ${MAVLINK_VARIANT} + CPPDEFS += -DMAVLINK + INCDIRS += thirdparty + CPPSRC += telemetry/mavlink.cpp gui/$(GUIDIRECTORY)/view_mavlink.cpp targets/common_avr/serial_driver.cpp + EEPROM_VARIANT += ${MAVLINK_VARIANT} endif ifeq ($(EXT), TELEMETREZ) @@ -1291,8 +1303,15 @@ ifeq ($(EXT), $(filter $(EXT), FRSKY FRSKY_SPORT TELEMETREZ)) EEPROM_VARIANT += ${FRSKY_VARIANT} endif -ifeq ($(DEBUG), YES) +ifeq ($(SIMU), YES) CPPDEFS += -DDEBUG + CPPSRC += dump.cpp +else ifeq ($(CLI), YES) + CPPDEFS += -DCLI -DDEBUG + CPPSRC += cli.cpp dump.cpp +else ifeq ($(DEBUG), YES) + CPPDEFS += -DDEBUG + CPPSRC += dump.cpp endif ifeq ($(EEPROM_PROGRESS_BAR), YES) diff --git a/radio/src/bin_allocator.cpp b/radio/src/bin_allocator.cpp index f74e351f2..73e847a18 100644 --- a/radio/src/bin_allocator.cpp +++ b/radio/src/bin_allocator.cpp @@ -39,11 +39,11 @@ void * bin_realloc(void * ptr, size_t size) // if it fits in current slot, return it // TODO if new size is smaller, try to relocate in smaller slot if ( slots1.can_fit(ptr, size) ) { - // TRACE("OUR realloc %p[%lu] fits in slot1", ptr, size); FLUSH(); + // TRACE("OUR realloc %p[%lu] fits in slot1", ptr, size); return ptr; } if ( slots2.can_fit(ptr, size) ) { - // TRACE("OUR realloc %p[%lu] fits in slot2", ptr, size); FLUSH(); + // TRACE("OUR realloc %p[%lu] fits in slot2", ptr, size); return ptr; } @@ -51,10 +51,10 @@ void * bin_realloc(void * ptr, size_t size) void * res = bin_malloc(size); if (res == 0) { // we don't have the space, use libc malloc - // TRACE("bin_malloc [%lu] FAILURE", size); FLUSH(); + // TRACE("bin_malloc [%lu] FAILURE", size); res = malloc(size); if (res == 0) { - TRACE("libc malloc [%lu] FAILURE", size); FLUSH(); + TRACE("libc malloc [%lu] FAILURE", size); return 0; } } @@ -73,7 +73,7 @@ void *bin_l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) if (ptr) { // avoid a bunch of NULL pointer free calls if (!bin_free(ptr)) { // not our range, use libc allocator - // TRACE("libc free %p", ptr); FLUSH(); + // TRACE("libc free %p", ptr); free(ptr); } } @@ -89,18 +89,18 @@ void *bin_l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) } if ( SimulateMallocFailure > 0) { // simulate one malloc failure - TRACE("bin_l_alloc(): simulating malloc failure at %p[%lu]", ptr, nsize); FLUSH(); + TRACE("bin_l_alloc(): simulating malloc failure at %p[%lu]", ptr, nsize); return 0; } #endif // #if defined(DEBUG) // try our allocator, if it fails use libc allocator void * res = bin_realloc(ptr, nsize); if (res && ptr) { - // TRACE("OUR realloc %p[%lu] -> %p[%lu]", ptr, osize, res, nsize); FLUSH(); + // TRACE("OUR realloc %p[%lu] -> %p[%lu]", ptr, osize, res, nsize); } if (res == 0) { res = realloc(ptr, nsize); - // TRACE("libc realloc %p[%lu] -> %p[%lu]", ptr, osize, res, nsize); FLUSH(); + // TRACE("libc realloc %p[%lu] -> %p[%lu]", ptr, osize, res, nsize); // if (res == 0 ){ // TRACE("realloc FAILURE %lu", nsize); // dumpFreeMemory(); diff --git a/radio/src/bin_allocator.h b/radio/src/bin_allocator.h index 1c50fb75b..bfb1b7a97 100644 --- a/radio/src/bin_allocator.h +++ b/radio/src/bin_allocator.h @@ -20,7 +20,7 @@ public: if (ptr == Bins[n].data) { Bins[n].Used = false; --NoUsedBins; - // TRACE("\tBinAllocator<%d> free %lu ------", SIZE_SLOT, n); FLUSH(); + // TRACE("\tBinAllocator<%d> free %lu ------", SIZE_SLOT, n); return true; } } @@ -31,22 +31,22 @@ public: } void * malloc(size_t size) { if (size > SIZE_SLOT) { - // TRACE("BinAllocator<%d> malloc [%lu] size > SIZE_SLOT", SIZE_SLOT, size); FLUSH(); + // TRACE("BinAllocator<%d> malloc [%lu] size > SIZE_SLOT", SIZE_SLOT, size); return 0; } if (NoUsedBins >= NUM_BINS) { - // TRACE("BinAllocator<%d> malloc [%lu] no free slots", SIZE_SLOT, size); FLUSH(); + // TRACE("BinAllocator<%d> malloc [%lu] no free slots", SIZE_SLOT, size); return 0; } for (size_t n = 0; n < NUM_BINS; ++n) { if (!Bins[n].Used) { Bins[n].Used = true; ++NoUsedBins; - // TRACE("\tBinAllocator<%d> malloc %lu[%lu]", SIZE_SLOT, n, size); FLUSH(); + // TRACE("\tBinAllocator<%d> malloc %lu[%lu]", SIZE_SLOT, n, size); return Bins[n].data; } } - // TRACE("BinAllocator<%d> malloc [%lu] no free slots", SIZE_SLOT , size); FLUSH(); + // TRACE("BinAllocator<%d> malloc [%lu] no free slots", SIZE_SLOT , size); return 0; } size_t size(void * ptr) { diff --git a/radio/src/cli.cpp b/radio/src/cli.cpp new file mode 100644 index 000000000..9a39e4466 --- /dev/null +++ b/radio/src/cli.cpp @@ -0,0 +1,315 @@ +/* + * Authors (alphabetical order) + * - Andre Bernet + * - Andreas Weitl + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Gabriel Birkus + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * opentx is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "opentx.h" +#include + +#define CLI_STACK_SIZE 500 +#define CLI_COMMAND_MAX_ARGS 8 +#define CLI_COMMAND_MAX_LEN 256 + +OS_TID cliTaskId; +OS_STK cliStack[CLI_STACK_SIZE]; +Fifo<256> cliRxFifo; +uint8_t cliTracesEnabled = false; + +typedef int (* CliFunction) (const char ** args); + +struct CliCommand +{ + const char * name; + CliFunction func; + const char * args; +}; + +struct MemArea +{ + const char * name; + void * start; + int size; +}; + +void cliPrompt() +{ + serialPutc('>'); +} + +int toInt(const char ** argv, int index, int * val) +{ + if (*argv[index] == '\0') { + return 0; + } + else { + int base = 10; + const char * s = argv[index]; + if (strlen(s) > 2 && s[0] == '0' && s[1] == 'x') { + base = 16; + s = &argv[index][2]; + } + char * endptr = NULL; + *val = strtol(s, &endptr, base); + if (*endptr == '\0') + return 1; + else { + serialPrint("%s: Invalid argument \"%s\"", argv[0], argv[index]); + return -1; + } + } +} + +int cliBeep(const char ** argv) +{ + int freq = BEEP_DEFAULT_FREQ; + int duration = 100; + if (toInt(argv, 1, &freq) >= 0 && toInt(argv, 2, &duration) >= 0) { + audioQueue.playTone(freq, duration, 20, PLAY_NOW); + } + return 0; +} + +int cliPlay(const char ** argv) +{ + audioQueue.playFile(argv[1], PLAY_NOW); + return 0; +} + +int cliLs(const char ** argv) +{ + FILINFO fno; + DIR dir; + char *fn; /* This function is assuming non-Unicode cfg. */ +#if _USE_LFN + TCHAR lfn[_MAX_LFN + 1]; + fno.lfname = lfn; + fno.lfsize = sizeof(lfn); +#endif + + FRESULT res = f_opendir(&dir, argv[1]); /* Open the directory */ + if (res == FR_OK) { + for (;;) { + res = f_readdir(&dir, &fno); /* Read a directory item */ + if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ + +#if _USE_LFN + fn = *fno.lfname ? fno.lfname : fno.fname; +#else + fn = fno.fname; +#endif + serialPrint(fn); + } + } + else { + serialPrint("%s: Invalid directory \"%s\"", argv[0], argv[1]); + } + return 0; +} + +int cliTrace(const char ** argv) +{ + if (!strcmp(argv[1], "on")) { + cliTracesEnabled = true; + } + else if (!strcmp(argv[1], "off")) { + cliTracesEnabled = false; + } + else { + serialPrint("%s: Invalid argument \"%s\"", argv[0], argv[1]); + } + return 0; +} + +int cliVolume(const char ** argv) +{ + int level = 0; + if (toInt(argv, 1, &level) > 0) { + setVolume(level); + } + else { + serialPrint("%s: Invalid argument \"%s\"", argv[0], argv[1]); + } + return 0; +} + +const MemArea memAreas[] = { + { "RCC", RCC, sizeof(RCC_TypeDef) }, + { "GPIOA", GPIOA, sizeof(GPIO_TypeDef) }, + { "GPIOB", GPIOB, sizeof(GPIO_TypeDef) }, + { "GPIOC", GPIOC, sizeof(GPIO_TypeDef) }, + { "GPIOD", GPIOD, sizeof(GPIO_TypeDef) }, + { "GPIOE", GPIOE, sizeof(GPIO_TypeDef) }, + { "GPIOF", GPIOF, sizeof(GPIO_TypeDef) }, + { "GPIOG", GPIOG, sizeof(GPIO_TypeDef) }, + { "USART1", USART1, sizeof(USART_TypeDef) }, + { "USART3", USART3, sizeof(USART_TypeDef) }, + { NULL, NULL, 0 }, +}; + +int cliDisplay(const char ** argv) +{ + int address = 0; + + for (const MemArea * area = memAreas; area->name != NULL; area++) { + if (!strcmp(area->name, argv[1])) { + dump((uint8_t *)area->start, area->size); + return 0; + } + } + + if (!strcmp(argv[1], "adc")) { + for (int i=0; i 0) { + int size = 256; + if (toInt(argv, 2, &size) >= 0) { + dump((uint8_t *)address, size); + } + } + return 0; +} + +int cliHelp(const char ** argv); + +const CliCommand cliCommands[] = { + { "beep", cliBeep, "[] []" }, + { "ls", cliLs, "" }, + { "play", cliPlay, "" }, + { "print", cliDisplay, "
[] | " }, + { "trace", cliTrace, "on | off" }, + { "volume", cliVolume, "" }, + { "help", cliHelp, "[]" }, + { NULL, NULL, NULL } /* sentinel */ +}; + +int cliHelp(const char ** argv) +{ + for (const CliCommand * command = cliCommands; command->name != NULL; command++) { + if (argv[1][0] == '\0' || !strcmp(command->name, argv[0])) { + serialPrint("%s %s", command->name, command->args); + if (argv[1][0] != '\0') { + return 0; + } + } + } + if (argv[1][0] != '\0') { + serialPrint("Invalid command \"%s\"", argv[0]); + } + return -1; +} + +int cliExecCommand(const char ** argv) +{ + if (argv[0][0] == '\0') + return 0; + + for (const CliCommand * command = cliCommands; command->name != NULL; command++) { + if (!strcmp(command->name, argv[0])) { + return command->func(argv); + } + } + serialPrint("Invalid command \"%s\"", argv[0]); + return -1; +} + +int cliExecLine(char * line) +{ + int len = strlen(line); + const char * argv[CLI_COMMAND_MAX_ARGS]; + memset(argv, 0, sizeof(argv)); + int argc = 1; + argv[0] = line; + for (int i=0; i + * - Andreas Weitl + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Gabriel Birkus + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * opentx is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _CLI_H_ +#define _CLI_H_ + +#include "serial.h" + +extern uint8_t cliTracesEnabled; + +#ifdef __cplusplus +#include "fifo.h" +extern Fifo<256> cliRxFifo; +#endif + +void cliStart(); + +#endif // _CLI_H_ diff --git a/radio/src/debug.cpp b/radio/src/debug.cpp index 468840cba..f210ef7d0 100644 --- a/radio/src/debug.cpp +++ b/radio/src/debug.cpp @@ -34,225 +34,33 @@ * */ -extern "C" { -#include -#include -} - #include "opentx.h" - -#if (defined(DEBUG) && defined(CPUARM)) || defined(SIMU) +#include #if defined(SIMU) traceCallbackFunc traceCallback = 0; #endif #if defined(SIMU) - #define PRINTF_BUFFER_SIZE 1024 -#else - #define PRINTF_BUFFER_SIZE 256 -#endif - -// Outputs a string to the UART -void debugPuts(const char *format, ...) +void debugPrintf(const char * format, ...) { va_list arglist; - char tmp[PRINTF_BUFFER_SIZE]; - + char * str; va_start(arglist, format); - vsnprintf(tmp, PRINTF_BUFFER_SIZE, format, arglist); + vasprintf(&str, format, arglist); va_end(arglist); - -#if defined(SIMU) - fputs(tmp, stdout); + fputs(str, stdout); fflush(stdout); if (traceCallback) { - traceCallback(tmp); - } -#else - const char *t = tmp; - while (*t) { - debugPutc(*t++); + traceCallback(str); } + free(str); +} #endif -} - -void dump(unsigned char *data, unsigned int size) -{ - debugPuts("DUMP %d bytes ...\n\r", size); - unsigned int i = 0, j=0; - while (i*32+j < size) { - debugPuts("%.2X ", data[i*32+j]); - j++; - if (j==32) { - i++; j=0; - debugPuts("\n\r"); - } - } - debugPuts("\n\r"); -} - - -#if !defined(SIMU) - -uint32_t Mem_address ; -uint32_t Next_mem_address ; -uint32_t Memaddmode ; -Fifo<512> debugRxFifo; - -void crlf() -{ - debugPutc( 13 ) ; - debugPutc( 10 ) ; -} - -// Send a single 4 bit value to the RS232 port as a hex digit -void hex_digit_send( unsigned char c ) -{ - c &= 0x0F ; - if ( c > 9 ) - { - c += 7 ; - } - c += '0' ; - debugPutc( c ) ; -} - -// Send the 8 bit value to the RS232 port as 2 hex digits -void p2hex( unsigned char c ) -{ -// asm("swap %c") ; - hex_digit_send( c >> 4 ) ; -// asm("swap %c") ; - hex_digit_send( c ) ; -} - -// Send the 16 bit value to the RS232 port as 4 hex digits -void p4hex( uint16_t value ) -{ - p2hex( value >> 8 ) ; - p2hex( value ) ; -} - -// Send the 32 bit value to the RS232 port as 8 hex digits -void p8hex( uint32_t value ) -{ - p4hex( value >> 16 ) ; - p4hex( value ) ; -} - - -static void dispw_256( register uint32_t address, register uint32_t lines ) -{ - register uint32_t i ; - register uint32_t j ; - address &= 0xFFFFFFFC ; - for ( i = 0 ; i < lines ; i += 1 ) - { - p8hex( address ) ; - for ( j = 0 ; j < 4 ; j += 1 ) - { - debugPutc(' ') ; - p8hex( *( (uint32_t *)address ) ) ; - address += 4 ; - } - crlf() ; - } -} - -extern Fifo<512> uart3TxFifo; - -void debugFlush() -{ - uart3TxFifo.flush(); -} - -void debugTask(void* pdata) -{ - uint8_t rxchar ; - - TRACE("DEBUG Task started"); - - crlf() ; - dispw_256( (uint32_t)USART3, 4 ) ; - - for (;;) { - - while ( (USART3->SR & USART_SR_RXNE) == 0 ) - CoTickDelay(5); // 10ms - - rxchar = USART3->DR; - - if ( Memaddmode ) - { - if ( ( rxchar >= 'a' ) && ( rxchar <= 'f' ) ) - { - rxchar -= 0x20; // toupper! - } - if ( ( ( rxchar >= '0' ) && ( rxchar <= '9' ) ) || ( ( rxchar >= 'A' ) && ( rxchar <= 'F' ) ) ) - { - debugPutc( rxchar ); - rxchar -= '0'; - if ( rxchar > 9 ) - { - rxchar -= 7; - } - Mem_address <<= 4; - Mem_address |= rxchar; - } - else if ( rxchar == 13 ) - { - crlf(); - if ( Mem_address == 0 ) - { - Mem_address = Next_mem_address; - } - dispw_256( Mem_address, 4 ); - Next_mem_address = Mem_address + 64; - Memaddmode = 0; - } - else if ( rxchar == 8 ) - { - debugPutc( rxchar ); - debugPutc( rxchar ); - debugPutc( rxchar ); - Mem_address >>= 4; - } - else if ( rxchar == 27 ) - { - crlf(); - Memaddmode = 0; - } - - } - - if ( rxchar == '?' ) - { - Memaddmode = 1; - Mem_address = 0; - debugPutc( '>' ); - } - - if ( rxchar == 'm' ) - { - crlf(); - p8hex( (uint32_t) &g_model.moduleData[0] ); - debugPutc( ' ' ); - p8hex( (uint32_t) &g_model.moduleData[1] ); - crlf(); - } - - } -} -#endif // #if !defined(SIMU) -#endif // #if (defined(DEBUG) && defined(CPUARM)) || defined(SIMU) - #if defined(DEBUG_TRACE_BUFFER) - static struct TraceElement traceBuffer[TRACE_BUFFER_LEN]; static uint8_t traceBufferPos; -extern Fifo<512> uart3TxFifo; gtime_t filltm(gtime_t *t, struct gtm *tp); void trace_event(enum TraceEvent event, uint32_t data) @@ -298,13 +106,11 @@ void dumpTraceBuffer() TRACE(" %03d 0x%08x", traceBuffer[n].event, traceBuffer[n].data); if (traceBuffer[n].time == 0 && traceBuffer[n].time_ms == 0) break; if ((n % 5) == 0) { - while (!uart3TxFifo.empty()) { + while (!serial2TxFifo.empty()) { CoTickDelay(1); } } } TRACE("End of Trace Buffer dump"); } - #endif - diff --git a/radio/src/debug.h b/radio/src/debug.h index 998b5550e..422d8b483 100644 --- a/radio/src/debug.h +++ b/radio/src/debug.h @@ -39,58 +39,40 @@ #include #include "rtc.h" +#include "dump.h" +#include "cli.h" -#if (defined(DEBUG) && defined(CPUARM)) || defined(SIMU) - -#ifdef __cplusplus +#if defined(__cplusplus) extern "C" { #endif +uint8_t serial2TracesEnabled(); +#if defined(__cplusplus) +} +#endif #if defined(SIMU) typedef void (*traceCallbackFunc)(const char * text); extern traceCallbackFunc traceCallback; +void debugPrintf(const char * format, ...); +#elif defined(DEBUG) && defined(CLI) && defined(USB_SERIAL) +#define debugPrintf(...) do { if (cliTracesEnabled) serialPrintf(__VA_ARGS__); } while(0) +#elif defined(DEBUG) && defined(CLI) +#define debugPrintf(...) do { if (serial2TracesEnabled() && cliTracesEnabled) serialPrintf(__VA_ARGS__); } while(0) +#elif defined(DEBUG) && defined(CPUARM) +#define debugPrintf(...) do { if (serial2TracesEnabled()) serialPrintf(__VA_ARGS__); } while(0) +#else +#define debugPrintf(...) #endif -void debugPuts(const char *string, ...); -void dump(unsigned char *data, unsigned int size); -void debugFlush(); - -#ifdef __cplusplus -} -#endif - -#define TRACE(...) do { debugPuts(__VA_ARGS__); debugPuts("\r\n"); } while(0) +#define TRACE(...) do { debugPrintf(__VA_ARGS__); debugPrintf("\r\n"); } while(0) #define DUMP(data, size) dump(data, size) -#define TRACE_DEBUG(...) debugPuts("-D- " __VA_ARGS__) -#define TRACE_DEBUG_WP(...) debugPuts(__VA_ARGS__) -#define TRACE_INFO(...) debugPuts("-I- " __VA_ARGS__) -#define TRACE_INFO_WP(...) debugPuts(__VA_ARGS__) -#define TRACE_WARNING(...) debugPuts("-W- " __VA_ARGS__) -#define TRACE_WARNING_WP(...) debugPuts(__VA_ARGS__) -#define TRACE_ERROR(...) debugPuts("-E- " __VA_ARGS__) - -#if !defined(SIMU) -#define FLUSH() debugFlush(); -void debugTask(void* pdata); -#else -#define FLUSH() -#endif - -#else - -#define TRACE(...) { } -#define DUMP(...) { } -#define TRACE_DEBUG(...) { } -#define TRACE_DEBUG_WP(...) { } -#define TRACE_INFO(...) { } -#define TRACE_INFO_WP(...) { } -#define TRACE_WARNING(...) { } -#define TRACE_WARNING_WP(...) { } -#define TRACE_ERROR(...) { } -#define FLUSH() - -#endif - +#define TRACE_DEBUG(...) debugPrintf("-D- " __VA_ARGS__) +#define TRACE_DEBUG_WP(...) debugPrintf(__VA_ARGS__) +#define TRACE_INFO(...) debugPrintf("-I- " __VA_ARGS__) +#define TRACE_INFO_WP(...) debugPrintf(__VA_ARGS__) +#define TRACE_WARNING(...) debugPrintf("-W- " __VA_ARGS__) +#define TRACE_WARNING_WP(...) debugPrintf(__VA_ARGS__) +#define TRACE_ERROR(...) debugPrintf("-E- " __VA_ARGS__) #if defined(DEBUG_TRACE_BUFFER) diff --git a/radio/src/dump.cpp b/radio/src/dump.cpp new file mode 100644 index 000000000..25bf29ab3 --- /dev/null +++ b/radio/src/dump.cpp @@ -0,0 +1,38 @@ +#include "opentx.h" + +#if defined(SIMU) +#define dumpPrintf(...) debugPrintf(__VA_ARGS__) +#else +#define dumpPrintf(...) serialPrintf(__VA_ARGS__) +#endif + +uint8_t dumpPosition; + +void dumpStart(unsigned int size) +{ + dumpPrintf("DUMP %d bytes ...\n\r", size); + dumpPosition = 0; +} + +void dumpBody(const uint8_t *data, unsigned int size) +{ + for (unsigned int i=0; i + * Authors (alphabetical order) + * - Andre Bernet + * - Andreas Weitl + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Gabriel Birkus + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer * - * Adapted from frsky + * opentx is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * */ #include "opentx.h" #include "serial.h" +#include +#include -/* - Receive serial (RS-232) characters, detecting and storing each Fr-Sky - 0x7e-framed packet as it arrives. When a complete packet has been - received, process its data into storage variables. NOTE: This is an - interrupt routine and should not get too lengthy. I originally had - the buffer being checked in the perMain function (because per10ms - isn't quite often enough for data streaming at 9600baud) but alas - that scheme lost packets also. So each packet is parsed as it arrives, - directly at the ISR function (through a call to frskyProcessPacket). +#define PRINTF_BUFFER_SIZE 256 - If this proves a problem in the future, then I'll just have to implement - a second buffer to receive data while one buffer is being processed (slowly). - */ - -#ifndef SIMU -ISR (USART0_RX_vect) +void serialPutc(char c) { - uint8_t iostat; //USART control and Status Register 0 A - // uint8_t rh; //USART control and Status Register 0 B - UCSR0B &= ~(1 << RXCIE0); // disable Interrupt - sei(); - iostat = UCSR0A; //USART control and Status Register 0 A - uint8_t byte = UDR0; - - /* - bit 7 6 5 4 3 2 1 0 - RxC0 TxC0 UDRE0 FE0 DOR0 UPE0 U2X0 MPCM0 - - RxC0: Receive complete - TXC0: Transmit Complete - UDRE0: USART Data Register Empty - FE0: Frame Error - DOR0: Data OverRun - UPE0: USART Parity Error - U2X0: Double Tx Speed - MPCM0: MultiProcessor Comms Mode - */ - if (iostat & ((1 << FE0) | (1 << DOR0) | (1 << UPE0))) { - byte = 0; - } - //rh = UCSR0B; //USART control and Status Register 0 B -#ifdef MAVLINK - (RXHandler)(byte); +#if defined(USB_SERIAL) + usbSerialPutc(c); +#else + serial2Putc(c); #endif - - cli(); - UCSR0B |= (1 << RXCIE0); // enable Interrupt - -} -#endif - -inline void SERIAL_EnableRXD(void) { - UCSR0B |= (1 << RXEN0); // enable RX - UCSR0B |= (1 << RXCIE0); // enable Interrupt } -#if 0 -void SERIAL_DisableRXD(void) { - UCSR0B &= ~(1 << RXEN0); // disable RX - UCSR0B &= ~(1 << RXCIE0); // disable Interrupt -} -#endif - -/* - USART0 (transmit) Data Register Emtpy ISR - Usef to transmit FrSky data packets, which are buffered in frskyTXBuffer. - */ -uint8_t serialTxBuffer[MAX_TX_BUFFER]; // 32 characters -uint8_t serialTxBufferCount = 0; -uint8_t * ptrTxISR = 0; -serial_tx_state_t serialTxState = TX_STATE_EMPTY; - -#ifndef SIMU -ISR(USART0_UDRE_vect) +void serialPrintf(const char * format, ...) { - if (serialTxBufferCount > 0) { - UDR0 = *ptrTxISR++; - serialTxBufferCount--; - } else { - UCSR0B &= ~(1 << UDRIE0); // disable UDRE0 interrupt - serialTxState = TX_STATE_EMPTY; - } -} -#endif + va_list arglist; + char tmp[PRINTF_BUFFER_SIZE]; -void SERIAL_start_uart_send() { - ptrTxISR = serialTxBuffer; - serialTxBufferCount = 0; + va_start(arglist, format); + vsnprintf(tmp, PRINTF_BUFFER_SIZE, format, arglist); + va_end(arglist); + + const char *t = tmp; + while (*t) { + serialPutc(*t++); + } } -void SERIAL_end_uart_send() { - ptrTxISR = serialTxBuffer; - //UCSR0B |= (1 << UDRIE0); // enable UDRE0 interrupt - serialTxState = TX_STATE_READY; +void serialCrlf() +{ + serialPutc('\r'); + serialPutc('\n'); } - -void SERIAL_send_uart_bytes(const uint8_t * buf, uint16_t len) { - while (len--) { - *ptrTxISR++ = *buf++; - serialTxBufferCount++; - } - -} - -#if 0 -void SERIAL_transmitBuffer(uint8_t len) { - serialTxBufferCount = len; - ptrTxISR = serialTxBuffer; - //UCSR0B |= (1 << UDRIE0); // enable UDRE0 interrupt - serialTxState = TX_STATE_READY; -} -#endif - -void SERIAL_startTX(void) { - if (serialTxState == TX_STATE_READY) { - serialTxState = TX_STATE_BUSY; - UCSR0B |= (1 << UDRIE0); // enable UDRE0 interrupt - } -} - -static void uart_4800(void) { -#ifndef SIMU -#undef BAUD // avoid compiler warning -#define BAUD 4800 -#include - UBRR0H = UBRRH_VALUE; - UBRR0L = UBRRL_VALUE; -#if USE_2X - UCSR0A |= (1 << U2X0); -#else - UCSR0A &= ~(1 << U2X0); -#endif -#endif -} - -static void uart_9600(void) { -#ifndef SIMU -#undef BAUD // avoid compiler warning -#define BAUD 9600 -#include - UBRR0H = UBRRH_VALUE; - UBRR0L = UBRRL_VALUE; -#if USE_2X - UCSR0A |= (1 << U2X0); -#else - UCSR0A &= ~(1 << U2X0); -#endif -#endif -} - -static void uart_14400(void) { -#ifndef SIMU -#undef BAUD // avoid compiler warning -#define BAUD 14400 -#include - UBRR0H = UBRRH_VALUE; - UBRR0L = UBRRL_VALUE; -#if USE_2X - UCSR0A |= (1 << U2X0); -#else - UCSR0A &= ~(1 << U2X0); -#endif -#endif -} - -static void uart_19200(void) { -#ifndef SIMU -#undef BAUD // avoid compiler warning -#define BAUD 19200 -#include - UBRR0H = UBRRH_VALUE; - UBRR0L = UBRRL_VALUE; -#if USE_2X - UCSR0A |= (1 << U2X0); -#else - UCSR0A &= ~(1 << U2X0); -#endif -#endif -} - -static void uart_38400(void) { -#ifndef SIMU -#undef BAUD // avoid compiler warning -#define BAUD 38400 -#include - UBRR0H = UBRRH_VALUE; - UBRR0L = UBRRL_VALUE; -#if USE_2X - UCSR0A |= (1 << U2X0); -#else - UCSR0A &= ~(1 << U2X0); -#endif -#endif -} - -static void uart_57600(void) { -#ifndef SIMU -#undef BAUD // avoid compiler warning -#define BAUD 57600 -#include - UBRR0H = UBRRH_VALUE; - UBRR0L = UBRRL_VALUE; -#if USE_2X - UCSR0A |= (1 << U2X0); -#else - UCSR0A &= ~(1 << U2X0); -#endif -#endif -} - - -static void uart_76800(void) { -#ifndef SIMU -#undef BAUD // avoid compiler warning -#define BAUD 76800 -#include - UBRR0H = UBRRH_VALUE; - UBRR0L = UBRRL_VALUE; -#if USE_2X - UCSR0A |= (1 << U2X0); -#else - UCSR0A &= ~(1 << U2X0); -#endif -#endif -} - -inline void SERIAL_EnableTXD(void) { - //UCSR0B |= (1 << TXEN0); // enable TX - UCSR0B |= (1 << TXEN0) | (1 << UDRIE0); // enable TX and TX interrupt -} - -#if 0 -void SERIAL_DisableTXD(void) { - UCSR0B &= ~(1 << TXEN0); // disable TX - UCSR0B &= ~(1 << UDRIE0); // disable Interrupt -} -#endif - -void SERIAL_Init(void) { - DDRE &= ~(1 << DDE0); // set RXD0 pin as input - PORTE &= ~(1 << PORTE0); // disable pullup on RXD0 pin - - switch (g_eeGeneral.mavbaud) { - case BAUD_4800: - uart_4800(); - break; - case BAUD_9600: - uart_9600(); - break; - case BAUD_14400: - uart_14400(); - break; - case BAUD_19200: - uart_19200(); - break; - case BAUD_38400: - uart_38400(); - break; - case BAUD_57600: - uart_57600(); - break; - case BAUD_76800: - uart_76800(); - break; - } - - - // UCSR0A &= ~(1 << U2X0); // disable double speed operation - // set 8N1 - UCSR0B = 0 | (0 << RXCIE0) | (0 << TXCIE0) | (0 << UDRIE0) | (0 << RXEN0) | (0 << TXEN0) | (0 << UCSZ02); - UCSR0C = 0 | (1 << UCSZ01) | (1 << UCSZ00); - while (UCSR0A & (1 << RXC0)) - UDR0; // flush receive buffer - - SERIAL_EnableTXD(); - SERIAL_EnableRXD(); -} - diff --git a/radio/src/serial.h b/radio/src/serial.h index a3089d691..9d887512b 100644 --- a/radio/src/serial.h +++ b/radio/src/serial.h @@ -1,59 +1,55 @@ -/* - * Authors - Gerard Valade - * - * Adapted from frsky - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - -#ifndef _SERIAL_H_ -#define _SERIAL_H_ - -typedef enum serial_tx_state_ { - TX_STATE_EMPTY = 0, // - TX_STATE_READY, // - TX_STATE_BUSY -} serial_tx_state_t; -extern serial_tx_state_t serialTxState; - -//! \brief Baudrate selection. -enum SERIAL_BAUDS { - BAUD_4800 = 0, - BAUD_9600, - BAUD_14400, - BAUD_19200, - BAUD_38400, - BAUD_57600, - BAUD_76800 -}; - -//! \brief Definition of baudrate settings item choices. -typedef void (*SerialFuncP)(uint8_t event); - -extern SerialFuncP RXHandler; - -#define MAX_TX_BUFFER 32 -//#if 0 -extern uint8_t serialTxBuffer[MAX_TX_BUFFER]; // 32 characters -extern uint8_t serialTxBufferCount; -extern uint8_t * ptrTxISR; -//#endif - -void SERIAL_Init(void); -//void SERIAL_transmitBuffer(uint8_t len); -extern void SERIAL_start_uart_send(); -extern void SERIAL_end_uart_send(); -extern void SERIAL_send_uart_bytes(uint8_t * buf, uint16_t len); - -void SERIAL_startTX(void); -#define IS_TX_BUSY (serialTxState!=TX_STATE_EMPTY) - -#endif +/* + * Authors (alphabetical order) + * - Andre Bernet + * - Andreas Weitl + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Gabriel Birkus + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * opentx is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _SERIAL_H_ +#define _SERIAL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void serialPutc(char c); +void serialPrintf(const char *format, ...); +void serialCrlf(); + +#ifdef __cplusplus +} +#endif + +#define serialPrint(...) do { serialPrintf(__VA_ARGS__); serialCrlf(); } while(0) + +#endif // _SERIAL_H_ + diff --git a/radio/src/targets/common_avr/serial_driver.cpp b/radio/src/targets/common_avr/serial_driver.cpp new file mode 100644 index 000000000..e46a48f3d --- /dev/null +++ b/radio/src/targets/common_avr/serial_driver.cpp @@ -0,0 +1,297 @@ +/* + * Authors - Gerard Valade + * + * Adapted from frsky + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include "serial_driver.h" +#include "opentx.h" + +/* + Receive serial (RS-232) characters, detecting and storing each Fr-Sky + 0x7e-framed packet as it arrives. When a complete packet has been + received, process its data into storage variables. NOTE: This is an + interrupt routine and should not get too lengthy. I originally had + the buffer being checked in the perMain function (because per10ms + isn't quite often enough for data streaming at 9600baud) but alas + that scheme lost packets also. So each packet is parsed as it arrives, + directly at the ISR function (through a call to frskyProcessPacket). + + If this proves a problem in the future, then I'll just have to implement + a second buffer to receive data while one buffer is being processed (slowly). + */ + +#ifndef SIMU +ISR (USART0_RX_vect) +{ + uint8_t iostat; //USART control and Status Register 0 A + // uint8_t rh; //USART control and Status Register 0 B + UCSR0B &= ~(1 << RXCIE0); // disable Interrupt + sei(); + iostat = UCSR0A; //USART control and Status Register 0 A + uint8_t byte = UDR0; + + /* + bit 7 6 5 4 3 2 1 0 + RxC0 TxC0 UDRE0 FE0 DOR0 UPE0 U2X0 MPCM0 + + RxC0: Receive complete + TXC0: Transmit Complete + UDRE0: USART Data Register Empty + FE0: Frame Error + DOR0: Data OverRun + UPE0: USART Parity Error + U2X0: Double Tx Speed + MPCM0: MultiProcessor Comms Mode + */ + if (iostat & ((1 << FE0) | (1 << DOR0) | (1 << UPE0))) { + byte = 0; + } + //rh = UCSR0B; //USART control and Status Register 0 B +#ifdef MAVLINK + (RXHandler)(byte); +#endif + + cli(); + UCSR0B |= (1 << RXCIE0); // enable Interrupt + +} +#endif + +inline void SERIAL_EnableRXD(void) { + UCSR0B |= (1 << RXEN0); // enable RX + UCSR0B |= (1 << RXCIE0); // enable Interrupt +} + +#if 0 +void SERIAL_DisableRXD(void) { + UCSR0B &= ~(1 << RXEN0); // disable RX + UCSR0B &= ~(1 << RXCIE0); // disable Interrupt +} +#endif + +/* + USART0 (transmit) Data Register Emtpy ISR + Usef to transmit FrSky data packets, which are buffered in frskyTXBuffer. + */ +uint8_t serialTxBuffer[MAX_TX_BUFFER]; // 32 characters +uint8_t serialTxBufferCount = 0; +uint8_t * ptrTxISR = 0; +serial_tx_state_t serialTxState = TX_STATE_EMPTY; + +#ifndef SIMU +ISR(USART0_UDRE_vect) +{ + if (serialTxBufferCount > 0) { + UDR0 = *ptrTxISR++; + serialTxBufferCount--; + } else { + UCSR0B &= ~(1 << UDRIE0); // disable UDRE0 interrupt + serialTxState = TX_STATE_EMPTY; + } +} +#endif + +void SERIAL_start_uart_send() { + ptrTxISR = serialTxBuffer; + serialTxBufferCount = 0; +} + +void SERIAL_end_uart_send() { + ptrTxISR = serialTxBuffer; + //UCSR0B |= (1 << UDRIE0); // enable UDRE0 interrupt + serialTxState = TX_STATE_READY; +} + +void SERIAL_send_uart_bytes(const uint8_t * buf, uint16_t len) { + while (len--) { + *ptrTxISR++ = *buf++; + serialTxBufferCount++; + } + +} + +#if 0 +void SERIAL_transmitBuffer(uint8_t len) { + serialTxBufferCount = len; + ptrTxISR = serialTxBuffer; + //UCSR0B |= (1 << UDRIE0); // enable UDRE0 interrupt + serialTxState = TX_STATE_READY; +} +#endif + +void SERIAL_startTX(void) { + if (serialTxState == TX_STATE_READY) { + serialTxState = TX_STATE_BUSY; + UCSR0B |= (1 << UDRIE0); // enable UDRE0 interrupt + } +} + +static void uart_4800(void) { +#ifndef SIMU +#undef BAUD // avoid compiler warning +#define BAUD 4800 +#include + UBRR0H = UBRRH_VALUE; + UBRR0L = UBRRL_VALUE; +#if USE_2X + UCSR0A |= (1 << U2X0); +#else + UCSR0A &= ~(1 << U2X0); +#endif +#endif +} + +static void uart_9600(void) { +#ifndef SIMU +#undef BAUD // avoid compiler warning +#define BAUD 9600 +#include + UBRR0H = UBRRH_VALUE; + UBRR0L = UBRRL_VALUE; +#if USE_2X + UCSR0A |= (1 << U2X0); +#else + UCSR0A &= ~(1 << U2X0); +#endif +#endif +} + +static void uart_14400(void) { +#ifndef SIMU +#undef BAUD // avoid compiler warning +#define BAUD 14400 +#include + UBRR0H = UBRRH_VALUE; + UBRR0L = UBRRL_VALUE; +#if USE_2X + UCSR0A |= (1 << U2X0); +#else + UCSR0A &= ~(1 << U2X0); +#endif +#endif +} + +static void uart_19200(void) { +#ifndef SIMU +#undef BAUD // avoid compiler warning +#define BAUD 19200 +#include + UBRR0H = UBRRH_VALUE; + UBRR0L = UBRRL_VALUE; +#if USE_2X + UCSR0A |= (1 << U2X0); +#else + UCSR0A &= ~(1 << U2X0); +#endif +#endif +} + +static void uart_38400(void) { +#ifndef SIMU +#undef BAUD // avoid compiler warning +#define BAUD 38400 +#include + UBRR0H = UBRRH_VALUE; + UBRR0L = UBRRL_VALUE; +#if USE_2X + UCSR0A |= (1 << U2X0); +#else + UCSR0A &= ~(1 << U2X0); +#endif +#endif +} + +static void uart_57600(void) { +#ifndef SIMU +#undef BAUD // avoid compiler warning +#define BAUD 57600 +#include + UBRR0H = UBRRH_VALUE; + UBRR0L = UBRRL_VALUE; +#if USE_2X + UCSR0A |= (1 << U2X0); +#else + UCSR0A &= ~(1 << U2X0); +#endif +#endif +} + + +static void uart_76800(void) { +#ifndef SIMU +#undef BAUD // avoid compiler warning +#define BAUD 76800 +#include + UBRR0H = UBRRH_VALUE; + UBRR0L = UBRRL_VALUE; +#if USE_2X + UCSR0A |= (1 << U2X0); +#else + UCSR0A &= ~(1 << U2X0); +#endif +#endif +} + +inline void SERIAL_EnableTXD(void) { + //UCSR0B |= (1 << TXEN0); // enable TX + UCSR0B |= (1 << TXEN0) | (1 << UDRIE0); // enable TX and TX interrupt +} + +#if 0 +void SERIAL_DisableTXD(void) { + UCSR0B &= ~(1 << TXEN0); // disable TX + UCSR0B &= ~(1 << UDRIE0); // disable Interrupt +} +#endif + +void SERIAL_Init(void) { + DDRE &= ~(1 << DDE0); // set RXD0 pin as input + PORTE &= ~(1 << PORTE0); // disable pullup on RXD0 pin + + switch (g_eeGeneral.mavbaud) { + case BAUD_4800: + uart_4800(); + break; + case BAUD_9600: + uart_9600(); + break; + case BAUD_14400: + uart_14400(); + break; + case BAUD_19200: + uart_19200(); + break; + case BAUD_38400: + uart_38400(); + break; + case BAUD_57600: + uart_57600(); + break; + case BAUD_76800: + uart_76800(); + break; + } + + + // UCSR0A &= ~(1 << U2X0); // disable double speed operation + // set 8N1 + UCSR0B = 0 | (0 << RXCIE0) | (0 << TXCIE0) | (0 << UDRIE0) | (0 << RXEN0) | (0 << TXEN0) | (0 << UCSZ02); + UCSR0C = 0 | (1 << UCSZ01) | (1 << UCSZ00); + while (UCSR0A & (1 << RXC0)) + UDR0; // flush receive buffer + + SERIAL_EnableTXD(); + SERIAL_EnableRXD(); +} + diff --git a/radio/src/targets/common_avr/serial_driver.h b/radio/src/targets/common_avr/serial_driver.h new file mode 100644 index 000000000..a3089d691 --- /dev/null +++ b/radio/src/targets/common_avr/serial_driver.h @@ -0,0 +1,59 @@ +/* + * Authors - Gerard Valade + * + * Adapted from frsky + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef _SERIAL_H_ +#define _SERIAL_H_ + +typedef enum serial_tx_state_ { + TX_STATE_EMPTY = 0, // + TX_STATE_READY, // + TX_STATE_BUSY +} serial_tx_state_t; +extern serial_tx_state_t serialTxState; + +//! \brief Baudrate selection. +enum SERIAL_BAUDS { + BAUD_4800 = 0, + BAUD_9600, + BAUD_14400, + BAUD_19200, + BAUD_38400, + BAUD_57600, + BAUD_76800 +}; + +//! \brief Definition of baudrate settings item choices. +typedef void (*SerialFuncP)(uint8_t event); + +extern SerialFuncP RXHandler; + +#define MAX_TX_BUFFER 32 +//#if 0 +extern uint8_t serialTxBuffer[MAX_TX_BUFFER]; // 32 characters +extern uint8_t serialTxBufferCount; +extern uint8_t * ptrTxISR; +//#endif + +void SERIAL_Init(void); +//void SERIAL_transmitBuffer(uint8_t len); +extern void SERIAL_start_uart_send(); +extern void SERIAL_end_uart_send(); +extern void SERIAL_send_uart_bytes(uint8_t * buf, uint16_t len); + +void SERIAL_startTX(void); +#define IS_TX_BUSY (serialTxState!=TX_STATE_EMPTY) + +#endif diff --git a/radio/src/targets/simu/simpgmspace.cpp b/radio/src/targets/simu/simpgmspace.cpp index 8ada390be..965b0922b 100644 --- a/radio/src/targets/simu/simpgmspace.cpp +++ b/radio/src/targets/simu/simpgmspace.cpp @@ -1228,7 +1228,6 @@ uint32_t pwrPressed() { return false; } #else uint32_t pwrCheck() { return true; } #endif -void usbStart() { } int usbPlugged() { return false; } void USART_DeInit(USART_TypeDef* ) { } ErrorStatus RTC_SetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct) { return SUCCESS; } diff --git a/radio/src/targets/sky9x/board_sky9x.h b/radio/src/targets/sky9x/board_sky9x.h index 2c9592c9b..d02404ced 100644 --- a/radio/src/targets/sky9x/board_sky9x.h +++ b/radio/src/targets/sky9x/board_sky9x.h @@ -290,7 +290,7 @@ uint32_t telemetryTransmitPending(); void telemetryTransmitBuffer(uint8_t * buffer, uint32_t size); // Second UART driver -void telemetrySecondPortInit(unsigned int protocol); +void serial2TelemetryInit(unsigned int protocol); bool telemetrySecondPortReceive(uint8_t & data); #endif diff --git a/radio/src/targets/sky9x/second_serial_driver.cpp b/radio/src/targets/sky9x/serial2_driver.cpp similarity index 92% rename from radio/src/targets/sky9x/second_serial_driver.cpp rename to radio/src/targets/sky9x/serial2_driver.cpp index 69b0d7bdf..4cd39bc3c 100644 --- a/radio/src/targets/sky9x/second_serial_driver.cpp +++ b/radio/src/targets/sky9x/serial2_driver.cpp @@ -53,7 +53,7 @@ Fifo<512> serial2RxFifo; * This function is synchronous (i.e. uses polling). * c Character to send. */ -void debugPutc(const char c) +void serial2Putc(const char c) { Uart *pUart = SECOND_SERIAL_UART; @@ -64,6 +64,11 @@ void debugPutc(const char c) pUart->UART_THR = c; } +uint8_t serial2TracesEnabled() +{ + return false; +} + /** * Configures a UART peripheral with the specified parameters. * @@ -117,7 +122,7 @@ extern "C" void UART0_IRQHandler() #endif #if defined(FRSKY) -void telemetrySecondPortInit(unsigned int /*protocol*/) +void serial2TelemetryInit(unsigned int /*protocol*/) { SECOND_UART_Configure(FRSKY_D_BAUDRATE, Master_frequency); // startPdcUsartReceive(); diff --git a/radio/src/targets/taranis/bluetooth_driver.cpp b/radio/src/targets/taranis/bluetooth_driver.cpp index d2d43c15c..65789778c 100755 --- a/radio/src/targets/taranis/bluetooth_driver.cpp +++ b/radio/src/targets/taranis/bluetooth_driver.cpp @@ -133,7 +133,7 @@ void bluetoothWriteString(const char * str) void bluetoothWriteWakeup(void) { if (bluetoothWriteState == BLUETOOTH_WRITE_IDLE) { - if (!btTxFifo.empty()) { + if (!btTxFifo.isEmpty()) { bluetoothWriteState = BLUETOOTH_WRITE_INIT; GPIO_ResetBits(BT_GPIO_BRTS, BT_GPIO_PIN_BRTS); } diff --git a/radio/src/targets/taranis/board_taranis.cpp b/radio/src/targets/taranis/board_taranis.cpp index 4d103d15e..e73accc14 100644 --- a/radio/src/targets/taranis/board_taranis.cpp +++ b/radio/src/targets/taranis/board_taranis.cpp @@ -277,7 +277,7 @@ void checkTrainerSettings() stop_sbus_on_heartbeat_capture() ; break; case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: - uart3Stop(); + serial2Stop(); } currentTrainerMode = requiredTrainerMode; @@ -292,8 +292,8 @@ void checkTrainerSettings() init_sbus_on_heartbeat_capture() ; break; case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: - if (g_eeGeneral.uart3Mode == UART_MODE_SBUS_TRAINER) { - uart3SbusInit(); + if (g_eeGeneral.serial2Mode == UART_MODE_SBUS_TRAINER) { + serial2SbusInit(); break; } // no break diff --git a/radio/src/targets/taranis/board_taranis.h b/radio/src/targets/taranis/board_taranis.h index e1171e99b..9430d7beb 100644 --- a/radio/src/targets/taranis/board_taranis.h +++ b/radio/src/targets/taranis/board_taranis.h @@ -74,9 +74,10 @@ extern "C" { #endif #if !defined(SIMU) - #include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Class/msc/inc/usbd_msc_core.h" - #include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Class/hid/inc/usbd_hid_core.h" - #include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Core/inc/usbd_usr.h" + #include "usbd_cdc_core.h" + #include "usbd_msc_core.h" + #include "usbd_hid_core.h" + #include "usbd_usr.h" #include "usbd_desc.h" #include "usb_conf.h" #include "usbd_conf.h" @@ -282,10 +283,8 @@ void backlightInit(void); // USB driver int usbPlugged(void); void usbInit(void); -void usbStart(void); -#if defined(USB_JOYSTICK) -void usbStop(void); -#endif +void usbDeInit(void); +void usbSerialPutc(uint8_t c); #if defined(__cplusplus) && !defined(SIMU) } @@ -323,13 +322,13 @@ void hapticOff(void); void hapticOn(void); #endif -// SERIAL_USART driver +// Second serial port driver #define DEBUG_BAUDRATE 115200 -void uart3Init(unsigned int mode, unsigned int protocol); -void uart3Putc(const char c); -#define telemetrySecondPortInit(protocol) uart3Init(UART_MODE_TELEMETRY, protocol) -void uart3SbusInit(void); -void uart3Stop(void); +void serial2Init(unsigned int mode, unsigned int protocol); +void serial2Putc(char c); +#define serial2TelemetryInit(protocol) serial2Init(UART_MODE_TELEMETRY, protocol) +void serial2SbusInit(void); +void serial2Stop(void); // BT driver #define BLUETOOTH_DEFAULT_BAUDRATE 115200 diff --git a/radio/src/targets/taranis/bootloader/Makefile b/radio/src/targets/taranis/bootloader/Makefile index 84e78cfb6..745ff1c4b 100755 --- a/radio/src/targets/taranis/bootloader/Makefile +++ b/radio/src/targets/taranis/bootloader/Makefile @@ -109,6 +109,8 @@ ifeq ($(PCB), TARANIS) EXTRAINCDIRS += $(STM32USBPATH)/STM32_USB_OTG_Driver/inc EXTRAINCDIRS += $(STM32USBPATH)/STM32_USB_Device_Library/Core/inc EXTRAINCDIRS += $(STM32USBPATH)/STM32_USB_Device_Library/Class/msc/inc + EXTRAINCDIRS += $(STM32USBPATH)/STM32_USB_Device_Library/Class/hid/inc + EXTRAINCDIRS += $(STM32USBPATH)/STM32_USB_Device_Library/Class/cdc/inc EXTRAINCDIRS += .. ../../.. ../../../fonts/std ifeq ($(PCBREV), REV4a) CPPDEFS += -DREV4a diff --git a/radio/src/targets/taranis/bootloader/boot.cpp b/radio/src/targets/taranis/bootloader/boot.cpp index 8567199e4..2460dd7fe 100755 --- a/radio/src/targets/taranis/bootloader/boot.cpp +++ b/radio/src/targets/taranis/bootloader/boot.cpp @@ -418,7 +418,6 @@ int main() // SD card detect pin sdInit(); usbInit(); - usbStart(); #endif for (;;) { diff --git a/radio/src/targets/taranis/uart3_driver.cpp b/radio/src/targets/taranis/serial2_driver.cpp similarity index 84% rename from radio/src/targets/taranis/uart3_driver.cpp rename to radio/src/targets/taranis/serial2_driver.cpp index d91ec4479..5b4f60036 100644 --- a/radio/src/targets/taranis/uart3_driver.cpp +++ b/radio/src/targets/taranis/serial2_driver.cpp @@ -36,8 +36,8 @@ #include "../../opentx.h" -uint8_t uart3Mode = UART_MODE_NONE; -Fifo<512> uart3TxFifo; +uint8_t serial2Mode = 0; +Fifo<512> serial2TxFifo; extern Fifo<512> telemetryFifo; extern Fifo<32> sbusFifo; @@ -73,17 +73,17 @@ void uart3Setup(unsigned int baudrate) NVIC_EnableIRQ(SERIAL_USART_IRQn); } -void uart3Init(unsigned int mode, unsigned int protocol) +void serial2Init(unsigned int mode, unsigned int protocol) { USART_DeInit(SERIAL_USART); - uart3Mode = false; + serial2Mode = mode; switch (mode) { case UART_MODE_TELEMETRY_MIRROR: uart3Setup(FRSKY_SPORT_BAUDRATE); break; -#if defined(DEBUG) +#if !defined(USB_SERIAL) && (defined(DEBUG) || defined(CLI)) case UART_MODE_DEBUG: uart3Setup(DEBUG_BAUDRATE); break; @@ -94,43 +94,38 @@ void uart3Init(unsigned int mode, unsigned int protocol) } break; } - - uart3Mode = mode; } -void uart3Putc(const char c) +void serial2Putc(char c) { - uart3TxFifo.push(c); + while (serial2TxFifo.isFull()); + serial2TxFifo.push(c); USART_ITConfig(SERIAL_USART, USART_IT_TXE, ENABLE); } -#if defined(DEBUG) -void debugPutc(const char c) -{ - if (uart3Mode == UART_MODE_DEBUG) { - uart3Putc(c); - } -} -#endif - -void uart3SbusInit() +void serial2SbusInit() { uart3Setup(100000); SERIAL_USART->CR1 |= USART_CR1_M | USART_CR1_PCE ; } -void uart3Stop() +void serial2Stop() { USART_DeInit(SERIAL_USART); } +uint8_t serial2TracesEnabled() +{ + return (serial2Mode == 0); +} + #if !defined(SIMU) extern "C" void SERIAL_USART_IRQHandler(void) { // Send if (USART_GetITStatus(SERIAL_USART, USART_IT_TXE) != RESET) { uint8_t txchar; - if (uart3TxFifo.pop(txchar)) { + if (serial2TxFifo.pop(txchar)) { /* Write one byte to the transmit data register */ USART_SendData(SERIAL_USART, txchar); } @@ -145,13 +140,18 @@ extern "C" void SERIAL_USART_IRQHandler(void) uint8_t data = SERIAL_USART->DR; if (!(status & USART_FLAG_ERRORS)) { - switch (uart3Mode) { + switch (serial2Mode) { case UART_MODE_TELEMETRY: telemetryFifo.push(data); break; case UART_MODE_SBUS_TRAINER: sbusFifo.push(data); break; +#if !defined(USB_SERIAL) && defined(CLI) + case UART_MODE_DEBUG: + cliRxFifo.push(data); + break; +#endif } } diff --git a/radio/src/targets/taranis/usb_conf.h b/radio/src/targets/taranis/usb_conf.h index a1e0279d4..a84c15bba 100644 --- a/radio/src/targets/taranis/usb_conf.h +++ b/radio/src/targets/taranis/usb_conf.h @@ -47,7 +47,7 @@ * when FS core is used. *******************************************************************************/ #ifndef USE_USB_OTG_FS - #define USE_USB_OTG_FS + #define USE_USB_OTG_FS // USB2.0 Full Speed == 12 Mbit #endif /* USE_USB_OTG_FS */ #ifdef USE_USB_OTG_FS diff --git a/radio/src/targets/taranis/usb_driver.c b/radio/src/targets/taranis/usb_driver.c index 97963ce06..448752fe3 100644 --- a/radio/src/targets/taranis/usb_driver.c +++ b/radio/src/targets/taranis/usb_driver.c @@ -35,8 +35,6 @@ */ #include "board_taranis.h" -#include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_OTG_Driver/inc/usb_dcd_int.h" -#include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_OTG_Driver/inc/usb_bsp.h" int usbPlugged(void) { @@ -63,28 +61,24 @@ USB_OTG_CORE_HANDLE USB_OTG_dev; void OTG_FS_IRQHandler(void) { - USBD_OTG_ISR_Handler (&USB_OTG_dev); + USBD_OTG_ISR_Handler(&USB_OTG_dev); } void usbInit(void) -{ - USB_OTG_BSP_Init(&USB_OTG_dev); -} - -void usbStart(void) { #if defined(USB_JOYSTICK) // initialize USB as HID device USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_HID_cb, &USR_cb); +#elif defined(USB_SERIAL) + // initialize USB as CDC device (virtual serial port) + USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_CDC_cb, &USR_cb); #elif defined(USB_MASS_STORAGE) // initialize USB as MSC device USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_MSC_cb, &USR_cb); #endif } -#if defined(USB_JOYSTICK) -void usbStop(void) +void usbDeInit(void) { USBD_DeInit(&USB_OTG_dev); } -#endif diff --git a/radio/src/targets/taranis/usbd_cdc.cpp b/radio/src/targets/taranis/usbd_cdc.cpp new file mode 100644 index 000000000..7cb2d061a --- /dev/null +++ b/radio/src/targets/taranis/usbd_cdc.cpp @@ -0,0 +1,219 @@ +/** + ****************************************************************************** + * @file usbd_cdc_vcp.c + * @author MCD Application Team + * @version V1.1.0 + * @date 19-March-2012 + * @brief Generic media access Layer. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2012 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED +#pragma data_alignment = 4 +#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ + +#include "opentx.h" + +extern "C" { + +/* Includes ------------------------------------------------------------------*/ +#include "usb_conf.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + + +/* These are external variables imported from CDC core to be used for IN + transfer management. */ +extern uint8_t APP_Rx_Buffer []; /* Write CDC received data in this buffer. + These data will be sent over USB IN endpoint + in the CDC core functions. */ +extern volatile uint32_t APP_Rx_ptr_in; /* Increment this pointer or roll it back to + start address when writing received data + in the buffer APP_Rx_Buffer. */ +extern volatile uint32_t APP_Rx_ptr_out; + +/* Private function prototypes -----------------------------------------------*/ +static uint16_t VCP_Init (void); +static uint16_t VCP_DeInit (void); +static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len); +static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len); + +// static uint16_t VCP_COMConfig(uint8_t Conf); + +CDC_IF_Prop_TypeDef VCP_fops = +{ + VCP_Init, + VCP_DeInit, + VCP_Ctrl, + 0, + VCP_DataRx +}; + +} // extern "C" + +bool cdcConnected = false; + +/* Private functions ---------------------------------------------------------*/ +/** + * @brief VCP_Init + * Initializes the Media on the STM32 + * @param None + * @retval Result of the opeartion (USBD_OK in all cases) + */ +static uint16_t VCP_Init(void) +{ + cdcConnected = true; + return USBD_OK; +} + +/** + * @brief VCP_DeInit + * DeInitializes the Media on the STM32 + * @param None + * @retval Result of the opeartion (USBD_OK in all cases) + */ +static uint16_t VCP_DeInit(void) +{ + cdcConnected = false; + return USBD_OK; +} + + +/** + * @brief VCP_Ctrl + * Manage the CDC class requests + * @param Cmd: Command code + * @param Buf: Buffer containing command data (request parameters) + * @param Len: Number of data to be sent (in bytes) + * @retval Result of the opeartion (USBD_OK in all cases) + */ +static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len) +{ + switch (Cmd) + { + case SEND_ENCAPSULATED_COMMAND: + /* Not needed for this driver */ + break; + + case GET_ENCAPSULATED_RESPONSE: + /* Not needed for this driver */ + break; + + case SET_COMM_FEATURE: + /* Not needed for this driver */ + break; + + case GET_COMM_FEATURE: + /* Not needed for this driver */ + break; + + case CLEAR_COMM_FEATURE: + /* Not needed for this driver */ + break; + + case SET_LINE_CODING: + /* Not needed for this driver */ + break; + + case GET_LINE_CODING: + /* Not needed for this driver */ + break; + + case SET_CONTROL_LINE_STATE: + /* Not needed for this driver */ + break; + + case SEND_BREAK: + /* Not needed for this driver */ + break; + + default: + break; + } + + return USBD_OK; +} + +// some debug vars +uint16_t usbWraps = 0; +uint16_t charsWritten = 0; + +void usbSerialPutc(uint8_t c) +{ + if (!cdcConnected) return; + + uint32_t txDataLen; + do { + txDataLen = APP_RX_DATA_SIZE + APP_Rx_ptr_in - APP_Rx_ptr_out; + if (txDataLen >= APP_RX_DATA_SIZE) { + txDataLen -= APP_RX_DATA_SIZE; + } + } while (txDataLen >= (APP_RX_DATA_SIZE - CDC_DATA_MAX_PACKET_SIZE)); + + APP_Rx_Buffer[APP_Rx_ptr_in] = c; + ++charsWritten; + /* To avoid buffer overflow */ + if (APP_Rx_ptr_in >= APP_RX_DATA_SIZE-1) { + APP_Rx_ptr_in = 0; + ++usbWraps; + } + else { + APP_Rx_ptr_in++; + } +} + +/** + * @brief VCP_DataRx + * Data received over USB OUT endpoint is available here + * + * @note + * This function will block any OUT packet reception on USB endpoint + * until exiting this function. If you exit this function before transfer + * is complete on CDC interface (ie. using DMA controller) it will result + * in receiving more data while previous ones are still not sent. + * + * @note + * This function is executed inside the USBD_OTG_ISR_Handler() interrupt handler! + + * @param Buf: Buffer of data to be received + * @param Len: Number of data received (in bytes) + * @retval Result of the opeartion: USBD_OK if all operations are OK else VCP_FAIL + */ +static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len) +{ + // TODO: try implementing inbound flow control: + // if the cliRxFifo does not have enough free space to receive all + // available characters, return VCP_FAIL. Maybe that will throttle down + // the sender and we will receive the same packet at a later time. + + //copy data to the application FIFO + for (uint32_t i = 0; i < Len; i++) + { + cliRxFifo.push(Buf[i]); + } + return USBD_OK; +} + + + +// /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/radio/src/targets/taranis/usbd_conf.h b/radio/src/targets/taranis/usbd_conf.h index 7308a64c8..557973a26 100644 --- a/radio/src/targets/taranis/usbd_conf.h +++ b/radio/src/targets/taranis/usbd_conf.h @@ -36,13 +36,13 @@ #define USBD_ITF_MAX_NUM 1 #define USB_MAX_STR_DESC_SIZ 64 -#define USBD_SELF_POWERED +#define USBD_SELF_POWERED /* Class Layer Parameter */ #define MSC_IN_EP 0x81 #define MSC_OUT_EP 0x01 -#define MSC_MAX_PACKET 64 +#define MSC_MAX_PACKET 64 #define MSC_MEDIA_PACKET 4096 @@ -52,6 +52,17 @@ #define HID_IN_PACKET 9 #define HID_OUT_PACKET 9 +#define CDC_IN_EP 0x81 /* EP1 for data IN */ +#define CDC_OUT_EP 0x01 /* EP1 for data OUT */ +#define CDC_CMD_EP 0x82 /* EP2 for CDC commands */ + +/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ +#define CDC_DATA_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */ +#define CDC_CMD_PACKET_SZE 8 /* Control Endpoint Packet size */ + +#define CDC_IN_FRAME_INTERVAL 5 /* Number of frames between IN transfers */ +#define APP_RX_DATA_SIZE 512 // USB serial port output buffer. TODO: tune this buffer size /* Total size of IN buffer: APP_RX_DATA_SIZE*8/MAX_BAUDARATE*1000 should be > CDC_IN_FRAME_INTERVAL */ +#define APP_FOPS VCP_fops #endif //__USBD_CONF__H__ diff --git a/radio/src/targets/taranis/usbd_desc.c b/radio/src/targets/taranis/usbd_desc.c index f61065a2a..2c2011255 100644 --- a/radio/src/targets/taranis/usbd_desc.c +++ b/radio/src/targets/taranis/usbd_desc.c @@ -73,6 +73,11 @@ #define USBD_PRODUCT_FS_STRING "FrSky Taranis Joystick" #define USBD_CONFIGURATION_FS_STRING "HID Config" #define USBD_INTERFACE_FS_STRING "HID Interface" +#elif defined(USB_SERIAL) + #define USBD_PID 0x5740 // do not change, this ID is used by the ST USB driver for Windows + #define USBD_PRODUCT_FS_STRING "FrSky Taranis Serial Port" + #define USBD_CONFIGURATION_FS_STRING "VSP Config" + #define USBD_INTERFACE_FS_STRING "VSP Interface" #elif defined(USB_MASS_STORAGE) #define USBD_PID 0x5720 #define USBD_PRODUCT_FS_STRING "FrSky Taranis Mass Storage" diff --git a/radio/src/tasks_arm.cpp b/radio/src/tasks_arm.cpp index 25e25cf61..5e0c1285d 100644 --- a/radio/src/tasks_arm.cpp +++ b/radio/src/tasks_arm.cpp @@ -40,7 +40,6 @@ #define MIXER_STACK_SIZE 500 #define AUDIO_STACK_SIZE 500 #define BT_STACK_SIZE 500 -#define DEBUG_STACK_SIZE 500 #if defined(_MSC_VER) #define _ALIGNED(x) __declspec(align(x)) @@ -63,11 +62,6 @@ OS_TID btTaskId; OS_STK btStack[BT_STACK_SIZE]; #endif -#if defined(DEBUG) -OS_TID debugTaskId; -OS_STK debugStack[DEBUG_STACK_SIZE]; -#endif - OS_MutexID audioMutex; OS_MutexID mixerMutex; @@ -205,8 +199,8 @@ void tasksStart() { CoInitOS(); -#if defined(CPUARM) && defined(DEBUG) && !defined(SIMU) - debugTaskId = CoCreateTaskEx(debugTask, NULL, 10, &debugStack[DEBUG_STACK_SIZE-1], DEBUG_STACK_SIZE, 1, false); +#if defined(CLI) + cliStart(); #endif #if defined(BLUETOOTH) diff --git a/radio/src/telemetry/frsky.cpp b/radio/src/telemetry/frsky.cpp index bb832b122..2402eb8f1 100644 --- a/radio/src/telemetry/frsky.cpp +++ b/radio/src/telemetry/frsky.cpp @@ -165,8 +165,8 @@ NOINLINE void processSerialData(uint8_t data) #endif #if defined(PCBTARANIS) - if (g_eeGeneral.uart3Mode == UART_MODE_TELEMETRY_MIRROR) { - uart3Putc(data); + if (g_eeGeneral.serial2Mode == UART_MODE_TELEMETRY_MIRROR) { + serial2Putc(data); } #endif @@ -604,7 +604,7 @@ void telemetryInit(void) } else if (telemetryProtocol==PROTOCOL_FRSKY_D_SECONDARY) { telemetryPortInit(0); - telemetrySecondPortInit(PROTOCOL_FRSKY_D_SECONDARY); + serial2TelemetryInit(PROTOCOL_FRSKY_D_SECONDARY); } else { telemetryPortInit(FRSKY_SPORT_BAUDRATE); diff --git a/radio/src/telemetry/mavlink.h b/radio/src/telemetry/mavlink.h index 9c76b54c6..63ae2f661 100644 --- a/radio/src/telemetry/mavlink.h +++ b/radio/src/telemetry/mavlink.h @@ -43,10 +43,8 @@ #define MAVLINK_COMM_NUM_BUFFERS 1 #include "GCS_MAVLink/include_v1.0/mavlink_types.h" -#include "serial.h" +#include "targets/common_avr/serial_driver.h" #include "opentx.h" -#include "serial.h" -//#include "include/mavlink_helpers.h" extern mavlink_system_t mavlink_system; diff --git a/radio/src/thirdparty/STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c b/radio/src/thirdparty/STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c index a91772b71..3856f778d 100644 --- a/radio/src/thirdparty/STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c +++ b/radio/src/thirdparty/STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c @@ -122,7 +122,7 @@ static uint8_t usbd_cdc_SOF (void *pdev); CDC specific management functions *********************************************/ static void Handle_USBAsynchXfer (void *pdev); -static uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length); +static const uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length); #ifdef USE_USB_OTG_HS static uint8_t *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length); #endif @@ -134,7 +134,7 @@ static uint8_t *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length); * @{ */ extern CDC_IF_Prop_TypeDef APP_FOPS; -extern uint8_t USBD_DeviceDesc [USB_SIZ_DEVICE_DESC]; +extern const uint8_t USBD_DeviceDesc [USB_SIZ_DEVICE_DESC]; #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED #if defined ( __ICCARM__ ) /*!< IAR Compiler */ @@ -179,8 +179,8 @@ __ALIGN_BEGIN uint8_t APP_Rx_Buffer [APP_RX_DATA_SIZE] __ALIGN_END ; #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ __ALIGN_BEGIN uint8_t CmdBuff[CDC_CMD_PACKET_SZE] __ALIGN_END ; -uint32_t APP_Rx_ptr_in = 0; -uint32_t APP_Rx_ptr_out = 0; +volatile uint32_t APP_Rx_ptr_in = 0; +volatile uint32_t APP_Rx_ptr_out = 0; uint32_t APP_Rx_length = 0; uint8_t USB_Tx_State = 0; @@ -782,7 +782,7 @@ static void Handle_USBAsynchXfer (void *pdev) * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length) +static const uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length) { *length = sizeof (usbd_cdc_CfgDesc); return usbd_cdc_CfgDesc;