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

Fixes #2595 - Cli added

Based on projectkk2glider work, with a lot of bugs I am sure. Still not
tested, this is why I preferred working on my own branch. I push it now
so that Jenkins do the first tests and you can review if I am on the
right track. 

I am really wondering if a merge with the Lua api would be possible /
nice, what do you think?
This commit is contained in:
bertrand 2015-08-10 22:42:04 +02:00
parent 70d77fd851
commit 2b312fdbb4
26 changed files with 970 additions and 653 deletions

View file

@ -232,7 +232,7 @@ namespace NAMESPACE {
#include "radio/src/targets/taranis/pulses_driver.cpp" #include "radio/src/targets/taranis/pulses_driver.cpp"
#include "radio/src/targets/taranis/rtc_driver.cpp" #include "radio/src/targets/taranis/rtc_driver.cpp"
#include "radio/src/targets/taranis/trainer_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) #elif defined(PCBSKY9X)
#include "radio/src/targets/sky9x/board_sky9x.cpp" #include "radio/src/targets/sky9x/board_sky9x.cpp"
#include "radio/src/targets/sky9x/telemetry_driver.cpp" #include "radio/src/targets/sky9x/telemetry_driver.cpp"
@ -243,7 +243,7 @@ namespace NAMESPACE {
#include "radio/src/targets/sky9x/sdcard_driver.cpp" #include "radio/src/targets/sky9x/sdcard_driver.cpp"
#include "radio/src/targets/sky9x/coproc_driver.cpp" #include "radio/src/targets/sky9x/coproc_driver.cpp"
#include "radio/src/targets/sky9x/haptic_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" #include "radio/src/targets/sky9x/pulses_driver.cpp"
#elif defined(PCBGRUVIN9X) #elif defined(PCBGRUVIN9X)
#include "radio/src/targets/gruvin9x/board_gruvin9x.cpp" #include "radio/src/targets/gruvin9x/board_gruvin9x.cpp"

View file

@ -268,6 +268,10 @@ SHUTDOWN_CONFIRMATION = NO
# Values = YES, NO # Values = YES, NO
DEBUG = NO DEBUG = NO
# Activate Command Line Interpreter
# Values = NO, YES
CLI = NO
# Activate writing of SPORT telemetry received data to sport.log file # Activate writing of SPORT telemetry received data to sport.log file
# Values = YES, NO # Values = YES, NO
SPORT_FILE_LOG = NO SPORT_FILE_LOG = NO
@ -800,7 +804,7 @@ ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO))
EEPROMSRC = eeprom_common.cpp eeprom_raw.cpp eeprom_conversions.cpp 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 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 += 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 CPPSRC += loadboot.cpp debug.cpp
BITMAPS += bitmaps/9X/splash.lbm bitmaps/9X/asterisk.lbm bitmaps/9X/about.lbm BITMAPS += bitmaps/9X/splash.lbm bitmaps/9X/asterisk.lbm bitmaps/9X/about.lbm
ifeq ($(SDCARD), YES) ifeq ($(SDCARD), YES)
@ -927,8 +931,8 @@ ifeq ($(PCB), TARANIS)
EEPROMSRC = eeprom_common.cpp eeprom_rlc.cpp eeprom_conversions.cpp EEPROMSRC = eeprom_common.cpp eeprom_rlc.cpp eeprom_conversions.cpp
PULSESSRC = pulses/pulses_arm.cpp pulses/ppm_arm.cpp pulses/pxx_arm.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 += 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 += 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 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 CPPSRC += loadboot.cpp
ifeq ($(PCBREV), REV9E) ifeq ($(PCBREV), REV9E)
CPPSRC += targets/taranis/top_lcd_driver.cpp CPPSRC += targets/taranis/top_lcd_driver.cpp
@ -1246,10 +1250,10 @@ ifeq ($(EXT), JETI)
endif endif
ifeq ($(EXT), MAVLINK) ifeq ($(EXT), MAVLINK)
CPPDEFS += -DMAVLINK CPPDEFS += -DMAVLINK
INCDIRS += thirdparty 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} EEPROM_VARIANT += ${MAVLINK_VARIANT}
endif endif
ifeq ($(EXT), TELEMETREZ) ifeq ($(EXT), TELEMETREZ)
@ -1290,8 +1294,15 @@ ifeq ($(EXT), $(filter $(EXT), FRSKY FRSKY_SPORT TELEMETREZ))
EEPROM_VARIANT += ${FRSKY_VARIANT} EEPROM_VARIANT += ${FRSKY_VARIANT}
endif endif
ifeq ($(DEBUG), YES) ifeq ($(SIMU), YES)
CPPDEFS += -DDEBUG 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 endif
ifeq ($(EEPROM_PROGRESS_BAR), YES) ifeq ($(EEPROM_PROGRESS_BAR), YES)

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_MAX_ARGS 8
extern Fifo<512> uart3TxFifo;
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_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_MAX_ARGS) {
argv[argc++] = &line[i+1];
}
}
}
return cliExecCommand(argv);
}
void cliTask(void * pdata)
{
char line[256];
uint8_t 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)) {
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,222 +34,30 @@
* *
*/ */
extern "C" {
#include <stdio.h>
#include <stdarg.h>
}
#include "opentx.h" #include "opentx.h"
#if (defined(DEBUG) && defined(CPUARM)) || defined(SIMU)
#if defined(SIMU) #if defined(SIMU)
traceCallbackFunc traceCallback = 0; traceCallbackFunc traceCallback = 0;
#endif #endif
#if defined(SIMU) #if defined(SIMU)
#define PRINTF_BUFFER_SIZE 1024 void debugPrintf(const char * format, ...)
#else
#define PRINTF_BUFFER_SIZE 256
#endif
// Outputs a string to the UART
void debugPuts(const char *format, ...)
{ {
va_list arglist; va_list arglist;
char tmp[PRINTF_BUFFER_SIZE]; char * str;
va_start(arglist, format); va_start(arglist, format);
vsnprintf(tmp, PRINTF_BUFFER_SIZE, format, arglist); vasprintf(&str, format, arglist);
va_end(arglist); va_end(arglist);
fputs(str, stdout);
#if defined(SIMU)
fputs(tmp, stdout);
fflush(stdout); fflush(stdout);
if (traceCallback) { if (traceCallback) {
traceCallback(tmp); traceCallback(str);
}
#else
const char *t = tmp;
while (*t) {
debugPutc(*t++);
} }
free(str);
}
#endif #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) #if defined(DEBUG_TRACE_BUFFER)
static struct TraceElement traceBuffer[TRACE_BUFFER_LEN]; static struct TraceElement traceBuffer[TRACE_BUFFER_LEN];
static uint8_t traceBufferPos; static uint8_t traceBufferPos;
extern Fifo<512> uart3TxFifo; extern Fifo<512> uart3TxFifo;
@ -305,6 +113,4 @@ void dumpTraceBuffer()
} }
TRACE("End of Trace Buffer dump"); TRACE("End of Trace Buffer dump");
} }
#endif #endif

