I have so far tried to identify the code-lines that deal with the output to the motors(in output.h) and would like to
obtain some of your thoughts and if I'm on the right way so far.
IMO 'writeMotors()' is just responsible for the PWM-Generation, setting the Output Compare Registers to the corresponding values => no change needed
Here the relevant code-lines for a QuadX
Code: Select all
void writeMotors() { // [1000;2000] => [125;250]
#if defined(MEGA)// [1000:2000] => [8000:16000] for timer 3 & 4 for mega
#if (NUMBER_MOTOR > 0)
#ifndef EXT_MOTOR_RANGE
OCR3C = motor[0]<<3; // pin 3
#else
OCR3C = ((motor[0]<<4) - 16000) + 128;
#endif
#endif
#if (NUMBER_MOTOR > 1)
#ifndef EXT_MOTOR_RANGE
OCR3A = motor[1]<<3; // pin 5
#else
OCR3A = ((motor[1]<<4) - 16000) + 128;
#endif
#endif
#if (NUMBER_MOTOR > 2)
#ifndef EXT_MOTOR_RANGE
OCR4A = motor[2]<<3; // pin 6
#else
OCR4A = ((motor[2]<<4) - 16000) + 128;
#endif
#endif
#if (NUMBER_MOTOR > 3)
#ifndef EXT_MOTOR_RANGE
OCR3B = motor[3]<<3; // pin 2
#else
OCR3B = ((motor[3]<<4) - 16000) + 128;
#endif
#endif
#if (NUMBER_MOTOR > 4)
#ifndef EXT_MOTOR_RANGE
OCR4B = motor[4]<<3; // pin 7
OCR4C = motor[5]<<3; // pin 8
#else
OCR4B = ((motor[4]<<4) - 16000) + 128;
OCR4C = ((motor[5]<<4) - 16000) + 128;
#endif
#endif
#if (NUMBER_MOTOR > 6)
#ifndef EXT_MOTOR_RANGE
OCR2B = motor[6]>>3; // pin 9
OCR2A = motor[7]>>3; // pin 10
#else
OCR2B = ((motor[6]>>2) - 250) + 2);
OCR2A = ((motor[7]>>2) - 250) + 2);
#endif
#endif
#endif
#if defined(PROMICRO)
#if (NUMBER_MOTOR > 0) // Timer 1 A & B [1000:2000] => [8000:16000]
OCR1A = motor[0]<<3; // pin 9
#endif
#if (NUMBER_MOTOR > 1)
OCR1B = motor[1]<<3; // pin 10
#endif
#if (NUMBER_MOTOR > 2) // Timer 4 A & D [1000:2000] => [1000:2000]
#if !defined(HWPWM6)
// to write values > 255 to timer 4 A/B we need to split the bytes
static uint8_t pwm4_HBA;
static uint16_t pwm4_LBA; // high and low byte for timer 4 A
pwm4_LBA = 2047-motor[2]; pwm4_HBA = 0; // channel A is inverted
while(pwm4_LBA > 255){
pwm4_HBA++;
pwm4_LBA-=256;
}
TC4H = pwm4_HBA; OCR4A = pwm4_LBA; // pin 5
#else
OCR3A = motor[2]<<3; // pin 5
#endif
#endif
#if (NUMBER_MOTOR > 3)
static uint8_t pwm4_HBD;
static uint16_t pwm4_LBD; // high and low byte for timer 4 D
pwm4_LBD = motor[3]; pwm4_HBD = 0;
while(pwm4_LBD > 255){
pwm4_HBD++;
pwm4_LBD-=256;
}
TC4H = pwm4_HBD; OCR4D = pwm4_LBD; // pin 6
#endif
afterwards in 'initOutput()' the Timers are being initialized and the Waveform Generation Mode is set to PWM, Phase Correct(ATmega documentation).
But where there is commented "connect pinx to timer y channel A/B/C" i can't find out how this codeline:
Code: Select all
TCCR3A |= _BV(COM3B1); // connect pin 2 to timer 3 channel B
and for completeness the complete code-block from initOutput() for a QuadX:
Code: Select all
void initOutput() {
for(uint8_t i=0;i<NUMBER_MOTOR;i++)
pinMode(PWM_PIN[i],OUTPUT);
#if defined(MEGA)
#if (NUMBER_MOTOR > 0)
// init 16bit timer 3
TCCR3A |= (1<<WGM31); // phase correct mode
TCCR3A &= ~(1<<WGM30);
TCCR3B |= (1<<WGM33);
TCCR3B &= ~(1<<CS31); // no prescaler
ICR3 |= 0x3FFF; // TOP to = 16383;
TCCR3A |= _BV(COM3C1); // connect pin 3 to timer 3 channel C
#endif
#if (NUMBER_MOTOR > 1)
TCCR3A |= _BV(COM3A1); // connect pin 5 to timer 3 channel A
#endif
#if (NUMBER_MOTOR > 2)
// init 16bit timer 4
TCCR4A |= (1<<WGM41); // phase correct mode
TCCR4A &= ~(1<<WGM40);
TCCR4B |= (1<<WGM43);
TCCR4B &= ~(1<<CS41); // no prescaler
ICR4 |= 0x3FFF; // TOP to = 16383;
TCCR4A |= _BV(COM4A1); // connect pin 6 to timer 4 channel A
#endif
#if (NUMBER_MOTOR > 3)
TCCR3A |= _BV(COM3B1); // connect pin 2 to timer 3 channel B
#endif
#if (NUMBER_MOTOR > 4)
TCCR4A |= _BV(COM4B1); // connect pin 7 to timer 4 channel B
TCCR4A |= _BV(COM4C1); // connect pin 8 to timer 4 channel C
#endif
I hope this is a detailed description of my problem and that someone can help me with this
so far,
Spambot