From 5dd7c105b6b65789d1a21f2302a4f11c49cc0f17 Mon Sep 17 00:00:00 2001 From: bsongis Date: Tue, 26 Jun 2012 10:09:31 +0000 Subject: [PATCH] Current consumption may depend on 3 different sources Flash saving in FrSky code SD card wav player (still read as raw 12000Hz 16bit samples) --- src/CoOS/kernel/OsConfig.h | 6 +- src/Makefile | 5 +- src/beeper.h | 5 +- src/board_ersky9x.cpp | 2 +- src/eeprom_arm.cpp | 14 +- src/ersky9x/audio.cpp | 196 ++++--- src/ersky9x/audio.h | 139 ++--- src/ersky9x/diskio.c | 1039 ++++++++++++++++++++++------------ src/ersky9x/sound_driver.cpp | 61 +- src/ersky9x/sound_driver.h | 15 +- src/frsky.cpp | 380 ++++++------- src/frsky.h | 29 +- src/general_menus.cpp | 39 +- src/gruvin9x/logs.cpp | 44 +- src/model_menus.cpp | 19 +- src/myeeprom.h | 15 +- src/open9x.cpp | 98 ++-- src/simpgmspace.cpp | 7 + src/simpgmspace.h | 10 + src/stock/audio.h | 5 +- src/translations.cpp | 6 +- src/translations.h | 9 +- src/translations/cz.h | 7 +- src/translations/de.h | 9 +- src/translations/en.h | 7 +- src/translations/fr.h | 7 +- src/translations/it.h | 7 +- src/translations/se.h | 7 +- util/tts.py | 3 +- 29 files changed, 1285 insertions(+), 905 deletions(-) diff --git a/src/CoOS/kernel/OsConfig.h b/src/CoOS/kernel/OsConfig.h index 5b2188438..66e127cdf 100644 --- a/src/CoOS/kernel/OsConfig.h +++ b/src/CoOS/kernel/OsConfig.h @@ -96,7 +96,7 @@ But in Dynamic Task Scheduling model(1),task resources will be recovered. If in Static Task Scheduling model(0),mutex module can not be used, as this model don't support to change task priority while CoOS running. */ -#define CFG_TASK_SCHEDULE_EN (0) +#define CFG_TASK_SCHEDULE_EN (1) /*---------------------- Task Management Config -----------------------------*/ @@ -232,7 +232,7 @@ Enable(1) or disable(0) flag management. Max number of flag is 32. */ #if CFG_TASK_WAITTING_EN > 0 -#define CFG_FLAG_EN (0) +#define CFG_FLAG_EN (1) #endif @@ -242,7 +242,7 @@ Enable(1) or disable(0) mutex management. */ #if CFG_TASK_WAITTING_EN > 0 #if CFG_TASK_SCHEDULE_EN > 0 -#define CFG_MUTEX_EN (0) +#define CFG_MUTEX_EN (1) #endif #endif diff --git a/src/Makefile b/src/Makefile index 87597ca1f..16dbbc3b6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -333,7 +333,7 @@ ifeq ($(PCB), ARM) EXTRAINCDIRS += ersky9x CoOS/kernel CoOS/portable BOARDSRC = board_ersky9x.cpp SRC += ersky9x/core_cm3.c ersky9x/board_lowlevel.c ersky9x/crt.c ersky9x/vectors_sam3s.c - SRC += CoOS/kernel/core.c CoOS/kernel/hook.c CoOS/kernel/task.c CoOS/kernel/event.c CoOS/kernel/time.c CoOS/kernel/timer.c CoOS/kernel/serviceReq.c CoOS/portable/GCC/port.c CoOS/portable/arch.c + SRC += CoOS/kernel/core.c CoOS/kernel/hook.c CoOS/kernel/task.c CoOS/kernel/event.c CoOS/kernel/time.c CoOS/kernel/timer.c CoOS/kernel/flag.c CoOS/kernel/mutex.c CoOS/kernel/serviceReq.c CoOS/portable/GCC/port.c CoOS/portable/arch.c SRC += FatFs/ff.c FatFs/fattime.c FatFs/option/ccsbcs.c ersky9x/diskio.c EEPROMSRC = eeprom_arm.cpp PULSESSRC = pulses_arm.cpp @@ -632,7 +632,7 @@ FOXLIB=-L/usr/local/lib \ -Wl,-rpath,$(FOXPATH)/src/.libs simu: stamp_header $(BOARDSRC) $(CPPSRC) Makefile simu.cpp simpgmspace.cpp *.h *.lbm eeprom.bin - g++ simu.cpp $(CPPFLAGS) $(BOARDSRC) $(CPPSRC) simpgmspace.cpp $(ARCH) -MD -DSIMU -o simu $(FOXINC) $(FOXLIB) -pthread + g++ $(CPPFLAGS) simu.cpp $(BOARDSRC) $(CPPSRC) simpgmspace.cpp $(ARCH) -MD -DSIMU -o simu $(FOXINC) $(FOXLIB) -pthread eeprom.bin: dd if=/dev/zero of=$@ bs=1 count=2048 @@ -719,6 +719,7 @@ clean_list : $(REMOVE) $(SRC:.c=.s) $(REMOVE) *.o $(REMOVE) */*.o + $(REMOVE) */*/*.o $(REMOVE) *.d $(REMOVE) *.lst $(REMOVE) allsrc.cpp diff --git a/src/beeper.h b/src/beeper.h index bfecb93e1..310b316d9 100644 --- a/src/beeper.h +++ b/src/beeper.h @@ -60,7 +60,6 @@ extern void beep(uint8_t val); #define AUDIO_KEYPAD_UP() beep(0) #define AUDIO_KEYPAD_DOWN() beep(0) #define AUDIO_MENUS() beep(0) -#define AUDIO_TRIM() beep(1) #define AUDIO_WARNING2() beep(2) #define AUDIO_WARNING1() beep(3) #define AUDIO_ERROR() beep(4) @@ -76,7 +75,9 @@ extern void beep(uint8_t val); #define AUDIO_POT_STICK_MIDDLE() beep(2) #define AUDIO_VARIO_UP() _beep(1) #define AUDIO_VARIO_DOWN() _beep(1) -#define AUDIO_TRIM_MIDDLE(f) beep(2) +#define AUDIO_TRIM(event, f) { if (event & _MSK_KEY_REPT) warble = true; beep(1); } +#define AUDIO_TRIM_MIDDLE(f) beep(2) +#define AUDIO_PLAY(p) beep(3) #define IS_AUDIO_BUSY() (g_beepCnt || beepAgain || beepOn) diff --git a/src/board_ersky9x.cpp b/src/board_ersky9x.cpp index 479e5a5cd..8fdbe762e 100644 --- a/src/board_ersky9x.cpp +++ b/src/board_ersky9x.cpp @@ -727,7 +727,7 @@ void board_init() __enable_irq() ; - start_sound() ; + startSound() ; eeprom_init(); diff --git a/src/eeprom_arm.cpp b/src/eeprom_arm.cpp index a70382065..b8fd997f2 100644 --- a/src/eeprom_arm.cpp +++ b/src/eeprom_arm.cpp @@ -920,14 +920,9 @@ const pm_char * eeBackupModel(uint8_t i_fileSrc) DIR archiveFolder; UINT written; - FRESULT result = f_mount(0, &g_FATFS_Obj); - if (result != FR_OK) { - return SDCARD_ERROR(result); - } - // check and create folder here strcpy(buf, STR_MODELS_PATH); - result = f_opendir(&archiveFolder, buf); + FRESULT result = f_opendir(&archiveFolder, buf); if (result != FR_OK) { result = f_mkdir(buf); if (result != FR_OK) @@ -995,17 +990,12 @@ const pm_char * eeRestoreModel(uint8_t i_fileDst, char *model_name) FIL restoreFile; UINT read; - FRESULT result = f_mount(0, &g_FATFS_Obj); - if (result != FR_OK) { - return SDCARD_ERROR(result); - } - strcpy(buf, STR_MODELS_PATH); buf[sizeof(MODELS_PATH)-1] = '/'; strcpy(&buf[sizeof(MODELS_PATH)], model_name); strcpy(&buf[strlen(buf)], STR_MODELS_EXT); - result = f_open(&restoreFile, buf, FA_OPEN_EXISTING | FA_READ); + FRESULT result = f_open(&restoreFile, buf, FA_OPEN_EXISTING | FA_READ); if (result != FR_OK) { return SDCARD_ERROR(result); } diff --git a/src/ersky9x/audio.cpp b/src/ersky9x/audio.cpp index ccd3d7ddc..9da5f38e8 100644 --- a/src/ersky9x/audio.cpp +++ b/src/ersky9x/audio.cpp @@ -33,7 +33,30 @@ #include "../open9x.h" -audioQueue::audioQueue() +uint8_t audioState = 0; + +uint8_t t_queueRidx; +uint8_t t_queueWidx; + +uint8_t toneFreq; +//int8_t toneFreqIncr; +uint8_t toneTimeLeft; +uint8_t tonePause; + +uint8_t tone2Freq; +uint8_t tone2TimeLeft; +uint8_t tone2Pause; + +char toneWavFile[32+1] = ""; + +// queue arrays +uint8_t queueToneFreq[AUDIO_QUEUE_LENGTH]; +// int8_t queueToneFreqIncr[AUDIO_QUEUE_LENGTH]; +uint8_t queueToneLength[AUDIO_QUEUE_LENGTH]; +uint8_t queueTonePause[AUDIO_QUEUE_LENGTH]; +uint8_t queueToneRepeat[AUDIO_QUEUE_LENGTH]; + +void audioInit() { toneTimeLeft = 0; tonePause = 0; @@ -42,80 +65,105 @@ audioQueue::audioQueue() t_queueWidx = 0; } -// heartbeat is responsibile for issueing the audio tones and general square waves -// it is essentially the life of the class. -// it is called every 10ms -void audioQueue::heartbeat() +void audioTimerHandle(void) { -#if defined(SIMU) - return; -#endif + CoSetFlag(audioFlag); +} - if (toneTimeLeft > 0) { - if (toneChanged) { - toneChanged = 0; - set_frequency(toneFreq * 61 / 2); - if(toneRateLimit == 0){ //only start if within rate limit - if(toneFreq == 0){ - tone_stop(); - } else { - tone_start(0); - } - } - toneRateLimit++; //count up the rate limit - if(toneRateLimit == TONE1_RATE_LIMIT){ //reset the rate limit - toneRateLimit = 0; - } +// TODO Should be here! +extern uint16_t Sine_values[]; + + +void audioTask(void* pdata) +{ + static FIL wavFile; + + while (1) { + CoWaitForSingleFlag(audioFlag, 0); + + audioState = 1; // TODO #define + + if (toneWavFile[0]) { + FRESULT result = FR_OK; + uint16_t bufsize = 2*WAV_BUFFER_SIZE; + uint16_t * bufdata = wavSamplesBuffer; + if (toneWavFile[1]) { + result = f_open(&wavFile, toneWavFile, FA_OPEN_EXISTING | FA_READ); + toneWavFile[1] = '\0'; + bufdata = wavSamplesArray; + bufsize = 4*WAV_BUFFER_SIZE; + register Dacc *dacptr = DACC; + dacptr->DACC_TPR = (uint32_t)wavSamplesArray; + wavSamplesBuffer = wavSamplesArray + WAV_BUFFER_SIZE; + dacptr->DACC_TNPR = (uint32_t)wavSamplesBuffer; + dacptr->DACC_TCR = WAV_BUFFER_SIZE/2; + dacptr->DACC_TNCR = WAV_BUFFER_SIZE/2; + setFrequency(12000); + toneStart(); + } + UINT read; + if (result != FR_OK || f_read(&wavFile, (uint8_t *)bufdata, bufsize, &read) != FR_OK || read != bufsize) { + f_close(&wavFile); + toneWavFile[0] = '\0'; + toneStop(); + } +#if 1 + else { + read /= 2; + for (uint32_t i=0; i> 4; + } + } +#endif } - else if (toneFreqIncr && (toneTimeLeft&1) == 0) { - toneFreq += toneFreqIncr; - set_frequency(toneFreq * 61 / 2); + else if (toneTimeLeft > 0) { + CoSetTmrCnt(audioTimer, toneTimeLeft, 0); + toneTimeLeft = 0; + // TODO function for that ... + DACC->DACC_TPR = (uint32_t) Sine_values ; + DACC->DACC_TCR = 50 ; // words, 100 16 bit values + DACC->DACC_TNPR = (uint32_t) Sine_values ; + DACC->DACC_TNCR = 50 ; // words, 100 16 bit values + setFrequency(toneFreq * 6100 / 2); + toneStart(); + CoStartTmr(audioTimer); } - toneTimeLeft--; //time gets counted down - } - else { - if (tonePause > 0) { - tone_stop(); - toneRateLimit = 0; //reset rate limit - tonePause--; //time gets counted down + else if (tonePause > 0) { + CoSetTmrCnt(audioTimer, tonePause, 0); + tonePause = 0; + toneStop(); + CoStartTmr(audioTimer); } else if (t_queueRidx != t_queueWidx) { - toneChanged = 1; toneFreq = queueToneFreq[t_queueRidx]; toneTimeLeft = queueToneLength[t_queueRidx]; - toneFreqIncr = queueToneFreqIncr[t_queueRidx]; + // TODO ? toneFreqIncr = queueToneFreqIncr[t_queueRidx]; tonePause = queueTonePause[t_queueRidx]; if (!queueToneRepeat[t_queueRidx]--) { t_queueRidx = (t_queueRidx + 1) % AUDIO_QUEUE_LENGTH; } + CoSetFlag(audioFlag); + } + else if (tone2TimeLeft > 0) { + CoSetTmrCnt(audioTimer, tone2TimeLeft, 0); + tone2TimeLeft = 0; + // TODO function for that ... + DACC->DACC_TPR = (uint32_t) Sine_values ; + DACC->DACC_TCR = 50 ; // words, 100 16 bit values + DACC->DACC_TNPR = (uint32_t) Sine_values ; + DACC->DACC_TNCR = 50 ; // words, 100 16 bit values + setFrequency(tone2Freq * 6100 / 2); + toneStart(); + CoStartTmr(audioTimer); } else { - if (tone2TimeLeft > 0) { - if (tone2Changed) { - tone2Changed = 0; - set_frequency(tone2Freq * 61 / 2); - if(tone2RateLimit == 0){ //only start if within rate limit - tone_start(0); - } - } - tone2TimeLeft--; //time gets counted down - tone2RateLimit++; //count up the rate limit - if(tone2RateLimit == TONE2_RATE_LIMIT){ //reset the rate limit - tone2RateLimit = 0; - } - } - else { - tone_stop(); - tone2RateLimit = 0; //reset rate limit - if (tone2Pause > 0) { - tone2Pause--; //time gets counted down - } - } + audioState = 0; + toneStop(); } } } -inline uint8_t audioQueue::getToneLength(uint8_t tLen) +inline uint8_t getToneLength(uint8_t tLen) { uint8_t result = tLen; // default if (g_eeGeneral.beeperLength < 0) { @@ -127,32 +175,33 @@ inline uint8_t audioQueue::getToneLength(uint8_t tLen) return result; } -void audioQueue::pause(uint8_t tLen) +void pause(uint8_t tLen) { - play(0, tLen, 5); // a pause + play(0, 0, tLen); // a pause } -void audioQueue::play(uint8_t tFreq, uint8_t tLen, uint8_t tPause, +void play(uint8_t tFreq, uint8_t tLen, uint8_t tPause, uint8_t tFlags, int8_t tFreqIncr) { if (tFlags & PLAY_SOUND_VARIO) { - tone2Changed = 1; tone2Freq = tFreq; tone2TimeLeft = tLen; tone2Pause = tPause; + if (audioState == 0) CoSetFlag(audioFlag); } else { if (tFreq > 0) { //we dont add pitch if zero as this is a pause only event tFreq += g_eeGeneral.speakerPitch + BEEP_OFFSET; // add pitch compensator } tLen = getToneLength(tLen); - if (tFlags & PLAY_NOW || (!busy() && empty())) { - toneChanged = 1; + if ((tFlags & PLAY_NOW) || audioState == 0) { + toneWavFile[0] = '\0'; toneFreq = tFreq; toneTimeLeft = tLen; tonePause = tPause; - toneFreqIncr = tFreqIncr; + // toneFreqIncr = tFreqIncr; t_queueWidx = t_queueRidx; + CoSetFlag(audioFlag); } else { tFlags++; @@ -166,14 +215,20 @@ void audioQueue::play(uint8_t tFreq, uint8_t tLen, uint8_t tPause, queueToneLength[t_queueWidx] = tLen; queueTonePause[t_queueWidx] = tPause; queueToneRepeat[t_queueWidx] = tFlags - 1; - queueToneFreqIncr[t_queueWidx] = tFreqIncr; + // queueToneFreqIncr[t_queueWidx] = tFreqIncr; t_queueWidx = next_queueWidx; } } } } -void audioQueue::event(uint8_t e, uint8_t f) +void playFile(const char *filename) +{ + strcpy(toneWavFile, filename); + CoSetFlag(audioFlag); +} + +void audioEvent(uint8_t e, uint8_t f) { #ifdef HAPTIC haptic.event(e); //do this before audio to help sync timings @@ -185,7 +240,7 @@ void audioQueue::event(uint8_t e, uint8_t f) } if (g_eeGeneral.beeperMode>0 || (g_eeGeneral.beeperMode==0 && e>=AU_TRIM_MOVE) || (g_eeGeneral.beeperMode>=-1 && e<=AU_ERROR)) { - if (e < AU_FRSKY_FIRST || empty()) { + if (e < AU_FRSKY_FIRST || audioEmpty()) { switch (e) { // inactivity timer alert case AU_INACTIVITY: @@ -193,7 +248,7 @@ void audioQueue::event(uint8_t e, uint8_t f) break; // low battery in tx case AU_TX_BATTERY_LOW: - if (empty()) { + if (audioEmpty()) { play(60, 40, 6, 2, 1); play(80, 40, 6, 2, -1); } @@ -343,8 +398,3 @@ void audioQueue::event(uint8_t e, uint8_t f) } } } - -void audioDefevent(uint8_t e) -{ - audio.event(e, BEEP_DEFAULT_FREQ); -} diff --git a/src/ersky9x/audio.h b/src/ersky9x/audio.h index 614589327..df84284f8 100644 --- a/src/ersky9x/audio.h +++ b/src/ersky9x/audio.h @@ -43,91 +43,72 @@ #define TONE1_RATE_LIMIT (10) #define TONE2_RATE_LIMIT (10) -class audioQueue +extern uint8_t t_queueRidx; +extern uint8_t t_queueWidx; + +extern uint8_t toneFreq; +//int8_t toneFreqIncr; +extern uint8_t toneTimeLeft; +extern uint8_t tonePause; + +extern char toneWavFile[32+1]; + +// vario +extern uint8_t tone2Freq; +extern uint8_t tone2TimeLeft; +extern uint8_t tone2Pause; + +// queue arrays +extern uint8_t queueToneFreq[AUDIO_QUEUE_LENGTH]; +// int8_t queueToneFreqIncr[AUDIO_QUEUE_LENGTH]; +extern uint8_t queueToneLength[AUDIO_QUEUE_LENGTH]; +extern uint8_t queueTonePause[AUDIO_QUEUE_LENGTH]; +extern uint8_t queueToneRepeat[AUDIO_QUEUE_LENGTH]; + +void initAudio(); + +void play(uint8_t tFreq, uint8_t tLen, uint8_t tPause, uint8_t tFlags=0, int8_t tFreqIncr=0); +void playFile(const char *filename); +void pause(uint8_t tLen); + +inline bool audioBusy() { - public: + return (toneTimeLeft > 0); +} - audioQueue(); +void audioEvent(uint8_t e, uint8_t f=BEEP_DEFAULT_FREQ); +inline bool audioEmpty() +{ + return (t_queueRidx == t_queueWidx); +} - void play(uint8_t tFreq, uint8_t tLen, uint8_t tPause, uint8_t tFlags=0, int8_t tFreqIncr=0); - void pause(uint8_t tLen); +#define AUDIO_KEYPAD_UP() audioEvent(AU_KEYPAD_UP) +#define AUDIO_KEYPAD_DOWN() audioEvent(AU_KEYPAD_DOWN) +#define AUDIO_MENUS() audioEvent(AU_MENUS) +#define AUDIO_WARNING1() audioEvent(AU_WARNING1) +#define AUDIO_WARNING2() audioEvent(AU_WARNING2) +#define AUDIO_ERROR() audioEvent(AU_ERROR) - inline bool busy() { - return (toneTimeLeft > 0); - } +#define IS_AUDIO_BUSY() audioBusy() - void event(uint8_t e, uint8_t f=BEEP_DEFAULT_FREQ); +#define AUDIO_TIMER_30() audioEvent(AU_TIMER_30) +#define AUDIO_TIMER_20() audioEvent(AU_TIMER_20) +#define AUDIO_TIMER_10() audioEvent(AU_TIMER_10) +#define AUDIO_TIMER_LT3() audioEvent(AU_TIMER_LT3) +#define AUDIO_MINUTE_BEEP() audioEvent(AU_WARNING1) +#define AUDIO_INACTIVITY() audioEvent(AU_INACTIVITY) +#define AUDIO_MIX_WARNING_1() audioEvent(AU_MIX_WARNING_1) +#define AUDIO_MIX_WARNING_2() audioEvent(AU_MIX_WARNING_2) +#define AUDIO_MIX_WARNING_3() audioEvent(AU_MIX_WARNING_3) +#define AUDIO_POT_STICK_MIDDLE() audioEvent(AU_POT_STICK_MIDDLE) +#define AUDIO_VARIO_UP() audioEvent(AU_KEYPAD_UP) +#define AUDIO_VARIO_DOWN() audioEvent(AU_KEYPAD_DOWN) +#define AUDIO_TRIM_MIDDLE(f) audioEvent(AU_TRIM_MIDDLE, f) +#define AUDIO_TRIM(event, f) audioEvent(AU_TRIM_MOVE, f) +#define AUDIO_PLAY(p) audioEvent(p) +#define AUDIO_VARIO(f, t) play(f, t, 0, PLAY_SOUND_VARIO) - // heartbeat is responsibile for issueing the audio tones and general square waves - // it is essentially the life of the class. - void heartbeat(); - - // bool freeslots(uint8_t slots); - - inline bool empty() { - return (t_queueRidx == t_queueWidx); - } - - protected: - inline uint8_t getToneLength(uint8_t tLen); - - private: - uint8_t t_queueRidx; - uint8_t t_queueWidx; - - uint8_t toneChanged; - uint8_t toneFreq; - int8_t toneFreqIncr; - uint8_t toneTimeLeft; - uint8_t tonePause; - uint8_t toneRateLimit; - - // vario - uint8_t tone2Changed; - uint8_t tone2Freq; - uint8_t tone2TimeLeft; - uint8_t tone2Pause; - uint8_t tone2RateLimit; - - // queue arrays - uint8_t queueToneFreq[AUDIO_QUEUE_LENGTH]; - int8_t queueToneFreqIncr[AUDIO_QUEUE_LENGTH]; - uint8_t queueToneLength[AUDIO_QUEUE_LENGTH]; - uint8_t queueTonePause[AUDIO_QUEUE_LENGTH]; - uint8_t queueToneRepeat[AUDIO_QUEUE_LENGTH]; - -}; - -//wrapper function - dirty but results in a space saving!!! -extern audioQueue audio; - -void audioDefevent(uint8_t e); - -#define AUDIO_KEYPAD_UP() audioDefevent(AU_KEYPAD_UP) -#define AUDIO_KEYPAD_DOWN() audioDefevent(AU_KEYPAD_DOWN) -#define AUDIO_MENUS() audioDefevent(AU_MENUS) -#define AUDIO_WARNING1() audioDefevent(AU_WARNING1) -#define AUDIO_WARNING2() audioDefevent(AU_WARNING2) -#define AUDIO_ERROR() audioDefevent(AU_ERROR) - - -#define IS_AUDIO_BUSY() audio.busy() - -#define AUDIO_TIMER_30() audioDefevent(AU_TIMER_30) -#define AUDIO_TIMER_20() audioDefevent(AU_TIMER_20) -#define AUDIO_TIMER_10() audioDefevent(AU_TIMER_10) -#define AUDIO_TIMER_LT3() audioDefevent(AU_TIMER_LT3) -#define AUDIO_MINUTE_BEEP() audioDefevent(AU_WARNING1) -#define AUDIO_INACTIVITY() audioDefevent(AU_INACTIVITY) -#define AUDIO_MIX_WARNING_1() audioDefevent(AU_MIX_WARNING_1) -#define AUDIO_MIX_WARNING_2() audioDefevent(AU_MIX_WARNING_2) -#define AUDIO_MIX_WARNING_3() audioDefevent(AU_MIX_WARNING_3) -#define AUDIO_POT_STICK_MIDDLE() audioDefevent(AU_POT_STICK_MIDDLE) -#define AUDIO_VARIO_UP() audioDefevent(AU_KEYPAD_UP) -#define AUDIO_VARIO_DOWN() audioDefevent(AU_KEYPAD_DOWN) -#define AUDIO_TRIM_MIDDLE(f) audio.event(AU_TRIM_MIDDLE, f) - -#define AUDIO_HEARTBEAT() audio.heartbeat() +#define AUDIO_HEARTBEAT() #endif diff --git a/src/ersky9x/diskio.c b/src/ersky9x/diskio.c index 085b2942f..37a97c527 100644 --- a/src/ersky9x/diskio.c +++ b/src/ersky9x/diskio.c @@ -40,8 +40,32 @@ #include "board.h" #include "../FatFs/diskio.h" +#include "../FatFs/ff.h" #include "../CoOS/kernel/CoOS.h" +#define CARD_TYPE_bmHC (1 << 0) /**< Bit for High-Capacity(Density) */ +#define CARD_TYPE_bmSDMMC (0x3 << 1) /**< Bits mask for SD/MMC */ +#define CARD_TYPE_bmUNKNOWN (0x0 << 1) /**< Bits for Unknown card */ +#define CARD_TYPE_bmSD (0x1 << 1) /**< Bits for SD */ +#define CARD_TYPE_bmMMC (0x2 << 1) /**< Bits for MMC */ +#define CARD_TYPE_bmSDIO (1 << 3) /**< Bit for SDIO */ +/** Card can not be identified */ +#define CARD_UNKNOWN (0) +/** SD Card (0x2) */ +#define CARD_SD (CARD_TYPE_bmSD) +/** SD High Capacity Card (0x3) */ +#define CARD_SDHC (CARD_TYPE_bmSD|CARD_TYPE_bmHC) +/** MMC Card (0x4) */ +#define CARD_MMC (CARD_TYPE_bmMMC) +/** MMC High-Density Card (0x5) */ +#define CARD_MMCHD (CARD_TYPE_bmMMC|CARD_TYPE_bmHC) +/** SDIO only card (0x8) */ +#define CARD_SDIO (CARD_TYPE_bmSDIO) +/** SDIO Combo, with SD embedded (0xA) */ +#define CARD_SDCOMBO (CARD_TYPE_bmSDIO|CARD_SD) +/** SDIO Combo, with SDHC embedded (0xB) */ +#define CARD_SDHCCOMBO (CARD_TYPE_bmSDIO|CARD_SDHC) + // States for initialising card #define SD_ST_EMPTY 0 #define SD_ST_INIT1 1 @@ -61,51 +85,7 @@ uint32_t Sd_128_resp[4] ; uint32_t Sd_rca ; uint32_t Cmd_8_resp ; uint32_t Cmd_A41_resp ; - -/** - * Configure the MCI SDCBUS in the MCI_SDCR register. Only two modes available - * - * \param busWidth MCI bus width mode. 00: 1-bit, 10: 4-bit. - */ -uint32_t SD_SetBusWidth( uint32_t busWidth) -{ - uint32_t mciSdcr; - - if( (busWidth != HSMCI_SDCR_SDCBUS_1) && (busWidth != HSMCI_SDCR_SDCBUS_4) ) - { - return (uint32_t)-1; - } - - busWidth &= HSMCI_SDCR_SDCBUS_Msk ; - - mciSdcr = (HSMCI->HSMCI_SDCR & ~(uint32_t)(HSMCI_SDCR_SDCBUS_Msk)); - HSMCI->HSMCI_SDCR = mciSdcr | busWidth; - - return 0; -} - -#if 0 -/** - * Configure the MCI_CFG to enable the HS mode - * \param hsEnable 1 to enable, 0 to disable HS mode. - */ -void SD_EnableHsMode( uint8_t hsEnable) -{ - uint32_t cfgr; - - cfgr = HSMCI->HSMCI_CFG; - if (hsEnable) - { - cfgr |= HSMCI_CFG_HSMODE; - } - else - { - cfgr &= ~(uint32_t)HSMCI_CFG_HSMODE; - } - - HSMCI->HSMCI_CFG = cfgr; -} -#endif +uint8_t cardType; /** * Configure the MCI CLKDIV in the MCI_MR register. The max. for MCI clock is @@ -113,40 +93,35 @@ void SD_EnableHsMode( uint8_t hsEnable) * \param mciSpeed MCI clock speed in Hz, 0 will not change current speed. * \return The actual speed used, 0 for fail. */ -uint32_t SD_SetSpeed( uint32_t mciSpeed ) +uint32_t sdSetSpeed(uint32_t mciSpeed ) { - uint32_t mciMr; - uint32_t clkdiv; + uint32_t mciMr; + uint32_t clkdiv; - mciMr = HSMCI->HSMCI_MR & (~(uint32_t)HSMCI_MR_CLKDIV_Msk); - /* Multimedia Card Interface clock (MCCK or MCI_CK) is Master Clock (MCK) - * divided by (2*(CLKDIV+1)) - * mciSpeed = MCK / (2*(CLKDIV+1)) */ - if (mciSpeed > 0) - { - clkdiv = (Master_frequency / 2 / mciSpeed); - /* Speed should not bigger than expired one */ - if (mciSpeed < Master_frequency/2/clkdiv) - { - clkdiv++; - } + mciMr = HSMCI->HSMCI_MR & (~(uint32_t) HSMCI_MR_CLKDIV_Msk); + /* Multimedia Card Interface clock (MCCK or MCI_CK) is Master Clock (MCK) + * divided by (2*(CLKDIV+1)) + * mciSpeed = MCK / (2*(CLKDIV+1)) */ + if (mciSpeed > 0) { + clkdiv = (Master_frequency / 2 / mciSpeed); + /* Speed should not bigger than expired one */ + if (mciSpeed < Master_frequency / 2 / clkdiv) { + clkdiv++; + } - if ( clkdiv > 0 ) - { - clkdiv -= 1; - } - } - else - { - clkdiv = 0 ; - } + if (clkdiv > 0) { + clkdiv -= 1; + } + } + else { + clkdiv = 0; + } - /* Actual MCI speed */ - mciSpeed = Master_frequency / 2 / (clkdiv + 1); - /* Modify MR */ - HSMCI->HSMCI_MR = mciMr | clkdiv; + /* Actual MCI speed */ + mciSpeed = Master_frequency / 2 / (clkdiv + 1); + /* Modify MR */HSMCI->HSMCI_MR = mciMr | clkdiv; - return (mciSpeed); + return mciSpeed; } #if 0 @@ -196,201 +171,185 @@ void SD_Reset( uint8_t keepSettings) } #endif -void sd_cmd55() -{ - uint32_t i ; - Hsmci *phsmci = HSMCI ; +const char SD_NORESPONSE[] = "No response"; - if ( CardIsConnected() ) - { - phsmci->HSMCI_ARGR = Sd_rca ; - phsmci->HSMCI_CMDR = 0x00001077 ; - - for ( i = 0 ; i < 30000 ; i += 1 ) - { - if ( phsmci->HSMCI_SR & HSMCI_SR_CMDRDY ) - { - break ; - } - } -// Cmd_55_resp = phsmci->HSMCI_RSPR[0] ; - } -} - -uint32_t sd_cmd0() +const char * sdCommand(uint32_t cmd, uint32_t arg) { uint32_t i; Hsmci *phsmci = HSMCI; if (CardIsConnected()) { - phsmci->HSMCI_ARGR = 0; - phsmci->HSMCI_CMDR = 0x00001000; + phsmci->HSMCI_ARGR = arg; + phsmci->HSMCI_CMDR = cmd; for (i = 0; i < 30000; i += 1) { if (phsmci->HSMCI_SR & HSMCI_SR_CMDRDY) { - break; + return 0; } } - return phsmci->HSMCI_RSPR[0]; + return SD_NORESPONSE; } else { - return 0; + return "No Sdcard"; } } -uint32_t sd_cmd8() +#define SDMMC_POWER_ON_INIT (0 | HSMCI_CMDR_TRCMD_NO_DATA \ + | HSMCI_CMDR_SPCMD_INIT \ + | HSMCI_CMDR_OPDCMD ) + +const char * sdPowerOn() { - uint32_t i; - Hsmci *phsmci = HSMCI; - - if (CardIsConnected()) { - phsmci->HSMCI_ARGR = 0X000001AA; - phsmci->HSMCI_CMDR = 0x00001048; - - for (i = 0; i < 30000; i += 1) { - if (phsmci->HSMCI_SR & HSMCI_SR_CMDRDY) { - break; - } - } - return Cmd_8_resp = phsmci->HSMCI_RSPR[0]; - } - else { - return 0; - } + return sdCommand(SDMMC_POWER_ON_INIT, 0); } -uint32_t sd_acmd41() +#define SDMMC_GO_IDLE_STATE (0 | HSMCI_CMDR_TRCMD_NO_DATA \ + | HSMCI_CMDR_SPCMD_STD ) + +const char * sdCmd0() { - uint32_t i; - Hsmci *phsmci = HSMCI; + return sdCommand(SDMMC_GO_IDLE_STATE, 0); +} - if (CardIsConnected()) { - sd_cmd55(); - phsmci->HSMCI_ARGR = 0x403F8000; - phsmci->HSMCI_CMDR = 0x00001069; +#if 0 +#define SDIO_SEND_OP_COND (5 | HSMCI_CMDR_SPCMD_STD \ + | HSMCI_CMDR_TRCMD_NO_DATA \ + | HSMCI_CMDR_RSPTYP_48_BIT \ + | HSMCI_CMDR_OPDCMD ) - for (i = 0; i < 30000; i += 1) { - if (phsmci->HSMCI_SR & HSMCI_SR_CMDRDY) { - break; - } - } - return Cmd_A41_resp = phsmci->HSMCI_RSPR[0] ; - } - else { - return 0; - } +const char * sdCmd5(uint32_t *pIo) +{ + const char * result = sdCommand(SDIO_SEND_OP_COND, *pIo); + if (result) + return result; + *pIo = HSMCI->HSMCI_RSPR[0]; + return 0; +} +#endif + +#define SD_SEND_IF_COND (8 | HSMCI_CMDR_TRCMD_NO_DATA \ + | HSMCI_CMDR_SPCMD_STD \ + | HSMCI_CMDR_RSPTYP_48_BIT \ + | HSMCI_CMDR_OPDCMD /* BSS difference */ \ + | HSMCI_CMDR_MAXLAT ) + +const char * sdCmd8(uint8_t supplyVoltage) +{ + return sdCommand(SD_SEND_IF_COND, (supplyVoltage << 8) | (0xAA)); +} + +#define SDMMC_APP_CMD (55| HSMCI_CMDR_SPCMD_STD \ + | HSMCI_CMDR_RSPTYP_48_BIT \ + | HSMCI_CMDR_TRCMD_NO_DATA \ + | HSMCI_CMDR_MAXLAT) + +const char * sdCmd55() +{ + return sdCommand(SDMMC_APP_CMD, Sd_rca); +} + +#define SD_SD_SEND_OP_COND (41| HSMCI_CMDR_SPCMD_STD \ + | HSMCI_CMDR_RSPTYP_48_BIT \ + | HSMCI_CMDR_TRCMD_NO_DATA \ + /*| HSMCI_CMDR_OPDCMD_OPENDRAIN */ ) + +const char * sdCmd41(uint32_t arg, uint32_t * status) +{ + const char * result = sdCommand(SD_SD_SEND_OP_COND, arg); + if (result) + return result; + *status = HSMCI->HSMCI_RSPR[0]; + return 0; +} + +#define OCR_VDD_27_28 ((uint32_t)(1 << 15)) +#define OCR_VDD_28_29 ((uint32_t)(1 << 16)) +#define OCR_VDD_29_30 ((uint32_t)(1 << 17)) +#define OCR_VDD_30_31 ((uint32_t)(1 << 18)) +#define OCR_VDD_31_32 ((uint32_t)(1 << 19)) +#define OCR_VDD_32_33 ((uint32_t)(1 << 20)) +#define OCR_VDD_33_34 ((uint32_t)(1 << 21)) + +#define SDMMC_HOST_VOLTAGE_RANGE (OCR_VDD_27_28 +\ + OCR_VDD_28_29 +\ + OCR_VDD_29_30 +\ + OCR_VDD_30_31 +\ + OCR_VDD_31_32 +\ + OCR_VDD_32_33 +\ + OCR_VDD_32_33) /* not in SAM3S reference code */ + +#define OCR_SD_CCS (1UL << 30) + +#define OCR_POWER_UP_BUSY (1UL << 31) + +const char * sdMemInit(uint8_t hcs, uint32_t *pCCS) +{ + const char * result; + uint32_t arg; + uint32_t status; + do { + result = sdCmd55(); + if (result) + return result; + arg = SDMMC_HOST_VOLTAGE_RANGE; + if (hcs) arg |= OCR_SD_CCS; + result = sdCmd41(arg, &status); + if (result) + return result; + *pCCS = (status & OCR_SD_CCS); + } while ((status & OCR_POWER_UP_BUSY) != OCR_POWER_UP_BUSY); + return 0; } // Get Card ID -uint32_t sd_cmd2() +const char * sdCmd2() { - uint32_t i ; - Hsmci *phsmci = HSMCI ; + const char * result = sdCommand(0x00001082, 0); + if (result) + return result; - if ( CardIsConnected() ) - { - phsmci->HSMCI_ARGR = 0 ; - phsmci->HSMCI_CMDR = 0x00001082 ; - - for ( i = 0 ; i < 30000 ; i += 1 ) - { - if ( phsmci->HSMCI_SR & HSMCI_SR_CMDRDY ) - { - break ; - } - } - Sd_128_resp[0] = phsmci->HSMCI_RSPR[0] ; - Sd_128_resp[1] = phsmci->HSMCI_RSPR[1] ; - Sd_128_resp[2] = phsmci->HSMCI_RSPR[2] ; - Sd_128_resp[3] = phsmci->HSMCI_RSPR[3] ; - return 1 ; - } - else - { - return 0 ; - } + Hsmci *phsmci = HSMCI ; + Card_ID[0] = phsmci->HSMCI_RSPR[0] ; + Card_ID[1] = phsmci->HSMCI_RSPR[1] ; + Card_ID[2] = phsmci->HSMCI_RSPR[2] ; + Card_ID[3] = phsmci->HSMCI_RSPR[3] ; + return 0; } // Get new RCA -uint32_t sd_cmd3() +const char * sdCmd3() { - uint32_t i ; - Hsmci *phsmci = HSMCI ; - - if ( CardIsConnected() ) - { - phsmci->HSMCI_ARGR = 0 ; - phsmci->HSMCI_CMDR = 0x00001043 ; - - for ( i = 0 ; i < 30000 ; i += 1 ) - { - if ( phsmci->HSMCI_SR & HSMCI_SR_CMDRDY ) - { - break ; - } - } - return phsmci->HSMCI_RSPR[0] ; - } - else - { - return 0 ; - } + const char * result = sdCommand(0x00001043, 0); + if (result) + return result; + Sd_rca = HSMCI->HSMCI_RSPR[0]; + return 0; } // Get CSD -uint32_t sd_cmd9() +const char * sdCmd9() { - uint32_t i ; - Hsmci *phsmci = HSMCI ; + const char * result = sdCommand(0x00001089, Sd_rca); + if (result) + return result; - if ( CardIsConnected() ) - { - phsmci->HSMCI_ARGR = Sd_rca ; - phsmci->HSMCI_CMDR = 0x00001089 ; - - for ( i = 0 ; i < 30000 ; i += 1 ) - { - if ( phsmci->HSMCI_SR & HSMCI_SR_CMDRDY ) - { - break ; - } - } - Sd_128_resp[0] = phsmci->HSMCI_RSPR[0] ; - Sd_128_resp[1] = phsmci->HSMCI_RSPR[1] ; - Sd_128_resp[2] = phsmci->HSMCI_RSPR[2] ; - Sd_128_resp[3] = phsmci->HSMCI_RSPR[3] ; - return 1 ; - } - else - { - return 0 ; - } + Hsmci *phsmci = HSMCI ; + Card_CSD[0] = phsmci->HSMCI_RSPR[0] ; + Card_CSD[1] = phsmci->HSMCI_RSPR[1] ; + Card_CSD[2] = phsmci->HSMCI_RSPR[2] ; + Card_CSD[3] = phsmci->HSMCI_RSPR[3] ; + return 0; } -// Select Card -uint32_t sd_cmd7() +/** Cmd7 MCI, ac, R1/R1b */ +#define SDMMC_SELECT_CARD (7 | HSMCI_CMDR_TRCMD_NO_DATA \ + | HSMCI_CMDR_SPCMD_STD \ + | HSMCI_CMDR_RSPTYP_R1B \ + | HSMCI_CMDR_MAXLAT /* TODO not the same */ ) + +const char * sdCmd7() { - uint32_t i ; - Hsmci *phsmci = HSMCI ; - - if ( CardIsConnected() ) - { - phsmci->HSMCI_ARGR = Sd_rca ; - phsmci->HSMCI_CMDR = 0x00001047 ; - - for ( i = 0 ; i < 30000 ; i += 1 ) - { - if ( phsmci->HSMCI_SR & HSMCI_SR_CMDRDY ) - { - break ; - } - } - return 1 ; - } - else - { - return 0 ; - } + return sdCommand(SDMMC_SELECT_CARD, Sd_rca); } #define SD_SEND_SCR (51 | HSMCI_CMDR_SPCMD_STD | HSMCI_CMDR_RSPTYP_48_BIT \ @@ -414,163 +373,492 @@ uint32_t sd_cmd7() | HSMCI_CMDR_MAXLAT) // Get SCR -uint32_t sd_acmd51( uint32_t *presult ) +const char * sdAcmd51() { - uint32_t i ; - uint32_t j = 0 ; - Hsmci *phsmci = HSMCI ; + const char * result; + result = sdCmd55(); + if (result) + return result; - if ( CardIsConnected() ) - { - sd_cmd55() ; - // Block size = 64/ 8, nblocks = 1 - phsmci->HSMCI_BLKR = ( ( 64 / 8 ) << 16 ) | 1 ; - phsmci->HSMCI_ARGR = 0 ; - phsmci->HSMCI_CMDR = SD_SEND_SCR ; + Hsmci *phsmci = HSMCI ; + // Block size = 64/ 8, nblocks = 1 + phsmci->HSMCI_BLKR = ( ( 64 / 8 ) << 16 ) | 1 ; + phsmci->HSMCI_ARGR = 0 ; + phsmci->HSMCI_CMDR = SD_SEND_SCR ; - for ( i = 0 ; i < 50000 ; i += 1 ) - { - if ( phsmci->HSMCI_SR & HSMCI_SR_RXRDY ) - { - *presult++ = __REV(phsmci->HSMCI_RDR) ; - j += 0x10000000 ; - } - if ( ( phsmci->HSMCI_SR & ( HSMCI_SR_CMDRDY | HSMCI_SR_XFRDONE ) ) == ( HSMCI_SR_CMDRDY | HSMCI_SR_XFRDONE ) ) - { - break ; - } - - } - if ( i >= 50000 ) - { - *presult = phsmci->HSMCI_SR ; - } - return i | j ; //phsmci->HSMCI_RSPR[0] ; - } - else - { - return 0 ; - } + uint8_t scrLen = 0; + uint32_t i; + for ( i = 0 ; i < 50000 ; i += 1 ) { + if ( phsmci->HSMCI_SR & HSMCI_SR_RXRDY ) + Card_SCR[scrLen++] = __REV(phsmci->HSMCI_RDR) ; + if ( ( phsmci->HSMCI_SR & ( HSMCI_SR_CMDRDY | HSMCI_SR_XFRDONE ) ) == ( HSMCI_SR_CMDRDY | HSMCI_SR_XFRDONE ) ) + return 0; + } + return "No response"; } #define SD_SET_BUS_WIDTH (6 | HSMCI_CMDR_SPCMD_STD | HSMCI_CMDR_RSPTYP_48_BIT \ | HSMCI_CMDR_MAXLAT) -// Set bus width to 4 bits, set speed to 9 MHz -uint32_t sd_acmd6() +void sdEnableHsMode(uint8_t enable) { - uint32_t i ; - Hsmci *phsmci = HSMCI ; - - if ( CardIsConnected() ) - { - sd_cmd55() ; - phsmci->HSMCI_ARGR = 2 ; // Bus width 4 bits - phsmci->HSMCI_CMDR = SD_SET_BUS_WIDTH ; - - for ( i = 0 ; i < 300000 ; i += 1 ) - { - if ( phsmci->HSMCI_SR & HSMCI_SR_CMDRDY ) - { - break ; - } - } - if ( i >= 300000 ) - { - return 0 ; - } - SD_SetBusWidth( HSMCI_SDCR_SDCBUS_4 ) ; - SD_SetSpeed( 9000000 ) ; - return i ; //phsmci->HSMCI_RSPR[0] ; - } - else - { - return 0 ; - } + Hsmci *phsmci = HSMCI; + if (enable) + phsmci->HSMCI_CFG |= HSMCI_CFG_HSMODE; + else + phsmci->HSMCI_CFG &= ~HSMCI_CFG_HSMODE; } -// This routine is called every 10 mS, and checks for card -// insertion and removal. -// When a card is inserted, it initialises it ready for read/write access. +void sdSetBusWidth(uint32_t busWidth) +{ + Hsmci *phsmci = HSMCI; + phsmci->HSMCI_SDCR = (HSMCI->HSMCI_SDCR & ~HSMCI_SDCR_SDCBUS_Msk) | busWidth; +} + +// Set bus width to 4 bits, set speed to 9 MHz +const char * sdAcmd6() +{ + const char * result; + result = sdCmd55() ; + if (result) + return result; + + result = sdCommand(SD_SET_BUS_WIDTH, 2); + if (result) + return result; + + sdSetBusWidth( HSMCI_SDCR_SDCBUS_4 ) ; + sdSetSpeed(9000000); + return 0; +} + +#if 0 +/** SDIO CMD52, R5 */ +#define SDIO_IO_RW_DIRECT (52| HSMCI_CMDR_SPCMD_STD \ + | HSMCI_CMDR_TRCMD_NO_DATA \ + | HSMCI_CMDR_RSPTYP_48_BIT \ + | HSMCI_CMDR_MAXLAT) + +static const char * sdCmd52(uint8_t wrFlag, + uint8_t funcNb, + uint8_t rdAfterWr, + uint32_t addr, + uint32_t *status) +{ + typedef struct + { + uint32_t data:8, /**< [ 7: 0] data for writing */ + stuff0:1, /**< [ 8] reserved */ + regAddress:17, /**< [25: 9] register address */ + stuff1:1, /**< [ 26] reserved */ + rawFlag:1, /**< [ 27] Read after Write flag */ + functionNum:3, /**< [30:28] Number of the function */ + rwFlag:1; /**< [ 31] Direction, 1:write, 0:read. */ + } SdioCmd52Arg; + + SdioCmd52Arg pArg52; + pArg52.rwFlag = wrFlag; + pArg52.functionNum = funcNb; + pArg52.rawFlag = rdAfterWr; + pArg52.regAddress = addr; + + const char * result = sdCommand(SDIO_IO_RW_DIRECT, *(uint32_t*)&pArg52); + if (result) + return result; + *status = HSMCI->HSMCI_RSPR[0]; + return 0; +} +#endif + +const char * sdSwReset(uint32_t retry) +{ + uint32_t i; + const char * result = 0; + + for (i = 0; i < retry; i++) { + result = sdCmd0(0); + if (result != SD_NORESPONSE) + break; + } + return result; +} + +/** + * \brief Run the SD/MMC/SDIO Mode initialization sequence. + * This function runs the initialization procedure and the identification + * process. Then it leaves the card in ready state. The following procedure must + * check the card type and continue to put the card into tran(for memory card) + * or cmd(for io card) state for data exchange. + * \param pSd Pointer to a SD card driver instance. + * \return 0 if successful; otherwise returns an \ref sdmmc_rc "SD_ERROR code". + */ + +#define SDIO_CIA 0 /**< SDIO Function 0 (CIA) */ +#define SDIO_IOA_REG 0x06 /**< I/O Abort */ + +/** SDIO state (in R5) */ +#define SDIO_R5_ERROR (1UL << 11)/**< General error */ +#define SDIO_R5_FUNC_NUM (1UL << 10)/**< Invalid function number */ +#define SDIO_R5_OUT_OF_RANGE (1UL << 9) /**< Argument out of range */ + +/** Status bits mask for SDIO R5 */ +#define STATUS_SDIO_R5 (0/*SDIO_R5_STATE*/ \ + | SDIO_R5_ERROR \ + | SDIO_R5_FUNC_NUM \ + | SDIO_R5_OUT_OF_RANGE) + + +#define OCR_SDIO_MP (1UL << 27) +#define OCR_SDIO_NF (7UL << 28) + +const char * sdIdentify() +{ + uint8_t mem = 0, io = 0, f8 = 0, mp = 1; + uint32_t status, ccs=0; + const char * result; + + /* Reset HC to default HS and BusMode */ + sdEnableHsMode(0); + sdSetBusWidth(HSMCI_SDCR_SDCBUS_1); + +#if 0 + /* Reset SDIO: CMD52, write 1 to RES bit in CCCR (bit 3 of register 6) */ + result = sdCmd52(1, SDIO_CIA, 0, SDIO_IOA_REG, &status); + if (result) + return result; + if (status & STATUS_SDIO_R5) + return "Identify.52 error"; +#endif + + /* Reset MEM: CMD0 */ + result = sdSwReset(1); + if (result) + return result; + + /* CMD8 is newly added in the Physical Layer Specification Version 2.00 to + * support multiple voltage ranges and used to check whether the card + * supports supplied voltage. The version 2.00 host shall issue CMD8 and + * verify voltage before card initialization. + * The host that does not support CMD8 shall supply high voltage range... */ + result = sdCmd8(1); + if (result == 0) f8 = 1; + else if (result == SD_NORESPONSE) CoTickDelay(1); /* 2ms delay after "no response" */ + else return "Identify.8 error"; + +#if 0 + /* CMD5 is newly added for SDIO initialize & power on */ + status = 0; + result = sdCmd5(&status); + if (!result && (status & OCR_SDIO_NF) > 0) { + unsigned int cmd5Retries = 10000; + do { + status &= SDMMC_HOST_VOLTAGE_RANGE; + result = sdCmd5(&status); + if (status & OCR_POWER_UP_BUSY) break; + } while(!result && cmd5Retries --); + if (result) + return "Identify.5 error"; + io = 1; + /* IO only ?*/ + mp = ((status & OCR_SDIO_MP) > 0); + } +#endif + + /* Has memory: SD/MMC/COMBO */ + /*if (mp) */ + { + /* Try SD memory initialize */ + result = sdMemInit(f8, &ccs); + if (result) { + //unsigned int cmd1Retries = 10000; + /* Try MMC initialize */ + result = sdSwReset(10); + if (result) + return "Reset error"; + /* TODO ccs = 1; + do { result = sdCmd1(&ccs); } while(result && cmd1Retries -- > 0); + if (error) { + TRACE_ERROR("SdMmcIdentify.Cmd1: %u\n\r", error); + return SDMMC_ERROR; + } + else if (ccs) cardType = CARD_MMCHD; + else cardType = CARD_MMC; + */ + return "TODO error"; + /* MMC card identification OK */ + return 0; + } + // mem = 1; + } + /* SD(IO) + MEM ? */ + /* if (!mem) { + if (io) cardType = CARD_SDIO; + else + return "Unknown SD"; + } */ + /* SD(HC) combo */ + /*else if (io) + cardType = ccs ? CARD_SDHCCOMBO : CARD_SDCOMBO;*/ + /* SD(HC) */ + //else + cardType = ccs ? CARD_SDHC : CARD_SD; + + return 0; +} + +#if 0 +const char * sdEnum() +{ + uint8_t mem , io; + const char * result; + uint32_t ioSpeed = 0, memSpeed = 0; + uint8_t hsExec = 0, bwExec = 0; + + /* - has Memory/IO/High-Capacity - */ + mem = ((cardType & CARD_TYPE_bmSDMMC) > 0); + io = ((cardType & CARD_TYPE_bmSDIO) > 0); + + /* For MEMORY cards: + * The host then issues the command ALL_SEND_CID (CMD2) to the card to get + * its unique card identification (CID) number. + * Card that is unidentified (i.e. which is in Ready State) sends its CID + * number as the response (on the CMD line). */ + if (mem) { + result = sdCmd2(); + if (result) + return result; + } + + /* For MEMORY and SDIO cards: + * Thereafter, the host issues CMD3 (SEND_RELATIVE_ADDR) asks the + * card to publish a new relative card address (RCA), which is shorter than + * CID and which is used to address the card in the future data transfer + * mode. Once the RCA is received the card state changes to the Stand-by + * State. At this point, if the host wants to assign another RCA number, it + * can ask the card to publish a new number by sending another CMD3 command + * to the card. The last published RCA is the actual RCA number of the + * card. */ + result = sdCmd3(); + if (result) + return result; + + /* For MEMORY cards: + * SEND_CSD (CMD9) to obtain the Card Specific Data (CSD register), + * e.g. block length, card storage capacity, etc... */ + if (mem) { + result = sdCmd9(); + if (result) + return result; + } + + /* Now select the card, to TRAN state */ + error = MmcSelectCard(pSd, pSd->cardAddress, 0); + if (error) { + TRACE_ERROR("SdMmcInit.SelCard(%d)\n\r", error); + return error; + } + + /* - Now in TRAN, obtain extended setup information - */ + + /* If the card support EXT_CSD, read it! */ + TRACE_INFO("Card Type %d, CSD_STRUCTURE %d\n\r", + pSd->cardType, SD_CSD_STRUCTURE(pSd)); + + /* Get extended information of the card */ + SdMmcUpdateInformation(pSd, 0, 1); + + /* Calculate transfer speed */ + if (io) ioSpeed = SdioGetMaxSpeed(pSd); + if (mem) memSpeed = SdmmcGetMaxSpeed(pSd); + /* Combo, min speed */ + if (io && mem) { + pSd->transSpeed = (ioSpeed > memSpeed) ? memSpeed : ioSpeed; + } + /* SDIO only */ + else if (io) { + pSd->transSpeed = ioSpeed; + } + /* Memory card only */ + else if (mem) { + pSd->transSpeed = memSpeed; + } + pSd->transSpeed *= 1000; + + /* Enable more bus width Mode */ + error = SdMmcDesideBuswidth(pSd); + if (!error) bwExec = 1; + else if (error != SDMMC_ERROR_NOT_SUPPORT) { + TRACE_ERROR("SdmmcEnum.DesideBusWidth: %u\n\r", error); + return SDMMC_ERROR; + } + + /* Enable High-Speed Mode */ + error = SdMmcEnableHighSpeed(pSd); + if (!error) hsExec = 1; + else if (error != SDMMC_ERROR_NOT_SUPPORT) { + TRACE_ERROR("SdmmcEnum.EnableHS: %u\n\r", error); + return SDMMC_ERROR; + } + + /* In HS mode transfer speed *2 */ + if (hsExec) pSd->transSpeed *= 2; + + /* Update card information since status changed */ + if (bwExec || hsExec) SdMmcUpdateInformation(pSd, hsExec, 1); + return 0; +} +#endif + +void sdInit() +{ + const char * result; + uint8_t i; + + /* Clear CID, CSD, EXT_CSD data */ + for (i = 0; i < 4; i++) Card_ID[i] = 0; + for (i = 0; i < 4; i++) Card_CSD[i] = 0; + // TODO for (i = 0; i < 512/4; i++) pSd->extData[i] = 0; + + /* Set low speed for device identification (LS device max speed) */ + sdSetSpeed(400000); + + /* Initialization delay: The maximum of 1 msec, 74 clock cycles and supply + * ramp up time. Supply ramp up time provides the time that the power is + * built up to the operating level (the bus master supply voltage) and the + * time to wait until the SD card can accept the first command. + */ + + /* Power On Init Special Command */ + result = sdPowerOn(); + if (result) + return; + + /* After power-on or CMD0, all cards? + * CMD lines are in input mode, waiting for start bit of the next command. + * The cards are initialized with a default relative card address + * (RCA=0x0000) and with a default driver stage register setting + * (lowest speed, highest driving current capability). + */ + result = sdIdentify(); + if (result) { + return; + } + +#if 0 + result = sdEnum(); + if (result) { + return; + } + + /* In the case of a Standard Capacity SD Memory Card, this command sets the + * block length (in bytes) for all following block commands + * (read, write, lock). + * Default block length is fixed to 512 Bytes. + * Set length is valid for memory access commands only if partial block read + * operation are allowed in CSD. + * In the case of a High Capacity SD Memory Card, block length set by CMD16 + * command does not affect the memory read and write commands. Always 512 + * Bytes fixed block length is used. This command is effective for + * LOCK_UNLOCK command. + * In both cases, if block length is set larger than 512Bytes, the card sets + * the BLOCK_LEN_ERROR bit. */ + if (pSd->cardType == CARD_SD) { + error = Cmd16(pSd, SDMMC_BLOCK_SIZE); + if (error) { + pSd->optCmdBitMap &= ~SD_CMD16_SUPPORT; + TRACE_INFO("SD_Init.Cmd16 (%d)\n\r", error); + TRACE_INFO("Fail to set BLK_LEN, default is 512\n\r"); + } + } + + /* Reset status for R/W */ + pSd->state = SD_STATE_READY; + + /* If MMC Card & get size from EXT_CSD */ + if ((pSd->cardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmMMC + && SD_CSD_C_SIZE(pSd) == 0xFFF) { + pSd->blockNr = SD_EXTCSD_BLOCKNR(pSd); + /* Block number less than 0x100000000/512 */ + if (pSd->blockNr > 0x800000) + pSd->totalSize = 0xFFFFFFFF; + else + pSd->totalSize = SD_EXTCSD_TOTAL_SIZE(pSd); + } + /* If SD CSD v2.0 */ + else if((pSd->cardType & CARD_TYPE_bmSDMMC) == CARD_TYPE_bmSD + && SD_CSD_STRUCTURE(pSd) >= 1) { + pSd->blockNr = SD_CSD_BLOCKNR_HC(pSd); + pSd->totalSize = 0xFFFFFFFF; + } + /* Normal SD/MMC card */ + else if (pSd->cardType & CARD_TYPE_bmSDMMC) { + pSd->totalSize = SD_CSD_TOTAL_SIZE(pSd); + pSd->blockNr = SD_CSD_BLOCKNR(pSd); + } + + if (pSd->cardType == CARD_UNKNOWN) { + return SDMMC_ERROR_NOT_INITIALIZED; + } + /* Automatically select the max clock */ + clock = SdmmcSetSpeed(pSd, pSd->transSpeed); + TRACE_WARNING_WP("-I- Set SD/MMC clock to %dK\n\r", clock/1000); + pSd->accSpeed = clock; +#endif +} + + +extern FATFS g_FATFS_Obj; void sd_poll_10mS() { - uint32_t i ; + if (!CardIsConnected()) { + Card_state = SD_ST_EMPTY; + Sd_rca = 0; + } - if ( !CardIsConnected() ) - { - Card_state = SD_ST_EMPTY ; - Sd_rca = 0 ; + switch (Card_state) { + case SD_ST_EMPTY: + if (CardIsConnected()) { + Card_state = SD_ST_INIT1; + } + break; - } + case SD_ST_INIT1: + sdCmd0(); + Card_state = SD_ST_INIT2; + break; - switch ( Card_state ) - { - case SD_ST_EMPTY : - if ( CardIsConnected() ) { - Card_state = SD_ST_INIT1 ; - } - break ; + case SD_ST_INIT2: + sdCmd8(1); + Card_state = SD_ST_IDLE; + break; - case SD_ST_INIT1 : - i = sd_cmd0() ; - Card_state = SD_ST_INIT2 ; - break ; + case SD_ST_IDLE: + sdMemInit(1, &Cmd_A41_resp); + Card_state = SD_ST_READY; + break; - case SD_ST_INIT2 : - i = sd_cmd8() ; - Card_state = SD_ST_IDLE ; - break ; + case SD_ST_READY: + if (!sdCmd2()) Card_state = SD_ST_IDENT; + break; - case SD_ST_IDLE : - i = sd_acmd41() ; - if ( i & 0x80000000 ) { - Card_state = SD_ST_READY ; - } - break ; + case SD_ST_IDENT: + if (!sdCmd3()) Card_state = SD_ST_STBY; + break; - case SD_ST_READY : - i = sd_cmd2() ; - if ( i ) - { - Card_ID[0] = Sd_128_resp[0] ; - Card_ID[1] = Sd_128_resp[1] ; - Card_ID[2] = Sd_128_resp[2] ; - Card_ID[3] = Sd_128_resp[3] ; - Card_state = SD_ST_IDENT ; - } - break ; + case SD_ST_STBY: + sdCmd9(); + sdCmd7(); // Select Card + Card_state = SD_ST_TRAN; + break; - case SD_ST_IDENT : - i = sd_cmd3() ; // Get new RCA - Sd_rca = i ; - Card_state = SD_ST_STBY ; - break ; - - case SD_ST_STBY : - i = sd_cmd9() ; - Card_CSD[0] = Sd_128_resp[0] ; - Card_CSD[1] = Sd_128_resp[1] ; - Card_CSD[2] = Sd_128_resp[2] ; - Card_CSD[3] = Sd_128_resp[3] ; - i = sd_cmd7() ; // Select Card -// txmit( '+' ) ; -// p8hex( i ) ; -// crlf() ; - Card_state = SD_ST_TRAN ; - break ; - - case SD_ST_TRAN : - i = sd_acmd51( Sd_128_resp ) ; - Card_SCR[0] = Sd_128_resp[0] ; - Card_SCR[1] = Sd_128_resp[1] ; - Card_state = SD_ST_DATA ; - i = sd_acmd6() ; // Set bus width to 4 bits, and speed to 9 MHz -// txmit( '-' ) ; -// p8hex( i ) ; -// crlf() ; - // Should check the card can do this **** - break ; - } + case SD_ST_TRAN: + sdAcmd51(); + Card_state = SD_ST_DATA; + sdAcmd6(); // Set bus width to 4 bits, and speed to 9 MHz + // Should check the card can do this **** + f_mount(0, &g_FATFS_Obj); + break; + } } // Checks for card ready for read/write @@ -612,18 +900,22 @@ uint32_t sd_cmd16() #endif } +extern OS_MutexID sdMutex; + uint32_t sd_read_block(uint32_t block_no, uint32_t *data) { uint32_t result = 0; Hsmci *phsmci = HSMCI; + CoEnterMutexSection(sdMutex); + if (Card_state == SD_ST_DATA) { if (CardIsConnected()) { sd_cmd16(); // Block size = 512, nblocks = 1 phsmci->HSMCI_BLKR = ((512) << 16) | 1; phsmci->HSMCI_MR = (phsmci->HSMCI_MR & (~(HSMCI_MR_BLKLEN_Msk|HSMCI_MR_FBYTE))) | (HSMCI_MR_PDCMODE|HSMCI_MR_WRPROOF|HSMCI_MR_RDPROOF) | (512 << 16); - phsmci->HSMCI_ARGR = Cmd_A41_resp & 0x40000000 ? block_no : block_no << 9; + phsmci->HSMCI_ARGR = (Cmd_A41_resp & OCR_SD_CCS ? block_no : (block_no << 9)); phsmci->HSMCI_RPR = (uint32_t)data; phsmci->HSMCI_RCR = 512 / 4; phsmci->HSMCI_PTCR = HSMCI_PTCR_RXTEN; @@ -641,7 +933,9 @@ uint32_t sd_read_block(uint32_t block_no, uint32_t *data) } } - phsmci->HSMCI_MR &= ~HSMCI_MR_PDCMODE; + phsmci->HSMCI_MR &= ~(uint32_t)HSMCI_MR_PDCMODE; + + CoLeaveMutexSection(sdMutex); return result; } @@ -650,13 +944,15 @@ uint32_t sd_write_block( uint32_t block_no, uint32_t *data ) uint32_t result = 0; Hsmci *phsmci = HSMCI; + CoEnterMutexSection(sdMutex); + if (Card_state == SD_ST_DATA) { if (CardIsConnected()) { sd_cmd16(); // Block size = 512, nblocks = 1 phsmci->HSMCI_BLKR = ((512) << 16) | 1; phsmci->HSMCI_MR = (phsmci->HSMCI_MR & (~(HSMCI_MR_BLKLEN_Msk|HSMCI_MR_FBYTE))) | (HSMCI_MR_PDCMODE|HSMCI_MR_WRPROOF|HSMCI_MR_RDPROOF) | (512 << 16); - phsmci->HSMCI_ARGR = Cmd_A41_resp & 0x40000000 ? block_no : block_no << 9; + phsmci->HSMCI_ARGR = (Cmd_A41_resp & OCR_SD_CCS ? block_no : (block_no << 9)); phsmci->HSMCI_TPR = (uint32_t)data; phsmci->HSMCI_TCR = 512 / 4; phsmci->HSMCI_CMDR = SD_WRITE_SINGLE_BLOCK; @@ -674,7 +970,10 @@ uint32_t sd_write_block( uint32_t block_no, uint32_t *data ) } } - phsmci->HSMCI_MR &= ~HSMCI_MR_PDCMODE; + phsmci->HSMCI_MR &= ~(uint32_t)HSMCI_MR_PDCMODE; + + CoLeaveMutexSection(sdMutex); + return result; } diff --git a/src/ersky9x/sound_driver.cpp b/src/ersky9x/sound_driver.cpp index c4fbf244c..eda83ec35 100644 --- a/src/ersky9x/sound_driver.cpp +++ b/src/ersky9x/sound_driver.cpp @@ -51,28 +51,14 @@ uint16_t Sine_values[] = 872, 976,1084,1196,1311,1429,1550,1673,1797,1922 } ; -const uint16_t PianoTones[] = -{ - 28, 29, 31, 33, 35, 37, 39, 41, 44, 46, - 49, 52, 55, 58, 62, 65, 69, 73, 78, 82, - 87, 92, 98, 104, 110, 117, 123, 131, 139, 147, - 156, 165, 175, 185, 196, 208, 220, 233, 247, 262, // d#, E, F, f#, G, g#, A, a#, B, C(middle) - 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, // c#, D, d#, E, F, f#, G, g#, A, a# - 494, 523, 554, 587, 622, 659, 698, 740, 784, 831, // B, C, c#, D, d#, E, F, f#, G, g# - 880, 932, 988, 1047, 1109, 1175, 1245, 1319, 1397, 1480, -1568, 1661, 1760, 1865, 1976, 2093, 2217, 2349, 2489, 2637, -2794, 2960, 3136, 3322, 3520 ,3729, 3951, 4186 -} ; - - // Sound routines -void start_sound() +void startSound() { register Pio *pioptr ; start_timer1() ; - init_dac() ; + initDac() ; init_twi() ; pioptr = PIOA ; @@ -115,20 +101,17 @@ void buzzer_sound( uint8_t time ) Buzzer_count = time ; } -void set_frequency( uint32_t frequency ) +void setFrequency( uint32_t frequency ) { register Tc *ptc ; register uint32_t timer ; - timer = Master_frequency / (800 * frequency) ; // MCK/8 and 100 000 Hz - if ( timer > 65535 ) - { - timer = 65535 ; - } - if ( timer < 2 ) - { - timer = 2 ; - } + timer = Master_frequency / (8 * frequency) ; // MCK/8 and 100 000 Hz + if (timer > 65535) + timer = 65535 ; + if (timer < 2) + timer = 2 ; + ptc = TC0 ; // Tc block 0 (TC0-2) ptc->TC_CHANNEL[1].TC_CCR = TC_CCR0_CLKDIS ; // Stop clock ptc->TC_CHANNEL[1].TC_RC = timer ; // 100 000 Hz @@ -136,7 +119,6 @@ void set_frequency( uint32_t frequency ) ptc->TC_CHANNEL[1].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger) } - // Start TIMER1 at 100000Hz, used for DACC trigger void start_timer1() { @@ -163,7 +145,7 @@ void start_timer1() // Configure DAC1 (or DAC0 for REVB) // Not sure why PB14 has not be allocated to the DAC, although it is an EXTRA function // So maybe it is automatically done -void init_dac() +void initDac() { register Dacc *dacptr ; @@ -181,23 +163,32 @@ void init_dac() #endif dacptr->DACC_CDR = 2048 ; // Half amplitude // Data for PDC must NOT be in flash, PDC needs a RAM source. -#ifndef SIMU dacptr->DACC_TPR = (uint32_t) Sine_values ; dacptr->DACC_TNPR = (uint32_t) Sine_values ; -#endif - dacptr->DACC_TCR = 50 ; // words, 100 16 bit values + dacptr->DACC_TCR = 50 ; // words, 100 16 bit values dacptr->DACC_TNCR = 50 ; // words, 100 16 bit values dacptr->DACC_PTCR = DACC_PTCR_TXTEN ; NVIC_EnableIRQ(DACC_IRQn) ; } +uint16_t wavSamplesArray[2*WAV_BUFFER_SIZE]; /* 2 buffers of 100ms at 12kHz */ +uint16_t *wavSamplesBuffer; + extern "C" void DAC_IRQHandler() { // Data for PDC must NOT be in flash, PDC needs a RAM source. -#ifndef SIMU - DACC->DACC_TNPR = (uint32_t) Sine_values ; -#endif - DACC->DACC_TNCR = 50 ; // words, 100 16 bit values + if (toneWavFile[0]) { + CoEnterISR(); // Enter the interrupt + CoSetFlag(audioFlag); + CoExitISR(); // Exit the interrupt + wavSamplesBuffer = (wavSamplesBuffer == wavSamplesArray) ? wavSamplesArray+WAV_BUFFER_SIZE : wavSamplesArray; + DACC->DACC_TNPR = (uint32_t)wavSamplesBuffer; + DACC->DACC_TNCR = WAV_BUFFER_SIZE/2; + } + else { + DACC->DACC_TNPR = (uint32_t) Sine_values ; + DACC->DACC_TNCR = 50 ; // words, 100 16 bit values + } } void end_sound() diff --git a/src/ersky9x/sound_driver.h b/src/ersky9x/sound_driver.h index c4763c899..b1de80d96 100644 --- a/src/ersky9x/sound_driver.h +++ b/src/ersky9x/sound_driver.h @@ -37,23 +37,26 @@ #define NUM_VOL_LEVELS 24 -extern void start_sound( void ) ; +extern void startSound( void ) ; extern void buzzer_on( void ) ; extern void buzzer_off( void ) ; extern void buzzer_sound( uint8_t time ) ; -extern void set_frequency( uint32_t frequency ) ; +extern void setFrequency( uint32_t frequency ) ; extern void start_timer1( void ) ; -extern void init_dac( void ) ; -extern "C" void DAC_IRQHandler( void ) ; +extern void initDac( void ) ; extern void end_sound( void ) ; -inline void tone_start( register uint32_t time ) +#define WAV_BUFFER_SIZE 1200 +extern uint16_t wavSamplesArray[2*WAV_BUFFER_SIZE]; /* 2 buffers of 100ms at 12kHz */ +extern uint16_t *wavSamplesBuffer; + +inline void toneStart() { PMC->PMC_PCER0 |= 0x40000000L ; // Enable peripheral clock to DAC DACC->DACC_IER = DACC_IER_ENDTX ; } -inline void tone_stop( void ) +inline void toneStop() { DACC->DACC_IDR = DACC_IDR_ENDTX ; // Disable interrupt } diff --git a/src/frsky.cpp b/src/frsky.cpp index b76d9aed7..589c9a990 100644 --- a/src/frsky.cpp +++ b/src/frsky.cpp @@ -59,23 +59,10 @@ uint8_t FrskyRxBufferReady = 0; int8_t frskyStreaming = -1; uint8_t frskyUsrStreaming = 0; uint8_t link_counter = 0; - -uint32_t consumption = 0; -uint16_t s_currTmr = 0; - -FrskyData frskyTelemetry[2]; -FrskyRSSI frskyRSSI[2]; - -struct FrskyAlarm { - uint8_t level; // The alarm's 'urgency' level. 0=disabled, 1=yellow, 2=orange, 3=red - uint8_t greater; // 1 = 'if greater than'. 0 = 'if less than' - uint8_t value; // The threshold above or below which the alarm will sound -}; - -struct FrskyAlarm frskyAlarms[4]; +uint16_t currentConsumptionBoundary = 0; +FrskyData frskyData; #if defined(FRSKY_HUB) || defined(WS_HOW_HIGH) -FrskyHubData frskyHubData; enum BarThresholdIdx { THLD_ALT, THLD_RPM, @@ -129,36 +116,36 @@ uint8_t frskyGetUserData(char *buffer, uint8_t bufSize) #ifdef FRSKY_HUB inline void getGpsPilotPosition() { - frskyHubData.pilotLatitude = ((uint32_t)(frskyHubData.gpsLatitude_bp / 100) * 1000000) + (((uint32_t)(frskyHubData.gpsLatitude_bp % 100) * 10000 + frskyHubData.gpsLatitude_ap) * 5) / 3; - frskyHubData.pilotLongitude = ((uint32_t)(frskyHubData.gpsLongitude_bp / 100) * 1000000) + (((uint32_t)(frskyHubData.gpsLongitude_bp % 100) * 10000 + frskyHubData.gpsLongitude_ap) * 5) / 3; - uint32_t lat = (uint32_t)(frskyHubData.gpsLatitude_bp / 100) * 100 + ((uint32_t)(frskyHubData.gpsLatitude_bp % 100) * 5) / 3; + frskyData.frskyHubData.pilotLatitude = ((uint32_t)(frskyData.frskyHubData.gpsLatitude_bp / 100) * 1000000) + (((uint32_t)(frskyData.frskyHubData.gpsLatitude_bp % 100) * 10000 + frskyData.frskyHubData.gpsLatitude_ap) * 5) / 3; + frskyData.frskyHubData.pilotLongitude = ((uint32_t)(frskyData.frskyHubData.gpsLongitude_bp / 100) * 1000000) + (((uint32_t)(frskyData.frskyHubData.gpsLongitude_bp % 100) * 10000 + frskyData.frskyHubData.gpsLongitude_ap) * 5) / 3; + uint32_t lat = (uint32_t)(frskyData.frskyHubData.gpsLatitude_bp / 100) * 100 + ((uint32_t)(frskyData.frskyHubData.gpsLatitude_bp % 100) * 5) / 3; uint32_t angle2 = (lat*lat) / 10000; uint32_t angle4 = angle2 * angle2; - frskyHubData.distFromEarthAxis = 139*(((uint32_t)10000000-((angle2*(uint32_t)123370)/81)+(angle4/25))/12500); - // printf("frskyHubData.distFromEarthAxis=%d\n", frskyHubData.distFromEarthAxis); fflush(stdout); + frskyData.frskyHubData.distFromEarthAxis = 139*(((uint32_t)10000000-((angle2*(uint32_t)123370)/81)+(angle4/25))/12500); + // printf("frskyData.frskyHubData.distFromEarthAxis=%d\n", frskyData.frskyHubData.distFromEarthAxis); fflush(stdout); } inline void getGpsDistance() { - uint32_t lat = ((uint32_t)(frskyHubData.gpsLatitude_bp / 100) * 1000000) + (((uint32_t)(frskyHubData.gpsLatitude_bp % 100) * 10000 + frskyHubData.gpsLatitude_ap) * 5) / 3; - uint32_t lng = ((uint32_t)(frskyHubData.gpsLongitude_bp / 100) * 1000000) + (((uint32_t)(frskyHubData.gpsLongitude_bp % 100) * 10000 + frskyHubData.gpsLongitude_ap) * 5) / 3; + uint32_t lat = ((uint32_t)(frskyData.frskyHubData.gpsLatitude_bp / 100) * 1000000) + (((uint32_t)(frskyData.frskyHubData.gpsLatitude_bp % 100) * 10000 + frskyData.frskyHubData.gpsLatitude_ap) * 5) / 3; + uint32_t lng = ((uint32_t)(frskyData.frskyHubData.gpsLongitude_bp / 100) * 1000000) + (((uint32_t)(frskyData.frskyHubData.gpsLongitude_bp % 100) * 10000 + frskyData.frskyHubData.gpsLongitude_ap) * 5) / 3; - // printf("lat=%d (%d), long=%d (%d)\n", lat, abs(lat - frskyHubData.pilotLatitude), lng, abs(lng - frskyHubData.pilotLongitude)); + // printf("lat=%d (%d), long=%d (%d)\n", lat, abs(lat - frskyData.frskyHubData.pilotLatitude), lng, abs(lng - frskyData.frskyHubData.pilotLongitude)); - uint32_t angle = (lat > frskyHubData.pilotLatitude) ? lat - frskyHubData.pilotLatitude : frskyHubData.pilotLatitude - lat; + uint32_t angle = (lat > frskyData.frskyHubData.pilotLatitude) ? lat - frskyData.frskyHubData.pilotLatitude : frskyData.frskyHubData.pilotLatitude - lat; uint32_t dist = EARTH_RADIUS * angle / 1000000; uint32_t result = dist*dist; - angle = (lng > frskyHubData.pilotLongitude) ? lng - frskyHubData.pilotLongitude : frskyHubData.pilotLongitude - lng; - dist = frskyHubData.distFromEarthAxis * angle / 1000000; + angle = (lng > frskyData.frskyHubData.pilotLongitude) ? lng - frskyData.frskyHubData.pilotLongitude : frskyData.frskyHubData.pilotLongitude - lng; + dist = frskyData.frskyHubData.distFromEarthAxis * angle / 1000000; result += dist*dist; - dist = abs(frskyHubData.baroAltitudeOffset ? frskyHubData.baroAltitude_bp : frskyHubData.gpsAltitude_bp); + dist = abs(frskyData.frskyHubData.baroAltitudeOffset ? frskyData.frskyHubData.baroAltitude_bp : frskyData.frskyHubData.gpsAltitude_bp); result += dist*dist; - frskyHubData.gpsDistance = isqrt32(result); - if (frskyHubData.gpsDistance > frskyHubData.maxGpsDistance) - frskyHubData.maxGpsDistance = frskyHubData.gpsDistance; + frskyData.frskyHubData.gpsDistance = isqrt32(result); + if (frskyData.frskyHubData.gpsDistance > frskyData.frskyHubData.maxGpsDistance) + frskyData.frskyHubData.maxGpsDistance = frskyData.frskyHubData.gpsDistance; } typedef enum { @@ -178,23 +165,23 @@ void evalVario(int16_t altitude_bp, uint16_t altitude_ap) { #if defined(VARIO) int32_t varioAltitude_cm = (int32_t)altitude_bp * 100 + (altitude_bp > 0 ? altitude_ap : -altitude_ap); - uint8_t varioAltitudeQueuePointer = frskyHubData.varioAltitudeQueuePointer + 1; + uint8_t varioAltitudeQueuePointer = frskyData.frskyHubData.varioAltitudeQueuePointer + 1; if (varioAltitudeQueuePointer == VARIO_QUEUE_LENGTH) varioAltitudeQueuePointer = 0; - frskyHubData.varioAltitudeQueuePointer = varioAltitudeQueuePointer; - frskyHubData.varioSpeed -= frskyHubData.varioAltitudeQueue[varioAltitudeQueuePointer] ; - frskyHubData.varioAltitudeQueue[varioAltitudeQueuePointer] = varioAltitude_cm - frskyHubData.varioAltitude_cm; - frskyHubData.varioAltitude_cm = varioAltitude_cm; - frskyHubData.varioSpeed += frskyHubData.varioAltitudeQueue[varioAltitudeQueuePointer] ; + frskyData.frskyHubData.varioAltitudeQueuePointer = varioAltitudeQueuePointer; + frskyData.frskyHubData.varioSpeed -= frskyData.frskyHubData.varioAltitudeQueue[varioAltitudeQueuePointer] ; + frskyData.frskyHubData.varioAltitudeQueue[varioAltitudeQueuePointer] = varioAltitude_cm - frskyData.frskyHubData.varioAltitude_cm; + frskyData.frskyHubData.varioAltitude_cm = varioAltitude_cm; + frskyData.frskyHubData.varioSpeed += frskyData.frskyHubData.varioAltitudeQueue[varioAltitudeQueuePointer] ; #endif } void checkMinMaxAltitude() { - if (frskyHubData.baroAltitude_bp > frskyHubData.maxAltitude) - frskyHubData.maxAltitude = frskyHubData.baroAltitude_bp; - if (frskyHubData.baroAltitude_bp < frskyHubData.minAltitude) - frskyHubData.minAltitude = frskyHubData.baroAltitude_bp; + if (frskyData.frskyHubData.baroAltitude_bp > frskyData.frskyHubData.maxAltitude) + frskyData.frskyHubData.maxAltitude = frskyData.frskyHubData.baroAltitude_bp; + if (frskyData.frskyHubData.baroAltitude_bp < frskyData.frskyHubData.minAltitude) + frskyData.frskyHubData.minAltitude = frskyData.frskyHubData.baroAltitude_bp; } void parseTelemHubByte(uint8_t byte) @@ -238,119 +225,119 @@ void parseTelemHubByte(uint8_t byte) if ((uint8_t)structPos == offsetof(FrskyHubData, gpsLatitude_bp)) { if (lowByte || byte) - frskyHubData.gpsFix = 1; - else if (frskyHubData.gpsFix > 0 && frskyHubData.gpsLatitude_bp > 1) - frskyHubData.gpsFix = 0; + frskyData.frskyHubData.gpsFix = 1; + else if (frskyData.frskyHubData.gpsFix > 0 && frskyData.frskyHubData.gpsLatitude_bp > 1) + frskyData.frskyHubData.gpsFix = 0; } else if ((uint8_t)structPos == offsetof(FrskyHubData, gpsLongitude_bp)) { if (lowByte || byte) - frskyHubData.gpsFix = 1; - else if (frskyHubData.gpsFix > 0 && frskyHubData.gpsLongitude_bp > 1) - frskyHubData.gpsFix = 0; + frskyData.frskyHubData.gpsFix = 1; + else if (frskyData.frskyHubData.gpsFix > 0 && frskyData.frskyHubData.gpsLongitude_bp > 1) + frskyData.frskyHubData.gpsFix = 0; } if ((uint8_t)structPos == offsetof(FrskyHubData, gpsAltitude_bp) || ((uint8_t)structPos >= offsetof(FrskyHubData, gpsAltitude_ap) && (uint8_t)structPos <= offsetof(FrskyHubData, gpsLatitudeNS) && (uint8_t)structPos != offsetof(FrskyHubData, baroAltitude_bp) && (uint8_t)structPos != offsetof(FrskyHubData, baroAltitude_ap))) { // If we don't have a fix, we may discard the value - if (frskyHubData.gpsFix <= 0) + if (frskyData.frskyHubData.gpsFix <= 0) return; } - ((uint8_t*)&frskyHubData)[structPos] = lowByte; - ((uint8_t*)&frskyHubData)[structPos+1] = byte; + ((uint8_t*)&frskyData.frskyHubData)[structPos] = lowByte; + ((uint8_t*)&frskyData.frskyHubData)[structPos+1] = byte; switch ((uint8_t)structPos) { case offsetof(FrskyHubData, rpm): - frskyHubData.rpm *= (uint8_t)60/(g_model.frsky.blades+2); - if (frskyHubData.rpm > frskyHubData.maxRpm) - frskyHubData.maxRpm = frskyHubData.rpm; + frskyData.frskyHubData.rpm *= (uint8_t)60/(g_model.frsky.blades+2); + if (frskyData.frskyHubData.rpm > frskyData.frskyHubData.maxRpm) + frskyData.frskyHubData.maxRpm = frskyData.frskyHubData.rpm; break; case offsetof(FrskyHubData, temperature1): - if (frskyHubData.temperature1 > frskyHubData.maxTemperature1) - frskyHubData.maxTemperature1 = frskyHubData.temperature1; + if (frskyData.frskyHubData.temperature1 > frskyData.frskyHubData.maxTemperature1) + frskyData.frskyHubData.maxTemperature1 = frskyData.frskyHubData.temperature1; break; case offsetof(FrskyHubData, temperature2): - if (frskyHubData.temperature2 > frskyHubData.maxTemperature2) - frskyHubData.maxTemperature2 = frskyHubData.temperature2; + if (frskyData.frskyHubData.temperature2 > frskyData.frskyHubData.maxTemperature2) + frskyData.frskyHubData.maxTemperature2 = frskyData.frskyHubData.temperature2; break; case offsetof(FrskyHubData, current): - if (frskyHubData.current > frskyHubData.maxCurrent) - frskyHubData.maxCurrent = frskyHubData.current; + if (frskyData.frskyHubData.current > frskyData.frskyHubData.maxCurrent) + frskyData.frskyHubData.maxCurrent = frskyData.frskyHubData.current; break; - + case offsetof(FrskyHubData, baroAltitude_bp): // First received barometer altitude => Altitude offset - if (!frskyHubData.baroAltitudeOffset) - frskyHubData.baroAltitudeOffset = -frskyHubData.baroAltitude_bp; + if (!frskyData.frskyHubData.baroAltitudeOffset) + frskyData.frskyHubData.baroAltitudeOffset = -frskyData.frskyHubData.baroAltitude_bp; if (g_model.varioSource == VARIO_SOURCE_BARO_V1) { - evalVario(frskyHubData.baroAltitude_bp, 0); + evalVario(frskyData.frskyHubData.baroAltitude_bp, 0); } - frskyHubData.baroAltitude_bp += frskyHubData.baroAltitudeOffset; + frskyData.frskyHubData.baroAltitude_bp += frskyData.frskyHubData.baroAltitudeOffset; checkMinMaxAltitude(); break; case offsetof(FrskyHubData, baroAltitude_ap): if (g_model.varioSource == VARIO_SOURCE_BARO_V2) { - evalVario(frskyHubData.baroAltitude_bp-frskyHubData.baroAltitudeOffset, frskyHubData.baroAltitude_ap); + evalVario(frskyData.frskyHubData.baroAltitude_bp-frskyData.frskyHubData.baroAltitudeOffset, frskyData.frskyHubData.baroAltitude_ap); } break; case offsetof(FrskyHubData, gpsAltitude_ap): - if (!frskyHubData.gpsAltitudeOffset) - frskyHubData.gpsAltitudeOffset = -frskyHubData.gpsAltitude_bp; - frskyHubData.gpsAltitude_bp += frskyHubData.gpsAltitudeOffset; - if (!frskyHubData.baroAltitudeOffset) { - if (frskyHubData.gpsAltitude_bp > frskyHubData.maxAltitude) - frskyHubData.maxAltitude = frskyHubData.gpsAltitude_bp; - if (frskyHubData.gpsAltitude_bp < frskyHubData.minAltitude) - frskyHubData.minAltitude = frskyHubData.gpsAltitude_bp; + if (!frskyData.frskyHubData.gpsAltitudeOffset) + frskyData.frskyHubData.gpsAltitudeOffset = -frskyData.frskyHubData.gpsAltitude_bp; + frskyData.frskyHubData.gpsAltitude_bp += frskyData.frskyHubData.gpsAltitudeOffset; + if (!frskyData.frskyHubData.baroAltitudeOffset) { + if (frskyData.frskyHubData.gpsAltitude_bp > frskyData.frskyHubData.maxAltitude) + frskyData.frskyHubData.maxAltitude = frskyData.frskyHubData.gpsAltitude_bp; + if (frskyData.frskyHubData.gpsAltitude_bp < frskyData.frskyHubData.minAltitude) + frskyData.frskyHubData.minAltitude = frskyData.frskyHubData.gpsAltitude_bp; } - if (!frskyHubData.pilotLatitude && !frskyHubData.pilotLongitude) { + if (!frskyData.frskyHubData.pilotLatitude && !frskyData.frskyHubData.pilotLongitude) { // First received GPS position => Pilot GPS position getGpsPilotPosition(); } - else if (frskyHubData.gpsDistNeeded || g_menuStack[0] == menuProcFrsky) { + else if (frskyData.frskyHubData.gpsDistNeeded || g_menuStack[0] == menuProcFrsky) { getGpsDistance(); } break; case offsetof(FrskyHubData, gpsSpeed_bp): // Speed => Max speed - if (frskyHubData.gpsSpeed_bp > frskyHubData.maxGpsSpeed) - frskyHubData.maxGpsSpeed = frskyHubData.gpsSpeed_bp; + if (frskyData.frskyHubData.gpsSpeed_bp > frskyData.frskyHubData.maxGpsSpeed) + frskyData.frskyHubData.maxGpsSpeed = frskyData.frskyHubData.gpsSpeed_bp; break; case offsetof(FrskyHubData, volts): // Voltage => Cell number + Cell voltage { - uint8_t battnumber = ((frskyHubData.volts & 0x00F0) >> 4); + uint8_t battnumber = ((frskyData.frskyHubData.volts & 0x00F0) >> 4); if (battnumber < 12) { - if (frskyHubData.cellsCount < battnumber+1) { - frskyHubData.cellsCount = battnumber+1; + if (frskyData.frskyHubData.cellsCount < battnumber+1) { + frskyData.frskyHubData.cellsCount = battnumber+1; } - uint8_t cellVolts = (uint8_t)(((((frskyHubData.volts & 0xFF00) >> 8) + ((frskyHubData.volts & 0x000F) << 8)))/10); - frskyHubData.cellVolts[battnumber] = cellVolts; - if (!frskyHubData.minCellVolts || cellVolts < frskyHubData.minCellVolts || battnumber==frskyHubData.minCellIdx) { - frskyHubData.minCellIdx = battnumber; - frskyHubData.minCellVolts = cellVolts; + uint8_t cellVolts = (uint8_t)(((((frskyData.frskyHubData.volts & 0xFF00) >> 8) + ((frskyData.frskyHubData.volts & 0x000F) << 8)))/10); + frskyData.frskyHubData.cellVolts[battnumber] = cellVolts; + if (!frskyData.frskyHubData.minCellVolts || cellVolts < frskyData.frskyHubData.minCellVolts || battnumber==frskyData.frskyHubData.minCellIdx) { + frskyData.frskyHubData.minCellIdx = battnumber; + frskyData.frskyHubData.minCellVolts = cellVolts; } } break; } case offsetof(FrskyHubData, hour): - frskyHubData.hour = ((uint8_t)(frskyHubData.hour + g_eeGeneral.timezone + 24)) % 24; + frskyData.frskyHubData.hour = ((uint8_t)(frskyData.frskyHubData.hour + g_eeGeneral.timezone + 24)) % 24; break; case offsetof(FrskyHubData, accelX): case offsetof(FrskyHubData, accelY): case offsetof(FrskyHubData, accelZ): - *(int16_t*)(&((uint8_t*)&frskyHubData)[structPos]) /= 10; + *(int16_t*)(&((uint8_t*)&frskyData.frskyHubData)[structPos]) /= 10; break; } @@ -361,12 +348,12 @@ void parseTelemHubByte(uint8_t byte) void parseTelemWSHowHighByte(uint8_t byte) { if (frskyUsrStreaming < (FRSKY_TIMEOUT10ms*3 - 10)) { - ((uint8_t*)&frskyHubData)[offsetof(FrskyHubData, baroAltitude_bp)] = byte; + ((uint8_t*)&frskyData.frskyHubData)[offsetof(FrskyHubData, baroAltitude_bp)] = byte; checkMinMaxAltitude(); } else { // At least 100mS passed since last data received - ((uint8_t*)&frskyHubData)[offsetof(FrskyHubData, baroAltitude_bp)+1] = byte; + ((uint8_t*)&frskyData.frskyHubData)[offsetof(FrskyHubData, baroAltitude_bp)+1] = byte; } // baroAltitude_bp unit here is feet! frskyUsrStreaming = FRSKY_TIMEOUT10ms*3; // reset counter @@ -391,27 +378,15 @@ void processFrskyPacket(uint8_t *packet) // What type of packet? switch (packet[0]) { - case A22PKT: - case A21PKT: - case A12PKT: - case A11PKT: - { - struct FrskyAlarm *alarmptr ; - alarmptr = &frskyAlarms[(packet[0]-A22PKT)] ; - alarmptr->value = packet[1]; - alarmptr->greater = packet[2] & 0x01; - alarmptr->level = packet[3] & 0x03; - } - break; case LINKPKT: // A1/A2/RSSI values link_counter += 32; - frskyTelemetry[0].set(packet[1], g_model.frsky.channels[0].type); - frskyTelemetry[1].set(packet[2], g_model.frsky.channels[1].type); - frskyRSSI[0].set(packet[3]); - frskyRSSI[1].set(packet[4] / 2); + frskyData.frskyTelemetry[0].set(packet[1], g_model.frsky.channels[0].type); + frskyData.frskyTelemetry[1].set(packet[2], g_model.frsky.channels[1].type); + frskyData.frskyRSSI[0].set(packet[3]); + frskyData.frskyRSSI[1].set(packet[4] / 2); frskyStreaming = FRSKY_TIMEOUT10ms; // reset counter only if valid frsky packets are being detected if (g_model.varioSource >= VARIO_SOURCE_A1) { - frskyHubData.varioSpeed = applyChannelRatio(g_model.varioSource - VARIO_SOURCE_A1, frskyTelemetry[g_model.varioSource - VARIO_SOURCE_A1].value); + frskyData.frskyHubData.varioSpeed = applyChannelRatio(g_model.varioSource - VARIO_SOURCE_A1, frskyData.frskyTelemetry[g_model.varioSource - VARIO_SOURCE_A1].value); } break; #if defined(FRSKY_HUB) || defined (WS_HOW_HIGH) @@ -650,22 +625,24 @@ void check_frsky() frskyStreaming--; } else { - frskyRSSI[0].set(0); - frskyRSSI[1].set(0); + frskyData.frskyRSSI[0].set(0); + frskyData.frskyRSSI[1].set(0); } #endif -uint16_t currint; -currint=(g_tmr10ms= currentConsumptionBoundary) { + frskyData.currentConsumption += 1; + frskyData.currentPrescale -= currentConsumptionBoundary; + } #if defined(VARIO) - static uint16_t s_varioTmr = 0; - if (isFunctionActive(FUNC_VARIO)) { + static uint16_t s_varioTmr = 0; + if (isFunctionActive(FUNC_VARIO)) { #if defined(AUDIO) int16_t varioSpeedUpMin = (g_model.varioSpeedUpMin - VARIO_SPEED_LIMIT_UP_CENTER)*VARIO_SPEED_LIMIT_MUL; int16_t varioSpeedDownMin = (VARIO_SPEED_LIMIT_DOWN_OFF - g_model.varioSpeedDownMin)*(-VARIO_SPEED_LIMIT_MUL); - int16_t verticalSpeed = limit((int16_t)(-VARIO_SPEED_LIMIT*100), frskyHubData.varioSpeed, (int16_t)(+VARIO_SPEED_LIMIT*100)); + int16_t verticalSpeed = limit((int16_t)(-VARIO_SPEED_LIMIT*100), frskyData.frskyHubData.varioSpeed, (int16_t)(+VARIO_SPEED_LIMIT*100)); uint8_t SoundVarioBeepNextFreq = 0; uint8_t SoundVarioBeepNextTime = 0; @@ -686,18 +663,18 @@ consumption+=(frskyHubData.current*currint); s_varioTmr = g_tmr10ms; SoundVarioBeepTime = SoundVarioBeepNextTime; SoundVarioBeepFreq = SoundVarioBeepNextFreq; - audio.play(SoundVarioBeepFreq, SoundVarioBeepTime, 0, PLAY_SOUND_VARIO); + AUDIO_VARIO(SoundVarioBeepFreq, SoundVarioBeepTime); } } else { // negative vertical speed gives sound without pauses SoundVarioBeepTime = SoundVarioBeepNextTime; SoundVarioBeepFreq = SoundVarioBeepNextFreq; - audio.play(SoundVarioBeepFreq, 1, 0, PLAY_SOUND_VARIO); + AUDIO_VARIO(SoundVarioBeepFreq, 1); } } #else - int8_t verticalSpeed = limit((int16_t)-100, (int16_t)(frskyHubData.varioSpeed/10), (int16_t)+100); + int8_t verticalSpeed = limit((int16_t)-100, (int16_t)(frskyData.frskyHubData.varioSpeed/10), (int16_t)+100); uint16_t interval; if (verticalSpeed == 0) { @@ -727,11 +704,11 @@ bool FRSKY_alarmRaised(uint8_t idx) for (int i=0; i<2; i++) { if (ALARM_LEVEL(idx, i) != alarm_off) { if (ALARM_GREATER(idx, i)) { - if (frskyTelemetry[idx].value > g_model.frsky.channels[idx].alarms_value[i]) + if (frskyData.frskyTelemetry[idx].value > g_model.frsky.channels[idx].alarms_value[i]) return true; } else { - if (frskyTelemetry[idx].value < g_model.frsky.channels[idx].alarms_value[i]) + if (frskyData.frskyTelemetry[idx].value < g_model.frsky.channels[idx].alarms_value[i]) return true; } } @@ -756,7 +733,6 @@ inline void FRSKY_EnableRXD(void) void FRSKY_Init(void) { // clear frsky variables - memset(frskyAlarms, 0, sizeof(frskyAlarms)); resetTelemetry(); #if defined(PCBARM) @@ -787,35 +763,7 @@ void FRSKY_Init(void) #endif } -#if 0 -// Send packet requesting all alarm settings be sent back to us -void frskyAlarmsRefresh() -{ - - if (frskyTxBufferCount) return; // we only have one buffer. If it's in use, then we can't send. Sorry. - - { - uint8_t *ptr ; - ptr = &frskyTxBuffer[0] ; - *ptr++ = START_STOP; // Start of packet - *ptr++ = ALRM_REQUEST; - *ptr++ = 0x00 ; - *ptr++ = 0x00 ; - *ptr++ = 0x00 ; - *ptr++ = 0x00 ; - *ptr++ = 0x00 ; - *ptr++ = 0x00 ; - *ptr++ = 0x00 ; - *ptr++ = 0x00 ; - *ptr++ = START_STOP; // End of packet - } - - frskyTxBufferCount = 11; - frskyTransmitBuffer(); -} -#endif - -void FrskyRSSI::set(uint8_t value) +void FrskyValueWithMin::set(uint8_t value) { if (this->value == 0) this->value = value; @@ -830,9 +778,9 @@ void FrskyRSSI::set(uint8_t value) min = value; } -void FrskyData::set(uint8_t value, uint8_t unit) +void FrskyValueWithMinMax::set(uint8_t value, uint8_t unit) { - FrskyRSSI::set(value); + FrskyValueWithMin::set(value); if (unit != UNIT_VOLTS) { this->value = value; } @@ -840,52 +788,62 @@ void FrskyData::set(uint8_t value, uint8_t unit) max = value; } +void frskyEvalCurrentConsumptionBoundary() +{ + if (g_model.frsky.currentSource == CURRENT_SOURCE_HUB) { + currentConsumptionBoundary = 360; + } + else { + currentConsumptionBoundary = 360000L / (g_model.frsky.channels[g_model.frsky.currentSource-1].ratio << g_model.frsky.channels[g_model.frsky.currentSource-1].multiplier); + } +} + void resetTelemetry() { - memset(frskyTelemetry, 0, sizeof(frskyTelemetry)); - memset(frskyRSSI, 0, sizeof(frskyRSSI)); - memset(&frskyHubData, 0, sizeof(frskyHubData)); + // TODO these structs could be assembled to have only one memset + memset(&frskyData, 0, sizeof(frskyData)); + + frskyEvalCurrentConsumptionBoundary(); #if defined(FRSKY_HUB) - frskyHubData.gpsLatitude_bp = 2; - frskyHubData.gpsLongitude_bp = 2; - frskyHubData.gpsFix = -1; + frskyData.frskyHubData.gpsLatitude_bp = 2; + frskyData.frskyHubData.gpsLongitude_bp = 2; + frskyData.frskyHubData.gpsFix = -1; #endif #ifdef SIMU frskyTelemetry[0].set(120, UNIT_VOLTS); frskyRSSI[0].set(75); - frskyHubData.fuelLevel = 75; - frskyHubData.rpm = 12000; + frskyData.frskyHubData.fuelLevel = 75; + frskyData.frskyHubData.rpm = 12000; - frskyHubData.gpsFix = 1; - frskyHubData.gpsLatitude_bp = 4401; - frskyHubData.gpsLatitude_ap = 7710; - frskyHubData.gpsLongitude_bp = 1006; - frskyHubData.gpsLongitude_ap = 8872; - frskyHubData.gpsSpeed_bp = (100 * 250) / 463; + frskyData.frskyHubData.gpsFix = 1; + frskyData.frskyHubData.gpsLatitude_bp = 4401; + frskyData.frskyHubData.gpsLatitude_ap = 7710; + frskyData.frskyHubData.gpsLongitude_bp = 1006; + frskyData.frskyHubData.gpsLongitude_ap = 8872; + frskyData.frskyHubData.gpsSpeed_bp = (100 * 250) / 463; getGpsPilotPosition(); - frskyHubData.gpsLatitude_bp = 4401; - frskyHubData.gpsLatitude_ap = 7455; - frskyHubData.gpsLongitude_bp = 1006; - frskyHubData.gpsLongitude_ap = 9533; + frskyData.frskyHubData.gpsLatitude_bp = 4401; + frskyData.frskyHubData.gpsLatitude_ap = 7455; + frskyData.frskyHubData.gpsLongitude_bp = 1006; + frskyData.frskyHubData.gpsLongitude_ap = 9533; getGpsDistance(); - frskyHubData.cellsCount = 6; + frskyData.frskyHubData.cellsCount = 6; - frskyHubData.gpsAltitude_bp = 50; - frskyHubData.baroAltitude_bp = 50; - frskyHubData.minAltitude = 10; - frskyHubData.maxAltitude = 500; + frskyData.frskyHubData.gpsAltitude_bp = 50; + frskyData.frskyHubData.baroAltitude_bp = 50; + frskyData.frskyHubData.minAltitude = 10; + frskyData.frskyHubData.maxAltitude = 500; - frskyHubData.accelY = 100; - frskyHubData.temperature1 = -30; - frskyHubData.maxTemperature1 = 100; - frskyHubData.maxCurrent = 56; - consumption=0; - s_currTmr = g_tmr10ms; - frskyHubData.current = 5; + frskyData.frskyHubData.accelY = 100; + frskyData.frskyHubData.temperature1 = -30; + frskyData.frskyHubData.maxTemperature1 = 100; + + frskyData.frskyHubData.current = 5; + frskyData.frskyHubData.maxCurrent = 56; #endif } @@ -942,8 +900,6 @@ const pm_uint8_t bchunit_ar[] PROGMEM = { UNIT_KTS, // Speed UNIT_METERS, // Dist UNIT_METERS, // GPS Alt - UNIT_AMPS, // current - UNIT_MILLIAMPS, // current consumption }; void putsTelemetryChannel(uint8_t x, uint8_t y, uint8_t channel, int16_t val, uint8_t att) @@ -983,6 +939,15 @@ void putsTelemetryChannel(uint8_t x, uint8_t y, uint8_t channel, int16_t val, ui putsTelemetryValue(x, y, val, UNIT_VOLTS, att|PREC2); break; + case TELEM_CURRENT-1: + case TELEM_MAX_CURRENT-1: + putsTelemetryValue(x, y, val, UNIT_AMPS, att); + break; + + case TELEM_CONSUMPTION-1: + putsTelemetryValue(x, y, val, UNIT_MAH, att); + break; + case TELEM_ACCx-1: case TELEM_ACCy-1: case TELEM_ACCz-1: @@ -995,15 +960,6 @@ void putsTelemetryChannel(uint8_t x, uint8_t y, uint8_t channel, int16_t val, ui putsTelemetryValue(x, y, val, UNIT_RAW, att); break; - case TELEM_CURRENT-1: - case TELEM_MAX_CURRENT-1: - putsTelemetryValue(x, y, val, UNIT_AMPS, att); - break; - - case TELEM_CONSUMPTION-1: - putsTelemetryValue(x, y, val, UNIT_MILLIAMPS, att); - break; - #if defined(IMPERIAL_UNITS) case TELEM_ALT-1: case TELEM_MIN_ALT-1: @@ -1044,11 +1000,11 @@ void displayRssiLine() { if (frskyStreaming > 0) { lcd_hline(0, 55, 128, 0); // separator - uint8_t rssi = min((uint8_t)99, frskyRSSI[1].value); + uint8_t rssi = min((uint8_t)99, frskyData.frskyRSSI[1].value); lcd_putsLeft(7*FH+1, STR_TX); lcd_outdezNAtt(4*FW, 7*FH+1, rssi, LEADING0, 2); lcd_rect(25, 57, 38, 7); lcd_filled_rect(26, 58, 4*rssi/11, 5, (rssi < getRssiAlarmValue(0)) ? DOTTED : SOLID); - rssi = min((uint8_t)99, frskyRSSI[0].value); + rssi = min((uint8_t)99, frskyData.frskyRSSI[0].value); lcd_puts(105, 7*FH+1, STR_RX); lcd_outdezNAtt(105+4*FW-1, 7*FH+1, rssi, LEADING0, 2); lcd_rect(65, 57, 38, 7); uint8_t v = 4*rssi/11; @@ -1065,17 +1021,17 @@ void displayGpsTime() { #define TIME_LINE (7*FH+1) uint8_t att = (frskyStreaming > 0 ? LEFT|LEADING0 : LEFT|LEADING0|BLINK); - lcd_outdezNAtt(6*FW+5, TIME_LINE, frskyHubData.hour, att, 2); + lcd_outdezNAtt(6*FW+5, TIME_LINE, frskyData.frskyHubData.hour, att, 2); lcd_putcAtt(8*FW+2, TIME_LINE, ':', att); - lcd_outdezNAtt(9*FW+2, TIME_LINE, frskyHubData.min, att, 2); + lcd_outdezNAtt(9*FW+2, TIME_LINE, frskyData.frskyHubData.min, att, 2); lcd_putcAtt(11*FW-1, TIME_LINE, ':', att); - lcd_outdezNAtt(12*FW-1, TIME_LINE, frskyHubData.sec, att, 2); + lcd_outdezNAtt(12*FW-1, TIME_LINE, frskyData.frskyHubData.sec, att, 2); lcd_status_line(); } void displayGpsCoord(uint8_t y, char direction, int16_t bp, int16_t ap) { - if (frskyHubData.gpsFix >= 0) { + if (frskyData.frskyHubData.gpsFix >= 0) { if (!direction) direction = '-'; lcd_outdezAtt(10*FW, y, bp / 100, LEFT); // ddd before '.' @@ -1162,9 +1118,9 @@ void menuProcFrsky(uint8_t event) if (frskyStreaming > 0) { if (field == TELEM_ACC) { lcd_putsLeft(7*FH+1, STR_ACCEL); - lcd_outdezNAtt(4*FW, 7*FH+1, frskyHubData.accelX, LEFT|PREC2); - lcd_outdezNAtt(10*FW, 7*FH+1, frskyHubData.accelY, LEFT|PREC2); - lcd_outdezNAtt(16*FW, 7*FH+1, frskyHubData.accelZ, LEFT|PREC2); + lcd_outdezNAtt(4*FW, 7*FH+1, frskyData.frskyHubData.accelX, LEFT|PREC2); + lcd_outdezNAtt(10*FW, 7*FH+1, frskyData.frskyHubData.accelY, LEFT|PREC2); + lcd_outdezNAtt(16*FW, 7*FH+1, frskyData.frskyHubData.accelZ, LEFT|PREC2); break; } else if (field == TELEM_GPS_TIME) { @@ -1261,19 +1217,19 @@ void menuProcFrsky(uint8_t event) if (g_model.frsky.channels[i].ratio) { blink = (FRSKY_alarmRaised(i) ? INVERS : 0); putsStrIdx(0, y, STR_A, i+1, TWO_DOTS); - putsTelemetryChannel(3*FW, y, i+MAX_TIMERS, frskyTelemetry[i].value, blink|DBLSIZE|LEFT); - lcd_putc(12*FW-1, y-FH, '<'); putsTelemetryChannel(17*FW, y-FH, i+MAX_TIMERS, frskyTelemetry[i].min, NO_UNIT); - lcd_putc(12*FW, y, '>'); putsTelemetryChannel(17*FW, y, i+MAX_TIMERS, frskyTelemetry[i].max, NO_UNIT); + putsTelemetryChannel(3*FW, y, i+MAX_TIMERS, frskyData.frskyTelemetry[i].value, blink|DBLSIZE|LEFT); + lcd_putc(12*FW-1, y-FH, '<'); putsTelemetryChannel(17*FW, y-FH, i+MAX_TIMERS, frskyData.frskyTelemetry[i].min, NO_UNIT); + lcd_putc(12*FW, y, '>'); putsTelemetryChannel(17*FW, y, i+MAX_TIMERS, frskyData.frskyTelemetry[i].max, NO_UNIT); y += 3*FH; } } #ifdef FRSKY_HUB // Cells voltage - if (frskyHubData.cellsCount > 0) { + if (frskyData.frskyHubData.cellsCount > 0) { uint8_t y = 1*FH; - for (uint8_t k=0; k> alarm) & 1) #define ALARM_LEVEL(channel, alarm) ((g_model.frsky.channels[channel].alarms_level >> (2*alarm)) & 3) -class FrskyRSSI { +class FrskyValueWithMin { public: uint8_t value; uint8_t min; @@ -60,7 +60,7 @@ class FrskyRSSI { void set(uint8_t value); }; -class FrskyData: public FrskyRSSI { +class FrskyValueWithMinMax: public FrskyValueWithMin { public: uint8_t max; void set(uint8_t value, uint8_t unit); @@ -119,7 +119,6 @@ PACK(struct FrskyHubData { uint16_t current; // 0x28 Current int16_t varioAltitudeQueue[VARIO_QUEUE_LENGTH]; //circular buffer int32_t varioAltitude_cm; - int16_t varioSpeed; /* next fields must keep this order! */ int16_t minAltitude; int16_t maxAltitude; @@ -128,6 +127,7 @@ PACK(struct FrskyHubData { int16_t maxTemperature2; uint16_t maxGpsSpeed; uint16_t maxGpsDistance; + uint16_t maxCurrent; /* end */ int16_t varioAcc1; int16_t varioAcc2; @@ -136,9 +136,9 @@ PACK(struct FrskyHubData { // end of FrSky Hub data uint16_t gpsDistance; int16_t gpsAltitudeOffset; + int16_t varioSpeed; uint8_t varioAltitudeQueuePointer; // circular-buffer pointer uint8_t minCellIdx; - uint16_t maxCurrent; }); #elif defined(WS_HOW_HIGH) @@ -150,23 +150,34 @@ struct FrskyHubData { #endif +struct FrskyData { + FrskyValueWithMinMax frskyTelemetry[2]; + FrskyValueWithMin frskyRSSI[2]; +#if defined(FRSKY_HUB) || defined(WS_HOW_HIGH) + FrskyHubData frskyHubData; +#endif + uint16_t currentConsumption; + uint16_t currentPrescale; +}; + #if defined(FRSKY_HUB) || defined(WS_HOW_HIGH) -extern FrskyHubData frskyHubData; extern uint8_t barsThresholds[]; #endif // Global Fr-Sky telemetry data variables extern int8_t frskyStreaming; // >0 (true) == data is streaming in. 0 = nodata detected for some time extern uint8_t frskyUsrStreaming; -extern uint32_t consumption; + #define SEND_MODEL_ALARMS 6 extern uint8_t FrskyAlarmSendState; -extern FrskyData frskyTelemetry[2]; -extern FrskyRSSI frskyRSSI[2]; +extern FrskyData frskyData; + extern uint8_t frskyTxBuffer[FRSKY_TX_PACKET_SIZE]; extern uint8_t frskyTxBufferCount; + + void FRSKY_Init(void); void check_frsky(void); @@ -175,6 +186,8 @@ inline void FRSKY_setModelAlarms(void) FrskyAlarmSendState = SEND_MODEL_ALARMS; } +extern void frskyEvalCurrentConsumptionBoundary(); + bool FRSKY_alarmRaised(uint8_t idx); void resetTelemetry(); diff --git a/src/general_menus.cpp b/src/general_menus.cpp index a66571ce3..1862757ad 100644 --- a/src/general_menus.cpp +++ b/src/general_menus.cpp @@ -523,9 +523,10 @@ extern uint32_t Cmd_A41_resp; #define OCR_SD_CCS (0) #endif -const char STR_DELETE_FILE[] = "Delete"; -const char STR_COPY_FILE[] = "Copy"; -const char STR_RENAME_FILE[] = "Rename"; +const pm_char STR_PLAY_FILE[] PROGMEM = "Play"; +const pm_char STR_DELETE_FILE[] PROGMEM = "Delete"; +const pm_char STR_COPY_FILE[] PROGMEM = "Copy"; +const pm_char STR_RENAME_FILE[] PROGMEM = "Rename"; void menuProcSd(uint8_t event) { @@ -536,6 +537,8 @@ void menuProcSd(uint8_t event) TCHAR lfn[_MAX_LFN + 1]; fno.lfname = lfn; fno.lfsize = sizeof(lfn); +#else + char lfn[32]; #endif uint8_t _event = event; @@ -549,7 +552,10 @@ void menuProcSd(uint8_t event) switch(event) { case EVT_ENTRY: +#if defined(PCBV4) + // TODO as ARM f_mount(0, &g_FATFS_Obj); +#endif f_chdir("/"); reusableBuffer.sd.offset = 255; break; @@ -562,6 +568,7 @@ void menuProcSd(uint8_t event) killEvents(event); f_chdir(reusableBuffer.sd.lines[index]); s_pgOfs = 0; + m_posVert = 1; reusableBuffer.sd.offset = 255; } } @@ -570,6 +577,13 @@ void menuProcSd(uint8_t event) case EVT_KEY_LONG(KEY_MENU): killEvents(event); if (m_posVert > 0) { +#if defined(PCBARM) + uint8_t index = m_posVert-1-s_pgOfs; + char * line = reusableBuffer.sd.lines[index]; + if (!strcmp(line+strlen(line)-4, ".wav")) { + s_menu[s_menu_count++] = STR_PLAY_FILE; + } +#endif s_menu[s_menu_count++] = STR_DELETE_FILE; s_menu[s_menu_count++] = STR_RENAME_FILE; s_menu[s_menu_count++] = STR_COPY_FILE; @@ -613,7 +627,7 @@ void menuProcSd(uint8_t event) for (uint8_t i=0; i<7; i++) { uint8_t y = FH+i*FH; uint8_t x = 0; - uint8_t attr = (m_posVert-1-s_pgOfs == i ? INVERS : 0); + uint8_t attr = (m_posVert-1-s_pgOfs == i ? BSS|INVERS : BSS); if (reusableBuffer.sd.flags[i]) { lcd_putcAtt(0, y, '[', attr); x += FW; } lcd_putsAtt(x, y, reusableBuffer.sd.lines[i], attr); if (reusableBuffer.sd.flags[i]) { lcd_putcAtt(lcdLastPos, y, ']', attr); } @@ -625,15 +639,23 @@ void menuProcSd(uint8_t event) uint8_t index = m_posVert-1-s_pgOfs; if (result == STR_DELETE_FILE) { f_getcwd(lfn, SD_SCREEN_FILE_LENGTH); - strcat_P(lfn, "/"); - strcat_P(lfn, reusableBuffer.sd.lines[index]); + strcat_P(lfn, PSTR("/")); + strcat(lfn, reusableBuffer.sd.lines[index]); f_unlink(lfn); strncpy(statusLineMsg, reusableBuffer.sd.lines[index], 13); strcpy_P(statusLineMsg+min((uint8_t)strlen(statusLineMsg), (uint8_t)13), PSTR(" removed")); showStatusLine(); - if (m_posVert == reusableBuffer.sd.count) m_posVert--; + if ((uint16_t)m_posVert == reusableBuffer.sd.count) m_posVert--; reusableBuffer.sd.offset = s_pgOfs-1; } +#if defined(PCBARM) + else if (result == STR_PLAY_FILE) { + f_getcwd(lfn, SD_SCREEN_FILE_LENGTH); + strcat_P(lfn, PSTR("/")); + strcat(lfn, reusableBuffer.sd.lines[index]); + playFile(lfn); + } +#endif } } } @@ -725,9 +747,6 @@ void menuProcDiagVers(uint8_t event) lcd_putsLeft(5*FH, stamp4); lcd_putsLeft(7*FH, STR_EEPROMV); lcd_outdezAtt(8*FW, 7*FH, g_eeGeneral.myVers, LEFT); -#if defined(PCBARM) && defined(SDCARD) - lcd_puts(12*FW, 7*FH, Card_state == 8 /* TODO SD_ST_DATA*/ ? "SDCARD OK" : "NO SDCARD"); -#endif } void menuProcDiagKeys(uint8_t event) diff --git a/src/gruvin9x/logs.cpp b/src/gruvin9x/logs.cpp index 51182f644..d32ce3f6d 100644 --- a/src/gruvin9x/logs.cpp +++ b/src/gruvin9x/logs.cpp @@ -130,31 +130,31 @@ void writeLogs() #ifdef FRSKY f_printf(&g_oLogFile, "%d,", frskyStreaming); - f_printf(&g_oLogFile, "%d,", frskyRSSI[0].value); - f_printf(&g_oLogFile, "%d,", frskyRSSI[1].value); - f_printf(&g_oLogFile, "%d,", frskyTelemetry[0].value); - f_printf(&g_oLogFile, "%d,", frskyTelemetry[1].value); + f_printf(&g_oLogFile, "%d,", frskyData.frskyRSSI[0].value); + f_printf(&g_oLogFile, "%d,", frskyData.frskyRSSI[1].value); + f_printf(&g_oLogFile, "%d,", frskyData.frskyTelemetry[0].value); + f_printf(&g_oLogFile, "%d,", frskyData.frskyTelemetry[1].value); #endif #ifdef FRSKY_HUB if (g_model.frsky.usrProto == USR_PROTO_FRSKY_HUB) { - f_printf(&g_oLogFile, "%4d-%02d-%02d,", frskyHubData.year+2000, frskyHubData.month, frskyHubData.day); - f_printf(&g_oLogFile, "%02d:%02d:%02d,", frskyHubData.hour, frskyHubData.min, frskyHubData.sec); - f_printf(&g_oLogFile, "%03d.%04d%c,", frskyHubData.gpsLongitude_bp, frskyHubData.gpsLongitude_ap, - frskyHubData.gpsLongitudeEW ? frskyHubData.gpsLongitudeEW : '-'); - f_printf(&g_oLogFile, "%03d.%04d%c,", frskyHubData.gpsLatitude_bp, frskyHubData.gpsLatitude_ap, - frskyHubData.gpsLatitudeNS ? frskyHubData.gpsLatitudeNS : '-'); - f_printf(&g_oLogFile, "%03d.%d,", frskyHubData.gpsCourse_bp, frskyHubData.gpsCourse_ap); - f_printf(&g_oLogFile, "%d.%d,", frskyHubData.gpsSpeed_bp, frskyHubData.gpsSpeed_ap); - f_printf(&g_oLogFile, "%03d.%d,", frskyHubData.gpsAltitude_bp, frskyHubData.gpsAltitude_ap); - f_printf(&g_oLogFile, "%d.%d,", frskyHubData.baroAltitude_bp, frskyHubData.baroAltitude_ap); - f_printf(&g_oLogFile, "%d,", frskyHubData.temperature1); - f_printf(&g_oLogFile, "%d,", frskyHubData.temperature2); - f_printf(&g_oLogFile, "%d,", frskyHubData.rpm); - f_printf(&g_oLogFile, "%d,", frskyHubData.fuelLevel); - f_printf(&g_oLogFile, "%d,", frskyHubData.volts); - f_printf(&g_oLogFile, "%d,", frskyHubData.accelX); - f_printf(&g_oLogFile, "%d,", frskyHubData.accelY); - f_printf(&g_oLogFile, "%d,", frskyHubData.accelZ); + f_printf(&g_oLogFile, "%4d-%02d-%02d,", frskyData.frskyHubData.year+2000, frskyData.frskyHubData.month, frskyData.frskyHubData.day); + f_printf(&g_oLogFile, "%02d:%02d:%02d,", frskyData.frskyHubData.hour, frskyData.frskyHubData.min, frskyData.frskyHubData.sec); + f_printf(&g_oLogFile, "%03d.%04d%c,", frskyData.frskyHubData.gpsLongitude_bp, frskyData.frskyHubData.gpsLongitude_ap, + frskyData.frskyHubData.gpsLongitudeEW ? frskyData.frskyHubData.gpsLongitudeEW : '-'); + f_printf(&g_oLogFile, "%03d.%04d%c,", frskyData.frskyHubData.gpsLatitude_bp, frskyData.frskyHubData.gpsLatitude_ap, + frskyData.frskyHubData.gpsLatitudeNS ? frskyData.frskyHubData.gpsLatitudeNS : '-'); + f_printf(&g_oLogFile, "%03d.%d,", frskyData.frskyHubData.gpsCourse_bp, frskyData.frskyHubData.gpsCourse_ap); + f_printf(&g_oLogFile, "%d.%d,", frskyData.frskyHubData.gpsSpeed_bp, frskyData.frskyHubData.gpsSpeed_ap); + f_printf(&g_oLogFile, "%03d.%d,", frskyData.frskyHubData.gpsAltitude_bp, frskyData.frskyHubData.gpsAltitude_ap); + f_printf(&g_oLogFile, "%d.%d,", frskyData.frskyHubData.baroAltitude_bp, frskyData.frskyHubData.baroAltitude_ap); + f_printf(&g_oLogFile, "%d,", frskyData.frskyHubData.temperature1); + f_printf(&g_oLogFile, "%d,", frskyData.frskyHubData.temperature2); + f_printf(&g_oLogFile, "%d,", frskyData.frskyHubData.rpm); + f_printf(&g_oLogFile, "%d,", frskyData.frskyHubData.fuelLevel); + f_printf(&g_oLogFile, "%d,", frskyData.frskyHubData.volts); + f_printf(&g_oLogFile, "%d,", frskyData.frskyHubData.accelX); + f_printf(&g_oLogFile, "%d,", frskyData.frskyHubData.accelY); + f_printf(&g_oLogFile, "%d,", frskyData.frskyHubData.accelZ); } #endif for (uint8_t i=0; i0 && sub<=13) + frskyEvalCurrentConsumptionBoundary(); + if (s_editMode>0 && sub<=ITEM_TELEMETRY_RSSI_ALARM2) FRSKY_setModelAlarms(); // update Fr-Sky module when edit mode exited break; } @@ -2385,7 +2390,7 @@ void menuProcTelemetry(uint8_t event) case ITEM_TELEMETRY_A2_LABEL: lcd_putsLeft(y, STR_ACHANNEL); lcd_outdezAtt(2*FW, y, ch+1, 0); - putsTelemetryChannel(TELEM_COL2+6*FW, y, ch+MAX_TIMERS, frskyTelemetry[ch].value, LEFT); + putsTelemetryChannel(TELEM_COL2+6*FW, y, ch+MAX_TIMERS, frskyData.frskyTelemetry[ch].value, LEFT); break; case ITEM_TELEMETRY_A1_RANGE: @@ -2496,6 +2501,12 @@ void menuProcTelemetry(uint8_t event) break; #endif + case ITEM_TELEMETRY_USR_CURRENT_SOURCE: + lcd_puts(4, y, STR_CURRENT); + lcd_putsiAtt(TELEM_COL2, y, STR_CURRENTSRC, g_model.frsky.currentSource, attr); + if (attr) CHECK_INCDEC_MODELVAR(event, g_model.frsky.currentSource, 0, 2); + break; + #if defined(VARIO) case ITEM_TELEMETRY_VARIO_LABEL: lcd_putsLeft(y, STR_VARIO); diff --git a/src/myeeprom.h b/src/myeeprom.h index b85bd1dd3..e070718e8 100644 --- a/src/myeeprom.h +++ b/src/myeeprom.h @@ -333,6 +333,7 @@ enum TelemetryUnit { UNIT_DEGREES, UNIT_PERCENT, UNIT_MILLIAMPS, + UNIT_MAH, UNIT_MAX, UNIT_FEET, UNIT_KTS @@ -402,7 +403,7 @@ enum VarioSource { }; PACK(typedef struct t_FrSkyBarData { - uint16_t source:4; + uint16_t source:4; // TODO modification in next EEPROM uint16_t barMin:6; // minimum for bar display uint16_t barMax:6; // ditto for max display (would usually = ratio) }) FrSkyBarData; @@ -413,12 +414,18 @@ enum FrskyUsrProtocols { USR_PROTO_WS_HOW_HIGH }; +enum CurrentSource { + CURRENT_SOURCE_HUB, + CURRENT_SOURCE_A1, + CURRENT_SOURCE_A2 +}; + PACK(typedef struct t_FrSkyData { FrSkyChannelData channels[2]; uint8_t usrProto:3; // Protocol in FrSky user data, 0=None, 1=FrSky hub, 2=WS HowHigh uint8_t imperial:1; uint8_t blades:2; // How many blades for RPMs, 0=2 blades, 1=3 blades - uint8_t spare:2; + uint8_t currentSource:2; FrSkyBarData bars[4]; FrSkyRSSIAlarm rssiAlarms[2]; }) FrSkyData; @@ -593,10 +600,10 @@ PACK(typedef struct t_ModelData { EXTDATA; - int8_t ppmFrameLength; // 0=22.5ms (10ms-30ms) 0.5msec increments + int8_t ppmFrameLength; // 0=22.5ms (10ms-30ms) 0.5ms increments uint8_t thrTraceSrc; uint8_t modelId; - uint8_t frskyLines[4]; + uint8_t frskyLines[4]; // TODO modification in next EEPROM uint16_t frskyLinesXtra; int8_t servoCenter[NUM_CHNOUT]; diff --git a/src/open9x.cpp b/src/open9x.cpp index f156b5a1b..c5ccbfb18 100644 --- a/src/open9x.cpp +++ b/src/open9x.cpp @@ -38,6 +38,7 @@ extern "C" { #define MIXER_STACK_SIZE 300 #define MENUS_STACK_SIZE 300 +#define AUDIO_STACK_SIZE 300 #define BT_STACK_SIZE 100 OS_TID mixerTaskId; @@ -46,6 +47,13 @@ OS_STK mixerStack[MIXER_STACK_SIZE]; OS_TID menusTaskId; OS_STK menusStack[MENUS_STACK_SIZE]; +OS_TID audioTaskId; +OS_STK audioStack[AUDIO_STACK_SIZE]; +OS_TCID audioTimer; +OS_FlagID audioFlag; + +OS_MutexID sdMutex; + /*OS_TID btTask; OS_STK btStack[BT_STACK_SIZE]; OS_TCID btTimer; @@ -82,7 +90,7 @@ uint16_t g_timeMainMax; uint8_t g_timeMainLast; #endif -#ifdef AUDIO +#if defined(AUDIO) && !defined(PCBARM) audioQueue audio; #endif @@ -449,32 +457,31 @@ int16_t getValue(uint8_t i) else if(ifunc == FUNC_PLAY_SOUND) { -#if defined(AUDIO) - audioDefevent(AU_FRSKY_FIRST+sd->param); -#else - // TODO sound with warble = !(g_tmr10ms % 60); AUDIO_WARNING2(); } - beep(3); -#endif + AUDIO_PLAY(AU_FRSKY_FIRST+sd->param); } #if defined(HAPTIC) @@ -2832,11 +2829,14 @@ void menusTask(void * pdata) while (1) { shutdown_state = check_soft_power(); #if 0 - if (shutdown_state == e_power_off) + if (shutdown_state == e_power_off) { break; + } else if (shutdown_state == e_power_usb) { - const char STR_SDCARD[] = "SD Card"; + const char STR_SDCARD[] = "Massstorage"; // TODO translations const char STR_BOOTLOADER[] = "Bootloader"; + lcd_clear(); + s_menu_count = 0; s_menu[s_menu_count++] = STR_SDCARD; s_menu[s_menu_count++] = STR_BOOTLOADER; uint8_t event = getEvent(false); @@ -2849,15 +2849,17 @@ void menusTask(void * pdata) s_menu_count = 0; } } + refreshDisplay(); } #else - if (shutdown_state >= e_power_usb) + if (shutdown_state >= e_power_usb) { break; + } #endif - - perMain(); + else { + perMain(); + } CoTickDelay(5); // 10ms for now - } SysTick->CTRL = 0; // turn off systick @@ -2887,6 +2889,10 @@ void menusTask(void * pdata) lcdSetRefVolt(0); // TODO before soft_power_off? } + +extern void audioTimerHandle(void); +extern void audioTask(void* pdata); + #endif int main(void) @@ -3031,8 +3037,14 @@ int main(void) // 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); - menusTaskId = CoCreateTask(menusTask, NULL, 10, &menusStack[MENUS_STACK_SIZE-1], MENUS_STACK_SIZE); 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); + + audioFlag = CoCreateFlag(true, false); // Auto-reset, start FALSE + audioTimer = CoCreateTmr(TMR_TYPE_ONE_SHOT, 1000/(1000/CFG_SYSTICK_FREQ), 1000/(1000/CFG_SYSTICK_FREQ), audioTimerHandle); + audioTaskId = CoCreateTask(audioTask, NULL, 7, &audioStack[AUDIO_STACK_SIZE-1], AUDIO_STACK_SIZE); + + sdMutex = CoCreateMutex(); CoStartOS(); #else diff --git a/src/simpgmspace.cpp b/src/simpgmspace.cpp index bf2916449..68175d469 100644 --- a/src/simpgmspace.cpp +++ b/src/simpgmspace.cpp @@ -47,6 +47,7 @@ Pio Pioa, Piob, Pioc; Pwm pwm; Twi Twio; Usart Usart0; +Dacc dacc; uint32_t eeprom_pointer; char* eeprom_buffer_data; volatile int32_t eeprom_buffer_size; @@ -354,5 +355,11 @@ int f_printf (FIL*, const TCHAR*, ...) /* Put a formatte return 0; } +FRESULT f_getcwd (TCHAR *path, UINT sz_path) +{ + getcwd(path, sz_path); + return FR_OK; +} + uint32_t Card_state = 8; #endif diff --git a/src/simpgmspace.h b/src/simpgmspace.h index 7d2e98a0d..40dc00ca8 100644 --- a/src/simpgmspace.h +++ b/src/simpgmspace.h @@ -99,6 +99,7 @@ extern sem_t *eeprom_write_sem; #if defined(PCBARM) extern Pio Pioa, Piob, Pioc; extern Twi Twio; +extern Dacc dacc; extern Usart Usart0; #undef USART0 #define USART0 (&Usart0) @@ -110,6 +111,8 @@ extern Usart Usart0; #define PIOC (&Pioc) #undef TWI0 #define TWI0 (&Twio) +#undef DACC +#define DACC (&dacc) extern Pwm pwm; #undef PWM #define PWM (&pwm) @@ -292,4 +295,11 @@ void eeprom_read_block (void *pointer_ram, #define wdt_reset() sleep(1/*ms*/) #define board_init() +#define CoSetFlag(...) +#define CoSetTmrCnt(...) +#define CoEnterISR(...) +#define CoExitISR(...) +#define CoStartTmr(...) +#define CoWaitForSingleFlag(...) + #endif diff --git a/src/stock/audio.h b/src/stock/audio.h index b2aa2b7b1..135994b3b 100644 --- a/src/stock/audio.h +++ b/src/stock/audio.h @@ -74,8 +74,6 @@ class audioQueue // it is essentially the life of the class. void heartbeat(); - // bool freeslots(uint8_t slots); - inline bool empty() { return (t_queueRidx == t_queueWidx); } @@ -132,6 +130,9 @@ void audioDefevent(uint8_t e); #define AUDIO_VARIO_UP() audioDefevent(AU_KEYPAD_UP) #define AUDIO_VARIO_DOWN() audioDefevent(AU_KEYPAD_DOWN) #define AUDIO_TRIM_MIDDLE(f) audio.event(AU_TRIM_MIDDLE, f) +#define AUDIO_TRIM(event, f) audio.event(AU_TRIM_MOVE, f) +#define AUDIO_PLAY(p) audio.event(p) +#define AUDIO_VARIO(f, t) audio.play(f, t, 0, PLAY_SOUND_VARIO) #define AUDIO_DRIVER() audio.driver() #define AUDIO_HEARTBEAT() audio.heartbeat() diff --git a/src/translations.cpp b/src/translations.cpp index 29c086ce8..937a180b9 100644 --- a/src/translations.cpp +++ b/src/translations.cpp @@ -71,6 +71,7 @@ const pm_char STR_OPEN9X[] PROGMEM = ISTR(VALARMFN) ISTR(VTELPROTO) ISTR(GPSFORMAT) + ISTR(CURRENTSRC) ISTR(VARIOSRC) #endif #ifdef TEMPLATES @@ -302,9 +303,12 @@ const pm_char STR_SHUTDOWN[] PROGMEM = TR_SHUTDOWN; const pm_char STR_BATT_CALIB[] PROGMEM = TR_BATT_CALIB; +#if defined(PCBARM) || defined(FRSKY) +const pm_char STR_CURRENT[] PROGMEM = TR_CURRENT; +#endif + #if defined(PCBARM) const pm_char STR_CURRENT_CALIB[] PROGMEM = TR_CURRENT_CALIB; -const pm_char STR_CURRENT[] PROGMEM = TR_CURRENT; #endif #if defined(SDCARD) diff --git a/src/translations.h b/src/translations.h index 5c685cd67..5ef64647f 100644 --- a/src/translations.h +++ b/src/translations.h @@ -98,7 +98,8 @@ extern const pm_char STR_OPEN9X[]; #define OFS_VALARMFN (OFS_VALARM + sizeof(TR_VALARM)) #define OFS_VTELPROTO (OFS_VALARMFN + sizeof(TR_VALARMFN)) #define OFS_GPSFORMAT (OFS_VTELPROTO + sizeof(TR_VTELPROTO)) -#define OFS_VARIOSRC (OFS_GPSFORMAT + sizeof(TR_GPSFORMAT)) +#define OFS_CURRENTSRC (OFS_GPSFORMAT + sizeof(TR_GPSFORMAT)) +#define OFS_VARIOSRC (OFS_CURRENTSRC + sizeof(TR_CURRENTSRC)) #define OFS_ENDTELEM (OFS_VARIOSRC + sizeof(TR_VARIOSRC)) #else #define OFS_ENDTELEM (OFS_VTELEMCHNS + sizeof(TR_VTELEMCHNS)) @@ -165,6 +166,7 @@ extern const pm_char STR_OPEN9X[]; #define STR_VALARMFN (STR_OPEN9X + OFS_VALARMFN) #define STR_VTELPROTO (STR_OPEN9X + OFS_VTELPROTO) #define STR_GPSFORMAT (STR_OPEN9X + OFS_GPSFORMAT) +#define STR_CURRENTSRC (STR_OPEN9X + OFS_CURRENTSRC) #define STR_VARIOSRC (STR_OPEN9X + OFS_VARIOSRC) #define STR_TELEMCHNS (STR_OPEN9X + OFS_TELEMCHNS) #endif @@ -373,9 +375,12 @@ extern const pm_char STR_SHUTDOWN[]; extern const pm_char STR_BATT_CALIB[]; +#if defined(PCBARM) || defined(FRSKY) +extern const pm_char STR_CURRENT[]; +#endif + #if defined(PCBARM) extern const pm_char STR_CURRENT_CALIB[]; -extern const pm_char STR_CURRENT[]; #define LEN_CALIB_FIELDS (PSIZE(TR_BATT_CALIB) > PSIZE(TR_CURRENT_CALIB) ? PSIZE(TR_BATT_CALIB) : PSIZE(TR_CURRENT_CALIB)) #else #define LEN_CALIB_FIELDS PSIZE(TR_BATT_CALIB) diff --git a/src/translations/cz.h b/src/translations/cz.h index eb359c5ed..67f716da2 100644 --- a/src/translations/cz.h +++ b/src/translations/cz.h @@ -138,7 +138,7 @@ #define TR_FUNCSOUNDS "Warn1 ""Warn2 ""Cheep ""Ring ""SciFi ""Robot ""Chirp ""Tada ""Crickt""Siren ""AlmClk""Ratata""Tick " #define LEN_VTELEMCHNS "\004" -#define TR_VTELEMCHNS "---\0""Tmr1""Tmr2""A1\0 ""A2\0 ""Tx\0 ""Rx\0 ""Alt\0""Rpm\0""Fuel""T1\0 ""T2\0 ""Spd\0""Dist""GAlt""Cell""A\0 ""mAh\0""AccX""AccY""AccZ""Hdg\0""VSpd""A1-\0""A2-\0""Alt-""Alt+""Rpm+""T1+\0""T2+\0""Spd+""A+\0 ""Dst+""Acc\0""Time" +#define TR_VTELEMCHNS "---\0""Tmr1""Tmr2""A1\0 ""A2\0 ""Tx\0 ""Rx\0 ""Alt\0""Rpm\0""Fuel""T1\0 ""T2\0 ""Spd\0""Dist""GAlt""Cell""Curr""Cnsp""AccX""AccY""AccZ""Hdg\0""VSpd""A1-\0""A2-\0""Alt-""Alt+""Rpm+""T1+\0""T2+\0""Spd+""Dst+""Cur+""Acc\0""Time" #ifdef IMPERIAL_UNITS #define LENGTH_UNIT "ft\0" @@ -149,7 +149,7 @@ #endif #define LEN_VTELEMUNIT "\003" -#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0" +#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) @@ -168,6 +168,9 @@ #define TR_VTELPROTO "" #endif +#define LEN_CURRENTSRC "\003" +#define TR_CURRENTSRC "Hub""A1\0""A2\0" + #define LEN_VARIOSRC "\006" #define TR_VARIOSRC "BaroV1""BaroV2""A1\0 ""A2\0" diff --git a/src/translations/de.h b/src/translations/de.h index d37c2c1aa..83cf6768e 100644 --- a/src/translations/de.h +++ b/src/translations/de.h @@ -139,7 +139,7 @@ #define TR_FUNCSOUNDS "Warn 1""Warn 2""Cheep ""Ring ""SciFi ""Robot ""Chirp ""Tada ""Crickt""Siren ""AlmClk""Ratata""Tick " #define LEN_VTELEMCHNS "\004" -#define TR_VTELEMCHNS "---\0""Tmr1""Tmr2""A1\0 ""A2\0 ""Tx\0 ""Rx\0 ""Alt\0""Rpm\0""Fuel""T1\0 ""T2\0 ""Spd\0""Dist""GAlt""Cell""A\0 ""mAh\0""AccX""AccY""AccZ""Hdg\0""VSpd""A1-\0""A2-\0""Alt-""Alt+""Rpm+""T1+\0""T2+\0""Spd+""A+\0 ""Dst+""Acc\0""Time" +#define TR_VTELEMCHNS "---\0""Tmr1""Tmr2""A1\0 ""A2\0 ""Tx\0 ""Rx\0 ""Alt\0""Rpm\0""Fuel""T1\0 ""T2\0 ""Spd\0""Dist""GAlt""Cell""Curr""Cnsp""AccX""AccY""AccZ""Hdg\0""VSpd""A1-\0""A2-\0""Alt-""Alt+""Rpm+""T1+\0""T2+\0""Spd+""Dst+""Cur+""Acc\0""Time" #ifdef IMPERIAL_UNITS #define LENGTH_UNIT "ft\0" @@ -150,7 +150,7 @@ #endif #define LEN_VTELEMUNIT "\003" -#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0" +#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) @@ -168,7 +168,10 @@ #else #define TR_VTELPROTO "" #endif - + +#define LEN_CURRENTSRC "\003" +#define TR_CURRENTSRC "Hub""A1\0""A2\0" + #define LEN_VARIOSRC "\006" #define TR_VARIOSRC "BaroV1""BaroV2""A1\0 ""A2\0" diff --git a/src/translations/en.h b/src/translations/en.h index bdf08e2f2..dbccfe17e 100644 --- a/src/translations/en.h +++ b/src/translations/en.h @@ -139,7 +139,7 @@ #define TR_FUNCSOUNDS "Warn1 ""Warn2 ""Cheep ""Ring ""SciFi ""Robot ""Chirp ""Tada ""Crickt""Siren ""AlmClk""Ratata""Tick " #define LEN_VTELEMCHNS "\004" -#define TR_VTELEMCHNS "---\0""Tmr1""Tmr2""A1\0 ""A2\0 ""Tx\0 ""Rx\0 ""Alt\0""Rpm\0""Fuel""T1\0 ""T2\0 ""Spd\0""Dist""GAlt""Cell""A\0 ""mAh\0""AccX""AccY""AccZ""Hdg\0""VSpd""A1-\0""A2-\0""Alt-""Alt+""Rpm+""T1+\0""T2+\0""Spd+""A+\0 ""Dst+""Acc\0""Time" +#define TR_VTELEMCHNS "---\0""Tmr1""Tmr2""A1\0 ""A2\0 ""Tx\0 ""Rx\0 ""Alt\0""Rpm\0""Fuel""T1\0 ""T2\0 ""Spd\0""Dist""GAlt""Cell""Curr""Cnsp""AccX""AccY""AccZ""Hdg\0""VSpd""A1-\0""A2-\0""Alt-""Alt+""Rpm+""T1+\0""T2+\0""Spd+""Dst+""Cur+""Acc\0""Time" #ifdef IMPERIAL_UNITS #define LENGTH_UNIT "ft\0" @@ -150,7 +150,7 @@ #endif #define LEN_VTELEMUNIT "\003" -#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0" +#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) @@ -169,6 +169,9 @@ #define TR_VTELPROTO "" #endif +#define LEN_CURRENTSRC "\003" +#define TR_CURRENTSRC "Hub""A1\0""A2\0" + #define LEN_VARIOSRC "\006" #define TR_VARIOSRC "BaroV1""BaroV2""A1\0 ""A2\0" diff --git a/src/translations/fr.h b/src/translations/fr.h index b0e6465d1..250bc16b7 100644 --- a/src/translations/fr.h +++ b/src/translations/fr.h @@ -133,7 +133,7 @@ #define TR_FUNCSOUNDS "Warn1 ""Warn2 ""Cheep ""Ring ""SciFi ""Robot ""Chirp ""Tada ""Crickt""Siren ""AlmClk""Ratata""Tick " #define LEN_VTELEMCHNS "\004" -#define TR_VTELEMCHNS "---\0""Chr1""Chr2""A1\0 ""A2\0 ""Tx\0 ""Rx\0 ""Alt\0""Rpm\0""Carb""T1\0 ""T2\0 ""Vit\0""Dist""AltG""Elem""A\0 ""mAh\0""AccX""AccY""AccZ""Cap\0""VitV""A1-\0""A2-\0""Alt-""Alt+""Rpm+""T1+\0""T2+\0""Vit+""A+\0 ""Dst+""Acc\0""Time" +#define TR_VTELEMCHNS "---\0""Chr1""Chr2""A1\0 ""A2\0 ""Tx\0 ""Rx\0 ""Alt\0""Rpm\0""Carb""T1\0 ""T2\0 ""Vit\0""Dist""AltG""Elem""Cour""Cnsm""AccX""AccY""AccZ""Cap\0""VitV""A1-\0""A2-\0""Alt-""Alt+""Rpm+""T1+\0""T2+\0""Vit+""Dst+""Cur+""Acc\0""Time" #ifdef IMPERIAL_UNITS #define LENGTH_UNIT "ft\0" @@ -144,7 +144,7 @@ #endif #define LEN_VTELEMUNIT "\003" -#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0" +#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) @@ -163,6 +163,9 @@ #define TR_VTELPROTO "" #endif +#define LEN_CURRENTSRC "\003" +#define TR_CURRENTSRC "Hub""A1\0""A2\0" + #define LEN_VARIOSRC "\006" #define TR_VARIOSRC "BaroV1""BaroV2""A1\0 ""A2\0" diff --git a/src/translations/it.h b/src/translations/it.h index 4eecfd1f5..641abbf38 100644 --- a/src/translations/it.h +++ b/src/translations/it.h @@ -138,7 +138,7 @@ #define TR_FUNCSOUNDS "Warn1 ""Warn2 ""Cheep ""Ring ""SciFi ""Robot ""Chirp ""Tada ""Crickt""Siren ""AlmClk""Ratata""Tick " #define LEN_VTELEMCHNS "\004" -#define TR_VTELEMCHNS "---\0""Tmr1""Tmr2""A1\0 ""A2\0 ""Tx\0 ""Rx\0 ""Alt\0""Rpm\0""Carb""T1\0 ""T2\0 ""Vel\0""Dist""GAlt""Cell""A\0 ""mAh\0""AccX""AccY""AccZ""Dir\0""VelV""A1-\0""A2-\0""Alt-""Alt+""Rpm+""T1+\0""T2+\0""Vel+""A+\0 ""Dst+""Acc\0""Time" +#define TR_VTELEMCHNS "---\0""Tmr1""Tmr2""A1\0 ""A2\0 ""Tx\0 ""Rx\0 ""Alt\0""Rpm\0""Carb""T1\0 ""T2\0 ""Vel\0""Dist""GAlt""Cell""Curr""Cnsp""AccX""AccY""AccZ""Dir\0""VelV""A1-\0""A2-\0""Alt-""Alt+""Rpm+""T1+\0""T2+\0""Vel+""Dst+""Cur+""Acc\0""Time" #ifdef IMPERIAL_UNITS #define LENGTH_UNIT "ft\0" @@ -149,7 +149,7 @@ #endif #define LEN_VTELEMUNIT "\003" -#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0" +#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) @@ -168,6 +168,9 @@ #define TR_VTELPROTO "" #endif +#define LEN_CURRENTSRC "\003" +#define TR_CURRENTSRC "Hub""A1\0""A2\0" + #define LEN_VARIOSRC "\006" #define TR_VARIOSRC "BaroV1""BaroV2""A1\0 ""A2\0" diff --git a/src/translations/se.h b/src/translations/se.h index 9201b6415..65953e848 100644 --- a/src/translations/se.h +++ b/src/translations/se.h @@ -133,7 +133,7 @@ #define TR_FUNCSOUNDS "Varn1 ""Varn2 ""F\200r ""Ring ""SciFi ""Robot ""Pip ""Tada ""Syrsa ""Siren ""Alarm ""Ratata""Tick " #define LEN_VTELEMCHNS "\004" -#define TR_VTELEMCHNS "---\0""Tmr1""Tmr2""A1\0 ""A2\0 ""Tx\0 ""Rx\0 ""H\202jd""Varv""Tank""T1\0 ""T2\0 ""Fart""Avst""GHjd""Batt""A\0 ""mAh\0""AccX""AccY""AccZ""Hdg\0""VFrt""A1-\0""A2-\0""Hjd-""Hjd+""Rpm+""T1+\0""T2+\0""Frt+""A+\0 ""Avs+""Acc\0""Tid\0" +#define TR_VTELEMCHNS "---\0""Tmr1""Tmr2""A1\0 ""A2\0 ""Tx\0 ""Rx\0 ""H\202jd""Varv""Tank""T1\0 ""T2\0 ""Fart""Avst""GHjd""Batt""Curr""Cnsp""AccX""AccY""AccZ""Hdg\0""VFrt""A1-\0""A2-\0""Hjd-""Hjd+""Rpm+""T1+\0""T2+\0""Frt+""Avs+""Cur+""Acc\0""Tid\0" #ifdef IMPERIAL_UNITS #define LENGTH_UNIT "fot" @@ -144,7 +144,7 @@ #endif #define LEN_VTELEMUNIT "\003" -#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0" +#define TR_VTELEMUNIT "v\0 ""A\0 ""m/s""-\0 " SPEED_UNIT LENGTH_UNIT "@\0 ""%\0 ""mA\0""mAh" #define STR_V (STR_VTELEMUNIT+1) #define STR_A (STR_VTELEMUNIT+4) @@ -163,6 +163,9 @@ #define TR_VTELPROTO "" #endif +#define LEN_CURRENTSRC "\003" +#define TR_CURRENTSRC "Hub""A1\0""A2\0" + #define LEN_VARIOSRC "\006" #define TR_VARIOSRC "BaroV1""BaroV2""A1 ""A2\0" diff --git a/util/tts.py b/util/tts.py index 3e19187cd..967171fe7 100644 --- a/util/tts.py +++ b/util/tts.py @@ -5,7 +5,8 @@ import os, sys, shutil, platform, subprocess def generate(str, idx): if platform.system() == "Windows": subprocess.Popen(["C:\Program Files\eSpeak\command_line\espeak.exe", "-w", "%04d.wav" % idx, str], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait() - subprocess.Popen(["D:\Perso\workspace\companion9x\AD4CONVERTER.EXE", "-E4", "%04d.WAV" % idx], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait() + if 'ad4' in sys.argv: + subprocess.Popen(["D:\Perso\workspace\companion9x\AD4CONVERTER.EXE", "-E4", "%04d.WAV" % idx], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait() if __name__ == "__main__":