diff --git a/src/Makefile b/src/Makefile index 949e57f94..4e3110c7d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -475,7 +475,7 @@ ifeq ($(PCB), ACT) 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 EEPROMSRC = eeprom_avr.cpp # TODO later eeprom_conversions.cpp CPPSRC += x9d/eeprom_driver.cpp x9d/pulses_driver.cpp act/keys_driver.cpp act/audio_driver.cpp - CPPSRC += sky9x/audio.cpp + CPPSRC += audio_arm.cpp PULSESSRC = pulses_arm.cpp CPPSRC += monitors_views.cpp endif @@ -484,14 +484,14 @@ ifeq ($(PCB), X9D) # X9D radio OPT = 2 CPPDEFS += -DPCBX9D -DCPUARM -DEEPROM_VARIANT=0 -DAUDIO -DPXX -DDSM2 -DDSM2_PPM - EXTRAINCDIRS += sky9x CoOS/kernel CoOS/portable + EXTRAINCDIRS += CoOS/kernel CoOS/portable EXTRAINCDIRS += x9d/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/inc x9d/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/CMSIS/Device/ST/STM32F2xx/Include BOARDSRC = x9d/board_x9d.cpp EXTRABOARDSRC += x9d/lcd_driver.cpp x9d/aspi.cpp x9d/i2c_ee.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 EEPROMSRC = eeprom_avr.cpp # TODO later eeprom_conversions.cpp PULSESSRC = pulses_arm.cpp - CPPSRC += sky9x/audio.cpp + CPPSRC += audio_arm.cpp CPPSRC += x9d/pwr_driver.cpp x9d/eeprom_driver.cpp x9d/pulses_driver.cpp x9d/keys_driver.cpp x9d/adc_driver.cpp x9d/trainer_driver.cpp x9d/audio_driver.cpp x9d/delays.cpp CPPSRC += bmp.cpp monitors_views.cpp SRC += x9d/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/CMSIS/Device/ST/STM32F2xx/Source/Templates/system_stm32f2xx.c @@ -536,8 +536,8 @@ ifeq ($(PCB), SKY9X) SRC += sky9x/MEDSdcard.c EEPROMSRC = eeprom_arm.cpp eeprom_conversions.cpp PULSESSRC = pulses_arm.cpp - CPPSRC += sky9x/audio.cpp haptic.cpp - CPPSRC += sky9x/pwr_driver.cpp sky9x/eeprom_driver.cpp sky9x/pulses_driver.cpp sky9x/keys_driver.cpp sky9x/audio_driver.cpp sky9x/haptic_driver.cpp sky9x/sdcard_driver.cpp sky9x/massstorage.cpp + CPPSRC += audio_arm.cpp haptic.cpp + CPPSRC += sky9x/pwr_driver.cpp sky9x/adc_driver.cpp sky9x/coproc_driver.cpp sky9x/rotenc_driver.cpp sky9x/eeprom_driver.cpp sky9x/pulses_driver.cpp sky9x/keys_driver.cpp sky9x/audio_driver.cpp sky9x/buzzer_driver.cpp sky9x/haptic_driver.cpp sky9x/sdcard_driver.cpp sky9x/massstorage.cpp ifeq ($(SDCARD), YES) EXTRAINCDIRS += FatFs FatFs/option @@ -571,7 +571,7 @@ ifeq ($(PCB), GRUVIN9X) EXTRABOARDSRC += stock/lcd_driver.cpp EEPROMSRC = eeprom_avr.cpp PULSESSRC = pulses_avr.cpp - CPPSRC += stock/audio.cpp haptic.cpp + CPPSRC += audio_avr.cpp haptic.cpp ifeq ($(SDCARD), YES) CPPDEFS += -DRTCLOCK @@ -602,7 +602,7 @@ ifeq ($(PCB), STD128) ifeq ($(AUDIO), YES) CPPDEFS += -DAUDIO - CPPSRC += stock/audio.cpp + CPPSRC += audio_avr.cpp else CPPSRC += beeper.cpp endif @@ -638,7 +638,7 @@ ifeq ($(PCB), STD) ifeq ($(AUDIO), YES) CPPDEFS += -DAUDIO - CPPSRC += stock/audio.cpp + CPPSRC += audio_avr.cpp else CPPSRC += beeper.cpp endif diff --git a/src/act/audio_driver.cpp b/src/act/audio_driver.cpp index c9896ba9e..111a4371a 100644 --- a/src/act/audio_driver.cpp +++ b/src/act/audio_driver.cpp @@ -34,26 +34,8 @@ #include "../open9x.h" -volatile uint8_t Buzzer_count ; - -// Must NOT be in flash, PDC needs a RAM source. -// Amplitude reduced to 30% to allow for voice volume -uint16_t Sine_values[] = -{ - 2048,2085,2123,2160,2197,2233,2268,2303,2336,2369, - 2400,2430,2458,2485,2510,2533,2554,2573,2590,2605, - 2618,2629,2637,2643,2646,2648,2646,2643,2637,2629, - 2618,2605,2590,2573,2554,2533,2510,2485,2458,2430, - 2400,2369,2336,2303,2268,2233,2197,2160,2123,2085, - 2048,2010,1972,1935,1898,1862,1826,1792,1758,1726, - 1695,1665,1637,1610,1585,1562,1541,1522,1505,1490, - 1477,1466,1458,1452,1448,1448,1448,1452,1458,1466, - 1477,1490,1505,1522,1541,1562,1585,1610,1637,1665, - 1695,1726,1758,1792,1826,1862,1898,1935,1972,2010 -}; - // Sound routines -void startSound() +void audioInit() { } @@ -71,29 +53,6 @@ void setFrequency(uint32_t frequency) } } -// Start TIMER1 at 100000Hz, used for DACC trigger -void start_timer1() -{ -} - - -// Configure DAC0 (or DAC1 for REVA) -// Not sure why PB14 has not be allocated to the DAC, although it is an EXTRA function -// So maybe it is automatically done -void initDac() -{ -} - -void end_sound() -{ -} - -// Set up for volume control (TWI0) -// Need PA3 and PA4 set to peripheral A -void init_twi() -{ -} - -void setVolume( unsigned char volume ) +void audioEnd() { } diff --git a/src/act/board_act.cpp b/src/act/board_act.cpp index 5d4efd369..d7e9b94e5 100644 --- a/src/act/board_act.cpp +++ b/src/act/board_act.cpp @@ -91,10 +91,6 @@ void interrupt5ms() // AUDIO_HEARTBEAT(); if ( ++pre_scale >= 2 ) { - /* if ( Buzzer_count ) { - if ( --Buzzer_count == 0 ) - buzzer_off() ; - } */ pre_scale = 0 ; per10ms(); } diff --git a/src/act/board_act.h b/src/act/board_act.h index a72605eb4..8cf4b7f84 100644 --- a/src/act/board_act.h +++ b/src/act/board_act.h @@ -87,7 +87,7 @@ extern volatile uint32_t Card_initialized; #define SD_GET_BLOCKNR() (0) #define SD_GET_SPEED() (0) -void soft_power_off(); +void pwrOff(); #define strcpy_P strcpy #define strcat_P strcat @@ -103,7 +103,7 @@ extern uint16_t sessionTimer; #define BOOTLOADER_REQUEST() (0/*usbPlugged()*/) -#define SLAVE_MODE() (0/*check_soft_power() == e_power_trainer*/) +#define SLAVE_MODE() (0/*pwrCheck() == e_power_trainer*/) #if !defined(SIMU) #define wdt_disable() @@ -111,7 +111,7 @@ extern uint16_t sessionTimer; #define wdt_reset() #endif -#define check_soft_power() e_power_on +#define pwrCheck() e_power_on #define setBacklight(xx) #define __BACKLIGHT_ON @@ -127,25 +127,27 @@ void eeWriteBlockCmp(const void *pointer_ram, uint16_t pointer_eeprom, size_t si #define NUM_VOL_LEVELS 24 -void startSound( void ) ; +void audioInit( void ) ; +void audioEnd( void ) ; + void setFrequency( uint32_t frequency ); uint32_t getFrequency(); -void start_timer1( void ); -void initDac( void ) ; -void end_sound( void ) ; + +#define dacFill(...) extern uint16_t *nextAudioData; extern uint16_t nextAudioSize; -inline void toneStart() +inline void dacStart() { } -inline void toneStop() +inline void dacStop() { } -extern void init_twi( void ) ; -extern void setVolume( register uint8_t volume ) ; +inline void setVolume( register uint8_t volume ) +{ +} #endif diff --git a/src/sky9x/audio.cpp b/src/audio_arm.cpp similarity index 95% rename from src/sky9x/audio.cpp rename to src/audio_arm.cpp index 98f4191c8..02ef5ce31 100644 --- a/src/sky9x/audio.cpp +++ b/src/audio_arm.cpp @@ -34,6 +34,22 @@ #include "../open9x.h" +// Must NOT be in flash, PDC needs a RAM source. +// Amplitude reduced to 30% to allow for voice volume +uint16_t Sine_values[] = +{ + 2048,2085,2123,2160,2197,2233,2268,2303,2336,2369, + 2400,2430,2458,2485,2510,2533,2554,2573,2590,2605, + 2618,2629,2637,2643,2646,2648,2646,2643,2637,2629, + 2618,2605,2590,2573,2554,2533,2510,2485,2458,2430, + 2400,2369,2336,2303,2268,2233,2197,2160,2123,2085, + 2048,2010,1972,1935,1898,1862,1826,1792,1758,1726, + 1695,1665,1637,1610,1585,1562,1541,1522,1505,1490, + 1477,1466,1458,1452,1448,1448,1448,1452,1458,1466, + 1477,1490,1505,1522,1541,1562,1585,1610,1637,1665, + 1695,1726,1758,1792,1826,1862,1898,1935,1972,2010 +}; + #if defined(SDCARD) const char * audioFilenames[] = { "inactiv", @@ -331,7 +347,7 @@ void AudioQueue::sdWakeup(AudioContext & context) } if (result != FR_OK) { - toneStop(); + dacStop(); memset(&fragment, 0, sizeof(fragment)); f_close(&context.wavFile); CoSetTmrCnt(audioTimer, (WAV_BUFFER_SIZE * 1000) / context.pcmFreq, 0); @@ -372,24 +388,15 @@ void AudioQueue::sdWakeup(AudioContext & context) read /= 2; -#if defined(PCBSKY9X) - register Dacc *dacptr = DACC; if (read) { state = AUDIO_PLAYING_WAV; - if (dacptr->DACC_ISR & DACC_ISR_TXBUFE) { - dacptr->DACC_TPR = CONVERT_PTR(wavSamplesBuffer); - dacptr->DACC_TCR = read; - CoSetFlag(audioFlag); - } - else if (dacptr->DACC_TNCR == 0) { - dacptr->DACC_TNPR = CONVERT_PTR(wavSamplesBuffer); - dacptr->DACC_TNCR = read; + if (dacQueue(wavSamplesBuffer, read)) { CoSetFlag(audioFlag); } else { nextAudioSize = read; nextAudioData = wavSamplesBuffer; - toneStart(); + dacStart(); CoSetTmrCnt(audioTimer, (WAV_BUFFER_SIZE * 500) / context.pcmFreq, 0); CoStartTmr(audioTimer); } @@ -401,7 +408,6 @@ void AudioQueue::sdWakeup(AudioContext & context) state = AUDIO_RESUMING; CoSetFlag(audioFlag); } -#endif } } else { @@ -428,14 +434,7 @@ void AudioQueue::wakeup() if (fragment.duration > 0) { if (state != AUDIO_PLAYING_TONE) { state = AUDIO_PLAYING_TONE; - -#if !defined(PCBX9D) && !defined(PCBACT) - register Dacc *dacptr = DACC; - dacptr->DACC_TPR = CONVERT_PTR(Sine_values); - dacptr->DACC_TNPR = CONVERT_PTR(Sine_values); - dacptr->DACC_TCR = 50 ; // words, 100 16 bit values - dacptr->DACC_TNCR = 50 ; // words, 100 16 bit values -#endif + dacFill(Sine_values, 50/*100 samples*/); } setFrequency(fragment.freq * 6100 / 4); @@ -449,7 +448,7 @@ void AudioQueue::wakeup() CoSetTmrCnt(audioTimer, fragment.duration*2, 0); fragment.duration = 0; } - toneStart(); + dacStart(); CoClearFlag(audioFlag); CoStartTmr(audioTimer); } @@ -457,7 +456,7 @@ void AudioQueue::wakeup() state = AUDIO_PLAYING_TONE; CoSetTmrCnt(audioTimer, fragment.pause*2, 0); fragment.pause = 0; - toneStop(); + dacStop(); CoClearFlag(audioFlag); CoStartTmr(audioTimer); } @@ -475,18 +474,12 @@ void AudioQueue::wakeup() else if (ridx == widx && prioIdx < 0 && backgroundContext.fragment.duration > 0) { if (state != AUDIO_PLAYING_TONE) { state = AUDIO_PLAYING_TONE; -#if !defined(PCBX9D) && !defined(PCBACT) - register Dacc *dacptr = DACC; - dacptr->DACC_TPR = CONVERT_PTR(Sine_values); - dacptr->DACC_TNPR = CONVERT_PTR(Sine_values); - dacptr->DACC_TCR = 50 ; // words, 100 16 bit values - dacptr->DACC_TNCR = 50 ; // words, 100 16 bit values -#endif + dacFill(Sine_values, 50/*100 samples*/); } CoSetTmrCnt(audioTimer, backgroundContext.fragment.duration*2, 0); backgroundContext.fragment.duration = 0; setFrequency(backgroundContext.fragment.freq * 6100 / 4); - toneStart(); + dacStart(); CoClearFlag(audioFlag); CoStartTmr(audioTimer); } @@ -497,7 +490,7 @@ void AudioQueue::wakeup() if (prioIdx >= 0) { ridx = prioIdx; prioIdx = -1; - toneStop(); + dacStop(); CoClearFlag(audioFlag); nextAudioData = NULL; if (state == AUDIO_PLAYING_WAV) { @@ -526,7 +519,7 @@ void AudioQueue::wakeup() else { memset(&fragment, 0, sizeof(fragment)); state = AUDIO_SLEEPING; - toneStop(); + dacStop(); } CoLeaveMutexSection(audioMutex); diff --git a/src/sky9x/audio.h b/src/audio_arm.h similarity index 96% rename from src/sky9x/audio.h rename to src/audio_arm.h index c4df6bc9d..fb863b9d5 100644 --- a/src/sky9x/audio.h +++ b/src/audio_arm.h @@ -43,6 +43,8 @@ #define BEEP_KEY_UP_FREQ (BEEP_DEFAULT_FREQ+5) #define BEEP_KEY_DOWN_FREQ (BEEP_DEFAULT_FREQ-5) +extern uint16_t Sine_values[]; + class ToneFragment { public: uint16_t freq; diff --git a/src/stock/audio.cpp b/src/audio_avr.cpp similarity index 100% rename from src/stock/audio.cpp rename to src/audio_avr.cpp diff --git a/src/stock/audio.h b/src/audio_avr.h similarity index 100% rename from src/stock/audio.h rename to src/audio_avr.h diff --git a/src/beeper.h b/src/beeper.h index f1183a88f..9a406784e 100644 --- a/src/beeper.h +++ b/src/beeper.h @@ -48,7 +48,7 @@ extern uint8_t hapticTick; #if defined(CPUARM) inline void _beep(uint8_t b) { - buzzer_sound(b); + buzzerSound(b); } #else inline void _beep(uint8_t b) diff --git a/src/eeprom_arm.cpp b/src/eeprom_arm.cpp index 007c74bea..db16e4c2a 100644 --- a/src/eeprom_arm.cpp +++ b/src/eeprom_arm.cpp @@ -471,9 +471,9 @@ void eeReadAll() ALERT(STR_EEPROMWARN, STR_BADEEPROMDATA, AU_BAD_EEPROM); - if (check_soft_power()==e_power_off) { + if (pwrCheck()==e_power_off) { // we don't want to store anything - soft_power_off(); // turn power off now + pwrOff(); // turn power off now } else { MESSAGE(STR_EEPROMWARN, STR_EEPROMFORMATTING, NULL, AU_EEPROM_FORMATTING); diff --git a/src/general_menus.cpp b/src/general_menus.cpp index 03d20ebb7..42f761d30 100644 --- a/src/general_menus.cpp +++ b/src/general_menus.cpp @@ -147,7 +147,7 @@ void menuGeneralSetup(uint8_t event) if ((m_posVert==ITEM_SETUP_DATE+1 || m_posVert==ITEM_SETUP_TIME+1) && s_editMode>0 && event == EVT_KEY_FIRST(KEY_ENTER)) { // set the date and time into RTC chip - rtc_settime(&t); + rtcSetTime(&t); } #endif diff --git a/src/gruvin9x/board_gruvin9x.cpp b/src/gruvin9x/board_gruvin9x.cpp index 97c92dc34..ba96baed1 100644 --- a/src/gruvin9x/board_gruvin9x.cpp +++ b/src/gruvin9x/board_gruvin9x.cpp @@ -164,7 +164,7 @@ ISR(USART1_RX_vect) #endif #endif // !SIMU -uint8_t check_soft_power() +uint8_t pwrCheck() { #if !defined(SIMU) && !defined(REV0) if ((PING & 0b00000010) && (~PINL & 0b01000000)) @@ -173,7 +173,7 @@ uint8_t check_soft_power() return e_power_on; } -void soft_power_off() +void pwrOff() { #ifndef REV0 PORTL = 0x7f; diff --git a/src/gruvin9x/rtc_driver.cpp b/src/gruvin9x/rtc_driver.cpp index 650a8c9f5..b5f25e989 100644 --- a/src/gruvin9x/rtc_driver.cpp +++ b/src/gruvin9x/rtc_driver.cpp @@ -249,7 +249,7 @@ int g9x_rtc_gettime (RTC *rtc) return 1; } -int g9x_rtc_settime (const RTC *rtc) +int g9x_rtcSetTime (const RTC *rtc) { BYTE buf[8]; @@ -278,7 +278,7 @@ void rtc_gettime(struct gtm * utm) utm->tm_wday = rtc.wday - 1; } -void rtc_settime(struct gtm * t) +void rtcSetTime(struct gtm * t) { g_rtcTime = gmktime(t); // update local timestamp and get wday calculated g_ms100 = 0; // start of next second begins now @@ -291,7 +291,7 @@ void rtc_settime(struct gtm * t) rtc.min = t->tm_min; rtc.sec = t->tm_sec; rtc.wday = t->tm_wday + 1; - g9x_rtc_settime(&rtc); + g9x_rtcSetTime(&rtc); } void rtcInit (void) diff --git a/src/open9x.cpp b/src/open9x.cpp index 71821f884..9d819ce2b 100644 --- a/src/open9x.cpp +++ b/src/open9x.cpp @@ -255,7 +255,7 @@ void per10ms() rtc_count++; } else { - read_coprocessor(true); + coprocReadData(true); } #endif g_ms100 = 0; @@ -1242,7 +1242,7 @@ void doSplash() #endif if (keyDown() || tsum!=inacSum) return; // wait for key release - if (check_soft_power()==e_power_off) return; + if (pwrCheck()==e_power_off) return; #if !defined(PCBSTD) && !defined(PCBX9D) if (curTime < get_tmr10ms()) { @@ -1313,7 +1313,7 @@ void checkTHR() int16_t v = thrAnaIn(thrchn); - if (check_soft_power()==e_power_off || keyDown() || v<=lowLim) + if (pwrCheck()==e_power_off || keyDown() || v<=lowLim) break; checkBacklight(); @@ -1367,7 +1367,7 @@ void checkSwitches() last_bad_switches = switches_states; } - if (check_soft_power()==e_power_off || keyDown()) return; // Usb on or power off + if (pwrCheck()==e_power_off || keyDown()) return; // Usb on or power off checkBacklight(); @@ -1385,7 +1385,7 @@ void alert(const pm_char * t, const pm_char *s MESSAGE_SOUND_ARG) { SIMU_SLEEP(1); - if (check_soft_power() == e_power_off) return; + if (pwrCheck() == e_power_off) return; if (keyDown()) return; // wait for key release @@ -3521,7 +3521,7 @@ void menusTask(void * pdata) { open9xInit(); - while (check_soft_power() != e_power_off) { + while (pwrCheck() != e_power_off) { perMain(); for (uint8_t i=0; i<5; i++) { usbMassStorage(); @@ -3563,7 +3563,7 @@ void menusTask(void * pdata) lcdRefresh(); lcdSetRefVolt(0); - soft_power_off(); // Only turn power off if necessary + pwrOff(); // Only turn power off if necessary } extern void audioTimerHandle(void); @@ -3636,7 +3636,7 @@ int main(void) #if defined(CPUARM) if (BOOTLOADER_REQUEST()) { - soft_power_off(); // Only turn power off if necessary + pwrOff(); // Only turn power off if necessary #if defined(HAPTIC) hapticOff(); @@ -3689,7 +3689,7 @@ int main(void) while(1) { #if defined(PCBGRUVIN9X) - if ((shutdown_state=check_soft_power()) > e_power_trainer) + if ((shutdown_state=pwrCheck()) > e_power_trainer) break; #endif @@ -3715,7 +3715,7 @@ int main(void) #endif lcd_clear() ; lcdRefresh() ; - soft_power_off(); // Only turn power off if necessary + pwrOff(); // Only turn power off if necessary wdt_disable(); while(1); // never return from main() - there is no code to return back, if any delays occurs in physical power it does dead loop. #endif diff --git a/src/open9x.h b/src/open9x.h index c18ddfede..19c7577dc 100644 --- a/src/open9x.h +++ b/src/open9x.h @@ -155,6 +155,21 @@ #define ROTARY_ENCODER_NAVIGATION #endif +#if defined(SIMU) +#ifndef FORCEINLINE +#define FORCEINLINE +#endif +#ifndef NOINLINE +#define NOINLINE +#endif +#define CONVERT_PTR(x) ((uint32_t)(uint64_t)(x)) +#else +#define FORCEINLINE inline __attribute__ ((always_inline)) +#define NOINLINE __attribute__ ((noinline)) +#define SIMU_SLEEP(x) +#define CONVERT_PTR(x) ((uint32_t)(x)) +#endif + /* #define HELI_VARIANT 0x0004 #define VOICE_VARIANT 0x0008 @@ -801,9 +816,9 @@ uint32_t switchState(EnumKeys enuk); #else bool switchState(EnumKeys enuk); #if defined(PCBGRUVIN9X) -uint8_t check_soft_power(); +uint8_t pwrCheck(); #else -#define check_soft_power() (e_power_on) +#define pwrCheck() (e_power_on) #endif #endif @@ -832,21 +847,6 @@ enum PerOutMode { e_perout_mode_noinput = e_perout_mode_notrainer+e_perout_mode_notrims+e_perout_mode_nosticks }; -#if defined(SIMU) -#ifndef FORCEINLINE -#define FORCEINLINE -#endif -#ifndef NOINLINE -#define NOINLINE -#endif -#define CONVERT_PTR(x) ((uint32_t)(uint64_t)(x)) -#else -#define FORCEINLINE inline __attribute__ ((always_inline)) -#define NOINLINE __attribute__ ((noinline)) -#define SIMU_SLEEP(x) -#define CONVERT_PTR(x) ((uint32_t)(x)) -#endif - // Fiddle to force compiler to use a pointer #define FORCE_INDIRECT(ptr) __asm__ __volatile__ ("" : "=e" (ptr) : "0" (ptr)) @@ -1318,9 +1318,9 @@ enum AUDIO_SOUNDS { #if defined(AUDIO) #if defined(CPUARM) -#include "sky9x/audio.h" +#include "audio_arm.h" #else -#include "stock/audio.h" +#include "audio_avr.h" #endif #else #include "beeper.h" diff --git a/src/rtc.h b/src/rtc.h index 099b39343..401f95b8f 100644 --- a/src/rtc.h +++ b/src/rtc.h @@ -59,7 +59,7 @@ void rtcInit(); #ifdef __cplusplus extern "C" { #endif -void rtc_settime(struct gtm * tm); +void rtcSetTime(struct gtm * tm); void gettime(struct gtm * tm); gtime_t gmktime (struct gtm *tm); #ifdef __cplusplus diff --git a/src/sky9x/adc_driver.cpp b/src/sky9x/adc_driver.cpp new file mode 100644 index 000000000..e629d5017 --- /dev/null +++ b/src/sky9x/adc_driver.cpp @@ -0,0 +1,112 @@ +/* + * Authors (alphabetical order) + * - Andre Bernet + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * open9x is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "../open9x.h" + +uint16_t Analog_values[NUMBER_ANALOG]; + +// Settings for mode register ADC_MR +// USEQ off - silicon problem, doesn't work +// TRANSFER = 1 +// TRACKTIM = 4 (5 clock periods) +// ANACH = 0 +// SETTLING = 1 (not used if ANACH = 0) +// STARTUP = 1 (8 clock periods) +// PRESCAL = 3.6 MHz clock (between 1 and 20MHz) +// FREERUN = 0 +// FWUP = 0 +// SLEEP = 0 +// LOWRES = 0 +// TRGSEL = 0 +// TRGEN = 0 (software trigger only) +void adcInit() +{ + register Adc *padc ; + register uint32_t timer ; + + timer = ( Master_frequency / (3600000*2) ) << 8 ; + // Enable peripheral clock ADC = bit 29 + PMC->PMC_PCER0 |= 0x20000000L ; // Enable peripheral clock to ADC + padc = ADC ; + padc->ADC_MR = 0x14110000 | timer ; // 0001 0100 0001 0001 xxxx xxxx 0000 0000 + padc->ADC_ACR = ADC_ACR_TSON ; // Turn on temp sensor +#if defined(REVA) + padc->ADC_CHER = 0x0000E23E ; // channels 1,2,3,4,5,9,13,14,15 +#else + padc->ADC_CHER = 0x0000E33E ; // channels 1,2,3,4,5,8,9,13,14,15 +#endif + padc->ADC_CGR = 0 ; // Gain = 1, all channels + padc->ADC_COR = 0 ; // Single ended, 0 offset, all channels +} + +// Read 8 (9 for REVB) ADC channels +// Documented bug, must do them 1 by 1 +void adcRead() +{ + register Adc *padc; + register uint32_t y; + register uint32_t x; + + padc = ADC; + y = padc->ADC_ISR; // Clear EOC flags + for (y = NUMBER_ANALOG+1; --y > 0;) { + padc->ADC_CR = 2; // Start conversion + x = 0; + while ((padc->ADC_ISR & 0x01000000) == 0) { + // wait for DRDY flag + if (++x > 1000000) { + break; // Software timeout + } + } + x = padc->ADC_LCDR; // Clear DRSY flag + } + // Next bit may be done using the PDC + Analog_values[0] = ADC->ADC_CDR1; + Analog_values[1] = ADC->ADC_CDR2; + Analog_values[2] = ADC->ADC_CDR3; + Analog_values[3] = ADC->ADC_CDR4; + Analog_values[4] = ADC->ADC_CDR5; + Analog_values[5] = ADC->ADC_CDR9; + Analog_values[6] = ADC->ADC_CDR13; + Analog_values[7] = ADC->ADC_CDR14; + +#if !defined(REVA) + Analog_values[8] = ADC->ADC_CDR8 ; +#endif + + temperature = (((int32_t)temperature * 7) + ((((int32_t)ADC->ADC_CDR15 - 838) * 621) >> 11)) >> 3; // Filter it + if (get_tmr10ms() >= 100 && temperature > maxTemperature) { + maxTemperature = temperature; + } +} diff --git a/src/sky9x/audio_driver.cpp b/src/sky9x/audio_driver.cpp index 8fd19096a..9a944800a 100644 --- a/src/sky9x/audio_driver.cpp +++ b/src/sky9x/audio_driver.cpp @@ -34,73 +34,6 @@ #include "../open9x.h" -volatile uint8_t Buzzer_count ; - -// Must NOT be in flash, PDC needs a RAM source. -// Amplitude reduced to 30% to allow for voice volume -uint16_t Sine_values[] = -{ - 2048,2085,2123,2160,2197,2233,2268,2303,2336,2369, - 2400,2430,2458,2485,2510,2533,2554,2573,2590,2605, - 2618,2629,2637,2643,2646,2648,2646,2643,2637,2629, - 2618,2605,2590,2573,2554,2533,2510,2485,2458,2430, - 2400,2369,2336,2303,2268,2233,2197,2160,2123,2085, - 2048,2010,1972,1935,1898,1862,1826,1792,1758,1726, - 1695,1665,1637,1610,1585,1562,1541,1522,1505,1490, - 1477,1466,1458,1452,1448,1448,1448,1452,1458,1466, - 1477,1490,1505,1522,1541,1562,1585,1610,1637,1665, - 1695,1726,1758,1792,1826,1862,1898,1935,1972,2010 -}; - -// Sound routines -void startSound() -{ - register Pio *pioptr ; - - start_timer1() ; - initDac() ; - init_twi() ; - - pioptr = PIOA ; -#if defined(REVA) - pioptr->PIO_CODR = 0x00010000L ; // Set bit A16 OFF - pioptr->PIO_PER = 0x00010000L ; // Enable bit A16 (Stock buzzer) - pioptr->PIO_OER = 0x00010000L ; // Set bit A16 as output -#else - pioptr->PIO_CODR = 0x02000000L ; // Set bit A25 OFF - pioptr->PIO_PER = 0x02000000L ; // Enable bit A25 (Stock buzzer) - pioptr->PIO_OER = 0x02000000L ; // Set bit A25 as output -#endif -} - -#if defined(REVA) -void buzzer_on() -{ - PIOA->PIO_SODR = 0x00010000L ; // Set bit A16 ON -} - -void buzzer_off() -{ - PIOA->PIO_CODR = 0x00010000L ; // Set bit A16 ON -} -#else -void buzzer_on() -{ - PIOA->PIO_SODR = 0x02000000L ; // Set bit A25 ON -} - -void buzzer_off() -{ - PIOA->PIO_CODR = 0x02000000L ; // Set bit A25 ON -} -#endif - -void buzzer_sound( uint8_t time ) -{ - buzzer_on() ; - Buzzer_count = time ; -} - uint32_t currentFrequency = 0; uint32_t getFrequency() @@ -131,7 +64,7 @@ void setFrequency(uint32_t frequency) } // Start TIMER1 at 100000Hz, used for DACC trigger -void start_timer1() +void dacTimerStart() { register Tc *ptc ; register uint32_t timer ; @@ -152,16 +85,17 @@ void start_timer1() // Sound_g.Frequency = 1000 ; } - // Configure DAC0 (or DAC1 for REVA) // Not sure why PB14 has not be allocated to the DAC, although it is an EXTRA function // So maybe it is automatically done -void initDac() +void dacInit() { - register Dacc *dacptr ; + dacTimerStart() ; PMC->PMC_PCER0 |= 0x40000000L ; // Enable peripheral clock to DAC - dacptr = DACC ; + + register Dacc *dacptr = DACC; + #if defined(REVA) dacptr->DACC_MR = 0x0B010215L ; // 0000 1011 0000 0001 0000 0010 0001 0101 dacptr->DACC_CHER = 2 ; // Enable channel 1 @@ -171,12 +105,11 @@ void initDac() #endif dacptr->DACC_CDR = 2048 ; // Half amplitude -// Data for PDC must NOT be in flash, PDC needs a RAM source. - dacptr->DACC_TPR = CONVERT_PTR(Sine_values); - dacptr->DACC_TNPR = CONVERT_PTR(Sine_values); - dacptr->DACC_TCR = 50 ; // words, 100 16 bit values - dacptr->DACC_TNCR = 50 ; // words, 100 16 bit values + + // Data for PDC must NOT be in flash, PDC needs a RAM source. + dacFill(Sine_values, 50/*100 samples*/); dacptr->DACC_PTCR = DACC_PTCR_TXTEN ; + NVIC_EnableIRQ(DACC_IRQn) ; } @@ -190,7 +123,7 @@ extern "C" void DAC_IRQHandler() nextAudioData = NULL; } else { - toneStop(); + dacStop(); } } else if (audioQueue.state == AUDIO_PLAYING_TONE){ @@ -198,11 +131,30 @@ extern "C" void DAC_IRQHandler() DACC->DACC_TNCR = 50 ; // words, 100 16 bit values } else { - toneStop(); + dacStop(); } } -void end_sound() +// Sound routines +void audioInit() +{ + register Pio *pioptr ; + + dacInit() ; + + pioptr = PIOA ; +#if defined(REVA) + pioptr->PIO_CODR = 0x00010000L ; // Set bit A16 OFF + pioptr->PIO_PER = 0x00010000L ; // Enable bit A16 (Stock buzzer) + pioptr->PIO_OER = 0x00010000L ; // Set bit A16 as output +#else + pioptr->PIO_CODR = 0x02000000L ; // Set bit A25 OFF + pioptr->PIO_PER = 0x02000000L ; // Enable bit A25 (Stock buzzer) + pioptr->PIO_OER = 0x02000000L ; // Set bit A25 as output +#endif +} + +void audioEnd() { DACC->DACC_IDR = DACC_IDR_ENDTX ; DACC->DACC_IDR = DACC_IDR_TXBUFE ; @@ -213,273 +165,29 @@ void end_sound() PMC->PMC_PCER0 &= ~0x40000000L ; // Disable peripheral clock to DAC } -// Set up for volume control (TWI0) -// Need PA3 and PA4 set to peripheral A -void init_twi() -{ - register Pio *pioptr ; - register uint32_t timing ; - - PMC->PMC_PCER0 |= 0x00080000L ; // Enable peripheral clock to TWI0 - - /* Configure PIO */ - pioptr = PIOA ; - pioptr->PIO_ABCDSR[0] &= ~0x00000018 ; // Peripheral A - pioptr->PIO_ABCDSR[1] &= ~0x00000018 ; // Peripheral A - pioptr->PIO_PDR = 0x00000018 ; // Assign to peripheral - - timing = Master_frequency * 5 / 1000000 ; // 5uS high and low - timing += 15 - 4 ; - timing /= 16 ; - timing |= timing << 8 ; - - TWI0->TWI_CWGR = 0x00040000 | timing ; // TWI clock set - TWI0->TWI_CR = TWI_CR_MSEN | TWI_CR_SVDIS ; // Master mode enable - TWI0->TWI_MMR = 0x002F0000 ; // Device 5E (>>1) and master is writing - NVIC_EnableIRQ(TWI0_IRQn) ; -} - -static int8_t Volume_required ; -static uint8_t Volume_read_pending ; -static uint8_t CoProc_read_pending ; -static uint8_t CoProc_write_pending ; -static uint8_t CoProc_appgo_pending ; -uint8_t Volume_read ; -uint8_t Coproc_read ; -int8_t Coproc_temp ; -int8_t Coproc_maxtemp=-127 ; -int8_t Coproc_valid ; -bool get_onlytemp; -static uint8_t *Twi_read_address ; -static uint8_t TwiOperation ; - -#define TWI_NONE 0 -#define TWI_READ_VOL 1 -#define TWI_WRITE_VOL 2 -#define TWI_READ_COPROC 3 -#define TWI_COPROC_APPGO 4 -#define TWI_WAIT_STOP 5 -#define TWI_WRITE_COPROC 6 - -// Commands to the coprocessor bootloader/application -#define TWI_CMD_PAGEUPDATE 0x01 // TWI Command to program a flash page -#define TWI_CMD_EXECUTEAPP 0x02 // TWI Command to jump to the application program -#define TWI_CMD_SETREAD_ADDRESS 0x03 // TWI Command to set address to read from -#define TWI_CMD_WRITE_DATA 0x04 // TWI Command send data to the application -#define COPROC_RX_BUXSIZE 22 -uint8_t Co_proc_status[COPROC_RX_BUXSIZE] ; -uint8_t *Co_proc_write_ptr ; -uint32_t Co_proc_write_count ; - - -// This is called from an interrupt routine, or -// interrupts must be disabled while it is called -// from elsewhere. -void i2c_check_for_request() -{ - if ( TWI0->TWI_IMR & TWI_IMR_TXCOMP ) - { - return ; // Busy - } - - if ( Volume_required >= 0 ) // Set volume to this value - { - TWI0->TWI_MMR = 0x002F0000 ; // Device 5E (>>1) and master is writing - TwiOperation = TWI_WRITE_VOL ; - TWI0->TWI_THR = Volume_required ; // Send data - Volume_required = -1 ; - TWI0->TWI_IER = TWI_IER_TXCOMP ; - TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx - } - else if ( CoProc_read_pending ) - { - Coproc_valid = 0 ; - CoProc_read_pending = 0 ; - TWI0->TWI_MMR = 0x00351000 ; // Device 35 and master is reading - TwiOperation = TWI_READ_COPROC ; -#ifndef SIMU - TWI0->TWI_RPR = (uint32_t)&Co_proc_status[0] ; -#endif - TWI0->TWI_RCR = COPROC_RX_BUXSIZE - 1 ; - if ( TWI0->TWI_SR & TWI_SR_RXRDY ) - { - (void) TWI0->TWI_RHR ; - } - TWI0->TWI_PTCR = TWI_PTCR_RXTEN ; // Start transfers - TWI0->TWI_CR = TWI_CR_START ; // Start Rx - TWI0->TWI_IER = TWI_IER_RXBUFF | TWI_IER_TXCOMP ; - } - else if ( Volume_read_pending ) - { - Volume_read_pending = 0 ; - TWI0->TWI_MMR = 0x002F1000 ; // Device 5E (>>1) and master is reading - TwiOperation = TWI_READ_VOL ; - Twi_read_address = &Volume_read ; - TWI0->TWI_CR = TWI_CR_START | TWI_CR_STOP ; // Start and stop Tx - TWI0->TWI_IER = TWI_IER_TXCOMP ; - } - else if ( CoProc_appgo_pending ) - { - CoProc_appgo_pending = 0 ; - TWI0->TWI_MMR = 0x00350000 ; // Device 35 and master is writing - TwiOperation = TWI_COPROC_APPGO ; - TWI0->TWI_THR = TWI_CMD_EXECUTEAPP ; // Send appgo command - TWI0->TWI_IER = TWI_IER_TXCOMP ; - TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx - } - else if ( CoProc_write_pending ) - { - CoProc_write_pending = 0 ; - TWI0->TWI_MMR = 0x00350000 ; // Device 35 and master is writing - TwiOperation = TWI_WRITE_COPROC ; -#ifndef SIMU - TWI0->TWI_TPR = (uint32_t)Co_proc_write_ptr ; -#endif - TWI0->TWI_TCR = Co_proc_write_count ; - TWI0->TWI_THR = TWI_CMD_WRITE_DATA ; // Send write command - TWI0->TWI_PTCR = TWI_PTCR_TXTEN ; // Start data transfer - TWI0->TWI_IER = TWI_IER_TXBUFE | TWI_IER_TXCOMP ; - } -} - -static const uint8_t Volume_scale[NUM_VOL_LEVELS] = +static const int8_t volumeScale[NUM_VOL_LEVELS] = { 0, 2, 4, 6, 8, 10, 13, 17, 22, 27, 33, 40, 64, 82, 96, 105, 112, 117, 120, 122, 124, 125, 126, 127 } ; -void setVolume( unsigned char volume ) +void setVolume(uint8_t volume) { -// PMC->PMC_PCER0 |= 0x00080000L ; // Enable peripheral clock to TWI0 - - if ( volume >= NUM_VOL_LEVELS ) - { - volume = NUM_VOL_LEVELS - 1 ; - } - volume = Volume_scale[volume] ; - Volume_required = volume ; + coprocVolumeRequired = volumeScale[min(volume, NUM_VOL_LEVELS-1)]; __disable_irq() ; - i2c_check_for_request() ; + coprocCheck() ; __enable_irq() ; } -void read_volume() +#if 0 +void getVolume() { - Volume_read_pending = 1 ; + coprocVolumeReadPending = 1 ; __disable_irq() ; - i2c_check_for_request() ; + coprocCheck() ; __enable_irq() ; } - -void read_coprocessor(bool onlytemp) -{ - get_onlytemp = onlytemp; - CoProc_read_pending = 1 ; - __disable_irq() ; - i2c_check_for_request() ; - __enable_irq() ; -} - -void write_coprocessor( uint8_t *ptr, uint32_t count ) -{ - Co_proc_write_ptr = ptr ; - Co_proc_write_count = count ; - CoProc_write_pending = 1 ; - __disable_irq() ; - i2c_check_for_request() ; - __enable_irq() ; -} - -void appgo_coprocessor() -{ - CoProc_appgo_pending = 1 ; - __disable_irq() ; - i2c_check_for_request() ; - __enable_irq() ; -} - -#if !defined(SIMU) -extern "C" void TWI0_IRQHandler() -{ - if ( TwiOperation == TWI_READ_VOL ) - { - if ( TWI0->TWI_SR & TWI_SR_RXRDY ) - { - *Twi_read_address = TWI0->TWI_RHR ; // Read data - } - } - - if ( TwiOperation == TWI_READ_COPROC ) - { - if ( TWI0->TWI_SR & TWI_SR_RXBUFF ) - { - TWI0->TWI_IDR = TWI_IDR_RXBUFF ; - TwiOperation = TWI_WAIT_STOP ; - TWI0->TWI_CR = TWI_CR_STOP ; // Stop Rx - TWI0->TWI_RCR = 1 ; // Last byte - return ; - } - else - { - Coproc_valid = -1 ; - } - } - - if ( TwiOperation == TWI_WAIT_STOP ) - { - Coproc_valid = 1 ; - Coproc_read = Co_proc_status[0] ; - if ( Coproc_read & 0x80 ) { - // Bootloader - CoProc_appgo_pending = 1 ; // Action application - } - else { - // Got data from tiny app - // Set the date and time - struct gtm utm; - if (!get_onlytemp) { - utm.tm_sec = Co_proc_status[1] ; - utm.tm_min = Co_proc_status[2] ; - utm.tm_hour = Co_proc_status[3] ; - utm.tm_mday = Co_proc_status[4] ; - utm.tm_mon = Co_proc_status[5] - 1; - utm.tm_year = (Co_proc_status[6] + ( Co_proc_status[7] << 8 )) - 1900; - g_rtcTime = gmktime(&utm); - } - Coproc_temp = Co_proc_status[8]; - if (Coproc_temp > Coproc_maxtemp) - Coproc_maxtemp=Coproc_temp; - } - TWI0->TWI_PTCR = TWI_PTCR_RXTDIS ; // Stop transfers - if ( TWI0->TWI_SR & TWI_SR_RXRDY ) { - (void) TWI0->TWI_RHR ; // Discard any rubbish data - } - } - -// if ( TwiOperation == TWI_WRITE_VOL ) -// { - -// } - - if ( TwiOperation == TWI_WRITE_COPROC ) - { - if ( TWI0->TWI_SR & TWI_SR_TXBUFE ) - { - TWI0->TWI_IDR = TWI_IDR_TXBUFE ; - TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx - TWI0->TWI_PTCR = TWI_PTCR_TXTDIS ; // Stop transfers - TwiOperation = TWI_NONE ; - return ; - } - } - - TWI0->TWI_IDR = TWI_IDR_TXCOMP | TWI_IDR_TXBUFE | TWI_PTCR_TXTDIS ; - if ( TWI0->TWI_SR & TWI_SR_NACK ) - { - } - TwiOperation = TWI_NONE ; - i2c_check_for_request() ; -} #endif + diff --git a/src/sky9x/audio_driver.h b/src/sky9x/audio_driver.h index 5e9ddb00d..fd76df51f 100644 --- a/src/sky9x/audio_driver.h +++ b/src/sky9x/audio_driver.h @@ -37,40 +37,53 @@ #define NUM_VOL_LEVELS 24 -extern void startSound( void ) ; -extern void buzzer_on( void ) ; -extern void buzzer_off( void ) ; -extern void buzzer_sound( uint8_t time ) ; -extern void setFrequency( uint32_t frequency ) ; -extern uint32_t getFrequency(); -extern void start_timer1( void ) ; -extern void initDac( void ) ; -extern void end_sound( void ) ; -extern void write_coprocessor( uint8_t *ptr, uint32_t count ) ; -extern void read_coprocessor( bool onlytemp=false ) ; -extern uint8_t Coproc_read ; -extern int8_t Coproc_valid ; -extern int8_t Coproc_temp ; -extern int8_t Coproc_maxtemp ; +void audioInit( void ) ; +void audioEnd( void ) ; + +void setFrequency( uint32_t frequency ) ; +uint32_t getFrequency(); extern uint16_t *nextAudioData; extern uint16_t nextAudioSize; -inline void toneStart() +inline void dacStart() { PMC->PMC_PCER0 |= 0x40000000L ; // Enable peripheral clock to DAC DACC->DACC_IER = DACC_IER_ENDTX ; } -inline void toneStop() +inline void dacStop() { DACC->DACC_IDR = DACC_IDR_ENDTX ; // Disable interrupt } -extern volatile uint8_t Buzzer_count ; +void setVolume(uint8_t volume); -extern void init_twi( void ) ; -extern void setVolume( register uint8_t volume ) ; -extern "C" void TWI0_IRQHandler (void) ; +inline void dacFill(uint16_t *data, uint16_t size) +{ + register Dacc *dacptr = DACC; + dacptr->DACC_TPR = CONVERT_PTR(data); + dacptr->DACC_TNPR = CONVERT_PTR(data); + dacptr->DACC_TCR = size; // words + dacptr->DACC_TNCR = size; // words +} + +inline uint16_t dacQueue(uint16_t *data, uint16_t size) +{ + register Dacc *dacptr = DACC; + if (dacptr->DACC_ISR & DACC_ISR_TXBUFE) { + dacptr->DACC_TPR = CONVERT_PTR(data); + dacptr->DACC_TCR = size; + return size; + } + else if (dacptr->DACC_TNCR == 0) { + dacptr->DACC_TNPR = CONVERT_PTR(data); + dacptr->DACC_TNCR = size; + return size; + } + else { + return 0; + } +} #endif diff --git a/src/sky9x/board_sky9x.cpp b/src/sky9x/board_sky9x.cpp index ee8bb1cc1..7fcc81f0a 100644 --- a/src/sky9x/board_sky9x.cpp +++ b/src/sky9x/board_sky9x.cpp @@ -34,9 +34,6 @@ #include "../open9x.h" -void pwrInit(); -void eepromInit(); - #if defined(DEBUG) && !defined(SIMU) void DEBUG_UART_Configure( uint32_t baudrate, uint32_t masterClock); void DEBUG_UART_Stop(); @@ -127,7 +124,7 @@ inline void setup_switches() #ifdef SIMU #define end_ppm_capture() -#define stop_rotary_encoder() +#define rotencEnd() #define sam_boot() #else @@ -341,46 +338,6 @@ void end_ppm_capture() NVIC_DisableIRQ(TC3_IRQn) ; } -static void init_rotary_encoder() -{ - configure_pins( PIO_PC19 | PIO_PC21, PIN_ENABLE | PIN_INPUT | PIN_PORTC | PIN_PULLUP ) ; // 19 and 21 are rotary encoder - configure_pins( PIO_PB6, PIN_ENABLE | PIN_INPUT | PIN_PORTB | PIN_PULLUP ) ; // rotary encoder switch - PIOC->PIO_IER = PIO_PC19 | PIO_PC21 ; - NVIC_EnableIRQ(PIOC_IRQn) ; -} - -static void stop_rotary_encoder() -{ - NVIC_DisableIRQ(PIOC_IRQn) ; - PIOC->PIO_IDR = PIO_PC19 | PIO_PC21 ; -} - -volatile uint32_t Rotary_position ; -extern "C" void PIOC_IRQHandler() -{ - register uint32_t dummy; - - dummy = PIOC->PIO_ISR ; // Read and clear status register - (void) dummy ; // Discard value - prevents compiler warning - - dummy = PIOC->PIO_PDSR ; // Read Rotary encoder (PC19, PC21) - dummy >>= 19 ; - dummy &= 0x05 ; // pick out the three bits - if ( dummy != ( Rotary_position & 0x05 ) ) - { - if ( ( Rotary_position & 0x01 ) ^ ( ( dummy & 0x04) >> 2 ) ) - { - incRotaryEncoder(0, +1); - } - else - { - incRotaryEncoder(0, -1); - } - Rotary_position &= ~0x45 ; - Rotary_position |= dummy ; - } -} - void interrupt5ms() { static uint32_t pre_scale ; // Used to get 10 Hz counter @@ -389,12 +346,9 @@ void interrupt5ms() AUDIO_HEARTBEAT(); if ( ++pre_scale >= 2 ) { - if ( Buzzer_count ) { - if ( --Buzzer_count == 0 ) - buzzer_off() ; - } - pre_scale = 0 ; - per10ms(); + BUZZER_HEARTBEAT(); + pre_scale = 0 ; + per10ms(); } } @@ -409,40 +363,6 @@ extern "C" void TC2_IRQHandler() interrupt5ms(); } -// Settings for mode register ADC_MR -// USEQ off - silicon problem, doesn't work -// TRANSFER = 1 -// TRACKTIM = 4 (5 clock periods) -// ANACH = 0 -// SETTLING = 1 (not used if ANACH = 0) -// STARTUP = 1 (8 clock periods) -// PRESCAL = 3.6 MHz clock (between 1 and 20MHz) -// FREERUN = 0 -// FWUP = 0 -// SLEEP = 0 -// LOWRES = 0 -// TRGSEL = 0 -// TRGEN = 0 (software trigger only) -inline void init_adc() -{ - register Adc *padc ; - register uint32_t timer ; - - timer = ( Master_frequency / (3600000*2) ) << 8 ; - // Enable peripheral clock ADC = bit 29 - PMC->PMC_PCER0 |= 0x20000000L ; // Enable peripheral clock to ADC - padc = ADC ; - padc->ADC_MR = 0x14110000 | timer ; // 0001 0100 0001 0001 xxxx xxxx 0000 0000 - padc->ADC_ACR = ADC_ACR_TSON ; // Turn on temp sensor -#if defined(REVA) - padc->ADC_CHER = 0x0000E23E ; // channels 1,2,3,4,5,9,13,14,15 -#else - padc->ADC_CHER = 0x0000E33E ; // channels 1,2,3,4,5,8,9,13,14,15 -#endif - padc->ADC_CGR = 0 ; // Gain = 1, all channels - padc->ADC_COR = 0 ; // Single ended, 0 offset, all channels -} - // PWM used for PPM generation, and LED Backlight // Output pin PB5 not used, PA17 used as PWMH3 peripheral C // PWM peripheral ID = 31 (0x80000000) @@ -619,17 +539,15 @@ void configure_pins( uint32_t pins, uint16_t config ) void boardInit() { - // register uint32_t goto_usb ; register Pio *pioptr ; - // Debug variable - // uint32_t both_on ; MATRIX->CCFG_SYSIO |= 0x000000F0L ; // Disable syspins, enable B4,5,6,7 PMC->PMC_PCER0 = (1<PIO_PER = PIO_PA21 ; // Enable bit A21 (EXT3) pioptr->PIO_OER = PIO_PA21 ; // Set bit A21 as output pioptr->PIO_SODR = PIO_PA21 ; // Set bit A21 ON @@ -691,69 +609,29 @@ void boardInit() start_timer2() ; start_timer0() ; - init_adc() ; + adcInit() ; init_pwm() ; __enable_irq() ; - startSound() ; - codecsInit(); + audioInit() ; + + coprocInit() ; + eepromInit(); - init_rotary_encoder(); + rotencInit(); init_SDcard(); } #endif -uint16_t Analog_values[NUMBER_ANALOG] ; uint8_t temperature = 0; // Raw temp reading uint8_t maxTemperature = 0 ; // Raw temp reading -// Read 8 (9 for REVB) ADC channels -// Documented bug, must do them 1 by 1 -void adcRead() -{ - register Adc *padc; - register uint32_t y; - register uint32_t x; - - padc = ADC; - y = padc->ADC_ISR; // Clear EOC flags - for (y = NUMBER_ANALOG+1; --y > 0;) { - padc->ADC_CR = 2; // Start conversion - x = 0; - while ((padc->ADC_ISR & 0x01000000) == 0) { - // wait for DRDY flag - if (++x > 1000000) { - break; // Software timeout - } - } - x = padc->ADC_LCDR; // Clear DRSY flag - } - // Next bit may be done using the PDC - Analog_values[0] = ADC->ADC_CDR1; - Analog_values[1] = ADC->ADC_CDR2; - Analog_values[2] = ADC->ADC_CDR3; - Analog_values[3] = ADC->ADC_CDR4; - Analog_values[4] = ADC->ADC_CDR5; - Analog_values[5] = ADC->ADC_CDR9; - Analog_values[6] = ADC->ADC_CDR13; - Analog_values[7] = ADC->ADC_CDR14; - -#if !defined(REVA) - Analog_values[8] = ADC->ADC_CDR8 ; -#endif - - temperature = (((int32_t)temperature * 7) + ((((int32_t)ADC->ADC_CDR15 - 838) * 621) >> 11)) >> 3; // Filter it - if (get_tmr10ms() >= 100 && temperature > maxTemperature) { - maxTemperature = temperature; - } -} - #define RX_UART_BUFFER_SIZE 32 struct t_rxUartBuffer @@ -872,12 +750,12 @@ void usbBootloader() // This might be replaced by a software reset // Any interrupts that have been enabled must be disabled here // BEFORE calling sam_boot() - stop_rotary_encoder(); + rotencEnd(); endPdcUsartReceive() ; // Terminate any serial reception end_bt_tx_interrupt() ; end_ppm_capture() ; end_spi() ; - end_sound() ; + audioEnd() ; TC0->TC_CHANNEL[2].TC_IDR = TC_IDR0_CPCS ; TC0->TC_CHANNEL[0].TC_CCR = TC_CCR0_CLKDIS ; diff --git a/src/sky9x/board_sky9x.h b/src/sky9x/board_sky9x.h index d7f29e22e..7dbb33201 100644 --- a/src/sky9x/board_sky9x.h +++ b/src/sky9x/board_sky9x.h @@ -38,11 +38,6 @@ #include #include "board.h" #include "audio_driver.h" -#include "haptic_driver.h" - -#if defined(BLUETOOTH) -#include "bluetooth.h" -#endif extern "C" { extern void init_SDcard(); @@ -127,35 +122,74 @@ extern uint32_t Current_used; extern uint16_t sessionTimer; #endif -void soft_power_off(); - #if defined(REVC) #define BOOTLOADER_REQUEST() (usbPlugged()) #else -#define BOOTLOADER_REQUEST() (check_soft_power() == e_power_usb) +#define BOOTLOADER_REQUEST() (pwrCheck() == e_power_usb) #endif -#define SLAVE_MODE() (check_soft_power() == e_power_trainer) +#define SLAVE_MODE() (pwrCheck() == e_power_trainer) #define JACK_PPM_OUT() PIOC->PIO_PDR = PIO_PC22 #define JACK_PPM_IN() PIOC->PIO_PER = PIO_PC22 void setSticksGain(uint8_t gains); -uint32_t spi_operation( register uint8_t *tx, register uint8_t *rx, register uint32_t count ); - +// WDT driver #if !defined(SIMU) #define wdt_disable() #define wdt_enable(x) WDT->WDT_MR = 0x3FFF217F; #define wdt_reset() WDT->WDT_CR = 0xA5000001 #endif -uint32_t check_soft_power(); - +// Backlight driver #define setBacklight(xx) PWM->PWM_CH_NUM[0].PWM_CDTYUPD = xx #define __BACKLIGHT_ON (PWM->PWM_CH_NUM[0].PWM_CDTY = g_eeGeneral.backlightBright) #define __BACKLIGHT_OFF (PWM->PWM_CH_NUM[0].PWM_CDTY = 100) #define IS_BACKLIGHT_ON() (PWM->PWM_CH_NUM[0].PWM_CDTY != 100) +// ADC driver +void adcInit(); void adcRead(void); +extern uint16_t Analog_values[]; + +// Buzzer driver +void buzzerSound(uint8_t duration); +void buzzerHeartbeat(); +#define BUZZER_HEARTBEAT buzzerHeartbeat + +// Coproc driver +void coprocInit(); +void coprocWriteData(uint8_t *data, uint32_t size); +void coprocReadData(bool onlytemp=false); +void coprocCheck(); +extern int8_t coprocVolumeRequired; +extern uint8_t coprocVolumeReadPending; +extern uint8_t Coproc_read; +extern int8_t Coproc_valid; +extern int8_t Coproc_temp; +extern int8_t Coproc_maxtemp; + +// Haptic driver +void hapticOff(void) ; +void hapticOn(uint32_t pwmPercent); + +// BlueTooth driver +#if defined(BLUETOOTH) +void btInit(); +void btTask(void* pdata); +void btPushByte(uint8_t data); +#endif + +// Power driver +void pwrInit(); +void pwrOff(); +uint32_t pwrCheck(); + +// EEPROM driver +void eepromInit(); + +// Rotary Encoder driver +void rotencInit(); +void rotencEnd(); #endif diff --git a/src/sky9x/bluetooth.h b/src/sky9x/buzzer_driver.cpp similarity index 64% rename from src/sky9x/bluetooth.h rename to src/sky9x/buzzer_driver.cpp index a0915bbb8..f23bffd7e 100644 --- a/src/sky9x/bluetooth.h +++ b/src/sky9x/buzzer_driver.cpp @@ -1,6 +1,6 @@ /* * Authors (alphabetical order) - * - Andre Bernet + * - Andre Bernet * - Bertrand Songis * - Bryan J. Rentoul (Gruvin) * - Cameron Weeks @@ -32,11 +32,42 @@ * */ -#ifndef bluetooth_h -#define bluetooth_h +#include "../open9x.h" -void btInit(); -void btTask(void* pdata); -void btPushByte(uint8_t data); +volatile uint8_t buzzerCount ; +#if defined(REVA) +void buzzerOn() +{ + PIOA->PIO_SODR = 0x00010000L ; // Set bit A16 ON +} + +void buzzerOff() +{ + PIOA->PIO_CODR = 0x00010000L ; // Set bit A16 ON +} +#else +void buzzerOn() +{ + PIOA->PIO_SODR = 0x02000000L ; // Set bit A25 ON +} + +void buzzerOff() +{ + PIOA->PIO_CODR = 0x02000000L ; // Set bit A25 ON +} #endif + +void buzzerSound(uint8_t duration) +{ + buzzerOn(); + buzzerCount = duration; +} + +void buzzerHeartbeat() +{ + if (buzzerCount) { + if (--buzzerCount == 0) + buzzerOff(); + } +} diff --git a/src/sky9x/coproc_driver.cpp b/src/sky9x/coproc_driver.cpp new file mode 100644 index 000000000..ad83aedf3 --- /dev/null +++ b/src/sky9x/coproc_driver.cpp @@ -0,0 +1,277 @@ +/* + * Authors (alphabetical order) + * - Andre Bernet + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * open9x is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "../open9x.h" + +int8_t coprocVolumeRequired ; +uint8_t coprocVolumeReadPending ; +uint8_t coprocReadDataPending ; +uint8_t coprocWriteDataPending ; +uint8_t CoProc_appgo_pending ; +uint8_t Volume_read ; +uint8_t Coproc_read ; +int8_t Coproc_temp ; +int8_t Coproc_maxtemp=-127 ; +int8_t Coproc_valid ; +bool get_onlytemp; +static uint8_t *Twi_read_address ; +static uint8_t TwiOperation ; + +#define TWI_NONE 0 +#define TWI_READ_VOL 1 +#define TWI_WRITE_VOL 2 +#define TWI_READ_COPROC 3 +#define TWI_COPROC_APPGO 4 +#define TWI_WAIT_STOP 5 +#define TWI_WRITE_COPROC 6 + +// Commands to the coprocessor bootloader/application +#define TWI_CMD_PAGEUPDATE 0x01 // TWI Command to program a flash page +#define TWI_CMD_EXECUTEAPP 0x02 // TWI Command to jump to the application program +#define TWI_CMD_SETREAD_ADDRESS 0x03 // TWI Command to set address to read from +#define TWI_CMD_WRITE_DATA 0x04 // TWI Command send data to the application +#define COPROC_RX_BUXSIZE 22 +uint8_t Co_proc_status[COPROC_RX_BUXSIZE] ; +uint8_t *coprocWriteDataPtr ; +uint32_t coprocWriteDataSize ; + + +// This is called from an interrupt routine, or +// interrupts must be disabled while it is called +// from elsewhere. +void coprocCheck() +{ + if ( TWI0->TWI_IMR & TWI_IMR_TXCOMP ) + { + return ; // Busy + } + + if ( coprocVolumeRequired >= 0 ) // Set volume to this value + { + TWI0->TWI_MMR = 0x002F0000 ; // Device 5E (>>1) and master is writing + TwiOperation = TWI_WRITE_VOL ; + TWI0->TWI_THR = coprocVolumeRequired ; // Send data + coprocVolumeRequired = -1 ; + TWI0->TWI_IER = TWI_IER_TXCOMP ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx + } + else if (coprocReadDataPending) + { + Coproc_valid = 0 ; + coprocReadDataPending = 0 ; + TWI0->TWI_MMR = 0x00351000 ; // Device 35 and master is reading + TwiOperation = TWI_READ_COPROC ; +#ifndef SIMU + TWI0->TWI_RPR = (uint32_t)&Co_proc_status[0] ; +#endif + TWI0->TWI_RCR = COPROC_RX_BUXSIZE - 1 ; + if ( TWI0->TWI_SR & TWI_SR_RXRDY ) + { + (void) TWI0->TWI_RHR ; + } + TWI0->TWI_PTCR = TWI_PTCR_RXTEN ; // Start transfers + TWI0->TWI_CR = TWI_CR_START ; // Start Rx + TWI0->TWI_IER = TWI_IER_RXBUFF | TWI_IER_TXCOMP ; + } + else if (coprocVolumeReadPending) + { + coprocVolumeReadPending = 0 ; + TWI0->TWI_MMR = 0x002F1000 ; // Device 5E (>>1) and master is reading + TwiOperation = TWI_READ_VOL ; + Twi_read_address = &Volume_read ; + TWI0->TWI_CR = TWI_CR_START | TWI_CR_STOP ; // Start and stop Tx + TWI0->TWI_IER = TWI_IER_TXCOMP ; + } + else if ( CoProc_appgo_pending ) + { + CoProc_appgo_pending = 0 ; + TWI0->TWI_MMR = 0x00350000 ; // Device 35 and master is writing + TwiOperation = TWI_COPROC_APPGO ; + TWI0->TWI_THR = TWI_CMD_EXECUTEAPP ; // Send appgo command + TWI0->TWI_IER = TWI_IER_TXCOMP ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx + } + else if ( coprocWriteDataPending ) + { + coprocWriteDataPending = 0 ; + TWI0->TWI_MMR = 0x00350000 ; // Device 35 and master is writing + TwiOperation = TWI_WRITE_COPROC ; +#ifndef SIMU + TWI0->TWI_TPR = (uint32_t)coprocWriteDataPtr ; +#endif + TWI0->TWI_TCR = coprocWriteDataSize ; + TWI0->TWI_THR = TWI_CMD_WRITE_DATA ; // Send write command + TWI0->TWI_PTCR = TWI_PTCR_TXTEN ; // Start data transfer + TWI0->TWI_IER = TWI_IER_TXBUFE | TWI_IER_TXCOMP ; + } +} + +void coprocReadData(bool onlytemp) +{ + get_onlytemp = onlytemp; + coprocReadDataPending = 1 ; + __disable_irq() ; + coprocCheck() ; + __enable_irq() ; +} + +void coprocWriteData(uint8_t *data, uint32_t size) +{ + coprocWriteDataPtr = data; + coprocWriteDataSize = size; + coprocWriteDataPending = 1; + __disable_irq(); + coprocCheck(); + __enable_irq(); +} + +#if 0 +void appgo_coprocessor() +{ + CoProc_appgo_pending = 1 ; + __disable_irq() ; + coprocCheck() ; + __enable_irq() ; +} +#endif + +// Set up for volume control (TWI0) +// Need PA3 and PA4 set to peripheral A +void coprocInit() +{ + register Pio *pioptr ; + register uint32_t timing ; + + PMC->PMC_PCER0 |= 0x00080000L ; // Enable peripheral clock to TWI0 + + /* Configure PIO */ + pioptr = PIOA ; + pioptr->PIO_ABCDSR[0] &= ~0x00000018 ; // Peripheral A + pioptr->PIO_ABCDSR[1] &= ~0x00000018 ; // Peripheral A + pioptr->PIO_PDR = 0x00000018 ; // Assign to peripheral + + timing = Master_frequency * 5 / 1000000 ; // 5uS high and low + timing += 15 - 4 ; + timing /= 16 ; + timing |= timing << 8 ; + + TWI0->TWI_CWGR = 0x00040000 | timing ; // TWI clock set + TWI0->TWI_CR = TWI_CR_MSEN | TWI_CR_SVDIS ; // Master mode enable + TWI0->TWI_MMR = 0x002F0000 ; // Device 5E (>>1) and master is writing + NVIC_EnableIRQ(TWI0_IRQn) ; +} + +#if !defined(SIMU) +extern "C" void TWI0_IRQHandler() +{ + if ( TwiOperation == TWI_READ_VOL ) + { + if ( TWI0->TWI_SR & TWI_SR_RXRDY ) + { + *Twi_read_address = TWI0->TWI_RHR ; // Read data + } + } + + if ( TwiOperation == TWI_READ_COPROC ) + { + if ( TWI0->TWI_SR & TWI_SR_RXBUFF ) + { + TWI0->TWI_IDR = TWI_IDR_RXBUFF ; + TwiOperation = TWI_WAIT_STOP ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Rx + TWI0->TWI_RCR = 1 ; // Last byte + return ; + } + else + { + Coproc_valid = -1 ; + } + } + + if ( TwiOperation == TWI_WAIT_STOP ) + { + Coproc_valid = 1 ; + Coproc_read = Co_proc_status[0] ; + if ( Coproc_read & 0x80 ) { + // Bootloader + CoProc_appgo_pending = 1 ; // Action application + } + else { + // Got data from tiny app + // Set the date and time + struct gtm utm; + if (!get_onlytemp) { + utm.tm_sec = Co_proc_status[1] ; + utm.tm_min = Co_proc_status[2] ; + utm.tm_hour = Co_proc_status[3] ; + utm.tm_mday = Co_proc_status[4] ; + utm.tm_mon = Co_proc_status[5] - 1; + utm.tm_year = (Co_proc_status[6] + ( Co_proc_status[7] << 8 )) - 1900; + g_rtcTime = gmktime(&utm); + } + Coproc_temp = Co_proc_status[8]; + if (Coproc_temp > Coproc_maxtemp) + Coproc_maxtemp=Coproc_temp; + } + TWI0->TWI_PTCR = TWI_PTCR_RXTDIS ; // Stop transfers + if ( TWI0->TWI_SR & TWI_SR_RXRDY ) { + (void) TWI0->TWI_RHR ; // Discard any rubbish data + } + } + +// if ( TwiOperation == TWI_WRITE_VOL ) +// { + +// } + + if ( TwiOperation == TWI_WRITE_COPROC ) + { + if ( TWI0->TWI_SR & TWI_SR_TXBUFE ) + { + TWI0->TWI_IDR = TWI_IDR_TXBUFE ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx + TWI0->TWI_PTCR = TWI_PTCR_TXTDIS ; // Stop transfers + TwiOperation = TWI_NONE ; + return ; + } + } + + TWI0->TWI_IDR = TWI_IDR_TXCOMP | TWI_IDR_TXBUFE | TWI_PTCR_TXTDIS ; + if ( TWI0->TWI_SR & TWI_SR_NACK ) + { + } + TwiOperation = TWI_NONE ; + coprocCheck() ; +} +#endif diff --git a/src/sky9x/haptic_driver.h b/src/sky9x/haptic_driver.h deleted file mode 100644 index 990e5a840..000000000 --- a/src/sky9x/haptic_driver.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Authors (alphabetical order) - * - Andre Bernet - * - Bertrand Songis - * - Bryan J. Rentoul (Gruvin) - * - Cameron Weeks - * - Erez Raviv - * - Jean-Pierre Parisy - * - Karl Szmutny - * - Michael Blandford - * - Michal Hlavinka - * - Pat Mackenzie - * - Philip Moss - * - Rob Thomson - * - Romolo Manfredini - * - Thomas Husterer - * - * open9x is based on code named - * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, - * er9x by Erez Raviv: http://code.google.com/p/er9x/, - * and the original (and ongoing) project by - * Thomas Husterer, th9x: http://code.google.com/p/th9x/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef haptic_driver_h -#define haptic_driver_h - -extern void hapticOff(void) ; -extern void hapticOn( uint32_t pwmPercent ) ; - -#endif diff --git a/src/sky9x/pwr_driver.cpp b/src/sky9x/pwr_driver.cpp index 5a868a220..4013e5d93 100644 --- a/src/sky9x/pwr_driver.cpp +++ b/src/sky9x/pwr_driver.cpp @@ -34,7 +34,7 @@ #include "../open9x.h" -uint32_t check_soft_power() +uint32_t pwrCheck() { #ifdef SIMU return e_power_on; @@ -83,7 +83,7 @@ uint32_t check_soft_power() } // turn off soft power -void soft_power_off() +void pwrOff() { #if !defined(REVA) configure_pins( PIO_PA8, PIN_ENABLE | PIN_OUTPUT | PIN_LOW | PIN_PORTA | PIN_NO_PULLUP ) ; diff --git a/src/sky9x/rotenc_driver.cpp b/src/sky9x/rotenc_driver.cpp new file mode 100644 index 000000000..a49b7346d --- /dev/null +++ b/src/sky9x/rotenc_driver.cpp @@ -0,0 +1,75 @@ +/* + * Authors (alphabetical order) + * - Andre Bernet + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * open9x is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "../open9x.h" + +void rotencInit() +{ + configure_pins( PIO_PC19 | PIO_PC21, PIN_ENABLE | PIN_INPUT | PIN_PORTC | PIN_PULLUP ) ; // 19 and 21 are rotary encoder + configure_pins( PIO_PB6, PIN_ENABLE | PIN_INPUT | PIN_PORTB | PIN_PULLUP ) ; // rotary encoder switch + PIOC->PIO_IER = PIO_PC19 | PIO_PC21 ; + NVIC_EnableIRQ(PIOC_IRQn) ; +} + +void rotencEnd() +{ + NVIC_DisableIRQ(PIOC_IRQn) ; + PIOC->PIO_IDR = PIO_PC19 | PIO_PC21 ; +} + +volatile uint32_t Rotary_position ; +extern "C" void PIOC_IRQHandler() +{ + register uint32_t dummy; + + dummy = PIOC->PIO_ISR ; // Read and clear status register + (void) dummy ; // Discard value - prevents compiler warning + + dummy = PIOC->PIO_PDSR ; // Read Rotary encoder (PC19, PC21) + dummy >>= 19 ; + dummy &= 0x05 ; // pick out the three bits + if ( dummy != ( Rotary_position & 0x05 ) ) + { + if ( ( Rotary_position & 0x01 ) ^ ( ( dummy & 0x04) >> 2 ) ) + { + incRotaryEncoder(0, +1); + } + else + { + incRotaryEncoder(0, -1); + } + Rotary_position &= ~0x45 ; + Rotary_position |= dummy ; + } +} diff --git a/src/sky9x/rtc_driver.cpp b/src/sky9x/rtc_driver.cpp index bac2c2965..1489b5614 100644 --- a/src/sky9x/rtc_driver.cpp +++ b/src/sky9x/rtc_driver.cpp @@ -40,7 +40,7 @@ struct t_i2cTime uint8_t Time[7] ; } I2CTime ; -void rtc_settime(struct gtm * t) +void rtcSetTime(struct gtm * t) { g_rtcTime = gmktime(t); // update local timestamp and get wday calculated g_ms100 = 0; // start of next second begins now @@ -51,12 +51,12 @@ void rtc_settime(struct gtm * t) I2CTime.Time[2] = t->tm_hour ; I2CTime.Time[3] = t->tm_mday ; I2CTime.Time[4] = t->tm_mon+1 ; - I2CTime.Time[5] = (uint8_t) (t->tm_year+1900) ; - I2CTime.Time[6] = (t->tm_year+1900) >> 8 ; - write_coprocessor( (uint8_t *) &I2CTime, 8 ) ; + I2CTime.Time[5] = (uint8_t) (t->tm_year+1900); + I2CTime.Time[6] = (t->tm_year+1900) >> 8; + coprocWriteData((uint8_t *) &I2CTime, 8); } void rtcInit() { - read_coprocessor(); + coprocReadData(); } diff --git a/src/x9d/audio_driver.cpp b/src/x9d/audio_driver.cpp index 15a3531a6..061748775 100644 --- a/src/x9d/audio_driver.cpp +++ b/src/x9d/audio_driver.cpp @@ -34,29 +34,6 @@ #include "../open9x.h" -volatile uint8_t Buzzer_count ; - -// Must NOT be in flash, PDC needs a RAM source. -// Amplitude reduced to 30% to allow for voice volume -uint16_t Sine_values[] = -{ - 2048,2085,2123,2160,2197,2233,2268,2303,2336,2369, - 2400,2430,2458,2485,2510,2533,2554,2573,2590,2605, - 2618,2629,2637,2643,2646,2648,2646,2643,2637,2629, - 2618,2605,2590,2573,2554,2533,2510,2485,2458,2430, - 2400,2369,2336,2303,2268,2233,2197,2160,2123,2085, - 2048,2010,1972,1935,1898,1862,1826,1792,1758,1726, - 1695,1665,1637,1610,1585,1562,1541,1522,1505,1490, - 1477,1466,1458,1452,1448,1448,1448,1452,1458,1466, - 1477,1490,1505,1522,1541,1562,1585,1610,1637,1665, - 1695,1726,1758,1792,1826,1862,1898,1935,1972,2010 -}; - -// Sound routines -void startSound() -{ -} - uint32_t currentFrequency = 0; uint32_t getFrequency() @@ -68,41 +45,91 @@ void setFrequency(uint32_t frequency) { if (currentFrequency != frequency) { currentFrequency = frequency; + + register uint32_t timer = (PERI1_FREQUENCY * TIMER_MULT_APB1) / frequency - 1 ; // MCK/8 and 100 000 Hz + + TIM6->CR1 &= ~TIM_CR1_CEN ; + TIM6->CNT = 0 ; + TIM6->ARR = limit(2, timer, 65535) ; + TIM6->CR1 |= TIM_CR1_CEN ; } } -// Start TIMER1 at 100000Hz, used for DACC trigger -void start_timer1() +// Start TIMER6 at 100000Hz, used for DAC trigger +void dacTimerInit() { -} + // Now for timer 6 + RCC->APB1ENR |= RCC_APB1ENR_TIM6EN ; // Enable clock + TIM6->PSC = 0 ; // Max speed + TIM6->ARR = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 100000 - 1 ; // 10 uS, 100 kHz + TIM6->CR2 = 0 ; + TIM6->CR2 = 0x20 ; + TIM6->CR1 = TIM_CR1_CEN ; +} // Configure DAC0 (or DAC1 for REVA) // Not sure why PB14 has not be allocated to the DAC, although it is an EXTRA function // So maybe it is automatically done -void initDac() +void dacInit() { + dacTimerInit(); + + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN ; // Enable portA clock + configure_pins( 0x0010, PIN_ANALOG | PIN_PORTA ) ; + RCC->APB1ENR |= RCC_APB1ENR_DACEN ; // Enable clock + RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN ; // Enable DMA1 clock + + // Chan 7, 16-bit wide, Medium priority, memory increments + DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA + DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits + DMA1_Stream5->CR = DMA_SxCR_CHSEL_0 | DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_2 | DMA_SxCR_PL_0 | + DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_CIRC ; + DMA1_Stream5->PAR = (uint32_t) &DAC->DHR12R1 ; + DMA1_Stream5->M0AR = (uint32_t) Sine_values ; + DMA1_Stream5->FCR = 0x05 ; //DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0 ; + DMA1_Stream5->NDTR = 100 ; + + DAC->DHR12R1 = 2010 ; + DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag + DAC->CR = DAC_CR_TEN1 | DAC_CR_EN1 ; // Enable DAC + NVIC_EnableIRQ(TIM6_DAC_IRQn) ; + NVIC_EnableIRQ(DMA1_Stream5_IRQn) ; } -void end_sound() +// Sound routines +void audioInit() { + dacInit() ; + + // TODO - for volume, shared with EEPROM? } -// Set up for volume control (TWI0) -// Need PA3 and PA4 set to peripheral A -void init_twi() +void audioEnd() { + DAC->CR = 0 ; + TIM6->CR1 = 0 ; + // Also need to turn off any possible interrupts + NVIC_DisableIRQ(TIM6_DAC_IRQn) ; + NVIC_DisableIRQ(DMA1_Stream5_IRQn) ; } -void setVolume( unsigned char volume ) +#ifndef SIMU +extern "C" void TIM6_DAC_IRQHandler() { + DAC->CR &= ~DAC_CR_DMAEN1 ; // Stop DMA requests + DAC->CR &= ~DAC_CR_DMAUDRIE1 ; // Stop underrun interrupt + DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag } -/* -void read_volume() + +extern "C" void DMA1_Stream5_IRQHandler() { -} */ - + DMA1_Stream5->CR &= ~DMA_SxCR_TCIE ; // Stop interrupt + DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear flags +} +#endif +#if 0 static void Audio_GPIO_Init() { GPIO_InitTypeDef GPIO_InitStructure; @@ -192,3 +219,4 @@ void audioInit() #error "DMA is not initialized" #endif } +#endif diff --git a/src/x9d/audio_driver.h b/src/x9d/audio_driver.h new file mode 100644 index 000000000..ea6796986 --- /dev/null +++ b/src/x9d/audio_driver.h @@ -0,0 +1,78 @@ +/* + * Authors (alphabetical order) + * - Andre Bernet + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * open9x is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef audio_driver_h +#define audio_driver_h + +extern void audioInit( void ) ; +extern void audioEnd( void ) ; + +#define NUM_VOL_LEVELS 24 + +extern void setFrequency( uint32_t frequency ) ; +extern uint32_t getFrequency(); + +extern uint16_t *nextAudioData; +extern uint16_t nextAudioSize; + +inline void dacStart() +{ + DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits + DMA1_Stream5->CR |= DMA_SxCR_CIRC | DMA_SxCR_EN ; // Enable DMA channel + DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag + DAC->CR |= DAC_CR_EN1 | DAC_CR_DMAEN1 ; // Enable DAC +} + +inline void dacStop() +{ + DMA1_Stream5->CR &= ~DMA_SxCR_CIRC ; +} + +inline void dacFill(uint16_t *data, uint16_t size) +{ + DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA channel + DMA1_Stream5->M0AR = CONVERT_PTR(data); + DMA1_Stream5->NDTR = size*2; +} + +inline uint16_t dacQueue(uint16_t *data, uint16_t size) +{ + return size; +} + +inline void setVolume( unsigned char volume ) +{ +} + +#endif diff --git a/src/x9d/board_x9d.cpp b/src/x9d/board_x9d.cpp index 2093e4810..9f1bdb7a1 100644 --- a/src/x9d/board_x9d.cpp +++ b/src/x9d/board_x9d.cpp @@ -146,13 +146,9 @@ void interrupt5ms() static uint32_t pre_scale ; // Used to get 10 Hz counter // HAPTIC_HEARTBEAT(); - // AUDIO_HEARTBEAT(); + AUDIO_HEARTBEAT(); if ( ++pre_scale >= 2 ) { - /* if ( Buzzer_count ) { - if ( --Buzzer_count == 0 ) - buzzer_off() ; - } */ pre_scale = 0 ; per10ms(); } diff --git a/src/x9d/board_x9d.h b/src/x9d/board_x9d.h index 2812c9805..ab09fb4de 100644 --- a/src/x9d/board_x9d.h +++ b/src/x9d/board_x9d.h @@ -48,6 +48,7 @@ #include "hal.h" #include "aspi.h" #include "i2c_ee.h" +#include "audio_driver.h" #define PERI1_FREQUENCY 30000000 #define PERI2_FREQUENCY 60000000 @@ -79,7 +80,7 @@ uint8_t getTemperature(); #define SD_GET_BLOCKNR() (0) #define SD_GET_SPEED() (0) -void soft_power_off(); +void pwrOff(); #define strcpy_P strcpy #define strcat_P strcat @@ -95,7 +96,7 @@ extern uint16_t sessionTimer; #define BOOTLOADER_REQUEST() (0/*usbPlugged()*/) -#define SLAVE_MODE() (0/*check_soft_power() == e_power_trainer*/) +#define SLAVE_MODE() (0/*pwrCheck() == e_power_trainer*/) #if !defined(SIMU) #define wdt_disable() @@ -103,7 +104,7 @@ extern uint16_t sessionTimer; #define wdt_reset() #endif -uint32_t check_soft_power(); +uint32_t pwrCheck(); #define setBacklight(xx) #define __BACKLIGHT_ON GPIO_SetBits(GPIOB, GPIO_Pin_BL) @@ -122,7 +123,6 @@ void pwrInit(); void eepromInit(); // TODO check it's not in another include void delaysInit(); void adcInit(); -void audioInit(); void debugInit(); void adcRead(); @@ -138,27 +138,4 @@ void uartSendChar(uint8_t c); void delaysInit(void); void delay_01us(uint16_t nb); -#define NUM_VOL_LEVELS 24 - -void startSound( void ) ; -void setFrequency( uint32_t frequency ); -uint32_t getFrequency(); -void start_timer1( void ); -void initDac( void ) ; -void end_sound( void ) ; - -extern uint16_t *nextAudioData; -extern uint16_t nextAudioSize; - -inline void toneStart() -{ -} - -inline void toneStop() -{ -} - -extern void init_twi( void ) ; -extern void setVolume( register uint8_t volume ) ; - #endif diff --git a/src/x9d/delays.cpp b/src/x9d/delays.cpp index bd96bdaa1..6734436e1 100644 --- a/src/x9d/delays.cpp +++ b/src/x9d/delays.cpp @@ -45,7 +45,6 @@ void delaysInit(void) TIM13->DIER = 0; } - void delay_01us(uint16_t nb) { TIM13->EGR = 1; diff --git a/src/x9d/i2c_ee.c b/src/x9d/i2c_ee.c index dd1ab2bb7..8500163d0 100644 --- a/src/x9d/i2c_ee.c +++ b/src/x9d/i2c_ee.c @@ -124,7 +124,7 @@ void I2C_SEND_DATA(char SendByte) short i=8; while (i--) { SCL_L; - I2C_delay(); + // I2C_delay(); if (SendByte & 0x80) SDA_H; else diff --git a/src/x9d/pwr_driver.cpp b/src/x9d/pwr_driver.cpp index de9d8eac5..8f28f703a 100644 --- a/src/x9d/pwr_driver.cpp +++ b/src/x9d/pwr_driver.cpp @@ -34,12 +34,12 @@ #include "../open9x.h" -void soft_power_off() +void pwrOff() { GPIO_ResetBits(GPIOPWR,PIN_MCU_PWR); } -uint32_t check_soft_power() +uint32_t pwrCheck() { #if defined(SIMU) return e_power_on; diff --git a/src/x9d/rtc_driver.cpp b/src/x9d/rtc_driver.cpp index a6735712c..0adb89df2 100644 --- a/src/x9d/rtc_driver.cpp +++ b/src/x9d/rtc_driver.cpp @@ -34,7 +34,7 @@ #include "../open9x.h" -void rtc_settime(struct gtm * t) +void rtcSetTime(struct gtm * t) { RTC_TimeTypeDef RTC_TimeStruct; RTC_DateTypeDef RTC_DateStruct; diff --git a/src/x9d/trainer_driver.cpp b/src/x9d/trainer_driver.cpp index c03d70848..57c8b17b3 100644 --- a/src/x9d/trainer_driver.cpp +++ b/src/x9d/trainer_driver.cpp @@ -91,7 +91,7 @@ void init_trainer_ppm() TIM8->CCR4 = 600 ; // 300 uS pulse TIM8->BDTR = TIM_BDTR_MOE ; TIM8->EGR = 1 ; - TIM8->DIER = TIM_DIER_UDE ; + // TIM8->DIER = TIM_DIER_UDE ; TIM8->SR &= ~TIM_SR_UIF ; // Clear flag TIM8->SR &= ~TIM_SR_CC2IF ; // Clear flag @@ -103,6 +103,15 @@ void init_trainer_ppm() NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn) ; } +// TODO - testing +void stop_trainer_ppm() +{ + configure_pins( 0x0200, PIN_INPUT | PIN_PORTC ) ; + TIM8->CR1 &= ~TIM_CR1_CEN ; // Stop counter + NVIC_DisableIRQ(TIM8_CC_IRQn) ; // Stop Interrupt + NVIC_DisableIRQ(TIM8_UP_TIM13_IRQn) ; // Stop Interrupt +} + extern "C" void TIM8_CC_IRQHandler() { TIM8->DIER &= ~TIM_DIER_CC2IE ; // stop this interrupt @@ -175,3 +184,4 @@ extern "C" void TIM3_IRQHandler() } } } +