View file

@ -39,58 +39,32 @@
#include <inttypes.h> #include <inttypes.h>
#include "rtc.h" #include "rtc.h"
#include "dump.h"
#if (defined(DEBUG) && defined(CPUARM)) || defined(SIMU) #include "cli.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(SIMU) #if defined(SIMU)
typedef void (*traceCallbackFunc)(const char * text); typedef void (*traceCallbackFunc)(const char * text);
extern traceCallbackFunc traceCallback; 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 (serialTracesEnabled() && cliTracesEnabled) serialPrintf(__VA_ARGS__); } while(0)
#elif defined(DEBUG) && defined(CPUARM)
#define debugPrintf(...) do { if (serialTracesEnabled()) serialPrintf(__VA_ARGS__); } while(0)
#else
#define debugPrintf(...)
#endif #endif
void debugPuts(const char *string, ...); #define TRACE(...) do { debugPrintf(__VA_ARGS__); debugPrintf("\r\n"); } while(0)
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 DUMP(data, size) dump(data, size) #define DUMP(data, size) dump(data, size)
#define TRACE_DEBUG(...) debugPuts("-D- " __VA_ARGS__) #define TRACE_DEBUG(...) debugPrintf("-D- " __VA_ARGS__)
#define TRACE_DEBUG_WP(...) debugPuts(__VA_ARGS__) #define TRACE_DEBUG_WP(...) debugPrintf(__VA_ARGS__)
#define TRACE_INFO(...) debugPuts("-I- " __VA_ARGS__) #define TRACE_INFO(...) debugPrintf("-I- " __VA_ARGS__)
#define TRACE_INFO_WP(...) debugPuts(__VA_ARGS__) #define TRACE_INFO_WP(...) debugPrintf(__VA_ARGS__)
#define TRACE_WARNING(...) debugPuts("-W- " __VA_ARGS__) #define TRACE_WARNING(...) debugPrintf("-W- " __VA_ARGS__)
#define TRACE_WARNING_WP(...) debugPuts(__VA_ARGS__) #define TRACE_WARNING_WP(...) debugPrintf(__VA_ARGS__)
#define TRACE_ERROR(...) debugPuts("-E- " __VA_ARGS__) #define TRACE_ERROR(...) debugPrintf("-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
#if defined(DEBUG_TRACE_BUFFER) #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

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

