From ce34047e121ce0e5fed455c251b201a0ef16a2c5 Mon Sep 17 00:00:00 2001 From: bsongis Date: Tue, 28 Aug 2012 18:42:46 +0000 Subject: [PATCH] [ersky9x] Bluetooth FrSky proxy added (ported from ersky9x, still untested, not part of the release) --- src/Makefile | 11 ++ src/board_ersky9x.cpp | 28 ++++- src/board_ersky9x.h | 4 + src/ersky9x/bluetooth.cpp | 209 ++++++++++++++++++++++++++++++++++++++ src/ersky9x/bluetooth.h | 40 ++++++++ src/ersky9x/board.h | 7 ++ src/frsky.cpp | 5 + src/general_menus.cpp | 20 +++- src/myeeprom.h | 4 +- src/open9x.cpp | 32 ++++-- src/simpgmspace.h | 9 +- 11 files changed, 353 insertions(+), 16 deletions(-) create mode 100644 src/ersky9x/bluetooth.cpp create mode 100644 src/ersky9x/bluetooth.h diff --git a/src/Makefile b/src/Makefile index 82fdb2414..0624dd58a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -148,6 +148,10 @@ VARIO = YES # Values = YES, NO SDCARD = NO +# BLUETOOTH +# Values = YES, NO +BLUETOOTH = NO + # PXX (FrSky PCM) protocol PXX = NO @@ -426,6 +430,13 @@ ifeq ($(PCB), ARM) ifeq ($(SDCARD), YES) SRC += FatFs/ff.c FatFs/fattime.c FatFs/option/ccsbcs.c ersky9x/diskio.c endif + + ifeq ($(BLUETOOTH), YES) + MODS:=${MODS}S + CPPDEFS += -DBLUETOOTH + CPPSRC += ersky9x/bluetooth.cpp +endif + endif ifeq ($(PCB), V4) diff --git a/src/board_ersky9x.cpp b/src/board_ersky9x.cpp index d625b0196..4749b0329 100644 --- a/src/board_ersky9x.cpp +++ b/src/board_ersky9x.cpp @@ -244,16 +244,36 @@ inline void UART3_Configure( uint32_t baudrate, uint32_t masterClock) /* Configure baudrate */ /* Asynchronous, no oversampling */ - pUart->UART_BRGR = (masterClock / baudrate) / 16; - -// baudrate = (masterClock * 8 / baudrate) / 16 ; -// pUart->UART_BRGR = ( baudrate / 8 ) || ( ( baudrate & 7 ) << 16 ) ; // Fractional part to allow 152000 baud + baudrate = (masterClock * 8 / baudrate) / 16 ; + pUart->UART_BRGR = ( baudrate / 8 ) | ( ( baudrate & 7 ) << 16 ) ; // Fractional part to allow 152000 baud // /* Disable PDC channel */ pUart->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS; /* Enable receiver and transmitter */ pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN; + +#if 0 + // TODO when we will want to be BT receiver + pUart->UART_IER = UART_IER_RXRDY ; + NVIC_EnableIRQ(UART1_IRQn) ; +#endif +} + +struct t_serial_tx * Current_bt ; + +extern "C" void UART1_IRQHandler() +{ + Uart *pUart = BT_USART ; + if ( pUart->UART_SR & UART_SR_TXBUFE ) { + pUart->UART_IDR = UART_IDR_TXBUFE ; + pUart->UART_PTCR = US_PTCR_TXTDIS ; + Current_bt->ready = 0 ; + } + /* TODO + if ( pUart->UART_SR & UART_SR_RXRDY ) { + put_fifo32( &BtRx_fifo, pUart->UART_RHR ) ; + } */ } // USART0 configuration diff --git a/src/board_ersky9x.h b/src/board_ersky9x.h index 6981ac24f..a1c78da46 100644 --- a/src/board_ersky9x.h +++ b/src/board_ersky9x.h @@ -38,6 +38,10 @@ #include "ersky9x/sound_driver.h" #include "ersky9x/haptic_driver.h" +#if defined(BLUETOOTH) +#include "ersky9x/bluetooth.h" +#endif + extern "C" { extern void init_SDcard(); extern void sdInit(); diff --git a/src/ersky9x/bluetooth.cpp b/src/ersky9x/bluetooth.cpp new file mode 100644 index 000000000..2ab0481eb --- /dev/null +++ b/src/ersky9x/bluetooth.cpp @@ -0,0 +1,209 @@ +/* + * Authors (alphabetical order) + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * open9x 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 "../open9x.h" + +class Fifo32 +{ + public: + Fifo32(): + widx(0), + ridx(0) + { + } + + void push(uint8_t byte) { + uint32_t next = (widx+1) & 0x1f; + if (next != ridx) { + fifo[widx] = byte; + widx = next; + } + } + + bool pop(uint8_t & byte) { + if (ridx == widx) { + return false; + } + else { + byte = fifo[ridx]; + ridx = (ridx+1) & 0x1f; + return true; + } + } + + protected: + uint8_t fifo[32]; + volatile uint32_t widx; + volatile uint32_t ridx; +}; + +OS_FlagID btFlag; +Fifo32 btFifo; + +struct t_serial_tx btTx ; +uint8_t btTxBuffer[32] ; + +extern struct t_serial_tx * Current_bt ; + +uint32_t txPdcBt(struct t_serial_tx *data) +{ +#ifndef SIMU + Uart *pUart = BT_USART ; + + if (pUart->UART_TNCR == 0) { + Current_bt = data; + data->ready = 1; + pUart->UART_TPR = (uint32_t) data->buffer; + pUart->UART_TCR = data->size; + pUart->UART_PTCR = US_PTCR_TXTEN; + pUart->UART_IER = UART_IER_TXBUFE; + NVIC_EnableIRQ(UART1_IRQn); + return 1; // Sent OK + } +#endif + return 0 ; // Busy +} + + +void btSendBuffer() +{ + btTx.buffer = btTxBuffer; + txPdcBt(&btTx); + while (btTx.ready == 1) { + CoTickDelay(1); // 2ms for now + } + btTx.size = 0; +} + +void btPollDevice() +{ +#if 0 + uint16_t x; + uint32_t y; + uint16_t rxchar; + + x = 'O'; +#endif + + btTxBuffer[0] = 'A'; + btTxBuffer[1] = 'T'; + btTx.size = 2; + btSendBuffer(); + +#if 0 + for (y = 0; y < 300; y += 1) { + if ((rxchar = rxBtuart()) != 0xFFFF) { + if (rxchar == x) { + if (x == 'O') { + x = 'K'; + } + else { + break; // Found "OK" + } + } + } + else { + CoTickDelay(1); // 2mS + } + } + if (y < 300) { + return 1; + } + else { + return 0; + } +#endif +} + + +/* +Commands to BT module +AT+VERSION Returns the software version of the module +AT+BAUDx Sets the baud rate of the module: +1 1200 +2 2400 +3 4800 +4 9600 (Default) +5 19200 +6 38400 +7 57600 +8 115200 +9 230400 +AT+NAME Sets the name of the module + +Any name can be specified up to 20 characters +AT+PINxxxx Sets the pairing password of the device + +Any 4 digit number can be used, the default pincode is 1234 +AT+PN Sets the parity of the module + +So we could send AT+VERSION at different baudrates until we get a response +Then we can change the baudrate to the required value. +Or maybe just AT and get OK back +*/ + +void btTask(void* pdata) +{ + uint8_t byte; + + btFlag = CoCreateFlag(true, false); + btTx.size = 0; + +// Look for BT module baudrate, try 115200, and 9600 +// Already initialised to g_eeGeneral.bt_baudrate +// 0 : 115200, 1 : 9600, 2 : 19200 + + btPollDevice(); // Do we get a response? + + while (1) { + uint32_t x = CoWaitForSingleFlag(btFlag, 10); // Wait for data in Fifo + if (x == E_OK) { + // We have some data in the Fifo + while (btFifo.pop(byte)) { + btTxBuffer[btTx.size++] = byte; + if (btTx.size > 31) { + btSendBuffer(); + } + } + } + else if (btTx.size) { + btSendBuffer(); + } + } +} + +void btPushByte(uint8_t data) +{ + btFifo.push(data); + CoSetFlag(btFlag); // Tell the Bt task something to do +} diff --git a/src/ersky9x/bluetooth.h b/src/ersky9x/bluetooth.h new file mode 100644 index 000000000..a905bcaa4 --- /dev/null +++ b/src/ersky9x/bluetooth.h @@ -0,0 +1,40 @@ +/* + * Authors (alphabetical order) + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * open9x 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 bluetooth_h +#define bluetooth_h + +void btTask(void* pdata); +void btPushByte(uint8_t data); + +#endif diff --git a/src/ersky9x/board.h b/src/ersky9x/board.h index 95bcde9a5..9efa39e89 100644 --- a/src/ersky9x/board.h +++ b/src/ersky9x/board.h @@ -645,4 +645,11 @@ extern int32_t Card_state; extern uint32_t Master_frequency ; +struct t_serial_tx +{ + uint8_t *buffer ; + uint16_t size ; + volatile uint16_t ready ; +}; + #endif diff --git a/src/frsky.cpp b/src/frsky.cpp index 87b8f9d6f..504e544c2 100644 --- a/src/frsky.cpp +++ b/src/frsky.cpp @@ -431,6 +431,11 @@ NOINLINE void processSerialData(uint8_t stat, uint8_t data) static uint8_t numPktBytes = 0; static uint8_t dataState = frskyDataIdle; +#if defined(BLUETOOTH) + // TODO if (g_model.bt_telemetry) + btPushByte(data); +#endif + #if !defined(PCBARM) if (stat & ((1 << FE0) | (1 << DOR0) | (1 << UPE0))) { // discard buffer and start fresh on any comms error diff --git a/src/general_menus.cpp b/src/general_menus.cpp index c8d4ff97c..13c12de53 100644 --- a/src/general_menus.cpp +++ b/src/general_menus.cpp @@ -137,6 +137,9 @@ enum menuProcSetupItems { ITEM_SETUP_CONTRAST, ITEM_SETUP_BATTERY_WARNING, ITEM_SETUP_INACTIVITY_ALARM, +#if defined(BLUETOOTH) + ITEM_SETUP_BT_BAUDRATE, +#endif #if defined(ROTARY_ENCODERS) ITEM_SETUP_RE_NAVIGATION, #endif @@ -193,13 +196,18 @@ void menuProcSetup(uint8_t event) #else #define ARM_ZEROS #endif +#ifdef BLUETOOTH +#define BLUETOOTH_ZEROS 0, +#else +#define BLUETOOTH_ZEROS +#endif #ifdef ROTARY_ENCODERS #define ROTARY_ENCODERS_ZEROS 0, #else #define ROTARY_ENCODERS_ZEROS #endif - MENU(STR_MENURADIOSETUP, menuTabDiag, e_Setup, ITEM_SETUP_MAX+2, {0, 0, AUDIO_ZEROS VOICE_ZEROS HAPTIC_ZEROS ARM_ZEROS ROTARY_ENCODERS_ZEROS 0, 0, 0, 0, 0, 0, 0, 0, 0, SPLASH_ZEROS 0, 0, 0, 0, FRSKY_ZEROS 0, (uint8_t)-1, 1}); + MENU(STR_MENURADIOSETUP, menuTabDiag, e_Setup, ITEM_SETUP_MAX+2, {0, 0, AUDIO_ZEROS VOICE_ZEROS HAPTIC_ZEROS ARM_ZEROS BLUETOOTH_ZEROS ROTARY_ENCODERS_ZEROS 0, 0, 0, 0, 0, 0, 0, 0, 0, SPLASH_ZEROS 0, 0, 0, 0, FRSKY_ZEROS 0, (uint8_t)-1, 1}); uint8_t sub = m_posVert - 1; @@ -316,6 +324,16 @@ void menuProcSetup(uint8_t event) if(attr) g_eeGeneral.inactivityTimer = checkIncDec(event, g_eeGeneral.inactivityTimer, 0, 250, EE_GENERAL); //0..250minutes break; +#if defined(BLUETOOTH) + case ITEM_SETUP_BT_BAUDRATE: + g_eeGeneral.btBaudrate = selectMenuItem(y, PSTR("BT Baudrate"), PSTR("\005115k 9600 19200"), g_eeGeneral.btBaudrate, 0, 2, attr, event); + if (attr && checkIncDec_Ret) { + uint32_t baudrate = (g_eeGeneral.btBaudrate==0 ? 115200 : (g_eeGeneral.btBaudrate==1 ? 9600 : 19200)); + UART3_Configure(baudrate, Master_frequency); + } + break; +#endif + #if defined(ROTARY_ENCODERS) case ITEM_SETUP_RE_NAVIGATION: g_eeGeneral.reNavigation = selectMenuItem(y, STR_RENAVIG, STR_VRENAVIG, g_eeGeneral.reNavigation, 0, ROTARY_ENCODERS, attr, event); diff --git a/src/myeeprom.h b/src/myeeprom.h index 10cab953d..5df295a58 100644 --- a/src/myeeprom.h +++ b/src/myeeprom.h @@ -131,7 +131,7 @@ PACK(typedef struct t_EEGeneral { int8_t backlightMode; TrainerData trainer; uint8_t view; //index of subview in main scrren - uint8_t spare0:3; + uint8_t btBaudrate:3; // TODO only needed on ARM int8_t beeperMode:2; uint8_t spare1:1; uint8_t disableMemoryWarning:1; @@ -390,7 +390,7 @@ enum TelemetryUnit { UNIT_A1A2_MAX = UNIT_MILLIAMPS, UNIT_MAH, UNIT_WATTS, - UNIT_DB, + UNIT_DBM, UNIT_FEET, UNIT_KTS, UNIT_HOURS, diff --git a/src/open9x.cpp b/src/open9x.cpp index 7accdb7aa..f7111e3f9 100644 --- a/src/open9x.cpp +++ b/src/open9x.cpp @@ -52,10 +52,10 @@ OS_MutexID sdMutex; OS_MutexID audioMutex; OS_MutexID mixerMutex; -/*OS_TID btTask; +#if defined(BLUETOOTH) +OS_TID btTaskId; OS_STK btStack[BT_STACK_SIZE]; -OS_TCID btTimer; -OS_FlagID btFlag;*/ +#endif #endif #include "open9x.h" @@ -1677,7 +1677,7 @@ PLAY_FUNCTION(playValue, uint8_t idx) #if defined(FRSKY) case NUM_XCHNRAW+TELEM_RSSI_TX-1: case NUM_XCHNRAW+TELEM_RSSI_RX-1: - PLAY_NUMBER(val, 1+UNIT_DB, 0); + PLAY_NUMBER(val, 1+UNIT_DBM, 0); break; case NUM_XCHNRAW+TELEM_MIN_A1-1: case NUM_XCHNRAW+TELEM_MIN_A2-1: @@ -3116,6 +3116,23 @@ inline void open9xInit(OPEN9X_INIT_ARGS) #if defined(PCBARM) setVolume(g_eeGeneral.speakerVolume); PWM->PWM_CH_NUM[0].PWM_CDTYUPD = g_eeGeneral.backlightBright; + +#if defined(BLUETOOTH) + uint32_t brate ; + switch (g_eeGeneral.btBaudrate) { + default : + case 0 : + brate = 115200 ; + break ; + case 1 : + brate = 9600 ; + break ; + case 2 : + brate = 19200 ; + break ; + } + UART3_Configure(brate, Master_frequency); +#endif #endif if (g_eeGeneral.backlightMode != e_backlight_mode_off) backlightOn(); // on Tx start turn the light on @@ -3764,10 +3781,9 @@ int main(void) #if defined(PCBARM) CoInitOS(); - // btFlag = CoCreateFlag(TRUE, FALSE); // Auto-reset, start FALSE - // btTimer = CoCreateTmr(TMR_TYPE_PERIODIC, 1000/(1000/CFG_SYSTICK_FREQ), 1000/(1000/CFG_SYSTICK_FREQ), btTimerHandle); - - // btTaskId = CoCreateTask(btTask, NULL, 19, &btStack[BT_STACK_SIZE-1], BT_STACK_SIZE); +#if defined(BLUETOOTH) + btTaskId = CoCreateTask(btTask, NULL, 19, &btStack[BT_STACK_SIZE-1], BT_STACK_SIZE); +#endif mixerTaskId = CoCreateTask(mixerTask, NULL, 5, &mixerStack[MIXER_STACK_SIZE-1], MIXER_STACK_SIZE); menusTaskId = CoCreateTask(menusTask, NULL, 10, &menusStack[MENUS_STACK_SIZE-1], MENUS_STACK_SIZE); diff --git a/src/simpgmspace.h b/src/simpgmspace.h index b03fe5516..3cc849383 100644 --- a/src/simpgmspace.h +++ b/src/simpgmspace.h @@ -296,14 +296,21 @@ void eeprom_read_block (void *pointer_ram, #define board_init() #define OS_MutexID int +#define OS_FlagID int + +#define E_OK 0 + #define CoSetFlag(...) #define CoClearFlag(...) #define CoSetTmrCnt(...) #define CoEnterISR(...) #define CoExitISR(...) #define CoStartTmr(...) -#define CoWaitForSingleFlag(...) +#define CoWaitForSingleFlag(...) 0 #define CoEnterMutexSection(...) #define CoLeaveMutexSection(...) +#define CoTickDelay(...) +#define CoCreateFlag(...) 0 +#define UART3_Configure(a, b) a=a #endif