Comparing sensitive data, confidential files or internal emails?

Most legal and privacy policies prohibit uploading sensitive data online. Diffchecker Desktop ensures your confidential information never leaves your computer. Work offline and compare documents securely.

Untitled diff

Created Diff never expires
0 removals
618 lines
0 additions
618 lines
/**************************************************************************************/
/**************************************************************************************/
/*************** Motor Pin order ********************/
/*************** Motor Pin order ********************/
/**************************************************************************************/
/**************************************************************************************/
// since we are uing the PWM generation in a direct way, the pin order is just to inizialie the right pins
// since we are uing the PWM generation in a direct way, the pin order is just to inizialie the right pins
// its not possible to change a PWM output pin just by changing the order
// its not possible to change a PWM output pin just by changing the order
#if defined(PROMINI)
#if defined(PROMINI)
uint8_t PWM_PIN[8] = {9,10,11,3,6,5,A2,12}; //for a quad+: rear,right,left,front
uint8_t PWM_PIN[8] = {9,10,11,3,6,5,A2,12}; //for a quad+: rear,right,left,front
#endif
#endif
#if defined(PROMICRO)
#if defined(PROMICRO)
#if !defined(HWPWM6)
#if !defined(HWPWM6)
#if !defined(TEENSY20)
#if !defined(TEENSY20)
uint8_t PWM_PIN[8] = {9,10,5,6,4,A2,A0,A1}; //for a quad+: rear,right,left,front
uint8_t PWM_PIN[8] = {9,10,5,6,4,A2,A0,A1}; //for a quad+: rear,right,left,front
#else
#else
uint8_t PWM_PIN[8] = {14,15,9,12,22,18,16,17}; //for a quad+: rear,right,left,front
uint8_t PWM_PIN[8] = {14,15,9,12,22,18,16,17}; //for a quad+: rear,right,left,front
#endif
#endif
#else
#else
#if !defined(TEENSY20)
#if !defined(TEENSY20)
uint8_t PWM_PIN[8] = {9,10,5,6,11,13,A0,A1}; //for a quad+: rear,right,left,front
uint8_t PWM_PIN[8] = {9,10,5,6,11,13,A0,A1}; //for a quad+: rear,right,left,front
#else
#else
uint8_t PWM_PIN[8] = {14,15,9,12,4,10,16,17}; //for a quad+: rear,right,left,front
uint8_t PWM_PIN[8] = {14,15,9,12,4,10,16,17}; //for a quad+: rear,right,left,front
#endif
#endif
#endif
#endif
#endif
#endif
#if defined(MEGA)
#if defined(MEGA)
uint8_t PWM_PIN[8] = {3,5,6,2,7,8,9,10}; //for a quad+: rear,right,left,front //+ for y6: 7:under right 8:under left
uint8_t PWM_PIN[8] = {3,5,6,2,7,8,9,10}; //for a quad+: rear,right,left,front //+ for y6: 7:under right 8:under left
#endif
#endif
/**************************************************************************************/
/**************************************************************************************/
/*************** Software PWM & Servo variables ********************/
/*************** Software PWM & Servo variables ********************/
/**************************************************************************************/
/**************************************************************************************/
#if defined(PROMINI) || (defined(PROMICRO) && defined(HWPWM6))
#if defined(PROMINI) || (defined(PROMICRO) && defined(HWPWM6))
#if defined(SERVO)
#if defined(SERVO)
#if defined(AIRPLANE)|| defined(HELICOPTER)
#if defined(AIRPLANE)|| defined(HELICOPTER)
// To prevent motor to start at reset. atomicServo[7]=5 or 249 if reversed servo
// To prevent motor to start at reset. atomicServo[7]=5 or 249 if reversed servo
volatile uint8_t atomicServo[8] = {125,125,125,125,125,125,125,5};
volatile uint8_t atomicServo[8] = {125,125,125,125,125,125,125,5};
#else
#else
volatile uint8_t atomicServo[8] = {125,125,125,125,125,125,125,125};
volatile uint8_t atomicServo[8] = {125,125,125,125,125,125,125,125};
#endif
#endif
#endif
#endif
#if (NUMBER_MOTOR > 4)
#if (NUMBER_MOTOR > 4)
//for HEX Y6 and HEX6/HEX6X flat for promini
//for HEX Y6 and HEX6/HEX6X flat for promini
volatile uint8_t atomicPWM_PIN5_lowState;
volatile uint8_t atomicPWM_PIN5_lowState;
volatile uint8_t atomicPWM_PIN5_highState;
volatile uint8_t atomicPWM_PIN5_highState;
volatile uint8_t atomicPWM_PIN6_lowState;
volatile uint8_t atomicPWM_PIN6_lowState;
volatile uint8_t atomicPWM_PIN6_highState;
volatile uint8_t atomicPWM_PIN6_highState;
#endif
#endif
#if (NUMBER_MOTOR > 6)
#if (NUMBER_MOTOR > 6)
//for OCTO on promini
//for OCTO on promini
volatile uint8_t atomicPWM_PINA2_lowState;
volatile uint8_t atomicPWM_PINA2_lowState;
volatile uint8_t atomicPWM_PINA2_highState;
volatile uint8_t atomicPWM_PINA2_highState;
volatile uint8_t atomicPWM_PIN12_lowState;
volatile uint8_t atomicPWM_PIN12_lowState;
volatile uint8_t atomicPWM_PIN12_highState;
volatile uint8_t atomicPWM_PIN12_highState;
#endif
#endif
#else
#else
#if defined(SERVO)
#if defined(SERVO)
#if defined(AIRPLANE)|| defined(HELICOPTER)
#if defined(AIRPLANE)|| defined(HELICOPTER)
// To prevent motor to start at reset. atomicServo[7]=5 or 249 if reversed servo
// To prevent motor to start at reset. atomicServo[7]=5 or 249 if reversed servo
volatile uint8_t atomicServo[8] = {8000,8000,8000,8000,8000,8000,8000,8000};
volatile uint8_t atomicServo[8] = {8000,8000,8000,8000,8000,8000,8000,8000};
#else
#else
volatile uint16_t atomicServo[8] = {8000,8000,8000,8000,8000,8000,8000,320};
volatile uint16_t atomicServo[8] = {8000,8000,8000,8000,8000,8000,8000,320};
#endif
#endif
#endif
#endif
#if (NUMBER_MOTOR > 4)
#if (NUMBER_MOTOR > 4)
//for HEX Y6 and HEX6/HEX6X and for Promicro
//for HEX Y6 and HEX6/HEX6X and for Promicro
volatile uint16_t atomicPWM_PIN5_lowState;
volatile uint16_t atomicPWM_PIN5_lowState;
volatile uint16_t atomicPWM_PIN5_highState;
volatile uint16_t atomicPWM_PIN5_highState;
volatile uint16_t atomicPWM_PIN6_lowState;
volatile uint16_t atomicPWM_PIN6_lowState;
volatile uint16_t atomicPWM_PIN6_highState;
volatile uint16_t atomicPWM_PIN6_highState;
#endif
#endif
#if (NUMBER_MOTOR > 6)
#if (NUMBER_MOTOR > 6)
//for OCTO on Promicro
//for OCTO on Promicro
volatile uint16_t atomicPWM_PINA2_lowState;
volatile uint16_t atomicPWM_PINA2_lowState;
volatile uint16_t atomicPWM_PINA2_highState;
volatile uint16_t atomicPWM_PINA2_highState;
volatile uint16_t atomicPWM_PIN12_lowState;
volatile uint16_t atomicPWM_PIN12_lowState;
volatile uint16_t atomicPWM_PIN12_highState;
volatile uint16_t atomicPWM_PIN12_highState;
#endif
#endif
#endif
#endif
/**************************************************************************************/
/**************************************************************************************/
/*************** Writes the Servos values to the needed format ********************/
/*************** Writes the Servos values to the needed format ********************/
/**************************************************************************************/
/**************************************************************************************/
void writeServos() {
void writeServos() {
#if defined(SERVO)
#if defined(SERVO)
#if defined(PRI_SERVO_FROM) // write primary servos
#if defined(PRI_SERVO_FROM) // write primary servos
for(uint8_t i = (PRI_SERVO_FROM-1); i < PRI_SERVO_TO; i++){
for(uint8_t i = (PRI_SERVO_FROM-1); i < PRI_SERVO_TO; i++){
#if defined(PROMINI) || (defined(PROMICRO) && defined(HWPWM6))
#if defined(PROMINI) || (defined(PROMICRO) && defined(HWPWM6))
atomicServo[i] = (servo[i]-1000)>>2;
atomicServo[i] = (servo[i]-1000)>>2;
#else
#else
atomicServo[i] = (servo[i]-1000)<<4;
atomicServo[i] = (servo[i]-1000)<<4;
#endif
#endif
}
}
#endif
#endif
#if defined(SEC_SERVO_FROM) // write secundary servos
#if defined(SEC_SERVO_FROM) // write secundary servos
#if defined(SERVO_TILT) && defined(MMSERVOGIMBAL)
#if defined(SERVO_TILT) && defined(MMSERVOGIMBAL)
// Moving Average Servo Gimbal by Magnetron1
// Moving Average Servo Gimbal by Magnetron1
static int16_t mediaMobileServoGimbalADC[3][MMSERVOGIMBALVECTORLENGHT];
static int16_t mediaMobileServoGimbalADC[3][MMSERVOGIMBALVECTORLENGHT];
static int32_t mediaMobileServoGimbalADCSum[3];
static int32_t mediaMobileServoGimbalADCSum[3];
static uint8_t mediaMobileServoGimbalIDX;
static uint8_t mediaMobileServoGimbalIDX;
uint8_t axis;
uint8_t axis;
mediaMobileServoGimbalIDX = ++mediaMobileServoGimbalIDX % MMSERVOGIMBALVECTORLENGHT;
mediaMobileServoGimbalIDX = ++mediaMobileServoGimbalIDX % MMSERVOGIMBALVECTORLENGHT;
for (axis=(SEC_SERVO_FROM-1); axis < SEC_SERVO_TO; axis++) {
for (axis=(SEC_SERVO_FROM-1); axis < SEC_SERVO_TO; axis++) {
mediaMobileServoGimbalADCSum[axis] -= mediaMobileServoGimbalADC[axis][mediaMobileServoGimbalIDX];
mediaMobileServoGimbalADCSum[axis] -= mediaMobileServoGimbalADC[axis][mediaMobileServoGimbalIDX];
mediaMobileServoGimbalADC[axis][mediaMobileServoGimbalIDX] = servo[axis];
mediaMobileServoGimbalADC[axis][mediaMobileServoGimbalIDX] = servo[axis];
mediaMobileServoGimbalADCSum[axis] += mediaMobileServoGimbalADC[axis][mediaMobileServoGimbalIDX];
mediaMobileServoGimbalADCSum[axis] += mediaMobileServoGimbalADC[axis][mediaMobileServoGimbalIDX];
#if defined(PROMINI) || (defined(PROMICRO) && defined(HWPWM6))
#if defined(PROMINI) || (defined(PROMICRO) && defined(HWPWM6))
atomicServo[axis] = (mediaMobileServoGimbalADCSum[axis] / MMSERVOGIMBALVECTORLENGHT - 1000)>>2;
atomicServo[axis] = (mediaMobileServoGimbalADCSum[axis] / MMSERVOGIMBALVECTORLENGHT - 1000)>>2;
#else
#else
atomicServo[axis] = (mediaMobileServoGimbalADCSum[axis] / MMSERVOGIMBALVECTORLENGHT - 1000)<<4;
atomicServo[axis] = (mediaMobileServoGimbalADCSum[axis] / MMSERVOGIMBALVECTORLENGHT - 1000)<<4;
#endif
#endif
}
}
#else
#else
for(uint8_t i = (SEC_SERVO_FROM-1); i < SEC_SERVO_TO; i++){
for(uint8_t i = (SEC_SERVO_FROM-1); i < SEC_SERVO_TO; i++){
#if defined(PROMINI) || (defined(PROMICRO) && defined(HWPWM6))
#if defined(PROMINI) || (defined(PROMICRO) && defined(HWPWM6))
atomicServo[i] = (servo[i]-1000)>>2;
atomicServo[i] = (servo[i]-1000)>>2;
#else
#else
atomicServo[i] = (servo[i]-1000)<<4;
atomicServo[i] = (servo[i]-1000)<<4;
#endif
#endif
}
}
#endif
#endif
#endif
#endif
#endif
#endif
}
}
/**************************************************************************************/
/**************************************************************************************/
/************ Writes the Motors values to the PWM compare register ******************/
/************ Writes the Motors values to the PWM compare register ******************/
/**************************************************************************************/
/**************************************************************************************/
void writeMotors() { // [1000;2000] => [125;250]
void writeMotors() { // [1000;2000] => [125;250]
/**************** Specific PWM Timers & Registers for the MEGA's *******************/
/**************** Specific PWM Timers & Registers for the MEGA's *******************/
#if defined(MEGA)// [1000:2000] => [8000:16000] for timer 3 & 4 for mega
#if defined(MEGA)// [1000:2000] => [8000:16000] for timer 3 & 4 for mega
#if (NUMBER_MOTOR > 0)
#if (NUMBER_MOTOR > 0)
#ifndef EXT_MOTOR_RANGE
#ifndef EXT_MOTOR_RANGE
OCR3C = motor[0]<<3; // pin 3
OCR3C = motor[0]<<3; // pin 3
#else
#else
OCR3C = ((motor[0]<<4) - 16000) + 128;
OCR3C = ((motor[0]<<4) - 16000) + 128;
#endif
#endif
#endif
#endif
#if (NUMBER_MOTOR > 1)
#if (NUMBER_MOTOR > 1)
#ifndef EXT_MOTOR_RANGE
#ifndef EXT_MOTOR_RANGE
OCR3A = motor[1]<<3; // pin 5
OCR3A = motor[1]<<3; // pin 5
#else
#else
OCR3A = ((motor[1]<<4) - 16000) + 128;
OCR3A = ((motor[1]<<4) - 16000) + 128;
#endif
#endif
#endif
#endif
#if (NUMBER_MOTOR > 2)
#if (NUMBER_MOTOR > 2)
#ifndef EXT_MOTOR_RANGE
#ifndef EXT_MOTOR_RANGE
OCR4A = motor[2]<<3; // pin 6
OCR4A = motor[2]<<3; // pin 6
#else
#else
OCR4A = ((motor[2]<<4) - 16000) + 128;
OCR4A = ((motor[2]<<4) - 16000) + 128;
#endif
#endif
#endif
#endif
#if (NUMBER_MOTOR > 3)
#if (NUMBER_MOTOR > 3)
#ifndef EXT_MOTOR_RANGE
#ifndef EXT_MOTOR_RANGE
OCR3B = motor[3]<<3; // pin 2
OCR3B = motor[3]<<3; // pin 2
#else
#else
OCR3B = ((motor[3]<<4) - 16000) + 128;
OCR3B = ((motor[3]<<4) - 16000) + 128;
#endif
#endif
#endif
#endif
#if (NUMBER_MOTOR > 4)
#if (NUMBER_MOTOR > 4)
#ifndef EXT_MOTOR_RANGE
#ifndef EXT_MOTOR_RANGE
OCR4B = motor[4]<<3; // pin 7
OCR4B = motor[4]<<3; // pin 7
OCR4C = motor[5]<<3; // pin 8
OCR4C = motor[5]<<3; // pin 8
#else
#else
OCR4B = ((motor[4]<<4) - 16000) + 128;
OCR4B = ((motor[4]<<4) - 16000) + 128;
OCR4C = ((motor[5]<<4) - 16000) + 128;
OCR4C = ((motor[5]<<4) - 16000) + 128;
#endif
#endif
#endif
#endif
#if (NUMBER_MOTOR > 6)
#if (NUMBER_MOTOR > 6)
#ifndef EXT_MOTOR_RANGE
#ifndef EXT_MOTOR_RANGE
OCR2B = motor[6]>>3; // pin 9
OCR2B = motor[6]>>3; // pin 9
OCR2A = motor[7]>>3; // pin 10
OCR2A = motor[7]>>3; // pin 10
#else
#else
OCR2B = ((motor[6]>>2) - 250) + 2);
OCR2B = ((motor[6]>>2) - 250) + 2);
OCR2A = ((motor[7]>>2) - 250) + 2);
OCR2A = ((motor[7]>>2) - 250) + 2);
#endif
#endif
#endif
#endif
#endif
#endif
/******** Specific PWM Timers & Registers for the atmega32u4 (Promicro) ************/
/******** Specific PWM Timers & Registers for the atmega32u4 (Promicro) ************/
#if defined(PROMICRO)
#if defined(PROMICRO)
#if (NUMBER_MOTOR > 0) // Timer 1 A & B [1000:2000] => [8000:16000]
#if (NUMBER_MOTOR > 0) // Timer 1 A & B [1000:2000] => [8000:16000]
OCR1A = motor[0]<<3; // pin 9
OCR1A = motor[0]<<3; // pin 9
#endif
#endif
#if (NUMBER_MOTOR > 1)
#if (NUMBER_MOTOR > 1)
OCR1B = motor[1]<<3; // pin 10
OCR1B = motor[1]<<3; // pin 10
#endif
#endif
#if (NUMBER_MOTOR > 2) // Timer 4 A & D [1000:2000] => [1000:2000]
#if (NUMBER_MOTOR > 2) // Timer 4 A & D [1000:2000] => [1000:2000]
#if !defined(HWPWM6)
#if !defined(HWPWM6)
// to write values > 255 to timer 4 A/B we need to split the bytes
// to write values > 255 to timer 4 A/B we need to split the bytes
TC4H = (2047-motor[2])>>8; OCR4A = ((2047-motor[2])&0xFF); // pin 5
TC4H = (2047-motor[2])>>8; OCR4A = ((2047-motor[2])&0xFF); // pin 5
#else
#else
OCR3A = motor[2]<<3; // pin 5
OCR3A = motor[2]<<3; // pin 5
#endif
#endif
#endif
#endif
#if (NUMBER_MOTOR > 3)
#if (NUMBER_MOTOR > 3)
TC4H = motor[3]>>8; OCR4D = (motor[3]&0xFF); // pin 6
TC4H = motor[3]>>8; OCR4D = (motor[3]&0xFF); // pin 6
#endif
#endif
#if (NUMBER_MOTOR > 4)
#if (NUMBER_MOTOR > 4)
#if !defined(HWPWM6)
#if !defined(HWPWM6)
#if (NUMBER_MOTOR == 6) && !defined(SERVO)
#if (NUMBER_MOTOR == 6) && !defined(SERVO)
atomicPWM_PIN5_highState = motor[4]<<3;
atomicPWM_PIN5_highState = motor[4]<<3;
atomicPWM_PIN5_lowState = 16383-atomicPWM_PIN5_highState;
atomicPWM_PIN5_lowState = 16383-atomicPWM_PIN5_highState;
atomicPWM_PIN6_highState = motor[5]<<3;
atomicPWM_PIN6_highState = motor[5]<<3;
atomicPWM_PIN6_lowState = 16383-atomicPWM_PIN6_highState;
atomicPWM_PIN6_lowState = 16383-atomicPWM_PIN6_highState;
#else
#else
atomicPWM_PIN5_highState = ((motor[4]-1000)<<4)+320;
atomicPWM_PIN5_highState = ((motor[4]-1000)<<4)+320;
atomicPWM_PIN5_lowState = 15743-atomicPWM_PIN5_highState;
atomicPWM_PIN5_lowState = 15743-atomicPWM_PIN5_highState;
atomicPWM_PIN6_highState = ((motor[5]-1000)<<4)+320;
atomicPWM_PIN6_highState = ((motor[5]-1000)<<4)+320;
atomicPWM_PIN6_lowState = 15743-atomicPWM_PIN6_highState;
atomicPWM_PIN6_lowState = 15743-atomicPWM_PIN6_highState;
#endif
#endif
#else
#else
OCR1C = motor[4]<<3; // pin 11
OCR1C = motor[4]<<3; // pin 11
TC4H = motor[5]>>8; OCR4A = (motor[5]&0xFF); // pin 13
TC4H = motor[5]>>8; OCR4A = (motor[5]&0xFF); // pin 13
#endif
#endif
#endif
#endif
#if (NUMBER_MOTOR > 6)
#if (NUMBER_MOTOR > 6)
#if !defined(HWPWM6)
#if !defined(HWPWM6)
atomicPWM_PINA2_highState = ((motor[6]-1000)<<4)+320;
atomicPWM_PINA2_highState = ((motor[6]-1000)<<4)+320;
atomicPWM_PINA2_lowState = 15743-atomicPWM_PINA2_highState;
atomicPWM_PINA2_lowState = 15743-atomicPWM_PINA2_highState;
atomicPWM_PIN12_highState = ((motor[7]-1000)<<4)+320;
atomicPWM_PIN12_highState = ((motor[7]-1000)<<4)+320;
atomicPWM_PIN12_lowState = 15743-atomicPWM_PIN12_highState;
atomicPWM_PIN12_lowState = 15743-atomicPWM_PIN12_highState;
#else
#else
atomicPWM_PINA2_highState = ((motor[6]-1000)>>2)+5;
atomicPWM_PINA2_highState = ((motor[6]-1000)>>2)+5;
atomicPWM_PINA2_lowState = 245-atomicPWM_PINA2_highState;
atomicPWM_PINA2_lowState = 245-atomicPWM_PINA2_highState;
atomicPWM_PIN12_highState = ((motor[7]-1000)>>2)+5;
atomicPWM_PIN12_highState = ((motor[7]-1000)>>2)+5;
atomicPWM_PIN12_lowState = 245-atomicPWM_PIN12_highState;
atomicPWM_PIN12_lowState = 245-atomicPWM_PIN12_highState;
#endif
#endif
#endif
#endif
#endif
#endif
/******** Specific PWM Timers & Registers for the atmega328P (Promini) ************/
/******** Specific PWM Timers & Registers for the atmega328P (Promini) ************/
#if defined(PROMINI)
#if defined(PROMINI)
#if (NUMBER_MOTOR > 0)
#if (NUMBER_MOTOR > 0)
#ifndef EXT_MOTOR_RANGE
#ifndef EXT_MOTOR_RANGE
OCR1A = motor[0]>>3; // pin 9
OCR1A = motor[0]>>3; // pin 9
#else
#else
OCR1A = ((motor[0]>>2) - 250) + 2;
OCR1A = ((motor[0]>>2) - 250) + 2;
#endif
#endif
#endif
#endif
#if (NUMBER_MOTOR > 1)
#if (NUMBER_MOTOR > 1)
#ifndef EXT_MOTOR_RANGE
#ifndef EXT_MOTOR_RANGE
OCR1B = motor[1]>>3; // pin 10
OCR1B = motor[1]>>3; // pin 10
#else
#else
OCR1B = ((motor[1]>>2) - 250) + 2;
OCR1B = ((motor[1]>>2) - 250) + 2;
#endif
#endif
#endif
#endif
#if (NUMBER_MOTOR > 2)
#if (NUMBER_MOTOR > 2)
#ifndef EXT_MOTOR_RANGE
#ifndef EXT_MOTOR_RANGE
OCR2A = motor[2]>>3; // pin 11
OCR2A = motor[2]>>3; // pin 11
#else
#else
OCR2A = ((motor[2]>>2) - 250) + 2;
OCR2A = ((motor[2]>>2) - 250) + 2;
#endif
#endif
#endif
#endif
#if (NUMBER_MOTOR > 3)
#if (NUMBER_MOTOR > 3)
#ifndef EXT_MOTOR_RANGE
#ifndef EXT_MOTOR_RANGE
OCR2B = motor[3]>>3; // pin 3
OCR2B = motor[3]>>3; // pin 3
#else
#else
OCR2B = ((motor[3]>>2) - 250) + 2;
OCR2B = ((motor[3]>>2) - 250) + 2;
#endif
#endif
#endif
#endif
#if (NUMBER_MOTOR > 4)
#if (NUMBER_MOTOR > 4)
#if (NUMBER_MOTOR == 6) && !defined(SERVO)
#if (NUMBER_MOTOR == 6) && !defined(SERVO)
#ifndef EXT_MOTOR_RANGE
#ifndef EXT_MOTOR_RANGE
atomicPWM_PIN6_highState = motor[4]>>3;
atomicPWM_PIN6_highState = motor[4]>>3;
atomicPWM_PIN5_highState = motor[5]>>3;
atomicPWM_PIN5_highState = motor[5]>>3;
#else
#else
atomicPWM_PIN6_highState = ((motor[4]>>2) - 250) + 2;
atomicPWM_PIN6_highState = ((motor[4]>>2) - 250) + 2;
atomicPWM_PIN5_highState = ((motor[5]>>2) - 250) + 2;
atomicPWM_PIN5_highState = ((motor[5]>>2) - 250) + 2;
#endif
#endif
atomicPWM_PIN6_lowState = 255-atomicPWM_PIN6_highState;
atomicPWM_PIN6_lowState = 255-atomicPWM_PIN6_highState;
atomicPWM_PIN5_lowState = 255-atomicPWM_PIN5_highState;
atomicPWM_PIN5_lowState = 255-atomicPWM_PIN5_highState;
#else //note: EXT_MOTOR_RANGE not possible here
#else //note: EXT_MOTOR_RANGE not possible here
atomicPWM_PIN6_highState = ((motor[4]-1000)>>2)+5;
atomicPWM_PIN6_highState = ((motor[4]-1000)>>2)+5;
atomicPWM_PIN6_lowState = 245-atomicPWM_PIN6_highState;
atomicPWM_PIN6_lowState = 245-atomicPWM_PIN6_highState;
atomicPWM_PIN5_highState = ((motor[5]-1000)>>2)+5;
atomicPWM_PIN5_highState = ((motor[5]-1000)>>2)+5;
atomicPWM_PIN5_lowState = 245-atomicPWM_PIN5_highState;
atomicPWM_PIN5_lowState = 245-atomicPWM_PIN5_highState;
#endif
#endif
#endif
#endif
#if (NUMBER_MOTOR > 6) //note: EXT_MOTOR_RANGE not possible here
#if (NUMBER_MOTOR > 6) //note: EXT_MOTOR_RANGE not possible here
atomicPWM_PINA2_highState = ((motor[6]-1000)>>2)+5;
atomicPWM_PINA2_highState = ((motor[6]-1000)>>2)+5;
atomicPWM_PINA2_lowState = 245-atomicPWM_PINA2_highState;
atomicPWM_PINA2_lowState = 245-atomicPWM_PINA2_highState;
atomicPWM_PIN12_highState = ((motor[7]-1000)>>2)+5;
atomicPWM_PIN12_highState = ((motor[7]-1000)>>2)+5;
atomicPWM_PIN12_lowState = 245-atomicPWM_PIN12_highState;
atomicPWM_PIN12_lowState = 245-atomicPWM_PIN12_highState;
#endif
#endif
#endif
#endif
}
}
/**************************************************************************************/
/**************************************************************************************/
/************ Writes the mincommand to all Motors ******************/
/************ Writes the mincommand to all Motors ******************/
/**************************************************************************************/
/**************************************************************************************/
void writeAllMotors(int16_t mc) { // Sends commands to all motors
void writeAllMotors(int16_t mc) { // Sends commands to all motors
for (uint8_t i =0;i<NUMBER_MOTOR;i++)
for (uint8_t i =0;i<NUMBER_MOTOR;i++)
motor[i]=mc;
motor[i]=mc;
writeMotors();
writeMotors();
}
}
/**************************************************************************************/
/**************************************************************************************/
/************ Initialize the PWM Timers and Registers ******************/
/************ Initialize the PWM Timers and Registers ******************/
/**************************************************************************************/
/**************************************************************************************/
void initOutput() {
void initOutput() {
/**************** mark all PWM pins as Output ******************/
/**************** mark all PWM pins as Output ******************/
for(uint8_t i=0;i<NUMBER_MOTOR;i++)
for(uint8_t i=0;i<NUMBER_MOTOR;i++)
pinMode(PWM_PIN[i],OUTPUT);
pinMode(PWM_PIN[i],OUTPUT);
/**************** Specific PWM Timers & Registers for the MEGA's ******************/
/**************** Specific PWM Timers & Registers for the MEGA's ******************/
#if defined(MEGA)
#if defined(MEGA)
#if (NUMBER_MOTOR > 0)
#if (NUMBER_MOTOR > 0)
// init 16bit timer 3
// init 16bit timer 3
TCCR3A |= (1<<WGM31); // phase correct mode
TCCR3A |= (1<<WGM31); // phase correct mode
TCCR3A &= ~(1<<WGM30);
TCCR3A &= ~(1<<WGM30);
TCCR3B |= (1<<WGM33);
TCCR3B |= (1<<WGM33);
TCCR3B &= ~(1<<CS31); // no prescaler
TCCR3B &= ~(1<<CS31); // no prescaler
ICR3 |= 0x3FFF; // TOP to 16383;
ICR3 |= 0x3FFF; // TOP to 16383;
TCCR3A |= _BV(COM3C1); // connect pin 3 to timer 3 channel C
TCCR3A |= _BV(COM3C1); // connect pin 3 to timer 3 channel C
#endif
#endif
#if (NUMBER_MOTOR > 1)
#if (NUMBER_MOTOR > 1)
TCCR3A |= _BV(COM3A1); // connect pin 5 to timer 3 channel A
TCCR3A |= _BV(COM3A1); // connect pin 5 to timer 3 channel A
#endif
#endif
#if (NUMBER_MOTOR > 2)
#if (NUMBER_MOTOR > 2)
// init 16bit timer 4
// init 16bit timer 4
TCCR4A |= (1<<WGM41); // phase correct mode
TCCR4A |= (1<<WGM41); // phase correct mode
TCCR4A &= ~(1<<WGM40);
TCCR4A &= ~(1<<WGM40);
TCCR4B |= (1<<WGM43);
TCCR4B |= (1<<WGM43);
TCCR4B &= ~(1<<CS41); // no prescaler
TCCR4B &= ~(1<<CS41); // no prescaler
ICR4 |= 0x3FFF; // TOP to 16383;
ICR4 |= 0x3FFF; // TOP to 16383;
TCCR4A |= _BV(COM4A1); // connect pin 6 to timer 4 channel A
TCCR4A |= _BV(COM4A1); // connect pin 6 to timer 4 channel A
#endif
#endif
#if (NUMBER_MOTOR > 3)
#if (NUMBER_MOTOR > 3)
TCCR3A |= _BV(COM3B1); // connect pin 2 to timer 3 channel B
TCCR3A |= _BV(COM3B1); // connect pin 2 to timer 3 channel B
#endif
#endif
#if (NUMBER_MOTOR > 4)
#if (NUMBER_MOTOR > 4)
TCCR4A |= _BV(COM4B1); // connect pin 7 to timer 4 channel B
TCCR4A |= _BV(COM4B1); // connect pin 7 to timer 4 channel B
TCCR4A |= _BV(COM4C1); // connect pin 8 to timer 4 channel C
TCCR4A |= _BV(COM4C1); // connect pin 8 to timer 4 channel C
#endif
#endif
#if (NUMBER_MOTOR > 6)
#if (NUMBER_MOTOR > 6)
// timer 2 is a 8bit timer so we cant change its range
// timer 2 is a 8bit timer so we cant change its range
TCCR2A |= _BV(COM2B1); // connect pin 9 to timer 2 channel B
TCCR2A |= _BV(COM2B1); // connect pin 9 to timer 2 channel B
TCCR2A |= _BV(COM2A1); // connect pin 10 to timer 2 channel A
TCCR2A |= _BV(COM2A1); // connect pin 10 to timer 2 channel A
#endif
#endif
#endif
#endif
/******** Specific PWM Timers & Registers for the atmega32u4 (Promicro) ************/
/******** Specific PWM Timers & Registers for the atmega32u4 (Promicro) ************/
#if defined(PROMICRO)
#if defined(PROMICRO)
#if (NUMBER_MOTOR > 0)
#if (NUMBER_MOTOR > 0)
TCCR1A |= (1<<WGM11); // phase correct mode & no prescaler
TCCR1A |= (1<<WGM11); // phase correct mode & no prescaler
TCCR1A &= ~(1<<WGM10);
TCCR1A &= ~(1<<WGM10);
TCCR1B &= ~(1<<WGM12) & ~(1<<CS11) & ~(1<<CS12);
TCCR1B &= ~(1<<WGM12) & ~(1<<CS11) & ~(1<<CS12);
TCCR1B |= (1<<WGM13) | (1<<CS10);
TCCR1B |= (1<<WGM13) | (1<<CS10);
ICR1 |= 0x3FFF; // TOP to 16383;
ICR1 |= 0x3FFF; // TOP to 16383;
TCCR1A |= _BV(COM1A1); // connect pin 9 to timer 1 channel A
TCCR1A |= _BV(COM1A1); // connect pin 9 to timer 1 channel A
#endif
#endif
#if (NUMBER_MOTOR > 1)
#if (NUMBER_MOTOR > 1)
TCCR1A |= _BV(COM1B1); // connect pin 10 to timer 1 channel B
TCCR1A |= _BV(COM1B1); // connect pin 10 to timer 1 channel B
#endif
#endif
#if (NUMBER_MOTOR > 2)
#if (NUMBER_MOTOR > 2)
#if !defined(HWPWM6) // timer 4A
#if !defined(HWPWM6) // timer 4A
TCCR4E |= (1<<ENHC4); // enhanced pwm mode
TCCR4E |= (1<<ENHC4); // enhanced pwm mode
TCCR4B &= ~(1<<CS41); TCCR4B |= (1<<CS42)|(1<<CS40); // prescaler to 16
TCCR4B &= ~(1<<CS41); TCCR4B |= (1<<CS42)|(1<<CS40); // prescaler to 16
TCCR4D |= (1<<WGM40); TC4H = 0x3; OCR4C = 0xFF; // phase and frequency correct mode & top to 1023 but with enhanced pwm mode we have 2047
TCCR4D |= (1<<WGM40); TC4H = 0x3; OCR4C = 0xFF; // phase and frequency correct mode & top to 1023 but with enhanced pwm mode we have 2047
TCCR4A |= (1<<COM4A0)|(1<<PWM4A); // connect pin 5 to timer 4 channel A
TCCR4A |= (1<<COM4A0)|(1<<PWM4A); // connect pin 5 to timer 4 channel A
#else // timer 3A
#else // timer 3A
TCCR3A |= (1<<WGM31); // phase correct mode & no prescaler
TCCR3A |= (1<<WGM31); // phase correct mode & no prescaler
TCCR3A &= ~(1<<WGM30);
TCCR3A &= ~(1<<WGM30);
TCCR3B &= ~(1<<WGM32) & ~(1<<CS31) & ~(1<<CS32);
TCCR3B &= ~(1<<WGM32) & ~(1<<CS31) & ~(1<<CS32);
TCCR3B |= (1<<WGM33) | (1<<CS30);
TCCR3B |= (1<<WGM33) | (1<<CS30);
ICR3 |= 0x3FFF; // TOP to 16383;
ICR3 |= 0x3FFF; // TOP to 16383;
TCCR3A |= _BV(COM3A1); // connect pin 5 to timer 3 channel A
TCCR3A |= _BV(COM3A1); // connect pin 5 to timer 3 channel A
#endif
#endif
#endif
#endif
#if (NUMBER_MOTOR > 3)
#if (NUMBER_MOTOR > 3)
#if defined(HWPWM6)
#if defined(HWPWM6)
TCCR4E |= (1<<ENHC4); // enhanced pwm mode
TCCR4E |= (1<<ENHC4); // enhanced pwm mode
TCCR4B &= ~(1<<CS41); TCCR4B |= (1<<CS42)|(1<<CS40); // prescaler to 16
TCCR4B &= ~(1<<CS41); TCCR4B |= (1<<CS42)|(1<<CS40); // prescaler to 16
TCCR4D |= (1<<WGM40); TC4H = 0x3; OCR4C = 0xFF; // phase and frequency correct mode & top to 1023 but with enhanced pwm mode we have 2047
TCCR4D |= (1<<WGM40); TC4H = 0x3; OCR4C = 0xFF; // phase and frequency correct mode & top to 1023 but with enhanced pwm mode we have 2047
#endif
#endif
TCCR4C |= (1<<COM4D1)|(1<<PWM4D); // connect pin 6 to timer 4 channel D
TCCR4C |= (1<<COM4D1)|(1<<PWM4D); // connect pin 6 to timer 4 channel D
#endif
#endif
#if (NUMBER_MOTOR > 4)
#if (NUMBER_MOTOR > 4)
#if defined(HWPWM6)
#if defined(HWPWM6)
TCCR1A |= _BV(COM1C1); // connect pin 11 to timer 1 channel C
TCCR1A |= _BV(COM1C1); // connect pin 11 to timer 1 channel C
TCCR4A |= (1<<COM4A1)|(1<<PWM4A); // connect pin 13 to timer 4 channel A
TCCR4A |= (1<<COM4A1)|(1<<PWM4A); // connect pin 13 to timer 4 channel A
#else
#else
initializeSoftPWM();
initializeSoftPWM();
#endif
#endif
#endif
#endif
#if (NUMBER_MOTOR > 6)
#if (NUMBER_MOTOR > 6)
#if defined(HWPWM6)
#if defined(HWPWM6)
initializeSoftPWM();
initializeSoftPWM();
#endif
#endif
#endif
#endif
#endif
#endif
/******** Specific PWM Timers & Registers for the atmega328P (Promini) ************/
/******** Specific PWM Timers & Registers for the atmega328P (Promini) ************/
#if defined(PROMINI)
#if defined(PROMINI)
#if (NUMBER_MOTOR > 0)
#if (NUMBER_MOTOR > 0)
TCCR1A |= _BV(COM1A1); // connect pin 9 to timer 1 channel A
TCCR1A |= _BV(COM1A1); // connect pin 9 to timer 1 channel A
#endif
#endif
#if (NUMBER_MOTOR > 1)
#if (NUMBER_MOTOR > 1)
TCCR1A |= _BV(COM1B1); // connect pin 10 to timer 1 channel B
TCCR1A |= _BV(COM1B1); // connect pin 10 to timer 1 channel B
#endif
#endif
#if (NUMBER_MOTOR > 2)
#if (NUMBER_MOTOR > 2)
TCCR2A |= _BV(COM2A1); // connect pin 11 to timer 2 channel A
TCCR2A |= _BV(COM2A1); // connect pin 11 to timer 2 channel A
#endif
#endif
#if (NUMBER_MOTOR > 3)
#if (NUMBER_MOTOR > 3)
TCCR2A |= _BV(COM2B1); // connect pin 3 to timer 2 channel B
TCCR2A |= _BV(COM2B1); // connect pin 3 to timer 2 channel B
#endif
#endif
#if (NUMBER_MOTOR > 5) // PIN 5 & 6 or A0 & A1
#if (NUMBER_MOTOR > 5) // PIN 5 & 6 or A0 & A1
initializeSoftPWM();
initializeSoftPWM();
#if defined(A0_A1_PIN_HEX) || (NUMBER_MOTOR > 6)
#if defined(A0_A1_PIN_HEX) || (NUMBER_MOTOR > 6)
pinMode(5,INPUT);pinMode(6,INPUT); // we reactivate the INPUT affectation for these two PINs
pinMode(5,INPUT);pinMode(6,INPUT); // we reactivate the INPUT affectation for these two PINs
pinMode(A0,OUTPUT);pinMode(A1,OUTPUT);
pinMode(A0,OUTPUT);pinMode(A1,OUTPUT);
#endif
#endif
#endif
#endif
#endif
#endif
writeAllMotors(MINCOMMAND);
writeAllMotors(MINCOMMAND);
delay(300);
delay(300);
#if defined(SERVO)
#if defined(SERVO)
initializeServo();
initializeServo();
#endif
#endif
}
}
#if defined(SERVO)
#if defined(SERVO)
/**************************************************************************************/
/**************************************************************************************/
/************ Initialize the PWM Servos ******************/
/************ Initialize the PWM Servos ******************/
/**************************************************************************************/
/**************************************************************************************/
void initializeServo() {
void initializeServo() {
#if (PRI_SERVO_FROM == 1) || (SEC_SERVO_FROM == 1)
#if (PRI_SERVO_FROM == 1) || (SEC_SERVO_FROM == 1)
SERVO_1_PINMODE;
SERVO_1_PINMODE;
#endif
#endif
#if (PRI_SERVO_FROM <= 2 && PRI_SERVO_TO >= 2) || (SEC_SERVO_FROM <= 2 && SEC_SERVO_TO >= 2)
#if (PRI_SERVO_FROM <= 2 && PRI_SERVO_TO >= 2) || (SEC_SERVO_FROM <= 2 && SEC_SERVO_TO >= 2)
SERVO_2_PINMODE;
SERVO_2_PINMODE;
#endif
#endif
#if (PRI_SERVO_FROM <= 3 && PRI_SERVO_TO >= 3) || (SEC_SERVO_FROM <= 3 && SEC_SERVO_TO >= 3)
#if (PRI_SERVO_FROM <= 3 && PRI_SERVO_TO >= 3) || (SEC_SERVO_FROM <= 3 && SEC_SERVO_TO >= 3)
SERVO_3_PINMODE;
SERVO_3_PINMODE;
#endif
#endif
#if (PRI_SERVO_FROM <= 4 && PRI_SERVO_TO >= 4) || (SEC_SERVO_FROM <= 4 && SEC_SERVO_TO >= 4)
#if (PRI_SERVO_FROM <= 4 && PRI_SERVO_TO >= 4) || (SEC_SERVO_FROM <= 4 && SEC_SERVO_TO >= 4)
SERVO_4_PINMODE;
SERVO_4_PINMODE;
#endif
#endif
#if (PRI_SERVO_FROM <= 5 && PRI_SERVO_TO >= 5) || (SEC_SERVO_FROM <= 5 && SEC_SERVO_TO >= 5)
#if (PRI_SERVO_FROM <= 5 && PRI_SERVO_TO >= 5) || (SEC_SERVO_FROM <= 5 && SEC_SERVO_TO >= 5)
SERVO_5_PINMODE;
SERVO_5_PINMODE;
#endif
#endif
#if (PRI_SERVO_FROM <= 6 && PRI_SERVO_TO >= 6) || (SEC_SERVO_FROM <= 6 && SEC_SERVO_TO >= 6)
#if (PRI_SERVO_FROM <= 6 && PRI_SERVO_TO >= 6) || (SEC_SERVO_FROM <= 6 && SEC_SERVO_TO >= 6)
SERVO_6_PINMODE;
SERVO_6_PINMODE;
#endif
#endif
#if (PRI_SERVO_FROM <= 7 && PRI_SERVO_TO >= 7) || (SEC_SERVO_FROM <= 7 && SEC_SERVO_TO >= 7)
#if (PRI_SERVO_FROM <= 7 && PRI_SERVO_TO >= 7) || (SEC_SERVO_FROM <= 7 && SEC_SERVO_TO >= 7)
SERVO_7_PINMODE;
SERVO_7_PINMODE;
#endif
#endif
#if (PRI_SERVO_FROM <= 8 && PRI_SERVO_TO >= 8) || (SEC_SERVO_FROM <= 8 && SEC_SERVO_TO >= 8)
#if (PRI_SERVO_FROM <= 8 && PRI_SERVO_TO >= 8) || (SEC_SERVO_FROM <= 8 && SEC_SERVO_TO >= 8)
SERVO_8_PINMODE;
SERVO_8_PINMODE;
#endif
#endif
#if defined(PROMINI) || (defined(PROMICRO) && defined(HWPWM6)) // uses timer 0 Comperator A (8 bit)
#if defined(PROMINI) || (defined(PROMICRO) && defined(HWPWM6)) // uses timer 0 Comperator A (8 bit)
TCCR0A = 0; // normal counting mode
TCCR0A = 0; // normal counting mode
TIMSK0 |= (1<<OCIE0A); // Enable CTC interrupt
TIMSK0 |= (1<<OCIE0A); // Enable CTC interrupt
#define SERVO_ISR TIMER0_COMPA_vect
#define SERVO_ISR TIMER0_COMPA_vect
#define SERVO_CHANNEL OCR0A
#define SERVO_CHANNEL OCR0A
#define SERVO_1K_US 250
#define SERVO_1K_US 250
#endif
#endif
#if (defined(PROMICRO) && !defined(HWPWM6)) // uses timer 3 Comperator A (11 bit)
#if (defined(PROMICRO) && !defined(HWPWM6)) // uses timer 3 Comperator A (11 bit)
TCCR3A &= ~(1<<WGM30) & ~(1<<WGM31); //normal counting & no prescaler
TCCR3A &= ~(1<<WGM30) & ~(1<<WGM31); //normal counting & no prescaler
TCCR3B &= ~(1<<WGM32) & ~(1<<CS31) & ~(1<<CS32) & ~(1<<WGM33);
TCCR3B &= ~(1<<WGM32) & ~(1<<CS31) & ~(1<<CS32) & ~(1<<WGM33);
TCCR3B |= (1<<CS30);
TCCR3B |= (1<<CS30);
TIMSK3 |= (1<<OCIE3A); // Enable CTC interrupt
TIMSK3 |= (1<<OCIE3A); // Enable CTC interrupt
#define SERVO_ISR TIMER3_COMPA_vect
#define SERVO_ISR TIMER3_COMPA_vect
#define SERVO_CHANNEL OCR3A
#define SERVO_CHANNEL OCR3A
#define SERVO_1K_US 16000
#define SERVO_1K_US 16000
#endif
#endif
#if defined(MEGA) // uses timer 5 Comperator A (11 bit)
#if defined(MEGA) // uses timer 5 Comperator A (11 bit)
TCCR5A &= ~(1<<WGM50) & ~(1<<WGM51); //normal counting & no prescaler
TCCR5A &= ~(1<<WGM50) & ~(1<<WGM51); //normal counting & no prescaler
TCCR5B &= ~(1<<WGM52) & ~(1<<CS51) & ~(1<<CS52) & ~(1<<WGM53);
TCCR5B &= ~(1<<WGM52) & ~(1<<CS51) & ~(1<<CS52) & ~(1<<WGM53);
TCCR5B |= (1<<CS50);
TCCR5B |= (1<<CS50);
TIMSK5 |= (1<<OCIE5A); // Enable CTC interrupt
TIMSK5 |= (1<<OCIE5A); // Enable CTC interrupt
#define SERVO_ISR TIMER5_COMPA_vect
#define SERVO_ISR TIMER5_COMPA_vect
#define SERVO_CHANNEL OCR5A
#define SERVO_CHANNEL OCR5A
#define SERVO_1K_US 16000
#define SERVO_1K_US 16000
#endif
#endif
}
}
/**************************************************************************************/
/**************************************************************************************/
/************ Servo software PWM generation ******************/
/************ Servo software PWM generation ******************/
/**************************************************************************************/
/**************************************************************************************/
// prescaler is set by default to 64 on Timer0
// prescaler is set by default to 64 on Timer0
// Duemilanove : 16MHz / 64 => 4 us
// Duemilanove : 16MHz / 64 => 4 us
// 256 steps = 1 counter cycle = 1024 us
// 256 steps = 1 counter cycle = 1024 us
// for servo 2-8
// for servo 2-8
// its almost the same as for servo 1
// its almost the same as for servo 1
#define SERVO_PULSE(PIN_HIGH,ACT_STATE,SERVO_NUM,LAST_PIN_LOW) \
#define SERVO_PULSE(PIN_HIGH,ACT_STATE,SERVO_NUM,LAST_PIN_LOW) \
}else if(state == ACT_STATE){ \
}else if(state == ACT_STATE){ \
LAST_PIN_LOW; \
LAST_PIN_LOW; \
PIN_HIGH; \
PIN_HIGH; \
SERVO_CHANNEL+=SERVO_1K_US; \
SERVO_CHANNEL+=SERVO_1K_US; \
state++; \
state++; \
}else if(state == ACT_STATE+1){ \
}else if(state == ACT_STATE+1){ \
SERVO_CHANNEL+=atomicServo[SERVO_NUM]; \
SERVO_CHANNEL+=atomicServo[SERVO_NUM]; \
state++; \
state++; \
ISR(SERVO_ISR) {
ISR(SERVO_ISR) {
static uint8_t state = 0; // indicates the current state of the chain
static uint8_t state = 0; // indicates the current state of the chain
if(state == 0){
if(state == 0){
SERVO_1_HIGH; // set servo 1's pin high
SERVO_1_HIGH; // set servo 1's pin high
SERVO_CHANNEL+=SERVO_1K_US; // wait 1000us
SERVO_CHANNEL+=SERVO_1K_US; // wait 1000us
state++; // count up the state
state++; // count up the state
}else if(state==1){
}else if(state==1){
SERVO_CHANNEL+=atomicServo[SERVO_1_ARR_POS]; // load the servo's value (0-1000us)
SERVO_CHANNEL+=atomicServo[SERVO_1_ARR_POS]; // load the servo's value (0-1000us)
state++; // count up the state
state++; // count up the state
#if defined(SERVO_2_HIGH)
#if defined(SERVO_2_HIGH)
SERVO_PULSE(SERVO_2_HIGH,2,SERVO_2_ARR_POS,SERVO_1_LOW); // the same here
SERVO_PULSE(SERVO_2_HIGH,2,SERVO_2_ARR_POS,SERVO_1_LOW); // the same here
#endif
#endif
#if defined(SERVO_3_HIGH)
#if defined(SERVO_3_HIGH)
SERVO_PULSE(SERVO_3_HIGH,4,SERVO_3_ARR_POS,SERVO_2_LOW);
SERVO_PULSE(SERVO_3_HIGH,4,SERVO_3_ARR_POS,SERVO_2_LOW);
#endif
#endif
#if defined(SERVO_4_HIGH)
#if defined(SERVO_4_HIGH)
SERVO_PULSE(SERVO_4_HIGH,6,SERVO_4_ARR_POS,SERVO_3_LOW);
SERVO_PULSE(SERVO_4_HIGH,6,SERVO_4_ARR_POS,SERVO_3_LOW);
#endif
#endif
#if defined(SERVO_5_HIGH)
#if defined(SERVO_5_HIGH)
SERVO_PULSE(SERVO_5_HIGH,8,SERVO_5_ARR_POS,SERVO_4_LOW);
SERVO_PULSE(SERVO_5_HIGH,8,SERVO_5_ARR_POS,SERVO_4_LOW);
#endif
#endif
#if defined(SERVO_6_HIGH)
#if defined(SERVO_6_HIGH)
SERVO_PULSE(SERVO_6_HIGH,10,SERVO_6_ARR_POS,SERVO_5_LOW);
SERVO_PULSE(SERVO_6_HIGH,10,SERVO_6_ARR_POS,SERVO_5_LOW);
#endif
#endif
#if defined(SERVO_7_HIGH)
#if defined(SERVO_7_HIGH)
SERVO_PULSE(SERVO_7_HIGH,12,SERVO_7_ARR_POS,SERVO_6_LOW);
SERVO_PULSE(SERVO_7_HIGH,12,SERVO_7_ARR_POS,SERVO_6_LOW);
#endif
#endif
#if defined(SERVO_8_HIGH)
#if defined(SERVO_8_HIGH)
SERVO_PULSE(SERVO_8_HIGH,14,SERVO_8_ARR_POS,SERVO_7_LOW);
SERVO_PULSE(SERVO_8_HIGH,14,SERVO_8_ARR_POS,SERVO_7_LOW);
#endif
#endif
}else{
}else{
LAST_LOW;
LAST_LOW;
#if defined(SERVO_RFR_300HZ)
#if defined(SERVO_RFR_300HZ)
#if defined(SERVO_3_HIGH) // if there are 3 or more servos we dont need to slow it down
#if defined(SERVO_3_HIGH) // if there are 3 or more servos we dont need to slow it down
SERVO_CHANNEL+=(SERVO_1K_US>>3); // 0 would be better but it causes bad jitter
SERVO_CHANNEL+=(SERVO_1K_US>>3); // 0 would be better but it causes bad jitter
state=0;
state=0;
#else // if there are less then 3 servos we need to slow it to not go over 300Hz (the highest working refresh rate for the digital servos for what i know..)
#else // if there are less then 3 servos we need to slow it to not go over 300Hz (the highest working refresh rate for the digital servos for what i know..)
SERVO_CHANNEL+=SERVO_1K_US;
SERVO_CHANNEL+=SERVO_1K_US;
if(state<4){
if(state<4){
state+=2;
state+=2;
}else{
}else{
state=0;
state=0;
}
}
#endif
#endif
#endif
#endif
#if defined(SERVO_RFR_160HZ)
#if defined(SERVO_RFR_160HZ)
#if defined(SERVO_4_HIGH) // if there are 4 or more servos we dont need to slow it down
#if defined(SERVO_4_HIGH) // if there are 4 or more servos we dont need to slow it down
SERVO_CHANNEL+=(SERVO_1K_US>>3); // 0 would be better but it causes bad jitter
SERVO_CHANNEL+=(SERVO_1K_US>>3); // 0 would be better but it causes bad jitter
state=0;
state=0;
#else // if there are less then 4 servos we need to slow it to not go over ~170Hz (the highest working refresh rate for analog servos)
#else // if there are less then 4 servos we need to slow it to not go over ~170Hz (the highest working refresh rate for analog servos)
SERVO_CHANNEL+=SERVO_1K_US;
SERVO_CHANNEL+=SERVO_1K_US;
if(state<8){
if(state<8){
state+=2;
state+=2;
}else{
}else{
state=0;
state=0;
}
}
#endif
#endif
#endif
#endif
#if defined(SERVO_RFR_50HZ) // to have ~ 50Hz for all servos
#if defined(SERVO_RFR_50HZ) // to have ~ 50Hz for all servos
SERVO_CHANNEL+=SERVO_1K_US;
SERVO_CHANNEL+=SERVO_1K_US;
if(state<30){
if(state<30){
state+=2;
state+=2;
}else{
}else{
state=0;
state=0;
}
}
#endif
#endif
}
}
}
}
#endif
#endif
/**************************************************************************************/
/**************************************************************************************/
/************ Motor software PWM generation ******************/
/************ Motor software PWM generation ******************/
/**************************************************************************************/
/**************************************************************************************/
// SW PWM is only used if there are not enough HW PWM pins (for exampe hexa on a promini)
// SW PWM is only used if there are not enough HW PWM pins (for exampe hexa on a promini)
#if (NUMBER_MOTOR > 4) && (defined(PROMINI) || defined(PROMICRO))
#if (NUMBER_MOTOR > 4) && (defined(PROMINI) || defined(PROMICRO))
/**************** Pre define the used ISR's and Timerchannels ******************/
/**************** Pre define the used ISR's and Timerchannels ******************/
#if !defined(PROMICRO)
#if !defined(PROMICRO)
#define SOFT_PWM_ISR1 TIMER0_COMPB_vect
#define SOFT_PWM_ISR1 TIMER0_COMPB_vect
#define SOFT_PWM_ISR2 TIMER0_COMPA_vect
#define SOFT_PWM_ISR2 TIMER0_COMPA_vect
#define SOFT_PWM_CHANNEL1 OCR0B
#define SOFT_PWM_CHANNEL1 OCR0B
#define SOFT_PWM_CHANNEL2 OCR0A
#define SOFT_PWM_CHANNEL2 OCR0A
#elif !defined(HWPWM6)
#elif !defined(HWPWM6)
#define SOFT_PWM_ISR1 TIMER3_COMPB_vect
#define SOFT_PWM_ISR1 TIMER3_COMPB_vect
#define SOFT_PWM_ISR2 TIMER3_COMPC_vect
#define SOFT_PWM_ISR2 TIMER3_COMPC_vect
#define SOFT_PWM_CHANNEL1 OCR3B
#define SOFT_PWM_CHANNEL1 OCR3B
#define SOFT_PWM_CHANNEL2 OCR3C
#define SOFT_PWM_CHANNEL2 OCR3C
#else
#else
#define SOFT_PWM_ISR2 TIMER0_COMPB_vect
#define SOFT_PWM_ISR2 TIMER0_COMPB_vect
#define SOFT_PWM_CHANNEL2 OCR0B
#define SOFT_PWM_CHANNEL2 OCR0B
#endif
#endif
/**************** Initialize Timers and PWM Channels ******************/
/**************** Initialize Timers and PWM Channels ******************/
void initializeSoftPWM() {
void initializeSoftPWM() {
#if !defined(PROMICRO)
#if !defined(PROMICRO)
TCCR0A = 0; // normal counting mode
TCCR0A = 0; // normal counting mode
#if (NUMBER_MOTOR > 4) && !defined(HWPWM6)
#if (NUMBER_MOTOR > 4) && !defined(HWPWM6)
TIMSK0 |= (1<<OCIE0B); // Enable CTC interrupt
TIMSK0 |= (1<<OCIE0B); // Enable CTC interrupt
#endif
#endif
#if (NUMBER_MOTOR > 6) || ((NUMBER_MOTOR == 6) && !defined(SERVO))
#if (NUMBER_MOTOR > 6) || ((NUMBER_MOTOR == 6) && !defined(SERVO))
TIMSK0 |= (1<<OCIE0A);
TIMSK0 |= (1<<OCIE0A);
#endif
#endif
#else
#else
#if !defined(HWPWM6)
#if !defined(HWPWM6)
TCCR3A &= ~(1<<WGM30) & ~(1<<WGM31); //normal counting & no prescaler
TCCR3A &= ~(1<<WGM30) & ~(1<<WGM31); //normal counting & no prescaler
TCCR3B &= ~(1<<WGM32) & ~(1<<CS31) & ~(1<<CS32) & ~(1<<WGM33);
TCCR3B &= ~(1<<WGM32) & ~(1<<CS31) & ~(1<<CS32) & ~(1<<WGM33);
TCCR3B |= (1<<CS30);
TCCR3B |= (1<<CS30);
TIMSK3 |= (1<<OCIE3B); // Enable CTC interrupt
TIMSK3 |= (1<<OCIE3B); // Enable CTC interrupt
#if (NUMBER_MOTOR > 6) || ((NUMBER_MOTOR == 6) && !defined(SERVO))
#if (NUMBER_MOTOR > 6) || ((NUMBER_MOTOR == 6) && !defined(SERVO))
TIMSK3 |= (1<<OCIE3C);
TIMSK3 |= (1<<OCIE3C);
#endif
#endif
#else
#else