View file

@ -219,9 +219,9 @@ void menuGeneralHardware(uint8_t event)
break; break;
#endif #endif
case ITEM_SETUP_HW_UART3_MODE: 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) { if (attr && checkIncDec_Ret) {
uart3Init(g_eeGeneral.uart3Mode, MODEL_TELEMETRY_PROTOCOL()); serial2Init(g_eeGeneral.serial2Mode, MODEL_TELEMETRY_PROTOCOL());
} }
break; break;
} }

View file

@ -574,7 +574,7 @@ void menuModelTelemetry(uint8_t event)
switch (k) { switch (k) {
case ITEM_TELEMETRY_PROTOCOL_TYPE: 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; break;
case ITEM_TELEMETRY_SENSORS_LABEL: case ITEM_TELEMETRY_SENSORS_LABEL:

View file

@ -384,7 +384,7 @@ enum BeeperMode {
#define LEN_SWITCH_NAME 3 #define LEN_SWITCH_NAME 3
#define LEN_ANA_NAME 3 #define LEN_ANA_NAME 3
#define LEN_BLUETOOTH_NAME 10 #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) #if defined(REV9E)
#define BLUETOOTH_FIELDS \ #define BLUETOOTH_FIELDS \
@ -396,7 +396,7 @@ enum BeeperMode {
#define EXTRA_GENERAL_FIELDS \ #define EXTRA_GENERAL_FIELDS \
EXTRA_GENERAL_FIELDS_ARM \ EXTRA_GENERAL_FIELDS_ARM \
uint8_t uart3Mode:6; \ uint8_t serial2Mode:6; \
uint8_t slidersConfig:2; \ uint8_t slidersConfig:2; \
uint8_t potsConfig; /*two bits for every pot*/\ uint8_t potsConfig; /*two bits for every pot*/\
uint8_t backlightColor; \ uint8_t backlightColor; \

View file

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

View file

@ -1759,10 +1759,4 @@ extern Clipboard clipboard;
extern uint16_t s_anaFilt[NUMBER_ANALOG]; extern uint16_t s_anaFilt[NUMBER_ANALOG];
#endif #endif
#if defined(USB_SERIAL)
extern Fifo<64> cliRxFifo;
void sendUsbSerialChar(uint8_t c);
#endif
#endif #endif

View file

@ -1,297 +1,75 @@
/* /*
* 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 * This program is free software; you can redistribute it and/or modify
* under the terms of the GNU General Public License version 2 as published * it under the terms of the GNU General Public License version 2 as
* by the Free Software Foundation. * published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, but WITHOUT * This program is distributed in the hope that it will be useful,
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * but WITHOUT ANY WARRANTY; without even the implied warranty of
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* more details. * GNU General Public License for more details.
* *
*/ */
#include "opentx.h" #include "opentx.h"
#include "serial.h" #include "serial.h"
/* extern "C" {
Receive serial (RS-232) characters, detecting and storing each Fr-Sky #include <stdio.h>
0x7e-framed packet as it arrives. When a complete packet has been #include <stdarg.h>
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 #define PRINTF_BUFFER_SIZE 256
a second buffer to receive data while one buffer is being processed (slowly).
*/
#ifndef SIMU void serialPutc(char c)
ISR (USART0_RX_vect)
{ {
uint8_t iostat; //USART control and Status Register 0 A #if defined(USB_SERIAL)
// uint8_t rh; //USART control and Status Register 0 B sendUsbSerialChar(c);
UCSR0B &= ~(1 << RXCIE0); // disable Interrupt #else
sei(); serial2Putc(c);
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 #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 serialPrintf(const char * format, ...)
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) { va_list arglist;
UDR0 = *ptrTxISR++; char tmp[PRINTF_BUFFER_SIZE];
serialTxBufferCount--;
} else {
UCSR0B &= ~(1 << UDRIE0); // disable UDRE0 interrupt
serialTxState = TX_STATE_EMPTY;
}
}
#endif
void SERIAL_start_uart_send() { va_start(arglist, format);
ptrTxISR = serialTxBuffer; vsnprintf(tmp, PRINTF_BUFFER_SIZE, format, arglist);
serialTxBufferCount = 0; va_end(arglist);
const char *t = tmp;
while (*t) {
serialPutc(*t++);
}
} }
void SERIAL_end_uart_send() { void serialCrlf()
ptrTxISR = serialTxBuffer; {
//UCSR0B |= (1 << UDRIE0); // enable UDRE0 interrupt serialPutc('\r');
serialTxState = TX_STATE_READY; 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 <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

@ -1,59 +1,55 @@
/* /*
* Authors - Gerard Valade <gerard.valade@gmail.com> * Authors (alphabetical order)
* * - Andre Bernet <bernet.andre@gmail.com>
* Adapted from frsky * - Andreas Weitl
* * - Bertrand Songis <bsongis@gmail.com>
* This program is free software; you can redistribute it and/or modify it * - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* under the terms of the GNU General Public License version 2 as published * - Cameron Weeks <th9xer@gmail.com>
* by the Free Software Foundation. * - Erez Raviv
* * - Gabriel Birkus
* This program is distributed in the hope that it will be useful, but WITHOUT * - Jean-Pierre Parisy
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * - Karl Szmutny
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * - Michael Blandford
* more details. * - Michal Hlavinka
* * - Pat Mackenzie
*/ * - Philip Moss
* - Rob Thomson
#ifndef _SERIAL_H_ * - Romolo Manfredini <romolo.manfredini@gmail.com>
#define _SERIAL_H_ * - Thomas Husterer
*
typedef enum serial_tx_state_ { * opentx is based on code named
TX_STATE_EMPTY = 0, // * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
TX_STATE_READY, // * er9x by Erez Raviv: http://code.google.com/p/er9x/,
TX_STATE_BUSY * and the original (and ongoing) project by
} serial_tx_state_t; * Thomas Husterer, th9x: http://code.google.com/p/th9x/
extern serial_tx_state_t serialTxState; *
* This program is free software; you can redistribute it and/or modify
//! \brief Baudrate selection. * it under the terms of the GNU General Public License version 2 as
enum SERIAL_BAUDS { * published by the Free Software Foundation.
BAUD_4800 = 0, *
BAUD_9600, * This program is distributed in the hope that it will be useful,
BAUD_14400, * but WITHOUT ANY WARRANTY; without even the implied warranty of
BAUD_19200, * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
BAUD_38400, * GNU General Public License for more details.
BAUD_57600, *
BAUD_76800 */
};
#ifndef _SERIAL_H_
//! \brief Definition of baudrate settings item choices. #define _SERIAL_H_
typedef void (*SerialFuncP)(uint8_t event);
#ifdef __cplusplus
extern SerialFuncP RXHandler; extern "C" {
#endif
#define MAX_TX_BUFFER 32
//#if 0 void serialPutc(char c);
extern uint8_t serialTxBuffer[MAX_TX_BUFFER]; // 32 characters void serialPrintf(const char *format, ...);
extern uint8_t serialTxBufferCount; void serialCrlf();
extern uint8_t * ptrTxISR;
//#endif #ifdef __cplusplus
}
void SERIAL_Init(void); #endif
//void SERIAL_transmitBuffer(uint8_t len);
extern void SERIAL_start_uart_send(); #define serialPrint(...) do { serialPrintf(__VA_ARGS__); serialCrlf(); } while(0)
extern void SERIAL_end_uart_send();
extern void SERIAL_send_uart_bytes(uint8_t * buf, uint16_t len); #endif // _SERIAL_H_
void SERIAL_startTX(void);
#define IS_TX_BUSY (serialTxState!=TX_STATE_EMPTY)
#endif

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

@ -290,7 +290,8 @@ uint32_t telemetryTransmitPending();
void telemetryTransmitBuffer(uint8_t * buffer, uint32_t size); void telemetryTransmitBuffer(uint8_t * buffer, uint32_t size);
// Second UART driver // Second UART driver
void telemetrySecondPortInit(unsigned int protocol); #define serialTracesEnabled() false
void serial2TelemetryInit(unsigned int protocol);
bool telemetrySecondPortReceive(uint8_t & data); bool telemetrySecondPortReceive(uint8_t & data);
#endif #endif

View file

@ -53,7 +53,7 @@ Fifo<512> serial2RxFifo;
* This function is synchronous (i.e. uses polling). * This function is synchronous (i.e. uses polling).
* c Character to send. * c Character to send.
*/ */
void debugPutc(const char c) void serial2Putc(const char c)
{ {
Uart *pUart = SECOND_SERIAL_UART; Uart *pUart = SECOND_SERIAL_UART;
@ -117,7 +117,7 @@ extern "C" void UART0_IRQHandler()
#endif #endif
#if defined(FRSKY) #if defined(FRSKY)
void telemetrySecondPortInit(unsigned int /*protocol*/) void serial2TelemetryInit(unsigned int /*protocol*/)
{ {
SECOND_UART_Configure(FRSKY_D_BAUDRATE, Master_frequency); SECOND_UART_Configure(FRSKY_D_BAUDRATE, Master_frequency);
// startPdcUsartReceive(); // startPdcUsartReceive();

View file

@ -260,7 +260,7 @@ void checkTrainerSettings()
stop_sbus_on_heartbeat_capture() ; stop_sbus_on_heartbeat_capture() ;
break; break;
case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT:
uart3Stop(); serial2Stop();
} }
currentTrainerMode = requiredTrainerMode; currentTrainerMode = requiredTrainerMode;
@ -275,8 +275,8 @@ void checkTrainerSettings()
init_sbus_on_heartbeat_capture() ; init_sbus_on_heartbeat_capture() ;
break; break;
case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT:
if (g_eeGeneral.uart3Mode == UART_MODE_SBUS_TRAINER) { if (g_eeGeneral.serial2Mode == UART_MODE_SBUS_TRAINER) {
uart3SbusInit(); serial2SbusInit();
break; break;
} }
// no break // no break

View file

@ -320,13 +320,15 @@ void hapticOff(void);
void hapticOn(void); void hapticOn(void);
#endif #endif
// SERIAL_USART driver // Second serial port driver
#define DEBUG_BAUDRATE 115200 #define DEBUG_BAUDRATE 115200
void uart3Init(unsigned int mode, unsigned int protocol); extern uint8_t serial2Mode;
void uart3Putc(const char c); #define serialTracesEnabled() (serial2Mode == 0)
#define telemetrySecondPortInit(protocol) uart3Init(UART_MODE_TELEMETRY, protocol) void serial2Init(unsigned int mode, unsigned int protocol);
void uart3SbusInit(void); void serial2Putc(char c);
void uart3Stop(void); #define serial2TelemetryInit(protocol) serial2Init(UART_MODE_TELEMETRY, protocol)
void serial2SbusInit(void);
void serial2Stop(void);
// BT driver // BT driver
#define BLUETOOTH_DEFAULT_BAUDRATE 115200 #define BLUETOOTH_DEFAULT_BAUDRATE 115200

View file

@ -36,7 +36,7 @@
#include "../../opentx.h" #include "../../opentx.h"
uint8_t uart3Mode = UART_MODE_NONE; uint8_t serial2Mode = 0;
Fifo<512> uart3TxFifo; Fifo<512> uart3TxFifo;
extern Fifo<512> telemetryFifo; extern Fifo<512> telemetryFifo;
extern Fifo<32> sbusFifo; extern Fifo<32> sbusFifo;
@ -73,17 +73,17 @@ void uart3Setup(unsigned int baudrate)
NVIC_EnableIRQ(SERIAL_USART_IRQn); 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); USART_DeInit(SERIAL_USART);
uart3Mode = false; serial2Mode = mode;
switch (mode) { switch (mode) {
case UART_MODE_TELEMETRY_MIRROR: case UART_MODE_TELEMETRY_MIRROR:
uart3Setup(FRSKY_SPORT_BAUDRATE); uart3Setup(FRSKY_SPORT_BAUDRATE);
break; break;
#if defined(DEBUG) #if !defined(USB_SERIAL) && (defined(DEBUG) || defined(CLI))
case UART_MODE_DEBUG: case UART_MODE_DEBUG:
uart3Setup(DEBUG_BAUDRATE); uart3Setup(DEBUG_BAUDRATE);
break; break;
@ -94,36 +94,21 @@ void uart3Init(unsigned int mode, unsigned int protocol)
} }
break; break;
} }
uart3Mode = mode;
} }
void uart3Putc(const char c) void serial2Putc(char c)
{ {
uart3TxFifo.push(c); uart3TxFifo.push(c);
USART_ITConfig(SERIAL_USART, USART_IT_TXE, ENABLE); USART_ITConfig(SERIAL_USART, USART_IT_TXE, ENABLE);
} }
#if defined(DEBUG) void serial2SbusInit()
void debugPutc(const char c)
{
if (uart3Mode == UART_MODE_DEBUG) {
uart3Putc(c);
#if defined(USB_SERIAL)
// also send debug output into USB serial port (if active)
sendUsbSerialChar(c);
#endif
}
}
#endif
void uart3SbusInit()
{ {
uart3Setup(100000); uart3Setup(100000);
SERIAL_USART->CR1 |= USART_CR1_M | USART_CR1_PCE ; SERIAL_USART->CR1 |= USART_CR1_M | USART_CR1_PCE ;
} }
void uart3Stop() void serial2Stop()
{ {
USART_DeInit(SERIAL_USART); USART_DeInit(SERIAL_USART);
} }
@ -149,13 +134,18 @@ extern "C" void SERIAL_USART_IRQHandler(void)
uint8_t data = SERIAL_USART->DR; uint8_t data = SERIAL_USART->DR;
if (!(status & USART_FLAG_ERRORS)) { if (!(status & USART_FLAG_ERRORS)) {
switch (uart3Mode) { switch (serial2Mode) {
case UART_MODE_TELEMETRY: case UART_MODE_TELEMETRY:
telemetryFifo.push(data); telemetryFifo.push(data);
break; break;
case UART_MODE_SBUS_TRAINER: case UART_MODE_SBUS_TRAINER:
sbusFifo.push(data); sbusFifo.push(data);
break; break;
#if !defined(USB_SERIAL) && defined(CLI)
case UART_MODE_DEBUG:
cliRxFifo.push(data);
break;
#endif
} }
} }

View file

@ -40,7 +40,6 @@
#define MIXER_STACK_SIZE 500 #define MIXER_STACK_SIZE 500
#define AUDIO_STACK_SIZE 500 #define AUDIO_STACK_SIZE 500
#define BT_STACK_SIZE 500 #define BT_STACK_SIZE 500
#define DEBUG_STACK_SIZE 500
#if defined(_MSC_VER) #if defined(_MSC_VER)
#define _ALIGNED(x) __declspec(align(x)) #define _ALIGNED(x) __declspec(align(x))
@ -63,11 +62,6 @@ OS_TID btTaskId;
OS_STK btStack[BT_STACK_SIZE]; OS_STK btStack[BT_STACK_SIZE];
#endif #endif
#if defined(DEBUG)
OS_TID debugTaskId;
OS_STK debugStack[DEBUG_STACK_SIZE];
#endif
OS_MutexID audioMutex; OS_MutexID audioMutex;
OS_MutexID mixerMutex; OS_MutexID mixerMutex;
@ -210,8 +204,8 @@ void tasksStart()
{ {
CoInitOS(); CoInitOS();
#if defined(CPUARM) && defined(DEBUG) && !defined(SIMU) #if defined(CLI)
debugTaskId = CoCreateTaskEx(debugTask, NULL, 10, &debugStack[DEBUG_STACK_SIZE-1], DEBUG_STACK_SIZE, 1, false); cliStart();
#endif #endif
#if defined(BLUETOOTH) #if defined(BLUETOOTH)

View file

@ -165,8 +165,8 @@ NOINLINE void processSerialData(uint8_t data)
#endif #endif
#if defined(PCBTARANIS) #if defined(PCBTARANIS)
if (g_eeGeneral.uart3Mode == UART_MODE_TELEMETRY_MIRROR) { if (g_eeGeneral.serial2Mode == UART_MODE_TELEMETRY_MIRROR) {
uart3Putc(data); serial2Putc(data);
} }
#endif #endif
@ -604,7 +604,7 @@ void telemetryInit(void)
} }
else if (telemetryProtocol==PROTOCOL_FRSKY_D_SECONDARY) { else if (telemetryProtocol==PROTOCOL_FRSKY_D_SECONDARY) {
telemetryPortInit(0); telemetryPortInit(0);
telemetrySecondPortInit(PROTOCOL_FRSKY_D_SECONDARY); serial2TelemetryInit(PROTOCOL_FRSKY_D_SECONDARY);
} }
else { else {
telemetryPortInit(FRSKY_SPORT_BAUDRATE); telemetryPortInit(FRSKY_SPORT_BAUDRATE);

View file

@ -43,10 +43,8 @@
#define MAVLINK_COMM_NUM_BUFFERS 1 #define MAVLINK_COMM_NUM_BUFFERS 1
#include "GCS_MAVLink/include_v1.0/mavlink_types.h" #include "GCS_MAVLink/include_v1.0/mavlink_types.h"
#include "serial.h" #include "targets/common_avr/serial_driver.h"
#include "opentx.h" #include "opentx.h"
#include "serial.h"
//#include "include/mavlink_helpers.h"
extern mavlink_system_t mavlink_system; extern mavlink_system_t mavlink_system;