From 32b5f479925bb839b3533eadc5c119065e7aedd0 Mon Sep 17 00:00:00 2001 From: "romolo.manfredini@gmail.com" Date: Sun, 30 Sep 2012 14:17:22 +0000 Subject: [PATCH] Add coprocessor support --- src/ersky9x/sound_driver.cpp | 238 +++++++++++++++++++++++++++++++---- src/ersky9x/sound_driver.h | 4 + src/general_menus.cpp | 35 ++++-- src/open9x.cpp | 2 + src/open9x.h | 13 ++ src/translations.cpp | 4 +- src/translations.h | 4 +- 7 files changed, 265 insertions(+), 35 deletions(-) diff --git a/src/ersky9x/sound_driver.cpp b/src/ersky9x/sound_driver.cpp index e28f4318f..468e9e84a 100644 --- a/src/ersky9x/sound_driver.cpp +++ b/src/ersky9x/sound_driver.cpp @@ -140,7 +140,7 @@ void start_timer1() ptc->TC_CHANNEL[1].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger) // Sound_g.Frequency = 1000 ; } - + // Configure DAC1 (or DAC0 for REVB) // Not sure why PB14 has not be allocated to the DAC, although it is an EXTRA function @@ -227,46 +227,238 @@ void init_twi() NVIC_EnableIRQ(TWI0_IRQn) ; setVolume(2) ; } +extern t_time Time; +static int8_t Volume_required ; +static uint8_t Volume_read_pending ; +static uint8_t CoProc_read_pending ; +static uint8_t CoProc_write_pending ; +static uint8_t CoProc_appgo_pending ; +uint8_t Volume_read ; +uint8_t Coproc_read ; +int8_t Coproc_valid ; +static uint8_t *Twi_read_address ; +static uint8_t TwiOperation ; + +#define TWI_NONE 0 +#define TWI_READ_VOL 1 +#define TWI_WRITE_VOL 2 +#define TWI_READ_COPROC 3 +#define TWI_COPROC_APPGO 4 +#define TWI_WAIT_STOP 5 +#define TWI_WRITE_COPROC 6 + +// Commands to the coprocessor bootloader/application +#define TWI_CMD_PAGEUPDATE 0x01 // TWI Command to program a flash page +#define TWI_CMD_EXECUTEAPP 0x02 // TWI Command to jump to the application program +#define TWI_CMD_SETREAD_ADDRESS 0x03 // TWI Command to set address to read from +#define TWI_CMD_WRITE_DATA 0x04 // TWI Command send data to the application +#define COPROC_RX_BUXSIZE 22 +uint8_t Co_proc_status[COPROC_RX_BUXSIZE] ; +uint8_t *Co_proc_write_ptr ; +uint32_t Co_proc_write_count ; + + +// This is called from an interrupt routine, or +// interrupts must be disabled while it is called +// from elsewhere. +void i2c_check_for_request() +{ + if ( TWI0->TWI_IMR & TWI_IMR_TXCOMP ) + { + return ; // Busy + } + + if ( Volume_required >= 0 ) // Set volume to this value + { + TWI0->TWI_MMR = 0x002F0000 ; // Device 5E (>>1) and master is writing + TwiOperation = TWI_WRITE_VOL ; + TWI0->TWI_THR = Volume_required ; // Send data + Volume_required = -1 ; + TWI0->TWI_IER = TWI_IER_TXCOMP ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx + } + else if ( CoProc_read_pending ) + { + Coproc_valid = 0 ; + CoProc_read_pending = 0 ; + TWI0->TWI_MMR = 0x00351000 ; // Device 35 and master is reading + TwiOperation = TWI_READ_COPROC ; +#ifndef SIMU + TWI0->TWI_RPR = (uint32_t)&Co_proc_status[0] ; +#endif + TWI0->TWI_RCR = COPROC_RX_BUXSIZE - 1 ; + if ( TWI0->TWI_SR & TWI_SR_RXRDY ) + { + (void) TWI0->TWI_RHR ; + } + TWI0->TWI_PTCR = TWI_PTCR_RXTEN ; // Start transfers + TWI0->TWI_CR = TWI_CR_START ; // Start Rx + TWI0->TWI_IER = TWI_IER_RXBUFF | TWI_IER_TXCOMP ; + } + else if ( Volume_read_pending ) + { + Volume_read_pending = 0 ; + TWI0->TWI_MMR = 0x002F1000 ; // Device 5E (>>1) and master is reading + TwiOperation = TWI_READ_VOL ; + Twi_read_address = &Volume_read ; + TWI0->TWI_CR = TWI_CR_START | TWI_CR_STOP ; // Start and stop Tx + TWI0->TWI_IER = TWI_IER_TXCOMP ; + } + else if ( CoProc_appgo_pending ) + { + CoProc_appgo_pending = 0 ; + TWI0->TWI_MMR = 0x00350000 ; // Device 35 and master is writing + TwiOperation = TWI_COPROC_APPGO ; + TWI0->TWI_THR = TWI_CMD_EXECUTEAPP ; // Send appgo command + TWI0->TWI_IER = TWI_IER_TXCOMP ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx + } + else if ( CoProc_write_pending ) + { + CoProc_write_pending = 0 ; + TWI0->TWI_MMR = 0x00350000 ; // Device 35 and master is writing + TwiOperation = TWI_WRITE_COPROC ; +#ifndef SIMU + TWI0->TWI_TPR = (uint32_t)Co_proc_write_ptr ; +#endif + TWI0->TWI_TCR = Co_proc_write_count ; + TWI0->TWI_THR = TWI_CMD_WRITE_DATA ; // Send write command + TWI0->TWI_PTCR = TWI_PTCR_TXTEN ; // Start data transfer + TWI0->TWI_IER = TWI_IER_TXBUFE | TWI_IER_TXCOMP ; + } +} -static int16_t volumeRequiredIrq ; static const uint8_t Volume_scale[NUM_VOL_LEVELS] = { 0, 2, 4, 6, 8, 10, 13, 17, 22, 27, 33, 40, 64, 82, 96, 105, 112, 117, 120, 122, 124, 125, 126, 127 } ; -void setVolume( register uint8_t volume ) +void setVolume( unsigned char volume ) { -// PMC->PMC_PCER0 |= 0x00080000L ; // Enable peripheral clock to TWI0 - - if (volume >= NUM_VOL_LEVELS) { - volume = NUM_VOL_LEVELS - 1 ; +// PMC->PMC_PCER0 |= 0x00080000L ; // Enable peripheral clock to TWI0 + + if ( volume >= NUM_VOL_LEVELS ) + { + volume = NUM_VOL_LEVELS - 1 ; } - volume = Volume_scale[volume] ; - + Volume_required = volume ; __disable_irq() ; - if ( TWI0->TWI_IMR & TWI_IMR_TXCOMP ) { - volumeRequiredIrq = volume ; - } - else { - TWI0->TWI_THR = volume ; // Send data - TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx - TWI0->TWI_IER = TWI_IER_TXCOMP ; - } + i2c_check_for_request() ; __enable_irq() ; } +void read_volume() +{ + Volume_read_pending = 1 ; + __disable_irq() ; + i2c_check_for_request() ; + __enable_irq() ; +} + +void read_coprocessor() +{ + CoProc_read_pending = 1 ; + __disable_irq() ; + i2c_check_for_request() ; + __enable_irq() ; +} + +void write_coprocessor( uint8_t *ptr, uint32_t count ) +{ + Co_proc_write_ptr = ptr ; + Co_proc_write_count = count ; + CoProc_write_pending = 1 ; + __disable_irq() ; + i2c_check_for_request() ; + __enable_irq() ; +} + +void appgo_coprocessor() +{ + CoProc_appgo_pending = 1 ; + __disable_irq() ; + i2c_check_for_request() ; + __enable_irq() ; +} + extern "C" void TWI0_IRQHandler() { - if ( volumeRequiredIrq >= 0 ) { - TWI0->TWI_THR = volumeRequiredIrq ; // Send data - volumeRequiredIrq = -1 ; - TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx + if ( TwiOperation == TWI_READ_VOL ) + { + if ( TWI0->TWI_SR & TWI_SR_RXRDY ) + { + *Twi_read_address = TWI0->TWI_RHR ; // Read data + } } - else { - TWI0->TWI_IDR = TWI_IDR_TXCOMP ; + + if ( TwiOperation == TWI_READ_COPROC ) + { + if ( TWI0->TWI_SR & TWI_SR_RXBUFF ) + { + TWI0->TWI_IDR = TWI_IDR_RXBUFF ; + TwiOperation = TWI_WAIT_STOP ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Rx + TWI0->TWI_RCR = 1 ; // Last byte + return ; + } + else + { + Coproc_valid = -1 ; + } + } + + if ( TwiOperation == TWI_WAIT_STOP ) + { + Coproc_valid = 1 ; + Coproc_read = Co_proc_status[0] ; + if ( Coproc_read & 0x80 ) // Bootloader + { + CoProc_appgo_pending = 1 ; // Action application + } + else + { // Got data from tiny app + // Set the date and time + t_time *p = &Time ; + + p->second = Co_proc_status[1] ; + p->minute = Co_proc_status[2] ; + p->hour = Co_proc_status[3] ; + p->date= Co_proc_status[4] ; + p->month = Co_proc_status[5] ; + p->year = Co_proc_status[6] + ( Co_proc_status[7] << 8 ) ; + } + TWI0->TWI_PTCR = TWI_PTCR_RXTDIS ; // Stop transfers + if ( TWI0->TWI_SR & TWI_SR_RXRDY ) + { + (void) TWI0->TWI_RHR ; // Discard any rubbish data + } } + +// if ( TwiOperation == TWI_WRITE_VOL ) +// { + +// } + + if ( TwiOperation == TWI_WRITE_COPROC ) + { + if ( TWI0->TWI_SR & TWI_SR_TXBUFE ) + { + TWI0->TWI_IDR = TWI_IDR_TXBUFE ; + TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx + TWI0->TWI_PTCR = TWI_PTCR_TXTDIS ; // Stop transfers + TwiOperation = TWI_NONE ; + return ; + } + } + + TWI0->TWI_IDR = TWI_IDR_TXCOMP | TWI_IDR_TXBUFE | TWI_PTCR_TXTDIS ; + if ( TWI0->TWI_SR & TWI_SR_NACK ) + { + } + TwiOperation = TWI_NONE ; + i2c_check_for_request() ; } diff --git a/src/ersky9x/sound_driver.h b/src/ersky9x/sound_driver.h index 22cb65462..646cd746f 100644 --- a/src/ersky9x/sound_driver.h +++ b/src/ersky9x/sound_driver.h @@ -45,6 +45,10 @@ extern void setFrequency( uint32_t frequency ) ; extern void start_timer1( void ) ; extern void initDac( void ) ; extern void end_sound( void ) ; +extern void write_coprocessor( uint8_t *ptr, uint32_t count ) ; +extern void read_coprocessor( void ) ; +extern uint8_t Coproc_read ; +extern int8_t Coproc_valid ; extern uint16_t *nextAudioData; extern uint16_t nextAudioSize; diff --git a/src/general_menus.cpp b/src/general_menus.cpp index 9f0a45a81..ff37adbc7 100644 --- a/src/general_menus.cpp +++ b/src/general_menus.cpp @@ -37,9 +37,17 @@ const pm_uchar sticks[] PROGMEM = { #include "sticks.lbm" }; +#if defined(PCBARM) +struct t_i2cTime +{ + uint8_t setCode ; + uint8_t Time[7] ; +} I2CTime ; +#endif + enum EnumTabDiag { e_Setup, -#if defined(PCBV4) && defined(SDCARD) +#if (defined(PCBV4) && defined(SDCARD)) || defined(PCBARM) e_FrskyTime, #endif #if defined(SDCARD) @@ -53,7 +61,7 @@ enum EnumTabDiag { }; void menuProcSetup(uint8_t event); -#if defined(PCBV4) && defined(SDCARD) +#if (defined(PCBV4) && defined(SDCARD)) || defined (PCBARM) void menuProcTime(uint8_t event); #endif #if defined(SDCARD) @@ -67,7 +75,7 @@ void menuProcDiagCalib(uint8_t event); const MenuFuncP_PROGMEM menuTabDiag[] PROGMEM = { menuProcSetup, -#if defined(PCBV4) && defined(SDCARD) +#if (defined(PCBV4) && defined(SDCARD)) || defined (PCBARM) menuProcTime, #endif #if defined(SDCARD) @@ -439,7 +447,7 @@ void menuProcSetup(uint8_t event) } -#if defined(PCBV4) && defined(SDCARD) +#if (defined(PCBV4) && defined(SDCARD)) || defined(PCBARM) // SD card interface contains Real-Time-Clock chip void menuProcTime(uint8_t event) { @@ -459,9 +467,9 @@ void menuProcTime(uint8_t event) case EVT_KEY_FIRST(KEY_MENU): if (sub >= 0 && s_editMode<=0) // set the date and time into RTC chip { - g_ms100 = 0; // start of next second begins now +#if (defined(PCBV4) && defined(SDCARD)) g_unixTime = gmktime(&t); // update local timestamp and get wday calculated - + g_ms100 = 0; // start of next second begins now RTC rtc; rtc.year = t.tm_year + 1900; rtc.month = t.tm_mon + 1; @@ -470,14 +478,25 @@ void menuProcTime(uint8_t event) rtc.min = t.tm_min; rtc.sec = t.tm_sec; rtc.wday = t.tm_wday + 1; - rtc_settime(&rtc); - +#else + I2CTime.setCode = 0x74 ; // Tiny SET TIME CODE command + I2CTime.Time[0] = t.tm_sec ; + I2CTime.Time[1] = t.tm_min ; + I2CTime.Time[2] = t.tm_hour ; + I2CTime.Time[3] = t.tm_mday ; + I2CTime.Time[4] = t.tm_mon+1 ; + I2CTime.Time[5] = (uint8_t) (t.tm_year+1900) ; + I2CTime.Time[6] = (t.tm_year+1900) >> 8 ; + write_coprocessor( (uint8_t *) &I2CTime, 8 ) ; +#endif } break; } +#if (defined(PCBV4) && defined(SDCARD)) if (s_editMode<=0) filltm(&g_unixTime, &t); +#endif lcd_putc(FW*10+2, FH*2, '-'); lcd_putc(FW*13, FH*2, '-'); lcd_putc(FW*10+1, FH*4, ':'); lcd_putc(FW*13-1, FH*4, ':'); diff --git a/src/open9x.cpp b/src/open9x.cpp index b47315154..69e7991af 100644 --- a/src/open9x.cpp +++ b/src/open9x.cpp @@ -87,6 +87,8 @@ ModelData g_model; #if !defined(PCBARM) uint8_t g_tmr1Latency_max; uint8_t g_tmr1Latency_min; +#else +t_time Time; #endif uint8_t unexpectedShutdown = 0; diff --git a/src/open9x.h b/src/open9x.h index 56ce4d59d..19e53c514 100644 --- a/src/open9x.h +++ b/src/open9x.h @@ -904,6 +904,19 @@ extern void deleteExpoMix(uint8_t expo, uint8_t idx); extern void incSubtrim(uint8_t idx, int16_t inc); extern void instantTrim(); extern void moveTrimsToOffsets(); +#if defined(PCBARM) +typedef struct +{ + unsigned char second; //enter the current time, date, month, and year + unsigned char minute; + unsigned char hour; + unsigned char date; + unsigned char month; + unsigned int year; +} t_time ; + +extern t_time Time ; +#endif #if defined(PCBARM) #define ACTIVE_EXPOS_TYPE uint32_t diff --git a/src/translations.cpp b/src/translations.cpp index 30ee57aab..247431e99 100644 --- a/src/translations.cpp +++ b/src/translations.cpp @@ -87,7 +87,7 @@ const pm_char STR_OPEN9X[] PROGMEM = #if defined(DSM2) ISTR(DSM2MODE) #endif -#if defined(PCBV4) +#if defined(PCBV4) || defined (PCBARM) ISTR(DATETIME) #endif ; @@ -233,7 +233,7 @@ const pm_char STR_EEPROMOVERFLOW[] PROGMEM = TR_EEPROMOVERFLOW; const pm_char STR_TRIMS2OFFSETS[] PROGMEM = TR_TRIMS2OFFSETS; const pm_char STR_MENURADIOSETUP[] PROGMEM = TR_MENURADIOSETUP; -#ifdef PCBV4 +#if defined(PCBV4) || defined(PCBARM) const pm_char STR_MENUDATEANDTIME[] PROGMEM = TR_MENUDATEANDTIME; #endif diff --git a/src/translations.h b/src/translations.h index c746e3894..9e68d64de 100644 --- a/src/translations.h +++ b/src/translations.h @@ -126,7 +126,7 @@ extern const pm_char STR_OPEN9X[]; #else #define OFS_ENDDSM2 (OFS_VTMRMODES + sizeof(TR_VTMRMODES)) #endif -#if defined(PCBV4) +#if defined(PCBV4) || defined (PCBARM) #define OFS_DATETIME (OFS_ENDDSM2) #endif @@ -190,7 +190,7 @@ extern const pm_char STR_OPEN9X[]; #define STR_VRENCODERS (STR_OPEN9X + OFS_VRENCODERS) #endif -#if defined(PCBV4) +#if defined(PCBV4) || defined(PCBARM) #define STR_DATETIME (STR_OPEN9X + OFS_DATETIME) #endif