mirror of
https://github.com/opentx/opentx.git
synced 2025-07-20 06:45:10 +03:00
Merge pull request #3407 from opentx/bsongis/adc_averaging_done_in_driver_layer
[ARM board] ADC are done 4 times inside the driver now. To be tested …
This commit is contained in:
commit
1f19256722
8 changed files with 192 additions and 147 deletions
|
@ -221,8 +221,6 @@ const char * debugTimerNames[DEBUG_TIMERS_COUNT] = {
|
||||||
,"Mix eval " // debugTimerEvalMixes,
|
,"Mix eval " // debugTimerEvalMixes,
|
||||||
,"Mix 10ms " // debugTimerMixes10ms,
|
,"Mix 10ms " // debugTimerMixes10ms,
|
||||||
,"ADC read " // debugTimerAdcRead,
|
,"ADC read " // debugTimerAdcRead,
|
||||||
,"ADC loop " // debugTimerAdcLoop,
|
|
||||||
,"ADC wait " // debugTimerAdcWait,
|
|
||||||
,"mix-pulses " // debugTimerMixerCalcToUsage
|
,"mix-pulses " // debugTimerMixerCalcToUsage
|
||||||
,"mix-int. " // debugTimerMixerIterval
|
,"mix-int. " // debugTimerMixerIterval
|
||||||
};
|
};
|
||||||
|
|
|
@ -321,8 +321,6 @@ enum DebugTimers {
|
||||||
debugTimerMixes10ms,
|
debugTimerMixes10ms,
|
||||||
|
|
||||||
debugTimerAdcRead,
|
debugTimerAdcRead,
|
||||||
debugTimerAdcLoop,
|
|
||||||
debugTimerAdcWait,
|
|
||||||
|
|
||||||
debugTimerMixerCalcToUsage,
|
debugTimerMixerCalcToUsage,
|
||||||
debugTimerMixerIterval,
|
debugTimerMixerIterval,
|
||||||
|
|
|
@ -162,7 +162,7 @@ bool menuStatsAnalogs(evt_t event)
|
||||||
#if defined(JITTER_MEASURE)
|
#if defined(JITTER_MEASURE)
|
||||||
lcdDrawNumber(x+100, y, rawJitter[i].get());
|
lcdDrawNumber(x+100, y, rawJitter[i].get());
|
||||||
lcdDrawNumber(x+140, y, avgJitter[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
|
#else
|
||||||
lcdDrawNumber(x+100, y, (int16_t)calibratedStick[CONVERT_MODE(i)]*25/256);
|
lcdDrawNumber(x+100, y, (int16_t)calibratedStick[CONVERT_MODE(i)]*25/256);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1463,30 +1463,20 @@ uint16_t BandGap = 225;
|
||||||
// G: Note that the above would have set the ADC prescaler to 128, equating to
|
// 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
|
// 125KHz sample rate. We now sample at 500KHz, with oversampling and other
|
||||||
// filtering options to produce 11-bit results.
|
// filtering options to produce 11-bit results.
|
||||||
uint16_t BandGap = 2040 ;
|
uint16_t BandGap = 2040;
|
||||||
#elif defined(PCBSTD)
|
#elif defined(PCBSTD)
|
||||||
uint16_t BandGap ;
|
uint16_t BandGap;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(JITTER_MEASURE)
|
#if defined(JITTER_MEASURE)
|
||||||
JitterMeter<uint16_t> rawJitter[NUMBER_ANALOG];
|
JitterMeter<uint16_t> rawJitter[NUMBER_ANALOG];
|
||||||
JitterMeter<uint16_t> avgJitter[NUMBER_ANALOG];
|
JitterMeter<uint16_t> avgJitter[NUMBER_ANALOG];
|
||||||
tmr10ms_t jitterResetTime = 0;
|
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
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(VIRTUALINPUTS) && defined(JITTER_FILTER)
|
#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 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<<JITTER_FILTER_STRENGTH)
|
#define JITTER_ALPHA (1<<JITTER_FILTER_STRENGTH)
|
||||||
#define ANALOG_MULTIPLIER (1<<ANALOG_SCALE)
|
#define ANALOG_MULTIPLIER (1<<ANALOG_SCALE)
|
||||||
|
@ -1536,8 +1526,6 @@ uint16_t anaIn(uint8_t chan)
|
||||||
#if defined(CPUARM)
|
#if defined(CPUARM)
|
||||||
void getADC()
|
void getADC()
|
||||||
{
|
{
|
||||||
uint16_t temp[NUMBER_ANALOG] = { 0 };
|
|
||||||
|
|
||||||
#if defined(JITTER_MEASURE)
|
#if defined(JITTER_MEASURE)
|
||||||
if (JITTER_MEASURE_ACTIVE() && jitterResetTime < get_tmr10ms()) {
|
if (JITTER_MEASURE_ACTIVE() && jitterResetTime < get_tmr10ms()) {
|
||||||
// reset jitter measurement every second
|
// reset jitter measurement every second
|
||||||
|
@ -1550,22 +1538,11 @@ void getADC()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DEBUG_TIMER_START(debugTimerAdcRead);
|
DEBUG_TIMER_START(debugTimerAdcRead);
|
||||||
for (uint8_t i=0; i<4; i++) {
|
adcRead();
|
||||||
adcRead();
|
|
||||||
for (uint8_t x=0; x<NUMBER_ANALOG; x++) {
|
|
||||||
uint16_t val = getAnalogValue(x);
|
|
||||||
#if defined(JITTER_MEASURE)
|
|
||||||
if (JITTER_MEASURE_ACTIVE()) {
|
|
||||||
rawJitter[x].measure(val);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
temp[x] += val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DEBUG_TIMER_STOP(debugTimerAdcRead);
|
DEBUG_TIMER_STOP(debugTimerAdcRead);
|
||||||
|
|
||||||
for (uint32_t x=0; x<NUMBER_ANALOG; x++) {
|
for (uint8_t x=0; x<NUMBER_ANALOG; x++) {
|
||||||
uint16_t v = temp[x] >> (3 - ANALOG_SCALE);
|
uint16_t v = getAnalogValue(x) >> (1 - ANALOG_SCALE);
|
||||||
|
|
||||||
#if defined(VIRTUALINPUTS) && defined(JITTER_FILTER)
|
#if defined(VIRTUALINPUTS) && defined(JITTER_FILTER)
|
||||||
// Jitter filter:
|
// Jitter filter:
|
||||||
|
|
|
@ -1790,7 +1790,16 @@ extern uint16_t s_anaFilt[NUMBER_ANALOG];
|
||||||
#if defined(JITTER_MEASURE)
|
#if defined(JITTER_MEASURE)
|
||||||
extern JitterMeter<uint16_t> rawJitter[NUMBER_ANALOG];
|
extern JitterMeter<uint16_t> rawJitter[NUMBER_ANALOG];
|
||||||
extern JitterMeter<uint16_t> avgJitter[NUMBER_ANALOG];
|
extern JitterMeter<uint16_t> 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
|
#define WDT_500MS 500
|
||||||
|
|
||||||
|
|
|
@ -18,11 +18,23 @@
|
||||||
* GNU General Public License for more details.
|
* 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_HIGH() (ADC_SPI_GPIO->BSRRL = ADC_SPI_PIN_CS)
|
||||||
#define ADC_CS_LOW() (ADC_SPI_GPIO->BSRRH = 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 RESETCMD 0x4000
|
||||||
#define MANUAL_MODE 0x1000 // manual mode channel 0
|
#define MANUAL_MODE 0x1000 // manual mode channel 0
|
||||||
|
|
||||||
|
@ -30,7 +42,7 @@
|
||||||
|
|
||||||
uint16_t adcValues[NUMBER_ANALOG] __DMA;
|
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);
|
while(SPI_I2S_GetFlagStatus(ADC_SPI,SPI_I2S_FLAG_TXE) == RESET);
|
||||||
SPI_I2S_SendData(ADC_SPI,value);
|
SPI_I2S_SendData(ADC_SPI,value);
|
||||||
|
@ -87,27 +99,13 @@ static void ADS7952_Init()
|
||||||
ADC_CS_LOW();
|
ADC_CS_LOW();
|
||||||
SPIx_ReadWriteByte(MANUAL_MODE);
|
SPIx_ReadWriteByte(MANUAL_MODE);
|
||||||
ADC_CS_HIGH();
|
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()
|
void adcInit()
|
||||||
{
|
{
|
||||||
ADS7952_Init();
|
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->CR1 = ADC_CR1_SCAN;
|
||||||
ADC3->CR2 = ADC_CR2_ADON | ADC_CR2_DMA | ADC_CR2_DDS;
|
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;
|
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] =
|
const uint16_t adcCommands[MOUSE1+2] =
|
||||||
{
|
{
|
||||||
MANUAL_MODE | ( SPI_STICK1 << 7 ),
|
MANUAL_MODE | (SPI_STICK1 << 7),
|
||||||
MANUAL_MODE | ( SPI_STICK2 << 7 ),
|
MANUAL_MODE | (SPI_STICK2 << 7),
|
||||||
MANUAL_MODE | ( SPI_STICK3 << 7 ),
|
MANUAL_MODE | (SPI_STICK3 << 7),
|
||||||
MANUAL_MODE | ( SPI_STICK4 << 7 ),
|
MANUAL_MODE | (SPI_STICK4 << 7),
|
||||||
MANUAL_MODE | ( SPI_S1 << 7 ),
|
MANUAL_MODE | (SPI_S1 << 7),
|
||||||
MANUAL_MODE | ( SPI_6POS << 7 ),
|
MANUAL_MODE | (SPI_6POS << 7),
|
||||||
MANUAL_MODE | ( SPI_S2 << 7 ),
|
MANUAL_MODE | (SPI_S2 << 7),
|
||||||
MANUAL_MODE | ( SPI_L1 << 7 ),
|
MANUAL_MODE | (SPI_L1 << 7),
|
||||||
MANUAL_MODE | ( SPI_L2 << 7 ),
|
MANUAL_MODE | (SPI_L2 << 7),
|
||||||
MANUAL_MODE | ( SPI_LS << 7 ),
|
MANUAL_MODE | (SPI_LS << 7),
|
||||||
MANUAL_MODE | ( SPI_RS << 7 ),
|
MANUAL_MODE | (SPI_RS << 7),
|
||||||
MANUAL_MODE | ( SPI_TX_VOLTAGE << 7 ),
|
MANUAL_MODE | (SPI_TX_VOLTAGE << 7),
|
||||||
MANUAL_MODE | ( 0 << 7 ), // small joystick left/right
|
MANUAL_MODE | (0 << 7 ), // small joystick left/right
|
||||||
MANUAL_MODE | ( 0 << 7 ) // small joystick up/down
|
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
|
DMA2_Stream1->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||||
ADC3->SR &= ~(uint32_t) ( ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR );
|
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
|
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->NDTR = 2;
|
||||||
DMA2_Stream1->CR |= DMA_SxCR_EN; // Enable DMA
|
DMA2_Stream1->CR |= DMA_SxCR_EN; // Enable DMA
|
||||||
ADC3->CR2 |= (uint32_t)ADC_CR2_SWSTART;
|
ADC3->CR2 |= (uint32_t)ADC_CR2_SWSTART;
|
||||||
|
}
|
||||||
|
|
||||||
// A dummy command to get things started
|
bool adcOnChipReadFinished()
|
||||||
// (because the sampled data is lagging behind for two command cycles)
|
{
|
||||||
ADC_CS_LOW();
|
return (DMA2->LISR & DMA_LISR_TCIF1);
|
||||||
delay_01us(1);
|
}
|
||||||
SPIx_ReadWriteByte(*command); // still sampling the old MUX channel
|
|
||||||
ADC_CS_HIGH();
|
|
||||||
delay_01us(1);
|
|
||||||
|
|
||||||
DEBUG_TIMER_START(debugTimerAdcLoop);
|
void adcRead()
|
||||||
for (uint32_t adcIndex=0; adcIndex<MOUSE1; adcIndex++) {
|
{
|
||||||
// MUX is changed to the channel that was sent in the previous command
|
uint16_t temp[NUMBER_ANALOG-MOUSE1] = { 0 };
|
||||||
// but the data is from the old MUX position
|
uint8_t noInternalReads = 0;
|
||||||
ADC_CS_LOW();
|
|
||||||
delay_01us(1);
|
|
||||||
SPIx_ReadWriteByte(*command);
|
|
||||||
ADC_CS_HIGH();
|
|
||||||
delay_01us(1);
|
|
||||||
|
|
||||||
// This delay is to allow charging of ADC input capacitor
|
adcOnChipReadStart();
|
||||||
// after the MUX changes from one channel to the other.
|
adcReadSPIDummy();
|
||||||
// It was determined experimentally. Biggest problem seems to be
|
adcReadSPIDummy();
|
||||||
// the cross-talk between A4:S1 and A5:MULTIPOS. Changing S1 for one extreme
|
for (uint32_t index=0; index<MOUSE1; index++) {
|
||||||
// to the other resulted in A5 change of:
|
adcValues[index] = adcReadNextSPIChannel(index);
|
||||||
//
|
if (noInternalReads < 4 && adcOnChipReadFinished()) {
|
||||||
// delay value A5 change
|
for (uint8_t x=0; x<NUMBER_ANALOG-MOUSE1; x++) {
|
||||||
// 0 76
|
uint16_t val = adcValues[MOUSE1+x];
|
||||||
// 100 26
|
#if defined(JITTER_MEASURE)
|
||||||
// 300 13
|
if (JITTER_MEASURE_ACTIVE()) {
|
||||||
// 500 undetectable
|
rawJitter[MOUSE1+x].measure(val);
|
||||||
delay_01us(500);
|
}
|
||||||
++command; // move to the next channel
|
#endif
|
||||||
|
temp[x] += val;
|
||||||
// First time the wanted ADC channel is actually sampled.
|
}
|
||||||
// This is delayed to allow MUX to settle (high input impedance)
|
if (++noInternalReads < 4) {
|
||||||
// Also the MUX channel is set to the next channel here,
|
adcOnChipReadStart();
|
||||||
// but the actual MUX change will happen in the next round
|
}
|
||||||
ADC_CS_LOW();
|
|
||||||
delay_01us(1);
|
|
||||||
adcValues[adcIndex] = (0x0fff & SPIx_ReadWriteByte(*command));
|
|
||||||
ADC_CS_HIGH();
|
|
||||||
delay_01us(1);
|
|
||||||
}
|
|
||||||
DEBUG_TIMER_STOP(debugTimerAdcLoop);
|
|
||||||
|
|
||||||
DEBUG_TIMER_START(debugTimerAdcWait);
|
|
||||||
for (uint32_t i=0; i<20000; i++) {
|
|
||||||
if (DMA2->LISR & DMA_LISR_TCIF1) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DEBUG_TIMER_STOP(debugTimerAdcWait);
|
|
||||||
|
|
||||||
// On chip ADC read should have finished
|
#if defined(DEBUG)
|
||||||
|
if (noInternalReads != 4) {
|
||||||
|
TRACE("Internal ADC problem: reads: %d", noInternalReads);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (uint8_t x=0; x<NUMBER_ANALOG-MOUSE1; x++) {
|
||||||
|
adcValues[MOUSE1+x] = temp[x] >> 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int8_t ana_direction[NUMBER_ANALOG] = {1,-1,1,-1, -1,1,-1, -1,-1, -1,1, 0,0,0};
|
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)
|
uint16_t getAnalogValue(uint8_t index)
|
||||||
{
|
{
|
||||||
if (ana_direction[index] < 0)
|
if (ana_direction[index] < 0)
|
||||||
return 4096 - adcValues[index];
|
return 4095 - adcValues[index];
|
||||||
else
|
else
|
||||||
return adcValues[index];
|
return adcValues[index];
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../opentx.h"
|
#include "opentx.h"
|
||||||
|
|
||||||
uint16_t adcValues[NUMBER_ANALOG];
|
uint16_t adcValues[NUMBER_ANALOG];
|
||||||
|
|
||||||
|
@ -63,12 +63,13 @@ void adcInit()
|
||||||
|
|
||||||
// Read 8 (9 for REVB) ADC channels
|
// Read 8 (9 for REVB) ADC channels
|
||||||
// Documented bug, must do them 1 by 1
|
// Documented bug, must do them 1 by 1
|
||||||
void adcRead()
|
void adcSingleRead()
|
||||||
{
|
{
|
||||||
register Adc *padc;
|
register Adc *padc;
|
||||||
register uint32_t y;
|
register uint32_t y;
|
||||||
register uint32_t x;
|
register uint32_t x;
|
||||||
|
|
||||||
|
for (uint8_t i=0; i<4; i++)
|
||||||
padc = ADC;
|
padc = ADC;
|
||||||
y = padc->ADC_ISR; // Clear EOC flags
|
y = padc->ADC_ISR; // Clear EOC flags
|
||||||
for (y = NUMBER_ANALOG+1; --y > 0;) {
|
for (y = NUMBER_ANALOG+1; --y > 0;) {
|
||||||
|
@ -112,6 +113,29 @@ void adcRead()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void adcRead()
|
||||||
|
{
|
||||||
|
uint16_t temp[NUMBER_ANALOG] = { 0 };
|
||||||
|
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
adcSingleRead();
|
||||||
|
for (uint8_t x=0; x<NUMBER_ANALOG; x++) {
|
||||||
|
uint16_t val = adcValues[x];
|
||||||
|
#if defined(JITTER_MEASURE)
|
||||||
|
if (JITTER_MEASURE_ACTIVE()) {
|
||||||
|
rawJitter[x].measure(val);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
temp[x] += val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t x=0; x<NUMBER_ANALOG; x++) {
|
||||||
|
adcValues[x] = temp[x] >> 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint16_t getAnalogValue(uint8_t value)
|
uint16_t getAnalogValue(uint8_t value)
|
||||||
{
|
{
|
||||||
return adcValues[value];
|
return adcValues[value];
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../../opentx.h"
|
#include "opentx.h"
|
||||||
|
|
||||||
#define PIN_ANALOG 0x0003
|
#define PIN_ANALOG 0x0003
|
||||||
#define PIN_PORTA 0x0000
|
#define PIN_PORTA 0x0000
|
||||||
|
@ -111,13 +111,14 @@ void adcInit()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void adcRead()
|
void adcSingleRead()
|
||||||
{
|
{
|
||||||
DMA2_Stream0->CR &= ~DMA_SxCR_EN ; // Disable DMA
|
DMA2_Stream0->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||||
ADC1->SR &= ~(uint32_t) ( ADC_SR_EOC | ADC_SR_STRT | ADC_SR_OVR ) ;
|
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->LIFCR = DMA_LIFCR_CTCIF0 | DMA_LIFCR_CHTIF0 | DMA_LIFCR_CTEIF0 | DMA_LIFCR_CDMEIF0 |
|
||||||
DMA2_Stream0->CR |= DMA_SxCR_EN ; // Enable DMA
|
DMA_LIFCR_CFEIF0; // Write ones to clear bits
|
||||||
ADC1->CR2 |= (uint32_t)ADC_CR2_SWSTART ;
|
DMA2_Stream0->CR |= DMA_SxCR_EN; // Enable DMA
|
||||||
|
ADC1->CR2 |= (uint32_t) ADC_CR2_SWSTART;
|
||||||
|
|
||||||
#if defined(REV9E)
|
#if defined(REV9E)
|
||||||
DMA2_Stream1->CR &= ~DMA_SxCR_EN ; // Disable DMA
|
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->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
|
DMA2_Stream1->CR |= DMA_SxCR_EN ; // Enable DMA
|
||||||
ADC3->CR2 |= (uint32_t)ADC_CR2_SWSTART ;
|
ADC3->CR2 |= (uint32_t)ADC_CR2_SWSTART ;
|
||||||
#endif // #if defined(REV9E)
|
#endif // defined(REV9E)
|
||||||
|
|
||||||
#if defined(REV9E)
|
#if defined(REV9E)
|
||||||
for (unsigned int i=0; i<10000; i++) {
|
for (unsigned int i=0; i<10000; i++) {
|
||||||
|
@ -136,15 +137,37 @@ void adcRead()
|
||||||
DMA2_Stream0->CR &= ~DMA_SxCR_EN ; // Disable DMA
|
DMA2_Stream0->CR &= ~DMA_SxCR_EN ; // Disable DMA
|
||||||
DMA2_Stream1->CR &= ~DMA_SxCR_EN ; // Disable DMA
|
DMA2_Stream1->CR &= ~DMA_SxCR_EN ; // Disable DMA
|
||||||
#else
|
#else
|
||||||
for (unsigned int i=0; i<10000; i++) {
|
for (unsigned int i = 0; i < 10000; i++) {
|
||||||
if (DMA2->LISR & DMA_LISR_TCIF0) {
|
if (DMA2->LISR & DMA_LISR_TCIF0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DMA2_Stream0->CR &= ~DMA_SxCR_EN ; // Disable DMA
|
DMA2_Stream0->CR &= ~DMA_SxCR_EN; // Disable DMA
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void adcRead()
|
||||||
|
{
|
||||||
|
uint16_t temp[NUMBER_ANALOG] = { 0 };
|
||||||
|
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
adcSingleRead();
|
||||||
|
for (uint8_t x=0; x<NUMBER_ANALOG; x++) {
|
||||||
|
uint16_t val = adcValues[x];
|
||||||
|
#if defined(JITTER_MEASURE)
|
||||||
|
if (JITTER_MEASURE_ACTIVE()) {
|
||||||
|
rawJitter[x].measure(val);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
temp[x] += val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t x=0; x<NUMBER_ANALOG; x++) {
|
||||||
|
adcValues[x] = temp[x] >> 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
void adcStop()
|
void adcStop()
|
||||||
{
|
{
|
||||||
|
@ -162,7 +185,7 @@ uint16_t getAnalogValue(uint8_t index)
|
||||||
index = ana_mapping[index];
|
index = ana_mapping[index];
|
||||||
#endif
|
#endif
|
||||||
if (ana_direction[index] < 0)
|
if (ana_direction[index] < 0)
|
||||||
return 4096 - adcValues[index];
|
return 4095 - adcValues[index];
|
||||||
else
|
else
|
||||||
return adcValues[index];
|
return adcValues[index];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue