1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-23 08:15:17 +03:00

Merge pull request #2696 from opentx/bsongis/issue2595_cli

Fixes #2595 and #2598: USB serial port and CLI added
This commit is contained in:
Damjan Adamic 2015-08-31 11:06:04 +02:00
commit 771206e1b2
40 changed files with 1316 additions and 709 deletions

View file

@ -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"

View file

@ -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
@ -1249,7 +1261,7 @@ endif
ifeq ($(EXT), MAVLINK)
CPPDEFS += -DMAVLINK
INCDIRS += thirdparty
CPPSRC += telemetry/mavlink.cpp gui/$(GUIDIRECTORY)/view_mavlink.cpp serial.cpp
CPPSRC += telemetry/mavlink.cpp gui/$(GUIDIRECTORY)/view_mavlink.cpp targets/common_avr/serial_driver.cpp
EEPROM_VARIANT += ${MAVLINK_VARIANT}
endif
@ -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)

View file

@ -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();

View file

@ -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) {

315
radio/src/cli.cpp Normal file
View file

@ -0,0 +1,315 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - 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 <ctype.h>
#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<NUMBER_ANALOG; i++) {
serialPrint("adc[%d] = %04X", i, Analog_values[i]);
}
}
else if (!strcmp(argv[1], "outputs")) {
for (int i=0; i<NUM_CHNOUT; i++) {
serialPrint("outputs[%d] = %04X", i, channelOutputs[i]);
}
}
else if (toInt(argv, 1, &address) > 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, "[<frequency>] [<duration>]" },
{ "ls", cliLs, "<directory>" },
{ "play", cliPlay, "<filename>" },
{ "print", cliDisplay, "<address> [<size>] | <what>" },
{ "trace", cliTrace, "on | off" },
{ "volume", cliVolume, "<level>" },
{ "help", cliHelp, "[<command>]" },
{ 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<len; i++) {
if (line[i] == ' ') {
line[i] = '\0';
if (argc < CLI_COMMAND_MAX_ARGS) {
argv[argc++] = &line[i+1];
}
}
}
return cliExecCommand(argv);
}
void cliTask(void * pdata)
{
char line[CLI_COMMAND_MAX_LEN+1];
int pos = 0;
cliPrompt();
for (;;) {
uint8_t c;
while (!cliRxFifo.pop(c)) {
CoTickDelay(5); // 10ms
}
if (c == 12) {
// clear screen
serialPrint("\033[2J\033[1;1H");
cliPrompt();
}
else if (c == 127) {
// backspace
if (pos) {
line[--pos] = '\0';
serialPutc(c);
}
}
else if (c == '\r' || c == '\n') {
// enter
serialCrlf();
line[pos] = '\0';
cliExecLine(line);
pos = 0;
cliPrompt();
}
else if (isascii(c) && pos < CLI_COMMAND_MAX_LEN) {
line[pos++] = c;
serialPutc(c);
}
}
}
void cliStart()
{
cliTaskId = CoCreateTaskEx(cliTask, NULL, 10, &cliStack[CLI_STACK_SIZE-1], CLI_STACK_SIZE, 1, false);
}

51
radio/src/cli.h Normal file
View file

@ -0,0 +1,51 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - 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_

View file

@ -34,225 +34,33 @@
*
*/
extern "C" {
#include <stdio.h>
#include <stdarg.h>
}
#include "opentx.h"
#if (defined(DEBUG) && defined(CPUARM)) || defined(SIMU)
#include <stdarg.h>
#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);
traceCallback(str);
}
#else
const char *t = tmp;
while (*t) {
debugPutc(*t++);
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

View file

@ -39,58 +39,40 @@
#include <inttypes.h>
#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)

38
radio/src/dump.cpp Normal file
View file

@ -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<size; i++) {
dumpPrintf("%.2X ", data[i]);
dumpPosition++;
if ((dumpPosition & (32-1)) == 0) {
dumpPrintf("\r\n");
}
}
}
void dumpEnd()
{
dumpPrintf("\r\n");
}
void dump(const uint8_t *data, unsigned int size)
{
dumpStart(size);
dumpBody(data, size);
dumpEnd();
}

13
radio/src/dump.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef _DUMP_H_
#define _DUMP_H_
#if defined(DEBUG) || defined(CLI)
void dumpStart(unsigned int size);
void dumpBody(const uint8_t * data, unsigned int size);
void dumpEnd();
void dump(const uint8_t * data, unsigned int size);
#else
#define dump(data, size)
#endif
#endif // _DUMP_H_

View file

