From d396e85fe022287cc81f8428004ce960b1e4e6b2 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Thu, 5 Dec 2013 11:06:58 +0100 Subject: [PATCH 01/13] 9XR-PRO support. Still not finished. --- radio/src/Makefile | 28 +-- radio/src/gui/menu_general.cpp | 2 +- radio/src/gui/view_statistics.cpp | 2 +- radio/src/opentx.cpp | 2 +- radio/src/targets/sky9x/audio_driver.cpp | 17 +- radio/src/targets/sky9x/board_sky9x.cpp | 8 +- radio/src/targets/sky9x/board_sky9x.h | 5 +- radio/src/targets/sky9x/coproc_driver.cpp | 55 ++---- radio/src/targets/sky9x/lcd_driver.cpp | 44 +++-- radio/src/targets/sky9x/rtc_driver.cpp | 201 ++++++++++++++++++++++ 10 files changed, 279 insertions(+), 85 deletions(-) diff --git a/radio/src/Makefile b/radio/src/Makefile index 73515c551..7ffe21961 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -50,7 +50,7 @@ DELAY = 5 #----------- BUILD OPTIONS --------------------------- # PCB version -# Values: 9X, 9X128, 9X2561, 9XR, 9XR128, 9XR2561, GRUVIN9X, MEGA2560, SKY9X, TARANIS +# Values: 9X, 9X128, 9X2561, 9XR, 9XR128, 9XR2561, GRUVIN9X, MEGA2560, SKY9X, 9XRPRO, TARANIS # Old values STD and STD128 are mapped to 9X and 9X128 for compatibility PCB = 9X @@ -264,7 +264,7 @@ INCDIRS = . translations EXTRAINCDIRS = # MCU name -ifneq ($(PCB), $(filter $(PCB), STD 9X 9XR STD128 9X128 9XR128 9X2561 9XR2561 GRUVIN9X MEGA2560 SKY9X TARANIS)) +ifneq ($(PCB), $(filter $(PCB), STD 9X 9XR STD128 9X128 9XR128 9X2561 9XR2561 GRUVIN9X MEGA2560 SKY9X 9XRPRO TARANIS)) $(error Sorry, the PCB $(PCB) is not supported yet in openTx) endif @@ -520,19 +520,25 @@ ifeq ($(PCB), MEGA2560) CPPDEFS += -DROTARY_ENCODERS=${ROTARY_ENCODERS} endif -ifeq ($(PCB), SKY9X) - # 9x radio with a sky9x replacement board +ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO)) + # 9x/9XR radio with a sky9x replacement board ARCH = ARM - CPPDEFS = -Dat91sam3s4 - ifeq ($(PCBREV), REVA) + CPPDEFS = -Dat91sam3s4 + ifeq ($(PCB), 9XRPRO) + CPPDEFS += -DREVX + LDSCRIPT = targets/sky9x/sam3s4c_flash.ld + else ifeq ($(PCBREV), REVA) CPPDEFS += -DREVA LDSCRIPT = targets/sky9x/sam3s2c_flash.ld + CPPSRC += targets/sky9x/coproc_driver.cpp else ifeq ($(PCBREV), REVB) - CPPDEFS += -DREVB + CPPDEFS += -DREVB -DCOPROCESSOR LDSCRIPT = targets/sky9x/sam3s4c_flash.ld + CPPSRC += targets/sky9x/coproc_driver.cpp else - CPPDEFS += -DREVC + CPPDEFS += -DREVC -DCOPROCESSOR LDSCRIPT = targets/sky9x/sam3s4c_flash.ld + CPPSRC += targets/sky9x/coproc_driver.cpp endif TRGT = arm-none-eabi- MCU = cortex-m3 @@ -553,7 +559,7 @@ ifeq ($(PCB), SKY9X) EEPROMSRC = eeprom_common.cpp eeprom_raw.cpp eeprom_conversions.cpp PULSESSRC = protocols/pulses_arm.cpp protocols/ppm_arm.cpp protocols/pxx_arm.cpp protocols/dsm2_arm.cpp CPPSRC += audio_arm.cpp haptic.cpp gui/view_about.cpp - CPPSRC += targets/sky9x/pwr_driver.cpp targets/sky9x/adc_driver.cpp targets/sky9x/coproc_driver.cpp targets/sky9x/rotenc_driver.cpp targets/sky9x/eeprom_driver.cpp targets/sky9x/pulses_driver.cpp targets/sky9x/keys_driver.cpp targets/sky9x/audio_driver.cpp targets/sky9x/buzzer_driver.cpp targets/sky9x/haptic_driver.cpp targets/sky9x/sdcard_driver.cpp targets/sky9x/massstorage.cpp + CPPSRC += targets/sky9x/pwr_driver.cpp targets/sky9x/adc_driver.cpp targets/sky9x/rotenc_driver.cpp targets/sky9x/eeprom_driver.cpp targets/sky9x/pulses_driver.cpp targets/sky9x/keys_driver.cpp targets/sky9x/audio_driver.cpp targets/sky9x/buzzer_driver.cpp targets/sky9x/haptic_driver.cpp targets/sky9x/sdcard_driver.cpp targets/sky9x/massstorage.cpp ifeq ($(SDCARD), YES) CPPDEFS += -DVOICE @@ -687,8 +693,8 @@ FORMAT = ihex TARGET = opentx # List C++ source files here. (C dependencies are automatically generated.) -ifeq ($(PCB), $(filter $(PCB), SKY9X TARANIS)) - TTS_SRC = translations/tts_cz.cpp translations/tts_de.cpp translations/tts_en.cpp translations/tts_es.cpp translations/tts_fr.cpp translations/tts_it.cpp translations/tts_pl.cpp translations/tts_pt.cpp translations/tts_sk.cpp translations/tts_se.cpp +ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO TARANIS)) + TTS_SRC = translations/tts_cz.cpp translations/tts_de.cpp translations/tts_en.cpp translations/tts_es.cpp translations/tts_fr.cpp translations/tts_it.cpp translations/tts_pt.cpp translations/tts_sk.cpp translations/tts_se.cpp else STD_TTS_SRC = translations/tts_$(shell sh -c "echo $(TTS) | tr '[:upper:]' '[:lower:]'").cpp TTS_SRC = $(shell sh -c "if test -f $(STD_TTS_SRC); then echo $(STD_TTS_SRC); else echo translations/tts_en.cpp; fi") diff --git a/radio/src/gui/menu_general.cpp b/radio/src/gui/menu_general.cpp index e6b7956ca..f2d2c2353 100644 --- a/radio/src/gui/menu_general.cpp +++ b/radio/src/gui/menu_general.cpp @@ -1040,7 +1040,7 @@ void menuGeneralVersion(uint8_t event) lcd_putsLeft(2*FH, stamp1); lcd_putsLeft(3*FH, stamp2); lcd_putsLeft(4*FH, stamp3); -#if defined(PCBSKY9X) && !defined(REVA) +#if defined(COPROCESSOR) if (Coproc_valid == 1) { lcd_putsLeft(5*FH, PSTR("CoPr:")); lcd_outdez8(10*FW, 5*FH, Coproc_read); diff --git a/radio/src/gui/view_statistics.cpp b/radio/src/gui/view_statistics.cpp index b352b85da..082f19df8 100644 --- a/radio/src/gui/view_statistics.cpp +++ b/radio/src/gui/view_statistics.cpp @@ -158,7 +158,7 @@ void menuStatisticsDebug(uint8_t event) putsTelemetryValue(20*FW+2, 3*FH, maxTemperature+g_eeGeneral.temperatureCalib, UNIT_DEGREES, 0); #endif -#if defined(PCBSKY9X) +#if defined(COPROCESSOR) lcd_putsLeft(4*FH, STR_COPROC_TEMP); if (Coproc_read==0) { diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index d1612ec1d..926eba440 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -316,7 +316,7 @@ void per10ms() /* Update global Date/Time every 100 per10ms cycles */ if (++g_ms100 == 100) { g_rtcTime++; // inc global unix timestamp one second -#if defined(PCBSKY9X) +#if defined(COPROCESSOR) if (g_rtcTime < 60 || rtc_count<5) { rtcInit(); rtc_count++; diff --git a/radio/src/targets/sky9x/audio_driver.cpp b/radio/src/targets/sky9x/audio_driver.cpp index d7c5dd323..ed00157b1 100644 --- a/radio/src/targets/sky9x/audio_driver.cpp +++ b/radio/src/targets/sky9x/audio_driver.cpp @@ -136,6 +136,11 @@ void audioInit() pioptr->PIO_PER = 0x02000000L ; // Enable bit A25 (Stock buzzer) pioptr->PIO_OER = 0x02000000L ; // Set bit A25 as output #endif + +#if defined(REVX) + configure_pins( PIO_PC26, PIN_ENABLE | PIN_LOW | PIN_OUTPUT | PIN_PORTC | PIN_NO_PULLUP ) ; + PIOC->PIO_CODR = PIO_PC26 ; +#endif } void audioEnd() @@ -159,19 +164,9 @@ void setVolume(uint8_t volume) { coprocVolumeRequired = volumeScale[min(volume, VOLUME_LEVEL_MAX)]; __disable_irq() ; - coprocCheck() ; + i2cCheck() ; __enable_irq() ; } -#if 0 -void getVolume() -{ - coprocVolumeReadPending = 1 ; - __disable_irq() ; - coprocCheck() ; - __enable_irq() ; -} -#endif - diff --git a/radio/src/targets/sky9x/board_sky9x.cpp b/radio/src/targets/sky9x/board_sky9x.cpp index a2cf97855..5a50c20df 100644 --- a/radio/src/targets/sky9x/board_sky9x.cpp +++ b/radio/src/targets/sky9x/board_sky9x.cpp @@ -606,11 +606,13 @@ void boardInit() adcInit() ; init_pwm() ; - __enable_irq() ; + __enable_irq(); - audioInit() ; + audioInit(); - coprocInit() ; +#if defined(COPROCESSOR) + coprocInit(); +#endif eepromInit(); diff --git a/radio/src/targets/sky9x/board_sky9x.h b/radio/src/targets/sky9x/board_sky9x.h index 873d3e7e5..d2b309f89 100644 --- a/radio/src/targets/sky9x/board_sky9x.h +++ b/radio/src/targets/sky9x/board_sky9x.h @@ -216,13 +216,14 @@ void buzzerSound(uint8_t duration); void buzzerHeartbeat(); #define BUZZER_HEARTBEAT buzzerHeartbeat +// i2c driver +void i2cCheck(); + // 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; diff --git a/radio/src/targets/sky9x/coproc_driver.cpp b/radio/src/targets/sky9x/coproc_driver.cpp index 8591a52ae..1a9cf190f 100644 --- a/radio/src/targets/sky9x/coproc_driver.cpp +++ b/radio/src/targets/sky9x/coproc_driver.cpp @@ -37,7 +37,6 @@ #include "../../opentx.h" int8_t coprocVolumeRequired ; -uint8_t coprocVolumeReadPending ; uint8_t coprocReadDataPending ; uint8_t coprocWriteDataPending ; uint8_t CoProc_appgo_pending ; @@ -51,7 +50,6 @@ 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 @@ -72,15 +70,13 @@ uint32_t coprocWriteDataSize ; // This is called from an interrupt routine, or // interrupts must be disabled while it is called // from elsewhere. -void coprocCheck() +void i2cCheck() { - if ( TWI0->TWI_IMR & TWI_IMR_TXCOMP ) - { + if ( TWI0->TWI_IMR & TWI_IMR_TXCOMP ) { return ; // Busy } - if ( coprocVolumeRequired >= 0 ) // Set volume to this value - { + 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 @@ -88,8 +84,7 @@ void coprocCheck() TWI0->TWI_IER = TWI_IER_TXCOMP ; TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx } - else if (coprocReadDataPending) - { + else if (coprocReadDataPending) { Coproc_valid = 0 ; coprocReadDataPending = 0 ; TWI0->TWI_MMR = 0x00351000 ; // Device 35 and master is reading @@ -98,25 +93,14 @@ void coprocCheck() TWI0->TWI_RPR = (uint32_t)&Co_proc_status[0] ; #endif TWI0->TWI_RCR = COPROC_RX_BUXSIZE - 1 ; - if ( TWI0->TWI_SR & TWI_SR_RXRDY ) - { + 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 ) - { + else if ( CoProc_appgo_pending ) { CoProc_appgo_pending = 0 ; TWI0->TWI_MMR = 0x00350000 ; // Device 35 and master is writing TwiOperation = TWI_COPROC_APPGO ; @@ -124,8 +108,7 @@ void coprocCheck() TWI0->TWI_IER = TWI_IER_TXCOMP ; TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx } - else if ( coprocWriteDataPending ) - { + else if ( coprocWriteDataPending ) { coprocWriteDataPending = 0 ; TWI0->TWI_MMR = 0x00350000 ; // Device 35 and master is writing TwiOperation = TWI_WRITE_COPROC ; @@ -144,7 +127,7 @@ void coprocReadData(bool onlytemp) get_onlytemp = onlytemp; coprocReadDataPending = 1 ; __disable_irq() ; - coprocCheck() ; + i2cCheck() ; __enable_irq() ; } @@ -154,20 +137,10 @@ void coprocWriteData(uint8_t *data, uint32_t size) coprocWriteDataSize = size; coprocWriteDataPending = 1; __disable_irq(); - coprocCheck(); + i2cCheck(); __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() @@ -197,14 +170,6 @@ void coprocInit() #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 ) @@ -275,6 +240,6 @@ extern "C" void TWI0_IRQHandler() { } TwiOperation = TWI_NONE ; - coprocCheck() ; + i2cCheck() ; } #endif diff --git a/radio/src/targets/sky9x/lcd_driver.cpp b/radio/src/targets/sky9x/lcd_driver.cpp index 9fa3a85e3..4bbedc638 100644 --- a/radio/src/targets/sky9x/lcd_driver.cpp +++ b/radio/src/targets/sky9x/lcd_driver.cpp @@ -88,7 +88,6 @@ const uint8_t Lcd_lookup[] = void lcdSendCtl(uint8_t val) { register Pio *pioptr ; -// register uint32_t x ; #if defined(REVA) pioptr = PIOC ; @@ -98,9 +97,13 @@ void lcdSendCtl(uint8_t val) pioptr->PIO_ODSR = Lcd_lookup[val] ; #else pioptr = PIOC ; - pioptr->PIO_CODR = LCD_CS1 ; // Select LCD + #if !defined(REVX) + pioptr->PIO_CODR = LCD_CS1 ; // Select LCD + #endif PIOA->PIO_CODR = LCD_A0 ; - pioptr->PIO_CODR = LCD_RnW ; // Write + #if !defined(REVX) + pioptr->PIO_CODR = LCD_RnW ; // Write + #endif pioptr->PIO_ODSR = val ; #endif @@ -117,7 +120,10 @@ void lcdSendCtl(uint8_t val) #else PIOA->PIO_SODR = LCD_A0 ; // Data #endif + +#if !defined(REVX) pioptr->PIO_SODR = LCD_CS1 ; // Deselect LCD +#endif } void lcdInit() @@ -126,6 +132,10 @@ void lcdInit() // /home/thus/txt/datasheets/lcd/KS0713.pdf // ~/txt/flieger/ST7565RV17.pdf from http://www.glyn.de/content.asp?wdid=132&sid= + // read the inputs, and lock the LCD lines + lcdInputs = PIOC->PIO_PDSR; // 6 LEFT, 5 RIGHT, 4 DOWN, 3 UP () + lcdLock = 1 ; + #if defined(REVA) pioptr = PIOC ; pioptr->PIO_PER = 0x0C00B0FFL ; // Enable bits 27,26,15,13,12,7-0 @@ -136,10 +146,16 @@ void lcdInit() #else configure_pins( LCD_A0, PIN_ENABLE | PIN_LOW | PIN_OUTPUT | PIN_PORTA | PIN_NO_PULLUP ) ; pioptr = PIOC ; - pioptr->PIO_PER = 0x0C0030FFL ; // Enable bits 27,26,13,12,7-0 - pioptr->PIO_CODR = LCD_E | LCD_RnW ; - pioptr->PIO_SODR = LCD_RES | LCD_CS1 ; - pioptr->PIO_OER = 0x0C0030FFL ; // Set bits 27,26,13,12,7-0 output + #if defined(REVX) + pioptr->PIO_PER = PIO_PC27 | PIO_PC12 | 0xFF ; + pioptr->PIO_CODR = LCD_E ; + pioptr->PIO_CODR = LCD_RnW | LCD_CS1 ; // No longer needed, used elsewhere + #else + pioptr->PIO_PER = PIO_PC27 | PIO_PC26 | PIO_PC13 | PIO_PC12 | 0xFF ; + pioptr->PIO_CODR = LCD_E | LCD_RnW | LCD_CS1 ; + #endif + pioptr->PIO_SODR = LCD_RES ; + pioptr->PIO_OER = PIO_PC27 | PIO_PC26 | PIO_PC13 | PIO_PC12 | 0xFF ; // Set bits 27,26,13,12,7-0 output pioptr->PIO_OWER = 0x000000FFL ; // Allow write to ls 8 bits in ODSR #endif @@ -178,6 +194,8 @@ void lcdInit() pioptr->PIO_PUER = 0x0000003AL ; // Set bits 1, 3, 4, 5 with pullups pioptr->PIO_ODSR = 0 ; // Drive D0 low #endif + + lcdLock = 0 ; } void lcdSetRefVolt(uint8_t val) @@ -246,9 +264,13 @@ void lcdRefresh() lcdSendCtl(0x10); //column addr 0 lcdSendCtl(y | 0xB0); //page addr y - pioptr->PIO_CODR = LCD_CS1; // Select LCD + #if !defined(REVX) + pioptr->PIO_CODR = LCD_CS1; // Select LCD + #endif PIOA->PIO_SODR = LCD_A0; // Data - pioptr->PIO_CODR = LCD_RnW; // Write + #if !defined(REVX) + pioptr->PIO_CODR = LCD_RnW; // Write + #endif #if defined(REVA) x = lookup[*p]; @@ -282,7 +304,9 @@ void lcdRefresh() // } pioptr->PIO_CODR = ebit; // End E pulse } - pioptr->PIO_SODR = LCD_CS1; // Deselect LCD + #if !defined(REVX) + pioptr->PIO_SODR = LCD_CS1; // Deselect LCD + #endif } pioptr->PIO_ODSR = 0xFF ; // Drive lines high diff --git a/radio/src/targets/sky9x/rtc_driver.cpp b/radio/src/targets/sky9x/rtc_driver.cpp index 4e72f2a93..ecda77339 100644 --- a/radio/src/targets/sky9x/rtc_driver.cpp +++ b/radio/src/targets/sky9x/rtc_driver.cpp @@ -36,6 +36,203 @@ #include "../opentx.h" +#if defined(REVX) +// TODO change this, not the right place +#define TWI_NONE 0 +#define TWI_WRITE_VOL 2 +#define TWI_READ_COPROC 3 +#define TWI_WAIT_STOP 5 +#define TWI_WRITE_COPROC 6 +int8_t coprocVolumeRequired ; +static uint8_t TwiOperation ; +#define RTC_RX_BUXSIZE 10 +#define RTC_SIZE 7 +uint8_t Rtc_status[RTC_RX_BUXSIZE] ; +uint8_t *Rtc_write_ptr ; +uint32_t Rtc_write_count ; +uint8_t RtcConfig[8] ; // For initial config and writing to RTC +// 0x80, 0, 0, 0x08, 0, 0, 0, 0x80 + +// This is called from an interrupt routine, or +// interrupts must be disabled while it is called +// from elsewhere. +void i2cCheck() +{ + 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 + Volume_required = -1 ; + TWI0->TWI_IER = TWI_IER_TXCOMP ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx + } + else if ( coprocReadDataPending ) { + Rtc_valid = 0 ; + coprocReadDataPending = 0 ; + TWI0->TWI_MMR = 0x006F1100 ; // Device 6F and master is reading, 1 byte addr + TWI0->TWI_IADR = 0 ; + TwiOperation = TWI_READ_RTC ; +#ifndef SIMU + TWI0->TWI_RPR = (uint32_t)&Rtc_status[0] ; +#endif + TWI0->TWI_RCR = RTC_SIZE - 1 ; + if ( TWI0->TWI_SR & TWI_SR_RXRDY ) + { + (void) TWI0->TWI_RHR ; + } + + if ( ( TWI0->TWI_SR & TWI_SR_TXCOMP ) == 0 ) + { + Debug_I2C_event += 1 ; + } + + 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 ( coprocWriteDataPending ) { + if ( coprocWriteDataPending & (2|4) ) { + TWI0->TWI_MMR = 0x006F0100 ; // Device 6F and master is writing, 1 byte addr + TwiOperation = TWI_WRITE_MFP ; + if ( Rtc_write_pending & 2 ) { + TWI0->TWI_IADR = 7 ; + TWI0->TWI_THR = MFPsetting ; // Send data + Rtc_write_pending &= ~2 ; + } + else { + TWI0->TWI_IADR = 8 ; + TWI0->TWI_THR = CALsetting ; // Send data + coprocWriteDataPending &= ~4 ; + } + TWI0->TWI_IER = TWI_IER_TXCOMP ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx + } + else { + coprocWriteDataPending &= ~1 ; + TWI0->TWI_MMR = 0x006F0100 ; // Device 6F and master is writing, 1 byte addr + TWI0->TWI_IADR = 0 ; + TwiOperation = TWI_WRITE_RTC ; +#ifndef SIMU + TWI0->TWI_TPR = (uint32_t)Rtc_write_ptr+1 ; +#endif + TWI0->TWI_TCR = Rtc_write_count-1 ; + TWI0->TWI_THR = *Rtc_write_ptr ; // First byte + TWI0->TWI_PTCR = TWI_PTCR_TXTEN ; // Start data transfer + TWI0->TWI_IER = TWI_IER_TXBUFE | TWI_IER_TXCOMP ; + } + } +} + +void writeRTC(uint8_t *ptr) +{ + uint32_t year ; + RtcConfig[0] = 0x80 | toBCD( *ptr++ ) ; + RtcConfig[1] = toBCD( *ptr++ ) ; + RtcConfig[2] = toBCD( *ptr++ ) ; + RtcConfig[3] = 0x08 ; + RtcConfig[4] = toBCD( *ptr++ ) ; + RtcConfig[5] = toBCD( *ptr++ ) ; + year = *ptr++ ; + year |= *ptr << 8 ; + RtcConfig[6] = toBCD( year - 2000 ) ; + RtcConfig[7] = MFPsetting ; + Rtc_write_ptr = RtcConfig ; + Rtc_write_count = 8 ; + __disable_irq() ; + Rtc_write_pending |= 1 ; + i2cCheck() ; + __enable_irq() ; +} + +void readRTC() +{ + Rtc_read_pending = 1 ; + __disable_irq() ; + i2cCheck() ; + __enable_irq() ; +} + +// TODO should be inside an i2c_driver.cpp +#ifndef SIMU +extern "C" void TWI0_IRQHandler() +{ + uint32_t status ; + status = TWI0->TWI_SR ; // Read only once, some bits cleared on read + + if ( TwiOperation == TWI_READ_RTC ) + { + if ( status & TWI_SR_RXBUFF ) + { + TWI0->TWI_IDR = TWI_IDR_RXBUFF ; + TwiOperation = TWI_WAIT_RTCSTOP ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Rx + TWI0->TWI_RCR = 1 ; // Last byte + return ; + } + else + { + // must be TXCOMP, prob. NAK in data + if ( TWI0->TWI_RCR > 0 ) + { + Rtc_valid = -1 ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Rx + } + } + } + + if ( TwiOperation == TWI_WAIT_RTCSTOP ) + { + Rtc_valid = 1 ; + // Set the date and time + t_time *p = &Time ; + + p->second = fromBCD( Rtc_status[0] & 0x7F ) ; + p->minute = fromBCD( Rtc_status[1] & 0x7F ) ; + p->hour = fromBCD( Rtc_status[2] & 0x3F ) ; + p->date = fromBCD( Rtc_status[4] & 0x3F ) ; + p->month = fromBCD( Rtc_status[5] & 0x1F ) ; + p->year = fromBCD( Rtc_status[6] ) + 2000 ; + + TWI0->TWI_PTCR = TWI_PTCR_RXTDIS ; // Stop transfers + if ( status & TWI_SR_RXRDY ) + { + (void) TWI0->TWI_RHR ; // Discard any rubbish data + } + } + + if ( status & TWI_SR_NACK ) + { + Debug_I2C_event += 0x100 ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx + } + + if ( status & TWI_SR_RXBUFF ) + { + if ( TWI0->TWI_IMR & TWI_IMR_RXBUFF ) + { + Debug_I2C_event += 0x1000000 ; + } + } + + TWI0->TWI_IDR = TWI_IDR_TXCOMP | TWI_IDR_TXBUFE | TWI_IDR_RXBUFF ; + TWI0->TWI_PTCR = TWI_PTCR_TXTDIS | TWI_PTCR_RXTDIS ; // Stop transfers + if ( ( status & TWI_SR_TXCOMP ) == 0 ) + { + TWI0->TWI_IER = TWI_IER_TXCOMP ; + TwiOperation = TWI_WAIT_COMP ; + return ; + } + + TwiOperation = TWI_NONE ; + i2cCheck() ; +} +#endif +#endif + struct t_i2cTime { uint8_t setCode ; @@ -55,7 +252,11 @@ void rtcSetTime(struct gtm * t) I2CTime.Time[4] = t->tm_mon+1 ; I2CTime.Time[5] = (uint8_t) (t->tm_year+1900); I2CTime.Time[6] = (t->tm_year+1900) >> 8; +#if defined(REVX) + writeRTC( (uint8_t *) &I2CTime.Time[0], 8 ) ; +#else coprocWriteData((uint8_t *) &I2CTime, 8); +#endif } void rtcInit() From ee1b51b214688c3d5ee869df73974b1c3cb993b5 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 21 Dec 2013 15:45:05 +0100 Subject: [PATCH 02/13] 9XR support n companion, still not finished --- companion/src/avroutputdialog.cpp | 2 +- companion/src/burnconfigdialog.cpp | 6 +- companion/src/eeprominterface.cpp | 5 +- companion/src/eeprominterface.h | 5 +- companion/src/file.cpp | 10 +-- .../src/firmwares/opentx/open9xeeprom.cpp | 4 +- .../src/firmwares/opentx/open9xinterface.cpp | 71 ++++++++++++++----- .../src/firmwares/opentx/open9xinterface.h | 1 + companion/src/helpers.cpp | 2 +- companion/src/mainwindow.cpp | 10 ++- companion/src/mdichild.cpp | 6 +- companion/src/modelslist.cpp | 4 +- 12 files changed, 86 insertions(+), 40 deletions(-) diff --git a/companion/src/avroutputdialog.cpp b/companion/src/avroutputdialog.cpp index a125d8e99..c31ce0b09 100644 --- a/companion/src/avroutputdialog.cpp +++ b/companion/src/avroutputdialog.cpp @@ -276,7 +276,7 @@ QString avrOutputDialog::getProgrammer() EEPROMInterface *eepromInterface = GetEepromInterface(); if (IS_TARANIS(eepromInterface->getBoard())) { return "DFU Util"; - } else if (eepromInterface->getBoard()==BOARD_SKY9X) { + } else if IS_SKY9X(eepromInterface->getBoard()) { return "SAM-BA"; } else { return "AVRDUDE"; diff --git a/companion/src/burnconfigdialog.cpp b/companion/src/burnconfigdialog.cpp index 71887d4da..d60ba768b 100644 --- a/companion/src/burnconfigdialog.cpp +++ b/companion/src/burnconfigdialog.cpp @@ -36,7 +36,7 @@ burnConfigDialog::burnConfigDialog(QWidget *parent) : ui->samba_location->hide(); ui->samba_port->hide(); ui->sb_browse->hide(); - } else if (eepromInterface->getBoard()==BOARD_SKY9X) { + } else if (IS_SKY9X(eepromInterface->getBoard())) { setWindowTitle(tr("SAM-BA Configuration")); ui->avrArgs->hide(); ui->avrdude_location->hide(); @@ -388,7 +388,7 @@ void burnConfigDialog::on_advCtrChkB_toggled(bool checked) if (IS_TARANIS(eepromInterface->getBoard())) { ui->label_dfu2->show(); ui->dfuArgs->show(); - } else if (eepromInterface->getBoard()==BOARD_SKY9X) { + } else if (IS_SKY9X(eepromInterface->getBoard())) { ui->label_sb2->show(); ui->arm_mcu->show(); } else { @@ -402,7 +402,7 @@ void burnConfigDialog::on_advCtrChkB_toggled(bool checked) if (IS_TARANIS(eepromInterface->getBoard())) { ui->label_dfu2->hide(); ui->dfuArgs->hide(); - } else if (eepromInterface->getBoard()==BOARD_SKY9X) { + } else if (IS_SKY9X(eepromInterface->getBoard())) { ui->label_sb2->hide(); ui->arm_mcu->hide(); } else { diff --git a/companion/src/eeprominterface.cpp b/companion/src/eeprominterface.cpp index 497149ca2..2391e7071 100644 --- a/companion/src/eeprominterface.cpp +++ b/companion/src/eeprominterface.cpp @@ -384,10 +384,10 @@ QString RawSwitch::toString() break; case SWITCH_TYPE_REA: if (index==0) { - if (GetEepromInterface()->getBoard() == BOARD_SKY9X) + if (IS_SKY9X(eepromInterface->getBoard())) return QObject::tr("REAs"); } else if (index==1) { - if (GetEepromInterface()->getBoard() == BOARD_SKY9X) + if (IS_SKY9X(eepromInterface->getBoard())) return QObject::tr("REAl"); } break; @@ -638,6 +638,7 @@ void RegisterEepromInterfaces() eepromInterfaces.push_back(new Open9xInterface(BOARD_M128)); eepromInterfaces.push_back(new Open9xInterface(BOARD_GRUVIN9X)); eepromInterfaces.push_back(new Open9xInterface(BOARD_SKY9X)); + eepromInterfaces.push_back(new Open9xInterface(BOARD_9XRPRO)); eepromInterfaces.push_back(new Open9xInterface(BOARD_TARANIS)); if (rev4a) eepromInterfaces.push_back(new Open9xInterface(BOARD_TARANIS_REV4a)); diff --git a/companion/src/eeprominterface.h b/companion/src/eeprominterface.h index 4f91a8719..38ff94ea2 100644 --- a/companion/src/eeprominterface.h +++ b/companion/src/eeprominterface.h @@ -37,6 +37,7 @@ #define EESIZE_TARANIS (32*1024) #define EESIZE_TARANIS_REV4a (64*1024) #define EESIZE_SKY9X (128*4096) +#define EESIZE_9XRPRO (128*4096) #define EESIZE_RLC_MAX EESIZE_TARANIS_REV4a template t LIMIT(t mi, t x, t ma) { return std::min(std::max(mi, x), ma); } @@ -46,11 +47,13 @@ enum BoardEnum { BOARD_M128, BOARD_GRUVIN9X, BOARD_SKY9X, + BOARD_9XRPRO, BOARD_TARANIS, BOARD_TARANIS_REV4a }; #define IS_STOCK(board) (board==BOARD_STOCK || board==BOARD_M128) -#define IS_ARM(board) (board==BOARD_SKY9X || board==BOARD_TARANIS || board==BOARD_TARANIS_REV4a) +#define IS_ARM(board) (board==BOARD_SKY9X || board==BOARD_9XRPRO || board==BOARD_TARANIS || board==BOARD_TARANIS_REV4a) +#define IS_SKY9X(board) (board==BOARD_SKY9X || board==BOARD_9XRPRO) #define IS_TARANIS(board) (board==BOARD_TARANIS || board==BOARD_TARANIS_REV4a) const uint8_t modn12x3[4][4]= { diff --git a/companion/src/file.cpp b/companion/src/file.cpp index 10c918cf3..9533db249 100644 --- a/companion/src/file.cpp +++ b/companion/src/file.cpp @@ -37,7 +37,7 @@ void EFile::EeFsCreate(uint8_t *eeprom, int size, BoardEnum board) this->eeprom_size = size; this->board = board; - if (board == BOARD_SKY9X) { + if (IS_SKY9X(board)) { memset(eeprom, 0xFF, size); } else if (IS_TARANIS(board)) { @@ -101,7 +101,7 @@ bool EFile::EeFsOpen(uint8_t *eeprom, int size, BoardEnum board) this->eeprom_size = size; this->board = board; - if (board == BOARD_SKY9X) { + if (IS_SKY9X(board)) { return 1; } else if (IS_TARANIS(board)) { @@ -254,7 +254,7 @@ unsigned int EFile::size(unsigned int id) unsigned int EFile::openRd(unsigned int i_fileId) { - if (board == BOARD_SKY9X) { + if (IS_SKY9X(board)) { m_fileId = get_current_block_number(i_fileId * 2, &m_size); m_pos = sizeof(t_eeprom_header); return 1; @@ -298,7 +298,7 @@ unsigned int EFile::readRlc12(uint8_t *buf, unsigned int i_len, bool rlc2) { memset(buf, 0, i_len); - if (board == BOARD_SKY9X) { + if (IS_SKY9X(board)) { int len = std::min((int)i_len, (int)m_size + (int)sizeof(t_eeprom_header) - (int)m_pos); if (len > 0) { eeprom_read_block(buf, (m_fileId << 12) + m_pos, len); @@ -461,7 +461,7 @@ unsigned int EFile::writeRlc1(unsigned int i_fileId, unsigned int typ, const uin */ unsigned int EFile::writeRlc2(unsigned int i_fileId, unsigned int typ, const uint8_t *buf, unsigned int i_len) { - if (board == BOARD_SKY9X) { + if (IS_SKY9X(board)) { openRd(i_fileId); eeprom_write_block(buf, (m_fileId << 12) + m_pos, i_len); t_eeprom_header header; diff --git a/companion/src/firmwares/opentx/open9xeeprom.cpp b/companion/src/firmwares/opentx/open9xeeprom.cpp index 9601cb35a..80969f79e 100644 --- a/companion/src/firmwares/opentx/open9xeeprom.cpp +++ b/companion/src/firmwares/opentx/open9xeeprom.cpp @@ -14,7 +14,7 @@ #define MAX_POTS(board) (IS_TARANIS(board) ? 4 : 3) #define MAX_SWITCHES(board) (IS_TARANIS(board) ? 8 : 7) #define MAX_SWITCHES_POSITION(board) (IS_TARANIS(board) ? 22 : 9) -#define MAX_ROTARY_ENCODERS(board) (board==BOARD_GRUVIN9X ? 2 : (board==BOARD_SKY9X ? 1 : 0)) +#define MAX_ROTARY_ENCODERS(board) (board==BOARD_GRUVIN9X ? 2 : (IS_SKY9X(board) ? 1 : 0)) #define MAX_PHASES(board, version) (IS_ARM(board) ? 9 : (IS_DBLRAM(board, version) ? 6 : 5)) #define MAX_MIXERS(board, version) (IS_ARM(board) ? 64 : 32) #define MAX_CHANNELS(board, version) (IS_ARM(board) ? 32 : 16) @@ -963,7 +963,7 @@ class CustomSwitchesAndSwitchesConversionTable: public ConversionTable { addConversion(RawSwitch(SWITCH_TYPE_VIRTUAL, i), val++); } } - else if (board == BOARD_SKY9X) { + else if (IS_SKY9X(board)) { for (int i=1; i<=8; i++) { int s = switchIndex(i, board, version); addConversion(RawSwitch(SWITCH_TYPE_SWITCH, -s), -val); diff --git a/companion/src/firmwares/opentx/open9xinterface.cpp b/companion/src/firmwares/opentx/open9xinterface.cpp index f5e9ce787..c2a8031da 100644 --- a/companion/src/firmwares/opentx/open9xinterface.cpp +++ b/companion/src/firmwares/opentx/open9xinterface.cpp @@ -72,6 +72,8 @@ const char * Open9xInterface::getName() return "openTx for FrSky Taranis Rev4a"; case BOARD_SKY9X: return "openTx for Sky9x board / 9X"; + case BOARD_9XRPRO: + return "openTx for 9XR-PRO"; default: return "openTx for an unknown board"; } @@ -88,6 +90,8 @@ const int Open9xInterface::getEEpromSize() return EESIZE_GRUVIN9X; case BOARD_SKY9X: return EESIZE_SKY9X; + case BOARD_9XRPRO: + return EESIZE_9XRPRO; case BOARD_TARANIS: return EESIZE_TARANIS; case BOARD_TARANIS_REV4a: @@ -194,7 +198,7 @@ bool Open9xInterface::loadModel(uint8_t version, ModelData &model, uint8_t *data if (board == BOARD_GRUVIN9X) { return loadModel(model, data, index, 0 /*no more stick mode messed*/); } - else if (board == BOARD_SKY9X) { + else if (IS_SKY9X(board)) { return loadModel(model, data, index, 0 /*no more stick mode messed*/); } else { @@ -205,7 +209,7 @@ bool Open9xInterface::loadModel(uint8_t version, ModelData &model, uint8_t *data if (board == BOARD_GRUVIN9X) { return loadModel(model, data, index, 0 /*no more stick mode messed*/); } - else if (board == BOARD_SKY9X) { + else if (IS_SKY9X(board)) { return loadModel(model, data, index, 0 /*no more stick mode messed*/); } else { @@ -216,7 +220,7 @@ bool Open9xInterface::loadModel(uint8_t version, ModelData &model, uint8_t *data if (board == BOARD_GRUVIN9X) { return loadModel(model, data, index, 0 /*no more stick mode messed*/); } - else if (board == BOARD_SKY9X) { + else if (IS_SKY9X(board)) { return loadModel(model, data, index, 0 /*no more stick mode messed*/); } else { @@ -227,7 +231,7 @@ bool Open9xInterface::loadModel(uint8_t version, ModelData &model, uint8_t *data if (board == BOARD_GRUVIN9X) { return loadModel(model, data, index, 0 /*no more stick mode messed*/); } - else if (board == BOARD_SKY9X) { + else if (IS_SKY9X(board)) { return loadModel(model, data, index, 0 /*no more stick mode messed*/); } else { @@ -235,7 +239,7 @@ bool Open9xInterface::loadModel(uint8_t version, ModelData &model, uint8_t *data } } else if (version == 212) { - if (board == BOARD_SKY9X) { + if (IS_SKY9X(board)) { return loadModel(model, data, index); } else { @@ -373,6 +377,9 @@ int Open9xInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t varian case BOARD_SKY9X: version = 215; break; + case BOARD_9XRPRO: + version = 215; + break; case BOARD_GRUVIN9X: version = 214; break; @@ -423,7 +430,7 @@ int Open9xInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t varian case 208: if (board == BOARD_GRUVIN9X) result = saveModel(i, radioData.models[i]); - else if (board == BOARD_SKY9X) + else if (IS_SKY9X(board)) result = saveModel(i, radioData.models[i]); else result = saveModel(i, radioData.models[i]); @@ -431,7 +438,7 @@ int Open9xInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t varian case 209: if (board == BOARD_GRUVIN9X) result = saveModel(i, radioData.models[i]); - else if (board == BOARD_SKY9X) + else if (IS_SKY9X(board)) result = saveModel(i, radioData.models[i]); else result = saveModel(i, radioData.models[i]); @@ -439,7 +446,7 @@ int Open9xInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t varian case 210: if (board == BOARD_GRUVIN9X) result = saveModel(i, radioData.models[i]); - else if (board == BOARD_SKY9X) + else if (IS_SKY9X(board)) result = saveModel(i, radioData.models[i]); else result = saveModel(i, radioData.models[i]); @@ -447,13 +454,13 @@ int Open9xInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t varian case 211: if (board == BOARD_GRUVIN9X) result = saveModel(i, radioData.models[i]); - else if (board == BOARD_SKY9X) + else if (IS_SKY9X(board)) result = saveModel(i, radioData.models[i]); else result = saveModel(i, radioData.models[i]); break; case 212: - if (board == BOARD_SKY9X) + if (IS_SKY9X(board)) result = saveModel(i, radioData.models[i]); else result = saveModelVariant(i, radioData.models[i], version, variant); @@ -477,7 +484,7 @@ int Open9xInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t varian int Open9xInterface::getSize(ModelData &model) { - if (board == BOARD_SKY9X) + if (IS_SKY9X(board)) return 0; if (model.isempty()) @@ -501,7 +508,7 @@ int Open9xInterface::getSize(ModelData &model) int Open9xInterface::getSize(GeneralSettings &settings) { - if (board == BOARD_SKY9X) + if (IS_SKY9X(board)) return 0; uint8_t tmp[EESIZE_RLC_MAX]; @@ -580,7 +587,7 @@ int Open9xInterface::getCapability(const Capability capability) case Timers: return 2; case PermTimers: - if (board == BOARD_GRUVIN9X || board == BOARD_SKY9X || IS_TARANIS(board) ) + if (board == BOARD_GRUVIN9X || IS_ARM(board)) return 1; else return 0; @@ -618,7 +625,7 @@ int Open9xInterface::getCapability(const Capability capability) case RotaryEncoders: if (board == BOARD_GRUVIN9X) return 2; - else if (board == BOARD_SKY9X) + else if (IS_SKY9X(board)) return 1; else return 0; @@ -754,13 +761,13 @@ int Open9xInterface::getCapability(const Capability capability) case HasFailsafe: if (IS_TARANIS(board)) return 32; // - return (board==BOARD_SKY9X ? 16 : 0); + return (IS_SKY9X(board) ? 16 : 0); case NumModules: return (IS_ARM(board) ? 2 : 1); case HasPPMStart: return (IS_ARM(board) ? true : false); case HasCurrentCalibration: - return (board==BOARD_SKY9X ? true : false); + return (IS_SKY9X(board) ? true : false); case HasVolume: return (IS_ARM(board) ? true : false); case HasBrightness: @@ -831,7 +838,7 @@ int Open9xInterface::isAvailable(Protocol proto, int port) return 0; } } - else if (board==BOARD_SKY9X) { + else if (IS_SKY9X(board)) { switch (port) { case 0: switch (proto) { @@ -884,6 +891,8 @@ SimulatorInterface * Open9xInterface::getSimulator() return new Open9xGruvin9xSimulator(this); case BOARD_SKY9X: return new Open9xSky9xSimulator(this); + case BOARD_9XRPRO: + return new Open9xSky9xSimulator(this); case BOARD_TARANIS: return new OpentxTaranisSimulator(this); case BOARD_TARANIS_REV4a: @@ -1041,6 +1050,7 @@ QString geturl( int board) url.append("/getfw.php?fw=%1.hex"); break; case BOARD_SKY9X: + case BOARD_9XRPRO: case BOARD_TARANIS: case BOARD_TARANIS_REV4a: url.append("/getfw.php?fw=%1.bin"); @@ -1073,6 +1083,7 @@ QString getstamp( int board) case BOARD_GRUVIN9X: url.append("v4.txt"); break; + case BOARD_9XRPRO: case BOARD_SKY9X: url.append("arm.txt"); break; @@ -1102,6 +1113,7 @@ QString getrnurl( int board) case BOARD_STOCK: case BOARD_M128: case BOARD_GRUVIN9X: + case BOARD_9XRPRO: case BOARD_SKY9X: url.append("9x.txt"); break; @@ -1309,6 +1321,31 @@ void RegisterOpen9xFirmwares() open9x->addOption("bluetooth", QObject::tr("Bluetooth interface")); open9x->addOptions(fai_options); firmwares.push_back(open9x); + + /* SKY9X board */ + open9x = new Open9xFirmware("opentx-9xrpro", QObject::tr("openTx for 9xr-pro board / 9X"), new Open9xInterface(BOARD_SKY9X), geturl(BOARD_SKY9X), getstamp(BOARD_SKY9X),getrnurl(BOARD_SKY9X), true); + open9x->setVariantBase(FRSKY_VARIANT); + open9x->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support")); + open9x->addOption("templates", QObject::tr("Enable TEMPLATES menu")); + open9x->addOption("nofp", QObject::tr("No flight modes")); + open9x->addOption("nocurves", QObject::tr("Disable curves menus")); + open9x->addOption("ppmca", QObject::tr("PPM center adjustment in limits")); + open9x->addOption("ppmus", QObject::tr("PPM values displayed in us")); + open9x->addOption("gvars", QObject::tr("Global variables"), GVARS_VARIANT); + open9x->addOption("symlimits", QObject::tr("Symetrical Limits")); + open9x->addOption("potscroll", QObject::tr("Pots use in menus navigation")); + open9x->addOption("autosource", QObject::tr("In model setup menus automatically set source by moving some of them")); + open9x->addOption("autoswitch", QObject::tr("In model setup menus automatically set switch by moving some of them")); + open9x->addOption("dblkeys", QObject::tr("Enable resetting values by pressing up and down at the same time")); + open9x->addOption("nographics", QObject::tr("No graphical check boxes and sliders")); + open9x->addOption("battgraph", QObject::tr("Battery graph")); + open9x->addOption("nobold", QObject::tr("Don't use bold font for highlighting active items")); + open9x->addOption("sqt5font", QObject::tr("Use alternative SQT5 font")); + open9x->addOption("tsticks", QObject::tr("Use FrSky Taranis sticks in a 9X/9XR")); + open9x->addOption("bluetooth", QObject::tr("Bluetooth interface")); + open9x->addOptions(fai_options); + firmwares.push_back(open9x); + #endif /* Taranis board */ diff --git a/companion/src/firmwares/opentx/open9xinterface.h b/companion/src/firmwares/opentx/open9xinterface.h index 351b1ba53..5712a83eb 100644 --- a/companion/src/firmwares/opentx/open9xinterface.h +++ b/companion/src/firmwares/opentx/open9xinterface.h @@ -109,6 +109,7 @@ class Open9xFirmware: public FirmwareInfo { virtual unsigned int getEepromVersion(unsigned int revision) { switch(this->eepromInterface->getBoard()) { + case BOARD_9XRPRO: case BOARD_SKY9X: if (revision == 0) return 212; diff --git a/companion/src/helpers.cpp b/companion/src/helpers.cpp index 30f2a9c6f..9af72f3da 100644 --- a/companion/src/helpers.cpp +++ b/companion/src/helpers.cpp @@ -847,7 +847,7 @@ void populateSwitchCB(QComboBox *b, const RawSwitch & value, unsigned long attr, if (item == value) b->setCurrentIndex(b->count()-1); } } - if (GetEepromInterface()->getBoard()==BOARD_SKY9X) { + if (IS_SKY9X(GetEepromInterface()->getBoard())) { item = RawSwitch(SWITCH_TYPE_REA,0); if (GetEepromInterface()->isAvailable(item, context)) { b->addItem(item.toString(), item.toValue()); diff --git a/companion/src/mainwindow.cpp b/companion/src/mainwindow.cpp index 9c8818c82..6dae2a3d0 100644 --- a/companion/src/mainwindow.cpp +++ b/companion/src/mainwindow.cpp @@ -833,7 +833,7 @@ QString MainWindow::GetAvrdudeLocation() EEPROMInterface *eepromInterface = GetEepromInterface(); if (IS_TARANIS(eepromInterface->getBoard())) { return bcd.getDFU(); - } else if (eepromInterface->getBoard()==BOARD_SKY9X) { + } else if (IS_SKY9X(GetEepromInterface()->getBoard())) { return bcd.getSAMBA(); } else { return bcd.getAVRDUDE(); @@ -920,7 +920,7 @@ QStringList MainWindow::GetReceiveEEpromCommand(const QString &filename) EEPROMInterface *eepromInterface = GetEepromInterface(); if (IS_TARANIS(eepromInterface->getBoard())) { // return NULL; // to be implemented - } else if (eepromInterface->getBoard() == BOARD_SKY9X) { + } else if (IS_SKY9X(eepromInterface->getBoard())) { ret=GetSambaArguments(QString("SERIALFLASH::Init 0\n") + "receive_file {SerialFlash AT25} \"" + filename + "\" 0x0 0x80000 0\n"); } else { ret=GetAvrdudeArguments("eeprom:r:", filename); @@ -934,7 +934,7 @@ QStringList MainWindow::GetSendEEpromCommand(const QString &filename) EEPROMInterface *eepromInterface = GetEepromInterface(); if (IS_TARANIS(eepromInterface->getBoard())) { // return NULL; // to be implemented - } else if (eepromInterface->getBoard() == BOARD_SKY9X) { + } else if (IS_SKY9X(eepromInterface->getBoard())) { ret=GetSambaArguments(QString("SERIALFLASH::Init 0\n") + "send_file {SerialFlash AT25} \"" + filename + "\" 0x0 0\n"); } else { ret=GetAvrdudeArguments("eeprom:w:", filename); @@ -950,6 +950,8 @@ QStringList MainWindow::GetSendFlashCommand(const QString &filename) ret=GetDFUUtilArguments("-D", filename); } else if (eepromInterface->getBoard() == BOARD_SKY9X) { ret=GetSambaArguments(QString("send_file {Flash} \"") + filename + "\" 0x400000 0\n" + "FLASH::ScriptGPNMV 2\n"); + } else if (eepromInterface->getBoard() == BOARD_9XRPRO) { + ret=GetSambaArguments(QString("send_file {Flash} \"") + filename + "\" 0x400000 0\n" + "FLASH::ScriptGPNMV 2\n"); } else { ret=GetAvrdudeArguments("flash:w:", filename); } @@ -963,6 +965,8 @@ QStringList MainWindow::GetReceiveFlashCommand(const QString &filename) return GetDFUUtilArguments("-U", filename); } else if (eepromInterface->getBoard() == BOARD_SKY9X) { return GetSambaArguments(QString("receive_file {Flash} \"") + filename + "\" 0x400000 0x40000 0\n"); + } else if (eepromInterface->getBoard() == BOARD_9XRPRO) { + return GetSambaArguments(QString("receive_file {Flash} \"") + filename + "\" 0x400000 0x40000 0\n"); } else { return GetAvrdudeArguments("flash:r:", filename); } diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp index 6fbd16afa..fb581fdfe 100644 --- a/companion/src/mdichild.cpp +++ b/companion/src/mdichild.cpp @@ -127,7 +127,7 @@ bool MdiChild::hasSelection() void MdiChild::updateTitle() { QString title = userFriendlyCurrentFile() + "[*]"+" ("+GetEepromInterface()->getName()+QString(")"); - if (GetEepromInterface()->getBoard() != BOARD_SKY9X) + if (!IS_SKY9X(GetEepromInterface()->getBoard())) title += QString(" - %1 ").arg(EEPromAvail) + tr("free bytes"); setWindowTitle(title); } @@ -345,7 +345,7 @@ bool MdiChild::saveAs(bool isNew) { QSettings settings("companion9x", "companion9x"); QString fileName; - if (GetEepromInterface()->getBoard() == BOARD_SKY9X) { + if (IS_SKY9X(GetEepromInterface()->getBoard())) { curFile.replace(".eepe", ".bin"); QFileInfo fi(curFile); #ifdef __APPLE__ @@ -381,7 +381,7 @@ bool MdiChild::saveFile(const QString &fileName, bool setCurrent) { QString myFile; myFile = fileName; - if (GetEepromInterface()->getBoard() == BOARD_SKY9X) { + if (IS_SKY9X(GetEepromInterface()->getBoard())) { myFile.replace(".eepe", ".bin"); } QFile file(myFile); diff --git a/companion/src/modelslist.cpp b/companion/src/modelslist.cpp index e63959491..73c0a5f9a 100644 --- a/companion/src/modelslist.cpp +++ b/companion/src/modelslist.cpp @@ -286,7 +286,7 @@ void ModelsListWidget::refreshList() QString item = QString().sprintf("%02d: ", i+1); if (!radioData->models[i].isempty()) { - if (eepromInterface && eepromInterface->getBoard() == BOARD_SKY9X) { + if (eepromInterface && IS_SKY9X(eepromInterface->getBoard())) { if (radioData->models[i].name[0]==0) { QString modelname="Model"; modelname.append(QString().sprintf("%02d", i+1)); @@ -330,7 +330,7 @@ void ModelsListWidget::refreshList() this->item(radioData->generalSettings.currModel+1)->setFont(f); } - if (eepromInterface && eepromInterface->getBoard() != BOARD_SKY9X) { + if (eepromInterface && !IS_SKY9X(eepromInterface->getBoard())) { ((MdiChild*)parent())->setEEpromAvail((availableEEpromSize/16)*15); } } From 4eedf94f03623de2a334c8267c0253df18742020 Mon Sep 17 00:00:00 2001 From: "romoloman@github.com" <> Date: Sat, 21 Dec 2013 20:05:20 +0100 Subject: [PATCH 03/13] 9XR support n companion, still not finished --- companion/src/burnconfigdialog.cpp | 6 +++++- companion/src/burnconfigdialog.ui | 5 +++++ companion/src/eeprominterface.cpp | 4 ++-- companion/src/mainwindow.cpp | 2 +- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/companion/src/burnconfigdialog.cpp b/companion/src/burnconfigdialog.cpp index d60ba768b..d7f2b53f7 100644 --- a/companion/src/burnconfigdialog.cpp +++ b/companion/src/burnconfigdialog.cpp @@ -102,7 +102,11 @@ void burnConfigDialog::getSettings() avrProgrammer = settings.value("programmer", QString("usbasp")).toString(); avrMCU = settings.value("mcu", QString("m64")).toString(); - armMCU = settings.value("arm_mcu", QString("at91sam3s4-9x")).toString(); + if (GetEepromInterface()->getBoard()==BOARD_SKY9X) { + armMCU = settings.value("arm_mcu", QString("at91sam3s4-9x")).toString(); + } else { + armMCU = settings.value("arm_mcu", QString("at91sam3s8-9xr")).toString(); + } avrPort = settings.value("avr_port", "").toString(); sambaPort = settings.value("samba_port", "\\USBserial\\COM23").toString(); diff --git a/companion/src/burnconfigdialog.ui b/companion/src/burnconfigdialog.ui index ba1adbf17..dd6d031ff 100644 --- a/companion/src/burnconfigdialog.ui +++ b/companion/src/burnconfigdialog.ui @@ -616,6 +616,11 @@ m2560 for v4.1 boards at91sam3s4-9x + + + at91sam3s8-9xr + + diff --git a/companion/src/eeprominterface.cpp b/companion/src/eeprominterface.cpp index 2391e7071..1325be6b3 100644 --- a/companion/src/eeprominterface.cpp +++ b/companion/src/eeprominterface.cpp @@ -384,10 +384,10 @@ QString RawSwitch::toString() break; case SWITCH_TYPE_REA: if (index==0) { - if (IS_SKY9X(eepromInterface->getBoard())) + if (IS_SKY9X(GetEepromInterface()->getBoard())) return QObject::tr("REAs"); } else if (index==1) { - if (IS_SKY9X(eepromInterface->getBoard())) + if (IS_SKY9X(GetEepromInterface()->getBoard())) return QObject::tr("REAl"); } break; diff --git a/companion/src/mainwindow.cpp b/companion/src/mainwindow.cpp index 6dae2a3d0..878834bf7 100644 --- a/companion/src/mainwindow.cpp +++ b/companion/src/mainwindow.cpp @@ -966,7 +966,7 @@ QStringList MainWindow::GetReceiveFlashCommand(const QString &filename) } else if (eepromInterface->getBoard() == BOARD_SKY9X) { return GetSambaArguments(QString("receive_file {Flash} \"") + filename + "\" 0x400000 0x40000 0\n"); } else if (eepromInterface->getBoard() == BOARD_9XRPRO) { - return GetSambaArguments(QString("receive_file {Flash} \"") + filename + "\" 0x400000 0x40000 0\n"); + return GetSambaArguments(QString("receive_file {Flash} \"") + filename + "\" 0x400000 0x80000 0\n"); } else { return GetAvrdudeArguments("flash:r:", filename); } From 76eec92bdd6e1f31a139a9e1255466009ff3684c Mon Sep 17 00:00:00 2001 From: root Date: Sat, 21 Dec 2013 20:06:05 +0100 Subject: [PATCH 04/13] 9XR support n companion, still not finished --- companion/src/firmwares/opentx/open9xinterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/companion/src/firmwares/opentx/open9xinterface.cpp b/companion/src/firmwares/opentx/open9xinterface.cpp index c2a8031da..ab87f6080 100644 --- a/companion/src/firmwares/opentx/open9xinterface.cpp +++ b/companion/src/firmwares/opentx/open9xinterface.cpp @@ -1323,7 +1323,7 @@ void RegisterOpen9xFirmwares() firmwares.push_back(open9x); /* SKY9X board */ - open9x = new Open9xFirmware("opentx-9xrpro", QObject::tr("openTx for 9xr-pro board / 9X"), new Open9xInterface(BOARD_SKY9X), geturl(BOARD_SKY9X), getstamp(BOARD_SKY9X),getrnurl(BOARD_SKY9X), true); + open9x = new Open9xFirmware("opentx-9xrpro", QObject::tr("openTx for 9XR-PRO"), new Open9xInterface(BOARD_9XRPRO), geturl(BOARD_9XRPRO), getstamp(BOARD_9XRPRO),getrnurl(BOARD_9XRPRO), true); open9x->setVariantBase(FRSKY_VARIANT); open9x->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support")); open9x->addOption("templates", QObject::tr("Enable TEMPLATES menu")); From 20ef6984ee2652eb8c8d56106fd713b7e2643bb6 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Sun, 22 Dec 2013 22:33:42 +0100 Subject: [PATCH 05/13] Now the FW compiles on 9XR-PRO. Still fighting with the drivers on my Windows machine... --- radio/src/Makefile | 2 +- radio/src/opentx.cpp | 2 +- radio/src/targets/sky9x/audio_driver.cpp | 2 +- radio/src/targets/sky9x/board_sky9x.h | 2 +- radio/src/targets/sky9x/coproc_driver.cpp | 8 +- radio/src/targets/sky9x/rtc_driver.cpp | 170 ++++++++++++---------- 6 files changed, 100 insertions(+), 86 deletions(-) diff --git a/radio/src/Makefile b/radio/src/Makefile index 7ffe21961..5ec44c66e 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -694,7 +694,7 @@ TARGET = opentx # List C++ source files here. (C dependencies are automatically generated.) ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO TARANIS)) - TTS_SRC = translations/tts_cz.cpp translations/tts_de.cpp translations/tts_en.cpp translations/tts_es.cpp translations/tts_fr.cpp translations/tts_it.cpp translations/tts_pt.cpp translations/tts_sk.cpp translations/tts_se.cpp + TTS_SRC = translations/tts_cz.cpp translations/tts_de.cpp translations/tts_en.cpp translations/tts_es.cpp translations/tts_fr.cpp translations/tts_it.cpp translations/tts_pt.cpp translations/tts_sk.cpp translations/tts_se.cpp translations/tts_pl.cpp else STD_TTS_SRC = translations/tts_$(shell sh -c "echo $(TTS) | tr '[:upper:]' '[:lower:]'").cpp TTS_SRC = $(shell sh -c "if test -f $(STD_TTS_SRC); then echo $(STD_TTS_SRC); else echo translations/tts_en.cpp; fi") diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 926eba440..2adf2574c 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -4138,7 +4138,7 @@ void opentxClose() hapticOff(); #endif -#if defined(CPUARM) +#if defined(CPUARM) && defined(FRSKY) if((g_model.frsky.mAhPersistent) && (g_model.frsky.storedMah != frskyData.hub.currentConsumption)) { g_model.frsky.storedMah = frskyData.hub.currentConsumption; eeDirty(EE_MODEL); diff --git a/radio/src/targets/sky9x/audio_driver.cpp b/radio/src/targets/sky9x/audio_driver.cpp index ed00157b1..a2fc9226d 100644 --- a/radio/src/targets/sky9x/audio_driver.cpp +++ b/radio/src/targets/sky9x/audio_driver.cpp @@ -162,7 +162,7 @@ static const int8_t volumeScale[VOLUME_LEVEL_MAX+1] = void setVolume(uint8_t volume) { - coprocVolumeRequired = volumeScale[min(volume, VOLUME_LEVEL_MAX)]; + volumeRequired = volumeScale[min(volume, VOLUME_LEVEL_MAX)]; __disable_irq() ; i2cCheck() ; __enable_irq() ; diff --git a/radio/src/targets/sky9x/board_sky9x.h b/radio/src/targets/sky9x/board_sky9x.h index d2b309f89..bd850aef0 100644 --- a/radio/src/targets/sky9x/board_sky9x.h +++ b/radio/src/targets/sky9x/board_sky9x.h @@ -223,7 +223,7 @@ void i2cCheck(); void coprocInit(); void coprocWriteData(uint8_t *data, uint32_t size); void coprocReadData(bool onlytemp=false); -extern int8_t coprocVolumeRequired; +extern int8_t volumeRequired; extern uint8_t Coproc_read; extern int8_t Coproc_valid; extern int8_t Coproc_temp; diff --git a/radio/src/targets/sky9x/coproc_driver.cpp b/radio/src/targets/sky9x/coproc_driver.cpp index 1a9cf190f..941ed1d8a 100644 --- a/radio/src/targets/sky9x/coproc_driver.cpp +++ b/radio/src/targets/sky9x/coproc_driver.cpp @@ -36,7 +36,7 @@ #include "../../opentx.h" -int8_t coprocVolumeRequired ; +int8_t volumeRequired ; uint8_t coprocReadDataPending ; uint8_t coprocWriteDataPending ; uint8_t CoProc_appgo_pending ; @@ -76,11 +76,11 @@ void i2cCheck() return ; // Busy } - if ( coprocVolumeRequired >= 0 ) { // Set volume to this value + if ( volumeRequired >= 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_THR = volumeRequired ; // Send data + volumeRequired = -1 ; TWI0->TWI_IER = TWI_IER_TXCOMP ; TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx } diff --git a/radio/src/targets/sky9x/rtc_driver.cpp b/radio/src/targets/sky9x/rtc_driver.cpp index ecda77339..cc1de8c66 100644 --- a/radio/src/targets/sky9x/rtc_driver.cpp +++ b/radio/src/targets/sky9x/rtc_driver.cpp @@ -40,11 +40,19 @@ // TODO change this, not the right place #define TWI_NONE 0 #define TWI_WRITE_VOL 2 -#define TWI_READ_COPROC 3 -#define TWI_WAIT_STOP 5 -#define TWI_WRITE_COPROC 6 -int8_t coprocVolumeRequired ; -static uint8_t TwiOperation ; +#define TWI_WAIT_COMP 7 +#define TWI_READ_RTC 8 +#define TWI_WRITE_RTC 9 +#define TWI_WAIT_RTCSTOP 10 +#define TWI_WRITE_MFP 11 +int8_t volumeRequired ; +int8_t Rtc_read_pending; +uint8_t Rtc_write_pending ; +int8_t Rtc_valid ; +uint8_t MFPsetting = 0 ; +uint8_t CALsetting = 0 ; +uint8_t *Twi_read_address ; +uint8_t TwiOperation ; #define RTC_RX_BUXSIZE 10 #define RTC_SIZE 7 uint8_t Rtc_status[RTC_RX_BUXSIZE] ; @@ -53,6 +61,18 @@ uint32_t Rtc_write_count ; uint8_t RtcConfig[8] ; // For initial config and writing to RTC // 0x80, 0, 0, 0x08, 0, 0, 0, 0x80 +static uint32_t fromBCD( uint8_t bcd_value ) +{ + return ( ( ( bcd_value & 0xF0 ) * 10 ) >> 4 ) + ( bcd_value & 0x0F ) ; +} + +static uint32_t toBCD( uint32_t value ) +{ + div_t qr ; + qr = div( value, 10 ) ; + return ( qr.quot << 4 ) + qr.rem ; +} + // This is called from an interrupt routine, or // interrupts must be disabled while it is called // from elsewhere. @@ -62,68 +82,70 @@ void i2cCheck() 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 - Volume_required = -1 ; - TWI0->TWI_IER = TWI_IER_TXCOMP ; - TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx + if ( volumeRequired >= 0 ) // Set volume to this value + { + TWI0->TWI_MMR = 0x002F0000 ; // Device 5E (>>1) and master is writing + TwiOperation = TWI_WRITE_VOL ; + TWI0->TWI_THR = volumeRequired ; // Send data + volumeRequired = -1 ; + TWI0->TWI_IER = TWI_IER_TXCOMP ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx } - else if ( coprocReadDataPending ) { - Rtc_valid = 0 ; - coprocReadDataPending = 0 ; - TWI0->TWI_MMR = 0x006F1100 ; // Device 6F and master is reading, 1 byte addr - TWI0->TWI_IADR = 0 ; - TwiOperation = TWI_READ_RTC ; + else if ( Rtc_read_pending ) + { + Rtc_valid = 0 ; + Rtc_read_pending = 0 ; + TWI0->TWI_MMR = 0x006F1100 ; // Device 6F and master is reading, 1 byte addr + TWI0->TWI_IADR = 0 ; + TwiOperation = TWI_READ_RTC ; #ifndef SIMU - TWI0->TWI_RPR = (uint32_t)&Rtc_status[0] ; + TWI0->TWI_RPR = (uint32_t)&Rtc_status[0] ; #endif - TWI0->TWI_RCR = RTC_SIZE - 1 ; - if ( TWI0->TWI_SR & TWI_SR_RXRDY ) - { - (void) TWI0->TWI_RHR ; - } + TWI0->TWI_RCR = RTC_SIZE - 1 ; + if ( TWI0->TWI_SR & TWI_SR_RXRDY ) + { + (void) TWI0->TWI_RHR ; + } - if ( ( TWI0->TWI_SR & TWI_SR_TXCOMP ) == 0 ) - { - Debug_I2C_event += 1 ; - } - - 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 ; + 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 ( coprocWriteDataPending ) { - if ( coprocWriteDataPending & (2|4) ) { - TWI0->TWI_MMR = 0x006F0100 ; // Device 6F and master is writing, 1 byte addr - TwiOperation = TWI_WRITE_MFP ; - if ( Rtc_write_pending & 2 ) { - TWI0->TWI_IADR = 7 ; - TWI0->TWI_THR = MFPsetting ; // Send data - Rtc_write_pending &= ~2 ; - } - else { - TWI0->TWI_IADR = 8 ; - TWI0->TWI_THR = CALsetting ; // Send data - coprocWriteDataPending &= ~4 ; - } - TWI0->TWI_IER = TWI_IER_TXCOMP ; - TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx - } - else { - coprocWriteDataPending &= ~1 ; - TWI0->TWI_MMR = 0x006F0100 ; // Device 6F and master is writing, 1 byte addr - TWI0->TWI_IADR = 0 ; - TwiOperation = TWI_WRITE_RTC ; + else if ( Rtc_write_pending ) + { + if ( Rtc_write_pending & (2|4) ) + { + TWI0->TWI_MMR = 0x006F0100 ; // Device 6F and master is writing, 1 byte addr + TwiOperation = TWI_WRITE_MFP ; + if ( Rtc_write_pending & 2 ) + { + TWI0->TWI_IADR = 7 ; + TWI0->TWI_THR = MFPsetting ; // Send data + Rtc_write_pending &= ~2 ; + } + else + { + TWI0->TWI_IADR = 8 ; + TWI0->TWI_THR = CALsetting ; // Send data + Rtc_write_pending &= ~4 ; + } + TWI0->TWI_IER = TWI_IER_TXCOMP ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx + } + else + { + Rtc_write_pending &= ~1 ; + TWI0->TWI_MMR = 0x006F0100 ; // Device 6F and master is writing, 1 byte addr + TWI0->TWI_IADR = 0 ; + TwiOperation = TWI_WRITE_RTC ; #ifndef SIMU - TWI0->TWI_TPR = (uint32_t)Rtc_write_ptr+1 ; + TWI0->TWI_TPR = (uint32_t)Rtc_write_ptr+1 ; #endif - TWI0->TWI_TCR = Rtc_write_count-1 ; - TWI0->TWI_THR = *Rtc_write_ptr ; // First byte - TWI0->TWI_PTCR = TWI_PTCR_TXTEN ; // Start data transfer - TWI0->TWI_IER = TWI_IER_TXBUFE | TWI_IER_TXCOMP ; - } + TWI0->TWI_TCR = Rtc_write_count-1 ; + TWI0->TWI_THR = *Rtc_write_ptr ; // First byte + TWI0->TWI_PTCR = TWI_PTCR_TXTEN ; // Start data transfer + TWI0->TWI_IER = TWI_IER_TXBUFE | TWI_IER_TXCOMP ; + } } } @@ -188,14 +210,15 @@ extern "C" void TWI0_IRQHandler() { Rtc_valid = 1 ; // Set the date and time - t_time *p = &Time ; + struct gtm utm; - p->second = fromBCD( Rtc_status[0] & 0x7F ) ; - p->minute = fromBCD( Rtc_status[1] & 0x7F ) ; - p->hour = fromBCD( Rtc_status[2] & 0x3F ) ; - p->date = fromBCD( Rtc_status[4] & 0x3F ) ; - p->month = fromBCD( Rtc_status[5] & 0x1F ) ; - p->year = fromBCD( Rtc_status[6] ) + 2000 ; + utm.tm_sec = fromBCD( Rtc_status[0] & 0x7F ) ; + utm.tm_min = fromBCD( Rtc_status[1] & 0x7F ) ; + utm.tm_hour = fromBCD( Rtc_status[2] & 0x3F ) ; + utm.tm_mday = fromBCD( Rtc_status[4] & 0x3F ) ; + utm.tm_mon = fromBCD( Rtc_status[5] & 0x1F ) ; + utm.tm_year = fromBCD( Rtc_status[6] ) + 2000 ; + g_rtcTime = gmktime(&utm); TWI0->TWI_PTCR = TWI_PTCR_RXTDIS ; // Stop transfers if ( status & TWI_SR_RXRDY ) @@ -206,18 +229,9 @@ extern "C" void TWI0_IRQHandler() if ( status & TWI_SR_NACK ) { - Debug_I2C_event += 0x100 ; TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx } - if ( status & TWI_SR_RXBUFF ) - { - if ( TWI0->TWI_IMR & TWI_IMR_RXBUFF ) - { - Debug_I2C_event += 0x1000000 ; - } - } - TWI0->TWI_IDR = TWI_IDR_TXCOMP | TWI_IDR_TXBUFE | TWI_IDR_RXBUFF ; TWI0->TWI_PTCR = TWI_PTCR_TXTDIS | TWI_PTCR_RXTDIS ; // Stop transfers if ( ( status & TWI_SR_TXCOMP ) == 0 ) @@ -253,7 +267,7 @@ void rtcSetTime(struct gtm * t) I2CTime.Time[5] = (uint8_t) (t->tm_year+1900); I2CTime.Time[6] = (t->tm_year+1900) >> 8; #if defined(REVX) - writeRTC( (uint8_t *) &I2CTime.Time[0], 8 ) ; + writeRTC((uint8_t *)&I2CTime.Time[0]) ; #else coprocWriteData((uint8_t *) &I2CTime, 8); #endif @@ -261,5 +275,5 @@ void rtcSetTime(struct gtm * t) void rtcInit() { - coprocReadData(); + // TODO ? coprocReadData(); } From e436e9dc797e7b236150422cdb8819909e0b4b8b Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Mon, 23 Dec 2013 16:31:28 +0100 Subject: [PATCH 06/13] 9XR-PRO soft power issue fixed --- radio/src/targets/sky9x/pwr_driver.cpp | 68 ++++++++++---------------- 1 file changed, 25 insertions(+), 43 deletions(-) diff --git a/radio/src/targets/sky9x/pwr_driver.cpp b/radio/src/targets/sky9x/pwr_driver.cpp index 6d51d53cd..1d6714078 100644 --- a/radio/src/targets/sky9x/pwr_driver.cpp +++ b/radio/src/targets/sky9x/pwr_driver.cpp @@ -38,57 +38,39 @@ uint32_t pwrCheck() { -#ifdef SIMU +#if defined(SIMU) return e_power_on; -#endif - -#if defined(REVC) - if ( PIOC->PIO_PDSR & PIO_PC17 ) // Power on - { - return e_power_on ; - } - - if ( PIOA->PIO_PDSR & PIO_PA8 ) // Trainer plugged in - { - return e_power_trainer ; - } +#elif defined(REVA) + if (PIOC->PIO_PDSR & PIO_PC25) + return e_power_usb; + else if (PIOA->PIO_PDSR & PIO_PA8) + return e_power_trainer; + else + return e_power_on; #elif defined(REVB) - if ( PIOC->PIO_PDSR & PIO_PC17 ) // Power on - { - return e_power_on ; - } - - if (usbPlugged()) - { - return e_power_usb ; // Detected USB - } - - if ( PIOA->PIO_PDSR & PIO_PA8 ) // Trainer plugged in - { - return e_power_trainer ; - } + if (PIOC->PIO_PDSR & PIO_PC17) + return e_power_on; + else if (usbPlugged()) + return e_power_usb; + else if ( PIOA->PIO_PDSR & PIO_PA8 ) + return e_power_trainer; + else + return e_power_off; #else - if ( PIOC->PIO_PDSR & PIO_PC25 ) - { - return e_power_usb ; // Detected USB - } - - if ( PIOA->PIO_PDSR & PIO_PA8 ) // Trainer plugged in - { - return e_power_trainer ; - } - - return e_power_on; + if (PIOC->PIO_PDSR & PIO_PC17) + return e_power_on; + else if (PIOA->PIO_PDSR & PIO_PA8) + return e_power_trainer; + else + return e_power_off; #endif - - return e_power_off; } // turn off soft power void pwrOff() { #if !defined(REVA) - configure_pins( PIO_PA8, PIN_ENABLE | PIN_OUTPUT | PIN_LOW | PIN_PORTA | PIN_NO_PULLUP ) ; + configure_pins(PIO_PA8, PIN_ENABLE | PIN_OUTPUT | PIN_LOW | PIN_PORTA | PIN_NO_PULLUP); #endif } @@ -96,7 +78,7 @@ void pwrOff() void pwrInit() { // Configure RF_power (PC17) - configure_pins( PIO_PC17, PIN_ENABLE | PIN_INPUT | PIN_PORTC | PIN_NO_PULLUP | PIN_PULLDOWN ) ; - configure_pins( PIO_PA8, PIN_ENABLE | PIN_INPUT | PIN_PORTA | PIN_PULLUP ) ; // Enable bit A8 (Soft Power) + configure_pins(PIO_PC17, PIN_ENABLE | PIN_INPUT | PIN_PORTC | PIN_NO_PULLUP | PIN_PULLDOWN); + configure_pins(PIO_PA8, PIN_ENABLE | PIN_INPUT | PIN_PORTA | PIN_PULLUP); // Enable bit A8 (Soft Power) } #endif From 445899b58bd7225a10f191081a82266824d3ecca Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Tue, 31 Dec 2013 11:05:55 +0100 Subject: [PATCH 07/13] [9XR-PRO] USB Bootloader fix --- radio/src/opentx.cpp | 24 +++++++++++++-------- radio/src/targets/sky9x/board_sky9x.cpp | 28 ++++++++++++++----------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 48843f784..44212e1f6 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -289,10 +289,24 @@ volatile tmr10ms_t g_tmr10ms; #if defined(CPUARM) volatile uint8_t rtc_count = 0; uint32_t watchdogTimeout = 0; + void watchdogSetTimeout(uint32_t timeout) { watchdogTimeout = timeout; } + +void opentxBootloader() +{ + BACKLIGHT_ON(); + + lcd_clear(); + lcd_putcAtt( 48, 24, 'U', DBLSIZE ) ; + lcd_putcAtt( 60, 24, 'S', DBLSIZE ) ; + lcd_putcAtt( 72, 24, 'B', DBLSIZE ) ; + lcdRefresh() ; + + usbBootloader(); +} #endif void per10ms() @@ -5066,15 +5080,7 @@ int main(void) g_eeGeneral.backlightBright = 0; g_eeGeneral.contrast = 25; - BACKLIGHT_ON(); - - lcd_clear(); - lcd_putcAtt( 48, 24, 'U', DBLSIZE ) ; - lcd_putcAtt( 60, 24, 'S', DBLSIZE ) ; - lcd_putcAtt( 72, 24, 'B', DBLSIZE ) ; - lcdRefresh() ; - - usbBootloader(); + opentxBootloader(); } CoInitOS(); diff --git a/radio/src/targets/sky9x/board_sky9x.cpp b/radio/src/targets/sky9x/board_sky9x.cpp index 5a50c20df..a873bb40b 100644 --- a/radio/src/targets/sky9x/board_sky9x.cpp +++ b/radio/src/targets/sky9x/board_sky9x.cpp @@ -529,6 +529,8 @@ void configure_pins( uint32_t pins, uint16_t config ) } } +void opentxBootloader(); + void boardInit() { register Pio *pioptr ; @@ -539,33 +541,35 @@ void boardInit() PMC->PMC_PCER0 = (1<PIO_PER = PIO_PC25 ; // Enable bit C25 (USB-detect) + +#if defined(REVX) + if (usbPlugged()) { + lcdInit() ; + opentxBootloader(); + } +#endif + #if defined(REVA) // On REVB, PA21 is used as AD8, and measures current consumption. pioptr = PIOA ; pioptr->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 -#else - pwrInit() ; -#endif - // pioptr->PIO_PUER = 0x80000000 ; // Enable pullup on bit A31 (EXIT) - // pioptr->PIO_PER = 0x80000000 ; // Enable bit A31 - - pioptr = PIOC ; - pioptr->PIO_PER = PIO_PC25 ; // Enable bit C25 (USB-detect) - // pioptr->PIO_OER = 0x80000000L ; // Set bit C31 as output - // pioptr->PIO_SODR = 0x80000000L ; // Set bit C31 - -#if defined(REVA) // Configure RF_power (PC17) and PPM-jack-in (PC19), neither need pullups pioptr->PIO_PER = 0x000A0000L ; // Enable bit C19, C17 pioptr->PIO_ODR = 0x000A0000L ; // Set bits C19 and C17 as input #endif +#if !defined(REVA) + pwrInit() ; +#endif + config_free_pins() ; // Next section configures the key inputs on the LCD data + pioptr = PIOC; #if defined(REVA) pioptr->PIO_PER = 0x0000003DL ; // Enable bits 2,3,4,5, 0 pioptr->PIO_OER = PIO_PC0 ; // Set bit 0 output From 6480741e422fb85c04c5338cae9ee873c55373a7 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Wed, 8 Jan 2014 15:01:08 +0100 Subject: [PATCH 08/13] [9XR-PRO] 64K Flash, 512K RAM --- radio/src/Makefile | 2 +- radio/src/targets/sky9x/sam3s2c_flash.ld | 5 +- radio/src/targets/sky9x/sam3s8c_flash.ld | 153 +++++++++++++++++++++++ 3 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 radio/src/targets/sky9x/sam3s8c_flash.ld diff --git a/radio/src/Makefile b/radio/src/Makefile index 5ec44c66e..bffc17efb 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -526,7 +526,7 @@ ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO)) CPPDEFS = -Dat91sam3s4 ifeq ($(PCB), 9XRPRO) CPPDEFS += -DREVX - LDSCRIPT = targets/sky9x/sam3s4c_flash.ld + LDSCRIPT = targets/sky9x/sam3s8c_flash.ld else ifeq ($(PCBREV), REVA) CPPDEFS += -DREVA LDSCRIPT = targets/sky9x/sam3s2c_flash.ld diff --git a/radio/src/targets/sky9x/sam3s2c_flash.ld b/radio/src/targets/sky9x/sam3s2c_flash.ld index f2e1fddc5..54dde2569 100644 --- a/radio/src/targets/sky9x/sam3s2c_flash.ld +++ b/radio/src/targets/sky9x/sam3s2c_flash.ld @@ -129,8 +129,11 @@ SECTIONS . = ALIGN(4); /* Align the end of the section */ } > RAM - _ebss = .; /* Provide the name for the end of this section */ + _ebss = .; /* Provide the name for the end of this section */ + . = ALIGN(4); /* Align the end of the section */ + __end = .; + _end = .; /* * The ".stack" section is our stack. diff --git a/radio/src/targets/sky9x/sam3s8c_flash.ld b/radio/src/targets/sky9x/sam3s8c_flash.ld new file mode 100644 index 000000000..c9605eb7f --- /dev/null +++ b/radio/src/targets/sky9x/sam3s8c_flash.ld @@ -0,0 +1,153 @@ +/**************************************************************************** +* Copyright (c) 2011 by Michael Fischer. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 3. Neither the name of the author nor the names of its contributors may +* be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +* +***************************************************************************** +* History: +* +* 22.05.2011 mifi First Version +****************************************************************************/ + + +/* + * In this linker script there is no heap available. + * The stack start at the end of the ram segment. + */ + + +/* + * Take a look in the "The GNU linker" manual, here you get + * the following information about the "MEMORY": + * + * "The MEMORY command describes the location and size of + * blocks of memory in the target." + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00400000, LENGTH = 512K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K +} + + +/* + * And the "SECTION" is used for: + * + * "The SECTIONS command tells the linker how to map input + * sections into output sections, and how to place the output + * sections in memory. + */ +SECTIONS +{ + + /* + * The ".text" section is used for the code, and + * read only (.rodata) data. Even the vectors (.vectors) + * MUST be saved at the start of this section. + */ + .text : + { + FILL(0xFFFF) + + CREATE_OBJECT_SYMBOLS + + *(.bootrodata) + *(.bootrodata.*) + + . = ALIGN(32768); + _stext = .; + KEEP(*(.vectors)) + + *(.text) + *(.text.*) + + . = ALIGN(4); /* Align the start of the exidx part */ + *(.ARM.exidx) + *(.ARM.exidx.*) + + . = ALIGN(4); /* Align the start of the rodata part */ + *(.rodata) + *(.rodata.*) + + . = ALIGN(4); /* Align the end of the section */ + } > FLASH = 0 + _etext = .; /* Provide the name for the end of this section */ + + + /* + * The ".data" section is used for initialized data + * and for functions (.fastrun) which should be copied + * from flash to ram. This functions will later be + * executed from ram instead of flash. + */ + .data : AT (_etext) + { + . = ALIGN(4); /* Align the start of the section */ + _sdata = .; /* Provide the name for the start of this section */ + + *(.data) + *(.data.*) + + . = ALIGN(4); /* Align the start of the fastrun part */ + *(.fastrun) + *(.fastrun.*) + + . = ALIGN(4); /* Align the end of the section */ + } > RAM + _edata = .; /* Provide the name for the end of this section */ + + + /* + * The ".bss" section is used for uninitialized data. + * This section will be cleared by the startup code. + */ + .bss : + { + . = ALIGN(4); /* Align the start of the section */ + _sbss = .; /* Provide the name for the start of this section */ + + *(.bss) + *(.bss.*) + + . = ALIGN(4); /* Align the end of the section */ + } > RAM + _ebss = .; /* Provide the name for the end of this section */ + + . = ALIGN(4); /* Align the end of the section */ + __end = .; + _end = .; + + /* + * The ".stack" section is our stack. + * Here this section starts at the end of the ram segment. + */ + _estack = ORIGIN(RAM) + LENGTH(RAM); + +} + +/*** EOF **/ + From f647971d71711c3335495c3844fc6d31ca3992da Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Wed, 8 Jan 2014 16:20:07 +0100 Subject: [PATCH 09/13] [9XR-PRO] Should fix the RTC issue (Date&Time was never read) --- radio/src/targets/sky9x/rtc_driver.cpp | 49 +++++++++++++------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/radio/src/targets/sky9x/rtc_driver.cpp b/radio/src/targets/sky9x/rtc_driver.cpp index cc1de8c66..1cfd15f3a 100644 --- a/radio/src/targets/sky9x/rtc_driver.cpp +++ b/radio/src/targets/sky9x/rtc_driver.cpp @@ -61,16 +61,15 @@ uint32_t Rtc_write_count ; uint8_t RtcConfig[8] ; // For initial config and writing to RTC // 0x80, 0, 0, 0x08, 0, 0, 0, 0x80 -static uint32_t fromBCD( uint8_t bcd_value ) +uint32_t fromBCD(uint8_t bcd_value) { - return ( ( ( bcd_value & 0xF0 ) * 10 ) >> 4 ) + ( bcd_value & 0x0F ) ; + return (((bcd_value & 0xF0) * 10) >> 4) + (bcd_value & 0x0F); } -static uint32_t toBCD( uint32_t value ) +uint32_t toBCD(uint32_t value) { - div_t qr ; - qr = div( value, 10 ) ; - return ( qr.quot << 4 ) + qr.rem ; + div_t qr = div(value, 10); + return (qr.quot << 4) + qr.rem; } // This is called from an interrupt routine, or @@ -151,23 +150,23 @@ void i2cCheck() void writeRTC(uint8_t *ptr) { - uint32_t year ; - RtcConfig[0] = 0x80 | toBCD( *ptr++ ) ; - RtcConfig[1] = toBCD( *ptr++ ) ; - RtcConfig[2] = toBCD( *ptr++ ) ; - RtcConfig[3] = 0x08 ; - RtcConfig[4] = toBCD( *ptr++ ) ; - RtcConfig[5] = toBCD( *ptr++ ) ; - year = *ptr++ ; - year |= *ptr << 8 ; - RtcConfig[6] = toBCD( year - 2000 ) ; - RtcConfig[7] = MFPsetting ; - Rtc_write_ptr = RtcConfig ; - Rtc_write_count = 8 ; - __disable_irq() ; - Rtc_write_pending |= 1 ; - i2cCheck() ; - __enable_irq() ; + uint32_t year; + RtcConfig[0] = 0x80 | toBCD(*ptr++); + RtcConfig[1] = toBCD(*ptr++); + RtcConfig[2] = toBCD(*ptr++); + RtcConfig[3] = 0x08; + RtcConfig[4] = toBCD(*ptr++); + RtcConfig[5] = toBCD( *ptr++); + year = *ptr++; + year |= *ptr << 8; + RtcConfig[6] = toBCD(year - 2000); + RtcConfig[7] = MFPsetting; + Rtc_write_ptr = RtcConfig; + Rtc_write_count = 8; + __disable_irq(); + Rtc_write_pending |= 1; + i2cCheck(); + __enable_irq(); } void readRTC() @@ -275,5 +274,7 @@ void rtcSetTime(struct gtm * t) void rtcInit() { - // TODO ? coprocReadData(); +#if defined(REVX) + readRTC(); +#endif } From b6aca8c0f5ec9a33fcb7b3e6f88c40d024812402 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Thu, 9 Jan 2014 11:20:11 +0100 Subject: [PATCH 10/13] [9XR-PRO] No bootloader for the moment --- radio/src/targets/sky9x/sam3s8c_flash.ld | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/radio/src/targets/sky9x/sam3s8c_flash.ld b/radio/src/targets/sky9x/sam3s8c_flash.ld index c9605eb7f..38943f5d9 100644 --- a/radio/src/targets/sky9x/sam3s8c_flash.ld +++ b/radio/src/targets/sky9x/sam3s8c_flash.ld @@ -71,16 +71,10 @@ SECTIONS */ .text : { - FILL(0xFFFF) + _stext = .; /* Provide the name for the start of this section */ CREATE_OBJECT_SYMBOLS - - *(.bootrodata) - *(.bootrodata.*) - - . = ALIGN(32768); - _stext = .; - KEEP(*(.vectors)) + KEEP(*(.vectors)) *(.text) *(.text.*) From b94da82e17586acac40304618824749aeb6323e9 Mon Sep 17 00:00:00 2001 From: Bertrand Songis Date: Thu, 9 Jan 2014 11:42:13 +0100 Subject: [PATCH 11/13] [9XR-PRO] i2c was not initialized --- radio/src/targets/sky9x/board_sky9x.cpp | 30 ++++++++++++++++++++--- radio/src/targets/sky9x/coproc_driver.cpp | 26 -------------------- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/radio/src/targets/sky9x/board_sky9x.cpp b/radio/src/targets/sky9x/board_sky9x.cpp index a873bb40b..344b3f0b1 100644 --- a/radio/src/targets/sky9x/board_sky9x.cpp +++ b/radio/src/targets/sky9x/board_sky9x.cpp @@ -531,6 +531,32 @@ void configure_pins( uint32_t pins, uint16_t config ) void opentxBootloader(); +// Set up for volume control (TWI0) +// Need PA3 and PA4 set to peripheral A +void i2cInit() +{ + 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) ; +} + void boardInit() { register Pio *pioptr ; @@ -614,9 +640,7 @@ void boardInit() audioInit(); -#if defined(COPROCESSOR) - coprocInit(); -#endif + i2cInit(); eepromInit(); diff --git a/radio/src/targets/sky9x/coproc_driver.cpp b/radio/src/targets/sky9x/coproc_driver.cpp index 941ed1d8a..af33f4099 100644 --- a/radio/src/targets/sky9x/coproc_driver.cpp +++ b/radio/src/targets/sky9x/coproc_driver.cpp @@ -141,32 +141,6 @@ void coprocWriteData(uint8_t *data, uint32_t size) __enable_irq(); } -// 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() { From 8662a4ec68293669008ddcbdea6eb87977ef5593 Mon Sep 17 00:00:00 2001 From: bsongis Date: Mon, 3 Mar 2014 16:50:05 +0100 Subject: [PATCH 12/13] Merge issues --- companion/src/firmwares/opentx/opentxinterface.cpp | 2 +- radio/src/opentx.cpp | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index 3e92ed502..447904e21 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -368,7 +368,7 @@ int OpenTxInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t varian version = 216; break; case BOARD_9XRPRO: - version = 215; + version = 216; break; case BOARD_GRUVIN9X: version = 216; diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 473d9a7b3..ac7a11211 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -4531,15 +4531,10 @@ void opentxClose() hapticOff(); #endif -<<<<<<< HEAD -#if defined(CPUARM) && defined(FRSKY) - if((g_model.frsky.mAhPersistent) && (g_model.frsky.storedMah != frskyData.hub.currentConsumption)) { -======= saveTimers(); #if defined(CPUARM) && defined(FRSKY) if ((g_model.frsky.mAhPersistent) && (g_model.frsky.storedMah != frskyData.hub.currentConsumption)) { ->>>>>>> origin/next g_model.frsky.storedMah = frskyData.hub.currentConsumption; eeDirty(EE_MODEL); } From e78beed2661d3fa90bd276586c6b4bd561e6fc65 Mon Sep 17 00:00:00 2001 From: bsongis Date: Sun, 11 May 2014 22:50:34 +0200 Subject: [PATCH 13/13] Unix line endings --- companion/src/mdichild.cpp | 1372 ++++++++++++++++++------------------ 1 file changed, 686 insertions(+), 686 deletions(-) diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp index 9ad9fb321..6b4f3dac7 100644 --- a/companion/src/mdichild.cpp +++ b/companion/src/mdichild.cpp @@ -1,192 +1,192 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial Usage -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mdichild.h" -#include "ui_mdichild.h" -#include "xmlinterface.h" -#include "hexinterface.h" -#include "mainwindow.h" -#include "modeledit/modeledit.h" -#include "generaledit.h" -#include "avroutputdialog.h" -#include "burnconfigdialog.h" -#include "printdialog.h" -#include "burndialog.h" -#include "helpers.h" -#include "appdata.h" +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mdichild.h" +#include "ui_mdichild.h" +#include "xmlinterface.h" +#include "hexinterface.h" +#include "mainwindow.h" +#include "modeledit/modeledit.h" +#include "generaledit.h" +#include "avroutputdialog.h" +#include "burnconfigdialog.h" +#include "printdialog.h" +#include "burndialog.h" +#include "helpers.h" +#include "appdata.h" #include "wizarddialog.h" #include "taranisnotfound.h" -#include - -#if defined WIN32 || !defined __GNUC__ -#include -#define sleep(x) Sleep(x*1000) -#else -#include -#endif - -MdiChild::MdiChild(): - QWidget(), - ui(new Ui::mdiChild), +#include + +#if defined WIN32 || !defined __GNUC__ +#include +#define sleep(x) Sleep(x*1000) +#else +#include +#endif + +MdiChild::MdiChild(): + QWidget(), + ui(new Ui::mdiChild), firmware(GetCurrentFirmware()), - isUntitled(true), - fileChanged(false) -{ - ui->setupUi(this); - this->setWindowIcon(CompanionIcon("open.png")); - ui->SimulateTxButton->setIcon(CompanionIcon("simulate.png")); - setAttribute(Qt::WA_DeleteOnClose); - - eepromInterfaceChanged(); - - if(!(this->isMaximized() || this->isMinimized())) { - adjustSize(); - } -} - + isUntitled(true), + fileChanged(false) +{ + ui->setupUi(this); + this->setWindowIcon(CompanionIcon("open.png")); + ui->SimulateTxButton->setIcon(CompanionIcon("simulate.png")); + setAttribute(Qt::WA_DeleteOnClose); + + eepromInterfaceChanged(); + + if(!(this->isMaximized() || this->isMinimized())) { + adjustSize(); + } +} + MdiChild::~MdiChild() { delete ui; } -void MdiChild::qSleep(int ms) -{ - if (ms<0) - return; - -#if defined WIN32 || !defined __GNUC__ - Sleep(uint(ms)); -#else - struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; - nanosleep(&ts, NULL); -#endif -} - -void MdiChild::eepromInterfaceChanged() -{ - ui->modelsList->refreshList(); +void MdiChild::qSleep(int ms) +{ + if (ms<0) + return; + +#if defined WIN32 || !defined __GNUC__ + Sleep(uint(ms)); +#else + struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; + nanosleep(&ts, NULL); +#endif +} + +void MdiChild::eepromInterfaceChanged() +{ + ui->modelsList->refreshList(); ui->SimulateTxButton->setEnabled(GetCurrentFirmware()/*firmware*/->getCapability(Simulation)); - updateTitle(); -} - -void MdiChild::cut() -{ - ui->modelsList->cut(); -} - -void MdiChild::copy() -{ - ui->modelsList->copy(); -} - -void MdiChild::paste() -{ - ui->modelsList->paste(); -} - -bool MdiChild::hasPasteData() -{ - return ui->modelsList->hasPasteData(); -} - -bool MdiChild::hasSelection() -{ - return ui->modelsList->hasSelection(); -} - -void MdiChild::updateTitle() -{ - QString title = userFriendlyCurrentFile() + "[*]"+" ("+GetEepromInterface()->getName()+QString(")"); - if (!IS_SKY9X(GetEepromInterface()->getBoard())) - title += QString(" - %1 ").arg(EEPromAvail) + tr("free bytes"); - setWindowTitle(title); -} - -void MdiChild::setModified() -{ - ui->modelsList->refreshList(); - fileChanged = true; - updateTitle(); - documentWasModified(); -} - -void MdiChild::on_SimulateTxButton_clicked() -{ - startSimulation(this, radioData, -1); -} - -void MdiChild::checkAndInitModel(int row) -{ - ModelData &model = radioData.models[row - 1]; - if (model.isempty()) { - model.setDefaultValues(row - 1, radioData.generalSettings); - setModified(); - } -} - -void MdiChild::generalEdit() -{ - GeneralEdit *t = new GeneralEdit(radioData, this); - connect(t, SIGNAL(modelValuesChanged()), this, SLOT(setModified())); - t->show(); -} - -void MdiChild::modelEdit() -{ - int row = ui->modelsList->currentRow(); - - if (row == 0){ - generalEdit(); - } - else { - QApplication::setOverrideCursor(Qt::WaitCursor); - checkAndInitModel( row ); - ModelData &model = radioData.models[row - 1]; - ModelEdit *t = new ModelEdit(this, radioData, (row - 1), GetCurrentFirmware()/*firmware*/); - t->setWindowTitle(tr("Editing model %1: ").arg(row) + model.name); - connect(t, SIGNAL(modified()), this, SLOT(setModified())); - t->show(); - QApplication::restoreOverrideCursor(); - } -} + updateTitle(); +} + +void MdiChild::cut() +{ + ui->modelsList->cut(); +} + +void MdiChild::copy() +{ + ui->modelsList->copy(); +} + +void MdiChild::paste() +{ + ui->modelsList->paste(); +} + +bool MdiChild::hasPasteData() +{ + return ui->modelsList->hasPasteData(); +} + +bool MdiChild::hasSelection() +{ + return ui->modelsList->hasSelection(); +} + +void MdiChild::updateTitle() +{ + QString title = userFriendlyCurrentFile() + "[*]"+" ("+GetEepromInterface()->getName()+QString(")"); + if (!IS_SKY9X(GetEepromInterface()->getBoard())) + title += QString(" - %1 ").arg(EEPromAvail) + tr("free bytes"); + setWindowTitle(title); +} + +void MdiChild::setModified() +{ + ui->modelsList->refreshList(); + fileChanged = true; + updateTitle(); + documentWasModified(); +} + +void MdiChild::on_SimulateTxButton_clicked() +{ + startSimulation(this, radioData, -1); +} + +void MdiChild::checkAndInitModel(int row) +{ + ModelData &model = radioData.models[row - 1]; + if (model.isempty()) { + model.setDefaultValues(row - 1, radioData.generalSettings); + setModified(); + } +} + +void MdiChild::generalEdit() +{ + GeneralEdit *t = new GeneralEdit(radioData, this); + connect(t, SIGNAL(modelValuesChanged()), this, SLOT(setModified())); + t->show(); +} + +void MdiChild::modelEdit() +{ + int row = ui->modelsList->currentRow(); + + if (row == 0){ + generalEdit(); + } + else { + QApplication::setOverrideCursor(Qt::WaitCursor); + checkAndInitModel( row ); + ModelData &model = radioData.models[row - 1]; + ModelEdit *t = new ModelEdit(this, radioData, (row - 1), GetCurrentFirmware()/*firmware*/); + t->setWindowTitle(tr("Editing model %1: ").arg(row) + model.name); + connect(t, SIGNAL(modified()), this, SLOT(setModified())); + t->show(); + QApplication::restoreOverrideCursor(); + } +} void MdiChild::wizardEdit() { @@ -201,535 +201,535 @@ void MdiChild::wizardEdit() } } } - -void MdiChild::openEditWindow() -{ - int row = ui->modelsList->currentRow(); - if (row == 0){ - generalEdit(); - } - else{ - ModelData &model = radioData.models[row - 1]; - if (model.isempty() && g.useWizard()) { - wizardEdit(); - } - else { - modelEdit(); - } - } -} - -void MdiChild::newFile() -{ - static int sequenceNumber = 1; - - isUntitled = true; - curFile = QString("document%1.eepe").arg(sequenceNumber++); - updateTitle(); -} - -bool MdiChild::loadFile(const QString &fileName, bool resetCurrentFile) -{ - QFile file(fileName); - - if (!file.exists()) { - QMessageBox::critical(this, tr("Error"), tr("Unable to find file %1!").arg(fileName)); - return false; - } - - int fileType = getFileType(fileName); - - if (fileType==FILE_TYPE_XML) { - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file - QMessageBox::critical(this, tr("Error"), - tr("Error opening file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - return false; - } - QTextStream inputStream(&file); - XmlInterface(inputStream).load(radioData); - } - else if (fileType==FILE_TYPE_HEX || fileType==FILE_TYPE_EEPE) { //read HEX file - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file - QMessageBox::critical(this, tr("Error"), - tr("Error opening file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - return false; - } - - QDomDocument doc(ER9X_EEPROM_FILE_TYPE); - bool xmlOK = doc.setContent(&file); - if(xmlOK) { - if (LoadEepromXml(radioData, doc)){ - ui->modelsList->refreshList(); - if(resetCurrentFile) setCurrentFile(fileName); - return true; - } - } - file.reset(); - - QTextStream inputStream(&file); - - if (fileType==FILE_TYPE_EEPE) { // read EEPE file header - QString hline = inputStream.readLine(); - if (hline!=EEPE_EEPROM_FILE_HEADER) { - file.close(); - return false; - } - } - - uint8_t eeprom[EESIZE_RLC_MAX]; - int eeprom_size = HexInterface(inputStream).load(eeprom, EESIZE_RLC_MAX); - if (!eeprom_size) { - QMessageBox::critical(this, tr("Error"), - tr("Invalid EEPROM File %1") - .arg(fileName)); - file.close(); - return false; - } - - file.close(); - - if (!LoadEeprom(radioData, eeprom, eeprom_size)) { - QMessageBox::critical(this, tr("Error"), - tr("Invalid EEPROM File %1") - .arg(fileName)); - return false; - } - - ui->modelsList->refreshList(); - if(resetCurrentFile) setCurrentFile(fileName); - - return true; - } - else if (fileType==FILE_TYPE_BIN) { //read binary - int eeprom_size = file.size(); - - if (!file.open(QFile::ReadOnly)) { //reading binary file - TODO HEX support - QMessageBox::critical(this, tr("Error"), - tr("Error opening file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - return false; - } - uint8_t *eeprom = (uint8_t *)malloc(eeprom_size); - memset(eeprom, 0, eeprom_size); - long result = file.read((char*)eeprom, eeprom_size); - file.close(); - - if (result != eeprom_size) { - QMessageBox::critical(this, tr("Error"), - tr("Error reading file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - - return false; - } - - if (!LoadEeprom(radioData, eeprom, eeprom_size) && !LoadBackup(radioData, eeprom, eeprom_size, 0)) { - QMessageBox::critical(this, tr("Error"), - tr("Invalid binary EEPROM File %1") - .arg(fileName)); - return false; - } - - ui->modelsList->refreshList(); - if(resetCurrentFile) setCurrentFile(fileName); - - free(eeprom); - return true; - } - - return false; -} - -bool MdiChild::save() -{ - if (isUntitled) { - return saveAs(true); - } - else { - return saveFile(curFile); - } -} - -bool MdiChild::saveAs(bool isNew) -{ - QString fileName; - if (IS_SKY9X(GetEepromInterface()->getBoard())) { - curFile.replace(".eepe", ".bin"); - QFileInfo fi(curFile); -#ifdef __APPLE__ - fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName()); -#else - fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName(), tr(BIN_FILES_FILTER)); -#endif - } - else { - QFileInfo fi(curFile); -#ifdef __APPLE__ - fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName()); -#else - fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName(), tr(EEPROM_FILES_FILTER)); -#endif - } - if (fileName.isEmpty()) - return false; - if (fileName.contains("rev4a")) { - g.rev4aSupport( true ); - } - if (fileName.contains("norev4a")) { - g.rev4aSupport( false ); - } - g.eepromDir( QFileInfo(fileName).dir().absolutePath() ); - if (isNew) - return saveFile(fileName); - else - return saveFile(fileName,true); -} - -bool MdiChild::saveFile(const QString &fileName, bool setCurrent) -{ - QString myFile; - myFile = fileName; - if (IS_SKY9X(GetEepromInterface()->getBoard())) { - myFile.replace(".eepe", ".bin"); - } - QFile file(myFile); - - int fileType = getFileType(myFile); - - uint8_t *eeprom = (uint8_t*)malloc(GetEepromInterface()->getEEpromSize()); - int eeprom_size = 0; - - if (fileType != FILE_TYPE_XML) { - eeprom_size = GetEepromInterface()->save(eeprom, radioData, GetCurrentFirmwareVariant(), 0/*last version*/); - if (!eeprom_size) { - QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile).arg(file.errorString())); - return false; - } - } - - if (!file.open(fileType == FILE_TYPE_BIN ? QIODevice::WriteOnly : (QIODevice::WriteOnly | QIODevice::Text))) { - QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile).arg(file.errorString())); - return false; - } - - QTextStream outputStream(&file); - - if (fileType==FILE_TYPE_XML) { - if (!XmlInterface(outputStream).save(radioData)) { - QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile).arg(file.errorString())); - file.close(); - return false; - } - } - else if (fileType==FILE_TYPE_HEX || fileType==FILE_TYPE_EEPE) { // write hex - if (fileType==FILE_TYPE_EEPE) - outputStream << EEPE_EEPROM_FILE_HEADER << "\n"; - - if (!HexInterface(outputStream).save(eeprom, eeprom_size)) { - QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile).arg(file.errorString())); - file.close(); - return false; - } - } - else if (fileType==FILE_TYPE_BIN) // write binary - { - long result = file.write((char*)eeprom, eeprom_size); - if(result!=eeprom_size) { - QMessageBox::warning(this, tr("Error"),tr("Error writing file %1:\n%2.").arg(myFile).arg(file.errorString())); - return false; - } - } - else { - QMessageBox::warning(this, tr("Error"),tr("Error writing file %1:\n%2.").arg(myFile).arg("Unknown format")); - return false; - } - - free(eeprom); // TODO free in all cases ... - file.close(); - if(setCurrent) setCurrentFile(myFile); - - return true; -} - -QString MdiChild::userFriendlyCurrentFile() -{ - return strippedName(curFile); -} - -void MdiChild::closeEvent(QCloseEvent *event) -{ - if (maybeSave()) { - event->accept(); - } - else { - event->ignore(); - } -} - -void MdiChild::documentWasModified() -{ - setWindowModified(fileChanged); -} - -bool MdiChild::maybeSave() -{ - if (fileChanged) { - QMessageBox::StandardButton ret; - ret = QMessageBox::warning(this, tr("Companion"), - tr("%1 has been modified.\n" - "Do you want to save your changes?").arg(userFriendlyCurrentFile()), - QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); - - if (ret == QMessageBox::Save) - return save(); - else if (ret == QMessageBox::Cancel) - return false; - } - return true; -} - -void MdiChild::setCurrentFile(const QString &fileName) -{ - curFile = QFileInfo(fileName).canonicalFilePath(); - isUntitled = false; - fileChanged = false; - setWindowModified(false); - updateTitle(); - int MaxRecentFiles = g.historySize(); - QStringList files = g.recentFiles(); - files.removeAll(fileName); - files.prepend(fileName); - while (files.size() > MaxRecentFiles) - files.removeLast(); - - g.recentFiles( files ); -} - -QString MdiChild::strippedName(const QString &fullFileName) -{ - return QFileInfo(fullFileName).fileName(); -} - -void MdiChild::writeEeprom() // write to Tx -{ - bool backupEnable=g.enableBackup(); - QString backupPath=g.backupDir(); - if (!backupPath.isEmpty()) { - if (!QDir(backupPath).exists()) { - if (backupEnable) { - QMessageBox::warning(this, tr("Backup is impossible"), tr("The backup dir set in preferences does not exist")); - } - backupEnable=false; - } + +void MdiChild::openEditWindow() +{ + int row = ui->modelsList->currentRow(); + if (row == 0){ + generalEdit(); + } + else{ + ModelData &model = radioData.models[row - 1]; + if (model.isempty() && g.useWizard()) { + wizardEdit(); + } + else { + modelEdit(); + } + } +} + +void MdiChild::newFile() +{ + static int sequenceNumber = 1; + + isUntitled = true; + curFile = QString("document%1.eepe").arg(sequenceNumber++); + updateTitle(); +} + +bool MdiChild::loadFile(const QString &fileName, bool resetCurrentFile) +{ + QFile file(fileName); + + if (!file.exists()) { + QMessageBox::critical(this, tr("Error"), tr("Unable to find file %1!").arg(fileName)); + return false; + } + + int fileType = getFileType(fileName); + + if (fileType==FILE_TYPE_XML) { + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file + QMessageBox::critical(this, tr("Error"), + tr("Error opening file %1:\n%2.") + .arg(fileName) + .arg(file.errorString())); + return false; + } + QTextStream inputStream(&file); + XmlInterface(inputStream).load(radioData); + } + else if (fileType==FILE_TYPE_HEX || fileType==FILE_TYPE_EEPE) { //read HEX file + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file + QMessageBox::critical(this, tr("Error"), + tr("Error opening file %1:\n%2.") + .arg(fileName) + .arg(file.errorString())); + return false; + } + + QDomDocument doc(ER9X_EEPROM_FILE_TYPE); + bool xmlOK = doc.setContent(&file); + if(xmlOK) { + if (LoadEepromXml(radioData, doc)){ + ui->modelsList->refreshList(); + if(resetCurrentFile) setCurrentFile(fileName); + return true; + } + } + file.reset(); + + QTextStream inputStream(&file); + + if (fileType==FILE_TYPE_EEPE) { // read EEPE file header + QString hline = inputStream.readLine(); + if (hline!=EEPE_EEPROM_FILE_HEADER) { + file.close(); + return false; + } + } + + uint8_t eeprom[EESIZE_RLC_MAX]; + int eeprom_size = HexInterface(inputStream).load(eeprom, EESIZE_RLC_MAX); + if (!eeprom_size) { + QMessageBox::critical(this, tr("Error"), + tr("Invalid EEPROM File %1") + .arg(fileName)); + file.close(); + return false; + } + + file.close(); + + if (!LoadEeprom(radioData, eeprom, eeprom_size)) { + QMessageBox::critical(this, tr("Error"), + tr("Invalid EEPROM File %1") + .arg(fileName)); + return false; + } + + ui->modelsList->refreshList(); + if(resetCurrentFile) setCurrentFile(fileName); + + return true; + } + else if (fileType==FILE_TYPE_BIN) { //read binary + int eeprom_size = file.size(); + + if (!file.open(QFile::ReadOnly)) { //reading binary file - TODO HEX support + QMessageBox::critical(this, tr("Error"), + tr("Error opening file %1:\n%2.") + .arg(fileName) + .arg(file.errorString())); + return false; + } + uint8_t *eeprom = (uint8_t *)malloc(eeprom_size); + memset(eeprom, 0, eeprom_size); + long result = file.read((char*)eeprom, eeprom_size); + file.close(); + + if (result != eeprom_size) { + QMessageBox::critical(this, tr("Error"), + tr("Error reading file %1:\n%2.") + .arg(fileName) + .arg(file.errorString())); + + return false; + } + + if (!LoadEeprom(radioData, eeprom, eeprom_size) && !LoadBackup(radioData, eeprom, eeprom_size, 0)) { + QMessageBox::critical(this, tr("Error"), + tr("Invalid binary EEPROM File %1") + .arg(fileName)); + return false; + } + + ui->modelsList->refreshList(); + if(resetCurrentFile) setCurrentFile(fileName); + + free(eeprom); + return true; + } + + return false; +} + +bool MdiChild::save() +{ + if (isUntitled) { + return saveAs(true); } else { - backupEnable=false; - } - QString stickCal=g.profile[g.id()].stickPotCalib(); - burnConfigDialog bcd; - QString tempDir = QDir::tempPath(); - QString tempFile = tempDir + "/temp.bin"; - saveFile(tempFile, false); - if(!QFileInfo(tempFile).exists()) { - QMessageBox::critical(this,tr("Error"), tr("Cannot write temporary file!")); - return; - } - EEPROMInterface *eepromInterface = GetEepromInterface(); - bool backup=false; - burnDialog *cd = new burnDialog(this, 1, &tempFile, &backup,strippedName(curFile)); - cd->exec(); - if (!tempFile.isEmpty()) { - if (backup) { - if (backupEnable) { - QString backupFile=backupPath+"/backup-"+QDateTime().currentDateTime().toString("yyyy-MM-dd-HHmmss")+".bin"; - if (IS_TARANIS(eepromInterface->getBoard())) { - QString path=((MainWindow *)this->parent())->FindTaranisPath(); - if (path.isEmpty()) { + return saveFile(curFile); + } +} + +bool MdiChild::saveAs(bool isNew) +{ + QString fileName; + if (IS_SKY9X(GetEepromInterface()->getBoard())) { + curFile.replace(".eepe", ".bin"); + QFileInfo fi(curFile); +#ifdef __APPLE__ + fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName()); +#else + fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName(), tr(BIN_FILES_FILTER)); +#endif + } + else { + QFileInfo fi(curFile); +#ifdef __APPLE__ + fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName()); +#else + fileName = QFileDialog::getSaveFileName(this, tr("Save As"), g.eepromDir() + "/" +fi.fileName(), tr(EEPROM_FILES_FILTER)); +#endif + } + if (fileName.isEmpty()) + return false; + if (fileName.contains("rev4a")) { + g.rev4aSupport( true ); + } + if (fileName.contains("norev4a")) { + g.rev4aSupport( false ); + } + g.eepromDir( QFileInfo(fileName).dir().absolutePath() ); + if (isNew) + return saveFile(fileName); + else + return saveFile(fileName,true); +} + +bool MdiChild::saveFile(const QString &fileName, bool setCurrent) +{ + QString myFile; + myFile = fileName; + if (IS_SKY9X(GetEepromInterface()->getBoard())) { + myFile.replace(".eepe", ".bin"); + } + QFile file(myFile); + + int fileType = getFileType(myFile); + + uint8_t *eeprom = (uint8_t*)malloc(GetEepromInterface()->getEEpromSize()); + int eeprom_size = 0; + + if (fileType != FILE_TYPE_XML) { + eeprom_size = GetEepromInterface()->save(eeprom, radioData, GetCurrentFirmwareVariant(), 0/*last version*/); + if (!eeprom_size) { + QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile).arg(file.errorString())); + return false; + } + } + + if (!file.open(fileType == FILE_TYPE_BIN ? QIODevice::WriteOnly : (QIODevice::WriteOnly | QIODevice::Text))) { + QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile).arg(file.errorString())); + return false; + } + + QTextStream outputStream(&file); + + if (fileType==FILE_TYPE_XML) { + if (!XmlInterface(outputStream).save(radioData)) { + QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile).arg(file.errorString())); + file.close(); + return false; + } + } + else if (fileType==FILE_TYPE_HEX || fileType==FILE_TYPE_EEPE) { // write hex + if (fileType==FILE_TYPE_EEPE) + outputStream << EEPE_EEPROM_FILE_HEADER << "\n"; + + if (!HexInterface(outputStream).save(eeprom, eeprom_size)) { + QMessageBox::warning(this, tr("Error"),tr("Cannot write file %1:\n%2.").arg(myFile).arg(file.errorString())); + file.close(); + return false; + } + } + else if (fileType==FILE_TYPE_BIN) // write binary + { + long result = file.write((char*)eeprom, eeprom_size); + if(result!=eeprom_size) { + QMessageBox::warning(this, tr("Error"),tr("Error writing file %1:\n%2.").arg(myFile).arg(file.errorString())); + return false; + } + } + else { + QMessageBox::warning(this, tr("Error"),tr("Error writing file %1:\n%2.").arg(myFile).arg("Unknown format")); + return false; + } + + free(eeprom); // TODO free in all cases ... + file.close(); + if(setCurrent) setCurrentFile(myFile); + + return true; +} + +QString MdiChild::userFriendlyCurrentFile() +{ + return strippedName(curFile); +} + +void MdiChild::closeEvent(QCloseEvent *event) +{ + if (maybeSave()) { + event->accept(); + } + else { + event->ignore(); + } +} + +void MdiChild::documentWasModified() +{ + setWindowModified(fileChanged); +} + +bool MdiChild::maybeSave() +{ + if (fileChanged) { + QMessageBox::StandardButton ret; + ret = QMessageBox::warning(this, tr("Companion"), + tr("%1 has been modified.\n" + "Do you want to save your changes?").arg(userFriendlyCurrentFile()), + QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + + if (ret == QMessageBox::Save) + return save(); + else if (ret == QMessageBox::Cancel) + return false; + } + return true; +} + +void MdiChild::setCurrentFile(const QString &fileName) +{ + curFile = QFileInfo(fileName).canonicalFilePath(); + isUntitled = false; + fileChanged = false; + setWindowModified(false); + updateTitle(); + int MaxRecentFiles = g.historySize(); + QStringList files = g.recentFiles(); + files.removeAll(fileName); + files.prepend(fileName); + while (files.size() > MaxRecentFiles) + files.removeLast(); + + g.recentFiles( files ); +} + +QString MdiChild::strippedName(const QString &fullFileName) +{ + return QFileInfo(fullFileName).fileName(); +} + +void MdiChild::writeEeprom() // write to Tx +{ + bool backupEnable=g.enableBackup(); + QString backupPath=g.backupDir(); + if (!backupPath.isEmpty()) { + if (!QDir(backupPath).exists()) { + if (backupEnable) { + QMessageBox::warning(this, tr("Backup is impossible"), tr("The backup dir set in preferences does not exist")); + } + backupEnable=false; + } + } + else { + backupEnable=false; + } + QString stickCal=g.profile[g.id()].stickPotCalib(); + burnConfigDialog bcd; + QString tempDir = QDir::tempPath(); + QString tempFile = tempDir + "/temp.bin"; + saveFile(tempFile, false); + if(!QFileInfo(tempFile).exists()) { + QMessageBox::critical(this,tr("Error"), tr("Cannot write temporary file!")); + return; + } + EEPROMInterface *eepromInterface = GetEepromInterface(); + bool backup=false; + burnDialog *cd = new burnDialog(this, 1, &tempFile, &backup,strippedName(curFile)); + cd->exec(); + if (!tempFile.isEmpty()) { + if (backup) { + if (backupEnable) { + QString backupFile=backupPath+"/backup-"+QDateTime().currentDateTime().toString("yyyy-MM-dd-HHmmss")+".bin"; + if (IS_TARANIS(eepromInterface->getBoard())) { + QString path=((MainWindow *)this->parent())->FindTaranisPath(); + if (path.isEmpty()) { taranisNotFoundDialog *tnfd = new taranisNotFoundDialog(this); tnfd->exec(); - return; - } - else { - QStringList str; - str << path << backupFile; + return; + } + else { + QStringList str; + str << path << backupFile; avrOutputDialog *ad = new avrOutputDialog(this,"", str, tr("Backup EEPROM From Radio")); //, AVR_DIALOG_KEEP_OPEN); - ad->setWindowIcon(CompanionIcon("read_eeprom.png")); - ad->exec(); - delete ad; - sleep(1); - } - } - else { - QStringList str = ((MainWindow *)this->parent())->GetReceiveEEpromCommand(backupFile); + ad->setWindowIcon(CompanionIcon("read_eeprom.png")); + ad->exec(); + delete ad; + sleep(1); + } + } + else { + QStringList str = ((MainWindow *)this->parent())->GetReceiveEEpromCommand(backupFile); avrOutputDialog *ad = new avrOutputDialog(this, ((MainWindow *)this->parent())->GetAvrdudeLocation(), str, tr("Backup EEPROM From Radio")); - ad->setWindowIcon(CompanionIcon("read_eeprom.png")); - ad->exec(); - delete ad; - sleep(1); - } - } - int oldrev=((MainWindow *)this->parent())->getEpromVersion(tempFile); - QString tempFlash=tempDir + "/flash.bin"; - QStringList str = ((MainWindow *)this->parent())->GetReceiveFlashCommand(tempFlash); + ad->setWindowIcon(CompanionIcon("read_eeprom.png")); + ad->exec(); + delete ad; + sleep(1); + } + } + int oldrev=((MainWindow *)this->parent())->getEpromVersion(tempFile); + QString tempFlash=tempDir + "/flash.bin"; + QStringList str = ((MainWindow *)this->parent())->GetReceiveFlashCommand(tempFlash); avrOutputDialog *ad = new avrOutputDialog(this, ((MainWindow *)this->parent())->GetAvrdudeLocation(), str, "Read Flash From Radio"); - ad->setWindowIcon(CompanionIcon("read_flash.png")); - ad->exec(); - delete ad; - sleep(1); - QString restoreFile = tempDir + "/compat.bin"; - if (!((MainWindow *)this->parent())->convertEEPROM(tempFile, restoreFile, tempFlash)) { - int ret = QMessageBox::question(this, tr("Error"), tr("Cannot check eeprom compatibility! Continue anyway?"), QMessageBox::Yes | QMessageBox::No); - if (ret == QMessageBox::No) - return; - } - else { - int rev=((MainWindow *)this->parent())->getEpromVersion(restoreFile); - if ((rev/100)!=(oldrev/100)) { - QMessageBox::warning(this,tr("Warning"), tr("Firmware in radio is of a different family of eeprom written, check file and preferences!")); - } - if (revgetBoard())) { - QString path=((MainWindow *)this->parent())->FindTaranisPath(); - if (path.isEmpty()) { + ad->setWindowIcon(CompanionIcon("read_flash.png")); + ad->exec(); + delete ad; + sleep(1); + QString restoreFile = tempDir + "/compat.bin"; + if (!((MainWindow *)this->parent())->convertEEPROM(tempFile, restoreFile, tempFlash)) { + int ret = QMessageBox::question(this, tr("Error"), tr("Cannot check eeprom compatibility! Continue anyway?"), QMessageBox::Yes | QMessageBox::No); + if (ret == QMessageBox::No) + return; + } + else { + int rev=((MainWindow *)this->parent())->getEpromVersion(restoreFile); + if ((rev/100)!=(oldrev/100)) { + QMessageBox::warning(this,tr("Warning"), tr("Firmware in radio is of a different family of eeprom written, check file and preferences!")); + } + if (revgetBoard())) { + QString path=((MainWindow *)this->parent())->FindTaranisPath(); + if (path.isEmpty()) { taranisNotFoundDialog *tnfd = new taranisNotFoundDialog(this); tnfd->exec(); - return; - } - else { - QFile::copy(path,backupFile); - } - } - else { - QStringList str = ((MainWindow *)this->parent())->GetReceiveEEpromCommand(backupFile); + return; + } + else { + QFile::copy(path,backupFile); + } + } + else { + QStringList str = ((MainWindow *)this->parent())->GetReceiveEEpromCommand(backupFile); avrOutputDialog *ad = new avrOutputDialog(this, ((MainWindow *)this->parent())->GetAvrdudeLocation(), str, tr("Backup EEPROM From Radio")); - ad->setWindowIcon(CompanionIcon("read_eeprom.png")); - ad->exec(); - delete ad; - sleep(1); - } - } - } - - if (IS_TARANIS(eepromInterface->getBoard())) { - QString path=((MainWindow *)this->parent())->FindTaranisPath(); - if (path.isEmpty()) { + ad->setWindowIcon(CompanionIcon("read_eeprom.png")); + ad->exec(); + delete ad; + sleep(1); + } + } + } + + if (IS_TARANIS(eepromInterface->getBoard())) { + QString path=((MainWindow *)this->parent())->FindTaranisPath(); + if (path.isEmpty()) { taranisNotFoundDialog *tnfd = new taranisNotFoundDialog(this); tnfd->exec(); - return; - } - else { - QStringList str; - str << tempFile << path; + return; + } + else { + QStringList str; + str << tempFile << path; avrOutputDialog *ad = new avrOutputDialog(this,"", str, tr("Write EEPROM To Radio"), AVR_DIALOG_SHOW_DONE); //, AVR_DIALOG_KEEP_OPEN); - ad->setWindowIcon(CompanionIcon("read_eeprom.png")); - ad->exec(); - delete ad; - sleep(1); - } - } - else { - QStringList str = ((MainWindow *)this->parent())->GetSendEEpromCommand(tempFile); + ad->setWindowIcon(CompanionIcon("read_eeprom.png")); + ad->exec(); + delete ad; + sleep(1); + } + } + else { + QStringList str = ((MainWindow *)this->parent())->GetSendEEpromCommand(tempFile); avrOutputDialog *ad = new avrOutputDialog(this, ((MainWindow *)this->parent())->GetAvrdudeLocation(), str, "Write EEPROM To Radio", AVR_DIALOG_SHOW_DONE); - ad->setWindowIcon(CompanionIcon("write_eeprom.png")); - ad->exec(); - delete ad; - } - } -} - -void MdiChild::simulate() -{ - if (ui->modelsList->currentRow() >= 1) { - startSimulation(this, radioData, ui->modelsList->currentRow()-1); - } -} - -void MdiChild::print(int model, QString filename) -{ + ad->setWindowIcon(CompanionIcon("write_eeprom.png")); + ad->exec(); + delete ad; + } + } +} + +void MdiChild::simulate() +{ + if (ui->modelsList->currentRow() >= 1) { + startSimulation(this, radioData, ui->modelsList->currentRow()-1); + } +} + +void MdiChild::print(int model, QString filename) +{ PrintDialog * pd = NULL; - if (model>=0 && !filename.isEmpty()) { + if (model>=0 && !filename.isEmpty()) { pd = new PrintDialog(this, GetCurrentFirmware()/*firmware*/, &radioData.generalSettings, &radioData.models[model], filename); } else if (ui->modelsList->currentRow() > 0) { pd = new PrintDialog(this, GetCurrentFirmware()/*firmware*/, &radioData.generalSettings, &radioData.models[ui->modelsList->currentRow()-1]); } - + if (pd) { pd->setAttribute(Qt::WA_DeleteOnClose, true); - pd->show(); - } -} - -void MdiChild::viableModelSelected(bool viable) -{ - emit copyAvailable(viable); -} - -void MdiChild::setEEpromAvail(int eavail) -{ - EEPromAvail=eavail; -} - -bool MdiChild::loadBackup() -{ - QString fileName = QFileDialog::getOpenFileName(this, tr("Open backup Models and Settings file"), g.eepromDir(),tr(EEPROM_FILES_FILTER)); - if (fileName.isEmpty()) - return false; - QFile file(fileName); - - if (!file.exists()) { - QMessageBox::critical(this, tr("Error"), tr("Unable to find file %1!").arg(fileName)); - return false; - } - if(ui->modelsList->currentRow()<1) return false; - int index=ui->modelsList->currentRow()-1; - - int eeprom_size = file.size(); - if (!file.open(QFile::ReadOnly)) { //reading binary file - TODO HEX support - QMessageBox::critical(this, tr("Error"), - tr("Error opening file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - return false; - } + pd->show(); + } +} + +void MdiChild::viableModelSelected(bool viable) +{ + emit copyAvailable(viable); +} + +void MdiChild::setEEpromAvail(int eavail) +{ + EEPromAvail=eavail; +} + +bool MdiChild::loadBackup() +{ + QString fileName = QFileDialog::getOpenFileName(this, tr("Open backup Models and Settings file"), g.eepromDir(),tr(EEPROM_FILES_FILTER)); + if (fileName.isEmpty()) + return false; + QFile file(fileName); + + if (!file.exists()) { + QMessageBox::critical(this, tr("Error"), tr("Unable to find file %1!").arg(fileName)); + return false; + } + if(ui->modelsList->currentRow()<1) return false; + int index=ui->modelsList->currentRow()-1; + + int eeprom_size = file.size(); + if (!file.open(QFile::ReadOnly)) { //reading binary file - TODO HEX support + QMessageBox::critical(this, tr("Error"), + tr("Error opening file %1:\n%2.") + .arg(fileName) + .arg(file.errorString())); + return false; + } QByteArray eeprom(eeprom_size, 0); long result = file.read((char*)eeprom.data(), eeprom_size); - file.close(); - - if (result != eeprom_size) { - QMessageBox::critical(this, tr("Error"), - tr("Error reading file %1:\n%2.") - .arg(fileName) - .arg(file.errorString())); - - return false; - } - - if (!LoadBackup(radioData, (uint8_t *)eeprom.data(), eeprom_size, index)) { - QMessageBox::critical(this, tr("Error"), - tr("Invalid binary backup File %1") - .arg(fileName)); - return false; - } - - ui->modelsList->refreshList(); + file.close(); - return true; -} + if (result != eeprom_size) { + QMessageBox::critical(this, tr("Error"), + tr("Error reading file %1:\n%2.") + .arg(fileName) + .arg(file.errorString())); + + return false; + } + + if (!LoadBackup(radioData, (uint8_t *)eeprom.data(), eeprom_size, index)) { + QMessageBox::critical(this, tr("Error"), + tr("Invalid binary backup File %1") + .arg(fileName)); + return false; + } + + ui->modelsList->refreshList(); + + return true; +}