diff --git a/radio/src/debug.cpp b/radio/src/debug.cpp index 101359994..3b1c32a64 100644 --- a/radio/src/debug.cpp +++ b/radio/src/debug.cpp @@ -221,8 +221,6 @@ const char * debugTimerNames[DEBUG_TIMERS_COUNT] = { ,"Mix eval " // debugTimerEvalMixes, ,"Mix 10ms " // debugTimerMixes10ms, ,"ADC read " // debugTimerAdcRead, - ,"ADC loop " // debugTimerAdcLoop, - ,"ADC wait " // debugTimerAdcWait, ,"mix-pulses " // debugTimerMixerCalcToUsage ,"mix-int. " // debugTimerMixerIterval }; diff --git a/radio/src/debug.h b/radio/src/debug.h index 6edabc6f0..299edfcfa 100644 --- a/radio/src/debug.h +++ b/radio/src/debug.h @@ -321,8 +321,6 @@ enum DebugTimers { debugTimerMixes10ms, debugTimerAdcRead, - debugTimerAdcLoop, - debugTimerAdcWait, debugTimerMixerCalcToUsage, debugTimerMixerIterval, diff --git a/radio/src/gui/horus/view_statistics.cpp b/radio/src/gui/horus/view_statistics.cpp index fb21b38b8..88a77a4ec 100644 --- a/radio/src/gui/horus/view_statistics.cpp +++ b/radio/src/gui/horus/view_statistics.cpp @@ -162,7 +162,7 @@ bool menuStatsAnalogs(evt_t event) #if defined(JITTER_MEASURE) lcdDrawNumber(x+100, y, rawJitter[i].get()); lcdDrawNumber(x+140, y, avgJitter[i].get()); - lcdDrawNumber(x+180, y, (int16_t)calibratedStick[CONVERT_MODE(i)]*25/256); + lcdDrawNumber(x+180, y, (int16_t)calibratedStick[CONVERT_MODE(i)]*250/256, PREC1); #else lcdDrawNumber(x+100, y, (int16_t)calibratedStick[CONVERT_MODE(i)]*25/256); #endif diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 92fa608ad..760a629bf 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -1463,30 +1463,20 @@ uint16_t BandGap = 225; // G: Note that the above would have set the ADC prescaler to 128, equating to // 125KHz sample rate. We now sample at 500KHz, with oversampling and other // filtering options to produce 11-bit results. -uint16_t BandGap = 2040 ; +uint16_t BandGap = 2040; #elif defined(PCBSTD) -uint16_t BandGap ; +uint16_t BandGap; #endif #if defined(JITTER_MEASURE) - JitterMeter rawJitter[NUMBER_ANALOG]; - JitterMeter avgJitter[NUMBER_ANALOG]; - tmr10ms_t jitterResetTime = 0; - #if defined(PCBHORUS) - #define JITTER_MEASURE_ACTIVE() (menuHandlers[menuLevel] == menuStatsAnalogs) - #elif defined(PCBTARANIS) - #define JITTER_MEASURE_ACTIVE() (menuHandlers[menuLevel] == menuGeneralDiagAna) - #elif defined(CLI) - #define JITTER_MEASURE_ACTIVE() (1) - #else - #define JITTER_MEASURE_ACTIVE() (0) - #endif +JitterMeter rawJitter[NUMBER_ANALOG]; +JitterMeter avgJitter[NUMBER_ANALOG]; +tmr10ms_t jitterResetTime = 0; #endif - #if defined(VIRTUALINPUTS) && defined(JITTER_FILTER) #define JITTER_FILTER_STRENGTH 4 // tune this value, bigger value - more filtering (range: 1-5) (see explanation below) - #define ANALOG_SCALE 1 // tune this value, bigger value - more filtering (range: 0-3) (see explanation below) + #define ANALOG_SCALE 1 // tune this value, bigger value - more filtering (range: 0-1) (see explanation below) #define JITTER_ALPHA (1<> (3 - ANALOG_SCALE); + for (uint8_t x=0; x> (1 - ANALOG_SCALE); #if defined(VIRTUALINPUTS) && defined(JITTER_FILTER) // Jitter filter: diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 350295206..8da83c82a 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -1790,7 +1790,16 @@ extern uint16_t s_anaFilt[NUMBER_ANALOG]; #if defined(JITTER_MEASURE) extern JitterMeter rawJitter[NUMBER_ANALOG]; extern JitterMeter avgJitter[NUMBER_ANALOG]; -#endif // defined(JITTER_MEASURE) +#if defined(PCBHORUS) + #define JITTER_MEASURE_ACTIVE() (menuHandlers[menuLevel] == menuStatsAnalogs) +#elif defined(PCBTARANIS) + #define JITTER_MEASURE_ACTIVE() (menuHandlers[menuLevel] == menuGeneralDiagAna) +#elif defined(CLI) + #define JITTER_MEASURE_ACTIVE() (1) +#else + #define JITTER_MEASURE_ACTIVE() (0) +#endif +#endif #define WDT_500MS 500 diff --git a/radio/src/targets/horus/adc_driver.cpp b/radio/src/targets/horus/adc_driver.cpp index 49c45d92b..def0d6f4c 100644 --- a/radio/src/targets/horus/adc_driver.cpp +++ b/radio/src/targets/horus/adc_driver.cpp @@ -18,11 +18,23 @@ * GNU General Public License for more details. */ -#include "../../opentx.h" +#include "opentx.h" #define ADC_CS_HIGH() (ADC_SPI_GPIO->BSRRL = ADC_SPI_PIN_CS) #define ADC_CS_LOW() (ADC_SPI_GPIO->BSRRH = ADC_SPI_PIN_CS) +#define SPI_STICK1 0 +#define SPI_STICK2 1 +#define SPI_STICK3 2 +#define SPI_STICK4 3 +#define SPI_S1 4 +#define SPI_6POS 5 +#define SPI_S2 6 +#define SPI_LS 7 +#define SPI_RS 8 +#define SPI_TX_VOLTAGE 9 +#define SPI_L2 10 +#define SPI_L1 11 #define RESETCMD 0x4000 #define MANUAL_MODE 0x1000 // manual mode channel 0 @@ -30,7 +42,7 @@ uint16_t adcValues[NUMBER_ANALOG] __DMA; -static u16 SPIx_ReadWriteByte(uint16_t value) +uint16_t SPIx_ReadWriteByte(uint16_t value) { while(SPI_I2S_GetFlagStatus(ADC_SPI,SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(ADC_SPI,value); @@ -87,27 +99,13 @@ static void ADS7952_Init() ADC_CS_LOW(); SPIx_ReadWriteByte(MANUAL_MODE); ADC_CS_HIGH(); - -// SPIx_ReadWriteByte(ProgramReg_Auto2 ); -// ADC_CS_HIGH(); - -// asm("nop"); -// ADC_CS_LOW(); -// SPIx_ReadWriteByte(AutoMode_2); -// ADC_CS_HIGH(); - -// asm("nop"); -// ADC_CS_LOW(); -// SPIx_ReadWriteByte(ContinuedSelectMode); -// ADC_CS_HIGH(); -// asm("nop"); } void adcInit() { ADS7952_Init(); - configure_pins( ADC_GPIO_PIN_MOUSE1 | ADC_GPIO_PIN_MOUSE2, PIN_ANALOG | PIN_PORTF ); + configure_pins(ADC_GPIO_PIN_MOUSE1 | ADC_GPIO_PIN_MOUSE2, PIN_ANALOG | PIN_PORTF); ADC3->CR1 = ADC_CR1_SCAN; ADC3->CR2 = ADC_CR2_ADON | ADC_CR2_DMA | ADC_CR2_DDS; @@ -126,42 +124,72 @@ void adcInit() DMA2_Stream1->FCR = DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0; } -#define SPI_STICK1 0 -#define SPI_STICK2 1 -#define SPI_STICK3 2 -#define SPI_STICK4 3 -#define SPI_S1 4 -#define SPI_6POS 5 -#define SPI_S2 6 -#define SPI_LS 7 -#define SPI_RS 8 -#define SPI_TX_VOLTAGE 9 -#define SPI_L2 10 -#define SPI_L1 11 - const uint16_t adcCommands[MOUSE1+2] = { - MANUAL_MODE | ( SPI_STICK1 << 7 ), - MANUAL_MODE | ( SPI_STICK2 << 7 ), - MANUAL_MODE | ( SPI_STICK3 << 7 ), - MANUAL_MODE | ( SPI_STICK4 << 7 ), - MANUAL_MODE | ( SPI_S1 << 7 ), - MANUAL_MODE | ( SPI_6POS << 7 ), - MANUAL_MODE | ( SPI_S2 << 7 ), - MANUAL_MODE | ( SPI_L1 << 7 ), - MANUAL_MODE | ( SPI_L2 << 7 ), - MANUAL_MODE | ( SPI_LS << 7 ), - MANUAL_MODE | ( SPI_RS << 7 ), - MANUAL_MODE | ( SPI_TX_VOLTAGE << 7 ), - MANUAL_MODE | ( 0 << 7 ), // small joystick left/right - MANUAL_MODE | ( 0 << 7 ) // small joystick up/down + MANUAL_MODE | (SPI_STICK1 << 7), + MANUAL_MODE | (SPI_STICK2 << 7), + MANUAL_MODE | (SPI_STICK3 << 7), + MANUAL_MODE | (SPI_STICK4 << 7), + MANUAL_MODE | (SPI_S1 << 7), + MANUAL_MODE | (SPI_6POS << 7), + MANUAL_MODE | (SPI_S2 << 7), + MANUAL_MODE | (SPI_L1 << 7), + MANUAL_MODE | (SPI_L2 << 7), + MANUAL_MODE | (SPI_LS << 7), + MANUAL_MODE | (SPI_RS << 7), + MANUAL_MODE | (SPI_TX_VOLTAGE << 7), + MANUAL_MODE | (0 << 7 ), // small joystick left/right + MANUAL_MODE | (0 << 7 ) // small joystick up/down }; -void adcRead() +void adcReadSPIDummy() { - const uint16_t * command = adcCommands; + // A dummy command to get things started + // (because the sampled data is lagging behind for two command cycles) + ADC_CS_LOW(); + delay_01us(1); + SPIx_ReadWriteByte(adcCommands[0]); + ADC_CS_HIGH(); + delay_01us(1); +} - // Start on chip ADC read +uint32_t adcReadNextSPIChannel(uint8_t index) +{ + uint32_t result = 0; + + // This delay is to allow charging of ADC input capacitor + // after the MUX changes from one channel to the other. + // It was determined experimentally. Biggest problem seems to be + // the cross-talk between A4:S1 and A5:MULTIPOS. Changing S1 for one extreme + // to the other resulted in A5 change of: + // + // delay value A5 change Time needed for adcRead() + // 1 16 0.154ms - 0.156ms + // 300 5 0.197ms - 0.199ms + // 500 0 0.225ms - 0.243ms + delay_01us(300); + + for (uint8_t i = 0; i < 4; i++) { + ADC_CS_LOW(); + delay_01us(1); + // command is changed to the next index for the last two readings + // (because the sampled data is lagging behind for two command cycles) + uint16_t val = (0x0fff & SPIx_ReadWriteByte(adcCommands[(i>1) ? index+1 : index])); +#if defined(JITTER_MEASURE) + if (JITTER_MEASURE_ACTIVE()) { + rawJitter[index].measure(val); + } +#endif + ADC_CS_HIGH(); + delay_01us(1); + result += val; + } + + return result >> 2; +} + +void adcOnChipReadStart() +{ DMA2_Stream1->CR &= ~DMA_SxCR_EN; // Disable DMA ADC3->SR &= ~(uint32_t) ( ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR ); DMA2->LIFCR = DMA_LIFCR_CTCIF1 | DMA_LIFCR_CHTIF1 |DMA_LIFCR_CTEIF1 | DMA_LIFCR_CDMEIF1 | DMA_LIFCR_CFEIF1; // Write ones to clear bits @@ -169,60 +197,48 @@ void adcRead() DMA2_Stream1->NDTR = 2; DMA2_Stream1->CR |= DMA_SxCR_EN; // Enable DMA ADC3->CR2 |= (uint32_t)ADC_CR2_SWSTART; +} - // A dummy command to get things started - // (because the sampled data is lagging behind for two command cycles) - ADC_CS_LOW(); - delay_01us(1); - SPIx_ReadWriteByte(*command); // still sampling the old MUX channel - ADC_CS_HIGH(); - delay_01us(1); +bool adcOnChipReadFinished() +{ + return (DMA2->LISR & DMA_LISR_TCIF1); +} - DEBUG_TIMER_START(debugTimerAdcLoop); - for (uint32_t adcIndex=0; adcIndexLISR & DMA_LISR_TCIF1) { - break; + adcOnChipReadStart(); + adcReadSPIDummy(); + adcReadSPIDummy(); + for (uint32_t index=0; index> 2; + } } const int8_t ana_direction[NUMBER_ANALOG] = {1,-1,1,-1, -1,1,-1, -1,-1, -1,1, 0,0,0}; @@ -230,7 +246,7 @@ const int8_t ana_direction[NUMBER_ANALOG] = {1,-1,1,-1, -1,1,-1, -1,-1, -1,1, uint16_t getAnalogValue(uint8_t index) { if (ana_direction[index] < 0) - return 4096 - adcValues[index]; + return 4095 - adcValues[index]; else return adcValues[index]; } diff --git a/radio/src/targets/sky9x/adc_driver.cpp b/radio/src/targets/sky9x/adc_driver.cpp index df38418ca..8cd4dc066 100644 --- a/radio/src/targets/sky9x/adc_driver.cpp +++ b/radio/src/targets/sky9x/adc_driver.cpp @@ -18,7 +18,7 @@ * GNU General Public License for more details. */ -#include "../opentx.h" +#include "opentx.h" uint16_t adcValues[NUMBER_ANALOG]; @@ -63,12 +63,13 @@ void adcInit() // Read 8 (9 for REVB) ADC channels // Documented bug, must do them 1 by 1 -void adcRead() +void adcSingleRead() { register Adc *padc; register uint32_t y; register uint32_t x; + for (uint8_t i=0; i<4; i++) padc = ADC; y = padc->ADC_ISR; // Clear EOC flags for (y = NUMBER_ANALOG+1; --y > 0;) { @@ -112,6 +113,29 @@ void adcRead() #endif } +void adcRead() +{ + uint16_t temp[NUMBER_ANALOG] = { 0 }; + + for (int i=0; i<4; i++) { + adcSingleRead(); + for (uint8_t x=0; x> 2; + } +} + + uint16_t getAnalogValue(uint8_t value) { return adcValues[value]; diff --git a/radio/src/targets/taranis/adc_driver.cpp b/radio/src/targets/taranis/adc_driver.cpp index 2b3ca7f75..1d010deb5 100644 --- a/radio/src/targets/taranis/adc_driver.cpp +++ b/radio/src/targets/taranis/adc_driver.cpp @@ -18,7 +18,7 @@ * GNU General Public License for more details. */ -#include "../../opentx.h" +#include "opentx.h" #define PIN_ANALOG 0x0003 #define PIN_PORTA 0x0000 @@ -111,13 +111,14 @@ void adcInit() #endif } -void adcRead() +void adcSingleRead() { - DMA2_Stream0->CR &= ~DMA_SxCR_EN ; // Disable DMA - ADC1->SR &= ~(uint32_t) ( ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR ) ; - DMA2->LIFCR = DMA_LIFCR_CTCIF0 | DMA_LIFCR_CHTIF0 |DMA_LIFCR_CTEIF0 | DMA_LIFCR_CDMEIF0 | DMA_LIFCR_CFEIF0 ; // Write ones to clear bits - DMA2_Stream0->CR |= DMA_SxCR_EN ; // Enable DMA - ADC1->CR2 |= (uint32_t)ADC_CR2_SWSTART ; + DMA2_Stream0->CR &= ~DMA_SxCR_EN; // Disable DMA + ADC1->SR &= ~(uint32_t)(ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR); + DMA2->LIFCR = DMA_LIFCR_CTCIF0 | DMA_LIFCR_CHTIF0 | DMA_LIFCR_CTEIF0 | DMA_LIFCR_CDMEIF0 | + DMA_LIFCR_CFEIF0; // Write ones to clear bits + DMA2_Stream0->CR |= DMA_SxCR_EN; // Enable DMA + ADC1->CR2 |= (uint32_t) ADC_CR2_SWSTART; #if defined(REV9E) DMA2_Stream1->CR &= ~DMA_SxCR_EN ; // Disable DMA @@ -125,7 +126,7 @@ void adcRead() DMA2->LIFCR = DMA_LIFCR_CTCIF1 | DMA_LIFCR_CHTIF1 |DMA_LIFCR_CTEIF1 | DMA_LIFCR_CDMEIF1 | DMA_LIFCR_CFEIF1 ; // Write ones to clear bits DMA2_Stream1->CR |= DMA_SxCR_EN ; // Enable DMA ADC3->CR2 |= (uint32_t)ADC_CR2_SWSTART ; -#endif // #if defined(REV9E) +#endif // defined(REV9E) #if defined(REV9E) for (unsigned int i=0; i<10000; i++) { @@ -136,15 +137,37 @@ void adcRead() DMA2_Stream0->CR &= ~DMA_SxCR_EN ; // Disable DMA DMA2_Stream1->CR &= ~DMA_SxCR_EN ; // Disable DMA #else - for (unsigned int i=0; i<10000; i++) { + for (unsigned int i = 0; i < 10000; i++) { if (DMA2->LISR & DMA_LISR_TCIF0) { break; } } - DMA2_Stream0->CR &= ~DMA_SxCR_EN ; // Disable DMA + DMA2_Stream0->CR &= ~DMA_SxCR_EN; // Disable DMA #endif } +void adcRead() +{ + uint16_t temp[NUMBER_ANALOG] = { 0 }; + + for (int i=0; i<4; i++) { + adcSingleRead(); + for (uint8_t x=0; x> 2; + } +} + // TODO void adcStop() { @@ -162,7 +185,7 @@ uint16_t getAnalogValue(uint8_t index) index = ana_mapping[index]; #endif if (ana_direction[index] < 0) - return 4096 - adcValues[index]; + return 4095 - adcValues[index]; else return adcValues[index]; }