@ -56,7 +56,7 @@ class Fifo
}
bool pop(uint8_t & byte) {
if (empty()) {
if (isEmpty()) {
return false;
}
else {
@ -66,12 +66,17 @@ class Fifo
}
}
bool empty() {
bool isEmpty() {
return (ridx == widx);
}
bool isFull() {
uint32_t next = (widx+1) & (N-1);
return (next == ridx);
}
void flush() {
while (!empty()) {};
while (!isEmpty()) {};
}
protected:
@ -80,4 +85,4 @@ class Fifo
volatile uint32_t ridx;
};
#endif
#endif // _FIFO_H_

View file

@ -46,7 +46,7 @@
#include "opentx.h"
#include "telemetry/mavlink.h"
#include "gui/9X/menus.h"
#include "serial.h"
#include "targets/common_avr/serial_driver.h"
#define APSIZE (BSS | DBLSIZE)

View file

@ -219,9 +219,9 @@ void menuGeneralHardware(uint8_t event)
break;
#endif
case ITEM_SETUP_HW_UART3_MODE:
g_eeGeneral.uart3Mode = selectMenuItem(HW_SETTINGS_COLUMN, y, STR_UART3MODE, STR_UART3MODES, g_eeGeneral.uart3Mode, 0, UART_MODE_MAX, attr, event);
g_eeGeneral.serial2Mode = selectMenuItem(HW_SETTINGS_COLUMN, y, STR_UART3MODE, STR_UART3MODES, g_eeGeneral.serial2Mode, 0, UART_MODE_MAX, attr, event);
if (attr && checkIncDec_Ret) {
uart3Init(g_eeGeneral.uart3Mode, MODEL_TELEMETRY_PROTOCOL());
serial2Init(g_eeGeneral.serial2Mode, MODEL_TELEMETRY_PROTOCOL());
}
break;
}

View file

@ -574,7 +574,7 @@ void menuModelTelemetry(uint8_t event)
switch (k) {
case ITEM_TELEMETRY_PROTOCOL_TYPE:
g_model.telemetryProtocol = selectMenuItem(TELEM_COL2, y, STR_TELEMETRY_TYPE, "\017FrSky S.PORT\0 FrSky D\0 FrSky D (cable)", g_model.telemetryProtocol, PROTOCOL_TELEMETRY_FIRST, g_eeGeneral.uart3Mode==UART_MODE_TELEMETRY ? PROTOCOL_FRSKY_D_SECONDARY : PROTOCOL_FRSKY_D, attr, event);
g_model.telemetryProtocol = selectMenuItem(TELEM_COL2, y, STR_TELEMETRY_TYPE, "\017FrSky S.PORT\0 FrSky D\0 FrSky D (cable)", g_model.telemetryProtocol, PROTOCOL_TELEMETRY_FIRST, g_eeGeneral.serial2Mode==UART_MODE_TELEMETRY ? PROTOCOL_FRSKY_D_SECONDARY : PROTOCOL_FRSKY_D, attr, event);
break;
case ITEM_TELEMETRY_SENSORS_LABEL:

View file

@ -98,9 +98,15 @@ void menuStatisticsView(uint8_t event)
#define MENU_DEBUG_Y_MIXMAX (2*FH-3)
#define MENU_DEBUG_Y_LUA (3*FH-2)
#define MENU_DEBUG_Y_FREE_RAM (4*FH-1)
#define MENU_DEBUG_Y_STACK (5*FH)
#define MENU_DEBUG_Y_USB (5*FH)
#define MENU_DEBUG_Y_RTOS (6*FH)
#if defined(USB_SERIAL)
extern uint16_t usbWraps;
extern uint16_t charsWritten;
extern "C" volatile uint32_t APP_Rx_ptr_in;
#endif
void menuStatisticsDebug(uint8_t event)
{
TITLE(STR_MENUDEBUG);
@ -172,6 +178,15 @@ void menuStatisticsDebug(uint8_t event)
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_MIXMAX, DURATION_MS_PREC2(maxMixerDuration), PREC2|LEFT);
lcd_puts(lcdLastPos, MENU_DEBUG_Y_MIXMAX, "ms");
#if defined(USB_SERIAL)
lcd_putsLeft(MENU_DEBUG_Y_USB, "Usb");
lcd_outdezAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_USB, charsWritten, LEFT);
lcd_puts(lcdLastPos, MENU_DEBUG_Y_USB, " ");
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_USB, APP_Rx_ptr_in, LEFT);
lcd_puts(lcdLastPos, MENU_DEBUG_Y_USB, " ");
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_USB, usbWraps, LEFT);
#endif
lcd_putsLeft(MENU_DEBUG_Y_RTOS, STR_FREESTACKMINB);
lcd_putsAtt(MENU_DEBUG_COL1_OFS, MENU_DEBUG_Y_RTOS+1, "[M]", SMLSIZE);
lcd_outdezAtt(lcdLastPos, MENU_DEBUG_Y_RTOS, stack_free(0), UNSIGN|LEFT);

View file

