TELEMETRY_MOD=14051_SWAPPED
TELEMETRY_MOD=14051 (by gerardv @ forum.turnigy9xr.com) makes USART0 available by reallocating AIL and THR onto pins 14 and 15 of the 14051 multiplexer. TELEMETRY_MOD=14051_SWAPPED is based on TELEMETRY_MOD=14051, but uses USART1 instead of USART0, freeing USART0 for other purposes (debugging, interfacing via AVRISP port). USART1 is freed up by reallocating LVert Trim Dn/Up onto 14051's 12 and 1 pins respectively. Additionally, this commit cleans a few things up: * moves AVR ADC-related code to adc_driver.cpp, * provides #defines to have a convenient way to access either USART0 or USART1 registers depending on static (build-time) configuration * moves code related to this telemetry mod to board_stock * replaces a few magic numbers with enums. Thanks to Bernard Songis for review and suggestions!
This commit is contained in:
+20
-144
@@ -1301,7 +1301,7 @@ uint8_t checkTrim(uint8_t event)
|
||||
}
|
||||
|
||||
#if !defined(SIMU)
|
||||
static uint16_t s_anaFilt[NUMBER_ANALOG];
|
||||
uint16_t s_anaFilt[NUMBER_ANALOG];
|
||||
#endif
|
||||
|
||||
#if defined(SIMU)
|
||||
@@ -1328,8 +1328,12 @@ uint16_t anaIn(uint8_t chan)
|
||||
}
|
||||
volatile uint16_t *p = &s_anaFilt[pgm_read_byte(crossAna+chan)];
|
||||
return *p;
|
||||
#else
|
||||
#if defined(TELEMETRY_MOD_14051) || defined(TELEMETRY_MOD_14051_SWAPPED)
|
||||
static const pm_char crossAna[] PROGMEM = {3,1,2,0,4,5,6,0/* shouldn't be used */,TX_VOLTAGE};
|
||||
#else
|
||||
static const pm_char crossAna[] PROGMEM = {3,1,2,0,4,5,6,7};
|
||||
#endif
|
||||
#if defined(FRSKY_STICKS)
|
||||
volatile uint16_t temp = s_anaFilt[pgm_read_byte(crossAna+chan)]; // volatile saves here 40 bytes; maybe removed for newer AVR when available
|
||||
if (chan < NUM_STICKS && (g_eeGeneral.stickReverse & (1 << chan))) {
|
||||
@@ -1378,132 +1382,6 @@ void getADC()
|
||||
s_anaFilt[x] = v;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
/**
|
||||
* Read ADC using 10 bits
|
||||
*/
|
||||
inline uint16_t read_adc10(uint8_t adc_input)
|
||||
{
|
||||
uint16_t temp_ana;
|
||||
ADMUX = adc_input|ADC_VREF_TYPE;
|
||||
#if defined(TELEMETRY_MOD_14051)
|
||||
ADCSRA &= 0x87;
|
||||
#endif
|
||||
ADCSRA |= 1 << ADSC; // Start the AD conversion
|
||||
while (ADCSRA & (1 << ADSC)); // Wait for the AD conversion to complete
|
||||
temp_ana = ADC;
|
||||
ADCSRA |= 1 << ADSC; // Start the second AD conversion
|
||||
while (ADCSRA & (1 << ADSC)); // Wait for the AD conversion to complete
|
||||
temp_ana += ADC;
|
||||
return temp_ana;
|
||||
}
|
||||
|
||||
#if defined(TELEMETRY_MOD_14051)
|
||||
enum MuxInput {
|
||||
MUX_BATT,
|
||||
MUX_THR,
|
||||
MUX_AIL,
|
||||
MUX_MAX = MUX_AIL
|
||||
};
|
||||
|
||||
uint8_t pf7_digital[2];
|
||||
/**
|
||||
* Update ADC PF7 using 14051 multiplexer
|
||||
* X0 : Battery voltage
|
||||
* X1 : THR SW
|
||||
* X2 : AIL SW
|
||||
*/
|
||||
void readMultiplexAna()
|
||||
{
|
||||
static uint8_t muxNum = MUX_BATT;
|
||||
uint16_t temp_ana;
|
||||
uint8_t nextMuxNum = muxNum-1;
|
||||
|
||||
DDRC |= 0xC1;
|
||||
temp_ana = read_adc10(7);
|
||||
|
||||
switch (muxNum) {
|
||||
case MUX_BATT:
|
||||
s_anaFilt[TX_VOLTAGE] = temp_ana;
|
||||
nextMuxNum = MUX_MAX;
|
||||
break;
|
||||
case MUX_THR:
|
||||
case MUX_AIL:
|
||||
// Digital switch depend from input voltage
|
||||
// take half voltage to determine digital state
|
||||
pf7_digital[muxNum-1] = (temp_ana >= (s_anaFilt[TX_VOLTAGE] / 2)) ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// set the mux number for the next ADC convert,
|
||||
// stabilize voltage before ADC read.
|
||||
muxNum = nextMuxNum;
|
||||
PORTC &= ~((1 << PC7) | (1 << PC6) | (1 << PC0)); // Clear CTRL ABC
|
||||
switch (muxNum) {
|
||||
case 1:
|
||||
PORTC |= (1 << PC6); // Mux CTRL A : SW_THR
|
||||
break;
|
||||
case 2:
|
||||
PORTC |= (1 << PC7); // Mux CTRL B : SW_AIL
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void getADC()
|
||||
{
|
||||
#if defined(TELEMETRY_MOD_14051)
|
||||
readMultiplexAna();
|
||||
#define ADC_READ_COUNT 7
|
||||
#else
|
||||
#define ADC_READ_COUNT 8
|
||||
#endif
|
||||
|
||||
for (uint8_t adc_input=0; adc_input<ADC_READ_COUNT; adc_input++) {
|
||||
s_anaFilt[adc_input] = read_adc10(adc_input);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(CPUARM)
|
||||
void getADC_bandgap()
|
||||
{
|
||||
#if defined(PCBGRUVIN9X)
|
||||
static uint8_t s_bgCheck = 0;
|
||||
static uint16_t s_bgSum = 0;
|
||||
ADCSRA|=0x40; // request sample
|
||||
s_bgCheck += 32;
|
||||
while ((ADCSRA & 0x10)==0); ADCSRA|=0x10; // wait for sample
|
||||
if (s_bgCheck == 0) { // 8x over-sample (256/32=8)
|
||||
BandGap = s_bgSum+ADC;
|
||||
s_bgSum = 0;
|
||||
}
|
||||
else {
|
||||
s_bgSum += ADC;
|
||||
}
|
||||
ADCSRB |= (1<<MUX5);
|
||||
#elif defined(PCBMEGA2560)
|
||||
BandGap = 2000;
|
||||
#else
|
||||
// TODO is the next line needed (because it has been called before perMain)?
|
||||
ADMUX = 0x1E|ADC_VREF_TYPE; // Switch MUX to internal 1.22V reference
|
||||
|
||||
/*
|
||||
MCUCR|=0x28; // enable Sleep (bit5) enable ADC Noise Reduction (bit2)
|
||||
asm volatile(" sleep \n\t"); // if _SLEEP() is not defined use this
|
||||
// ADCSRA|=0x40;
|
||||
while ((ADCSRA & 0x10)==0);
|
||||
ADCSRA|=0x10; // take sample clear flag?
|
||||
BandGap=ADC;
|
||||
MCUCR&=0x08; // disable sleep
|
||||
*/
|
||||
|
||||
ADCSRA |= 0x40;
|
||||
while (ADCSRA & 0x40);
|
||||
BandGap = ADC;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SIMU
|
||||
@@ -1619,12 +1497,10 @@ void doMixerCalculations()
|
||||
Current_analogue = (Current_analogue*31 + s_anaFilt[8] ) >> 5 ;
|
||||
if (Current_analogue > Current_max)
|
||||
Current_max = Current_analogue ;
|
||||
#elif defined(PCBGRUVIN9X) && !defined(SIMU)
|
||||
// For PCB V4, use our own 1.2V, external reference (connected to ADC3)
|
||||
ADCSRB &= ~(1<<MUX5);
|
||||
ADMUX = 0x03|ADC_VREF_TYPE; // Switch MUX to internal reference
|
||||
#elif defined(PCBSTD) && !defined(SIMU)
|
||||
ADMUX = 0x1E|ADC_VREF_TYPE; // Switch MUX to internal reference
|
||||
#endif
|
||||
|
||||
#if !defined(CPUARM)
|
||||
adcPrepareBandgap();
|
||||
#endif
|
||||
|
||||
evalMixes(tick10ms);
|
||||
@@ -2176,14 +2052,14 @@ ISR(TIMER3_CAPT_vect) // G: High frequency noise can cause stack overflo with IS
|
||||
#endif
|
||||
|
||||
#if defined(DSM2_SERIAL) && !defined(CPUARM)
|
||||
FORCEINLINE void DSM2_USART0_vect()
|
||||
FORCEINLINE void DSM2_USART_vect()
|
||||
{
|
||||
UDR0 = *((uint16_t*)pulses2MHzRPtr); // transmit next byte
|
||||
|
||||
pulses2MHzRPtr += sizeof(uint16_t);
|
||||
|
||||
if (pulses2MHzRPtr == pulses2MHzWPtr) { // if reached end of DSM2 data buffer ...
|
||||
UCSR0B &= ~(1 << UDRIE0); // disable UDRE0 interrupt
|
||||
UCSRB_N(TLM_USART) &= ~(1 << UDRIE_N(TLM_USART)); // disable UDRE interrupt
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -2192,30 +2068,30 @@ FORCEINLINE void DSM2_USART0_vect()
|
||||
|
||||
#if defined (FRSKY)
|
||||
|
||||
// USART0 Transmit Data Register Emtpy ISR
|
||||
FORCEINLINE void FRSKY_USART0_vect()
|
||||
FORCEINLINE void FRSKY_USART_vect()
|
||||
{
|
||||
if (frskyTxBufferCount > 0) {
|
||||
UDR0 = frskyTxBuffer[--frskyTxBufferCount];
|
||||
UDR_N(TLM_USART) = frskyTxBuffer[--frskyTxBufferCount];
|
||||
}
|
||||
else {
|
||||
UCSR0B &= ~(1 << UDRIE0); // disable UDRE0 interrupt
|
||||
UCSRB_N(TLM_USART) &= ~(1 << UDRIE_N(TLM_USART)); // disable UDRE interrupt
|
||||
}
|
||||
}
|
||||
|
||||
ISR(USART0_UDRE_vect)
|
||||
// USART0/1 Transmit Data Register Emtpy ISR
|
||||
ISR(USART_UDRE_vect_N(TLM_USART))
|
||||
{
|
||||
#if defined(FRSKY) && defined(DSM2_SERIAL)
|
||||
if (IS_DSM2_PROTOCOL(g_model.protocol)) { // TODO not s_current_protocol?
|
||||
DSM2_USART0_vect();
|
||||
DSM2_USART_vect();
|
||||
}
|
||||
else {
|
||||
FRSKY_USART0_vect();
|
||||
FRSKY_USART_vect();
|
||||
}
|
||||
#elif defined(FRSKY)
|
||||
FRSKY_USART0_vect();
|
||||
FRSKY_USART_vect();
|
||||
#else
|
||||
DSM2_USART0_vect();
|
||||
DSM2_USART_vect();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user