@ -44,29 +44,40 @@ void handleUsbConnection()
{
#if defined(PCBTARANIS) && !defined(SIMU)
static bool usbStarted = false;
if (!usbStarted && usbPlugged()) {
usbStarted = true;
/*
We used to initialize USB peripheral and driver here.
According to my tests this is way too late. The USB peripheral
therefore does not have enough information to start responding to
USB host request, which causes very slow USB device recognition,
multiple USB device resets, etc...
If we want to change the USB profile, the procedure is simple:
* USB cable must be disconnected
* call usbDeInit();
* call usbUnit(); which initializes USB with the new profile.
Obviously the usbInit() should be modified to have a runtime
selection of the USB profile.
*/
#if defined(USB_MASS_STORAGE)
opentxClose();
#endif
usbStart();
#if defined(USB_MASS_STORAGE)
usbPluggedIn();
#endif
usbStarted = true;
}
if (usbStarted && !usbPlugged()) {
usbStarted = false;
}
#if defined(USB_JOYSTICK)
if (usbStarted ) {
if (!usbPlugged()) {
//disable USB
usbStop();
usbStarted = false;
}
else {
usbJoystickUpdate();
}
}
#endif
#endif //#if defined(PCBTARANIS) && !defined(SIMU)
}

View file

@ -382,7 +382,7 @@ enum BeeperMode {
#define LEN_SWITCH_NAME 3
#define LEN_ANA_NAME 3
#define LEN_BLUETOOTH_NAME 10
#define HAS_WIRELESS_TRAINER_HARDWARE() (g_eeGeneral.uart3Mode==UART_MODE_SBUS_TRAINER/* || g_eeGeneral.uart3Mode==UART_MODE_CPPM_TRAINER*/)
#define HAS_WIRELESS_TRAINER_HARDWARE() (g_eeGeneral.serial2Mode==UART_MODE_SBUS_TRAINER/* || g_eeGeneral.serial2Mode==UART_MODE_CPPM_TRAINER*/)
#if defined(REV9E)
#define BLUETOOTH_FIELDS \
@ -394,7 +394,7 @@ enum BeeperMode {
#define EXTRA_GENERAL_FIELDS \
EXTRA_GENERAL_FIELDS_ARM \
uint8_t uart3Mode:6; \
uint8_t serial2Mode:6; \
uint8_t slidersConfig:2; \
uint8_t potsConfig; /*two bits for every pot*/\
uint8_t backlightColor; \

View file

@ -2451,7 +2451,7 @@ void opentxInit(OPENTX_INIT_ARGS)
backlightOn();
#if defined(PCBTARANIS)
uart3Init(g_eeGeneral.uart3Mode, MODEL_TELEMETRY_PROTOCOL());
serial2Init(g_eeGeneral.serial2Mode, MODEL_TELEMETRY_PROTOCOL());
#endif
#if defined(PCBSKY9X) && !defined(SIMU)

View file

@ -1,297 +1,72 @@
/*
* Authors - Gerard Valade <gerard.valade@gmail.com>
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - 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 <stdarg.h>
#include <stdio.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).
#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);
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
const char *t = tmp;
while (*t) {
serialPutc(*t++);
}
}
static void uart_4800(void) {
#ifndef SIMU
#undef BAUD // avoid compiler warning
#define BAUD 4800
#include <util/setbaud.h>
UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE;
#if USE_2X
UCSR0A |= (1 << U2X0);
#else
UCSR0A &= ~(1 << U2X0);
#endif
#endif
void serialCrlf()
{
serialPutc('\r');
serialPutc('\n');
}
static void uart_9600(void) {
#ifndef SIMU
#undef BAUD // avoid compiler warning
#define BAUD 9600
#include <util/setbaud.h>
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 <util/setbaud.h>
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 <util/setbaud.h>
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 <util/setbaud.h>
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 <util/setbaud.h>
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 <util/setbaud.h>
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();
}

View file

@ -1,59 +1,55 @@
/*
* Authors - Gerard Valade <gerard.valade@gmail.com>
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - 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.
*
*/
#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)
#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_

View file

@ -0,0 +1,297 @@
/*
* Authors - Gerard Valade <gerard.valade@gmail.com>
*
* 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 <util/setbaud.h>
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 <util/setbaud.h>
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 <util/setbaud.h>
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 <util/setbaud.h>
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 <util/setbaud.h>
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 <util/setbaud.h>
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 <util/setbaud.h>
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();
}

View file

@ -0,0 +1,59 @@
/*
* Authors - Gerard Valade <gerard.valade@gmail.com>
*
* 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

View file

@ -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; }

View file

@ -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

View file

@ -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();

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -418,7 +418,6 @@ int main()
// SD card detect pin
sdInit();
usbInit();
usbStart();
#endif
for (;;) {

View file

@ -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
}
}

View file

@ -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

View file

@ -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)
{
@ -67,24 +65,20 @@ void OTG_FS_IRQHandler(void)
}
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

View file

@ -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
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* 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****/

View file

@ -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__

View file

@ -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"

View file

@ -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)

View file

@ -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);

View file

@ -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;

View file

@ -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;