Arduino Due support on IRSenderPWM

This commit is contained in:
Toni 2018-08-30 17:23:21 +03:00
parent 2761aba5fd
commit 882736230f
1 changed files with 77 additions and 1 deletions

View File

@ -10,16 +10,81 @@
// For PWM on Arduino, see http://playground.arduino.cc/Main/TimerPWMCheatsheet
#if defined(__SAM3X8E__) || defined(__SAM3X8H__)
// Arduino Due
uint32_t IR_USE_PWM_PINMASK;
byte IR_USE_PWM_CH;
#endif
IRSenderPWM::IRSenderPWM(uint8_t pin) : IRSender(pin)
{
pinMode(_pin, OUTPUT);
digitalWrite(_pin, LOW); // When not sending PWM, we want it low
#if defined(__SAM3X8E__) || defined(__SAM3X8H__)
// Arduino Due
pmc_set_writeprotect(false);
switch (_pin)
{
case 6:
IR_USE_PWM_PINMASK = PIO_PC24;
IR_USE_PWM_CH = 7;
break;
case 7:
IR_USE_PWM_PINMASK = PIO_PC23;
IR_USE_PWM_CH = 6;
break;
case 8:
IR_USE_PWM_PINMASK = PIO_PC22;
IR_USE_PWM_CH = 5;
break;
case 9:
IR_USE_PWM_PINMASK = PIO_PC21;
IR_USE_PWM_CH = 4;
break;
case 34:
IR_USE_PWM_PINMASK = PIO_PC2;
IR_USE_PWM_CH = 0;
break;
case 36:
IR_USE_PWM_PINMASK = PIO_PC4;
IR_USE_PWM_CH = 1;
break;
case 38:
IR_USE_PWM_PINMASK = PIO_PC6;
IR_USE_PWM_CH = 2;
break;
case 40:
IR_USE_PWM_PINMASK = PIO_PC8;
IR_USE_PWM_CH = 3;
break;
}
#endif
}
// Set the PWM frequency. The selected pin determines which timer to use
void IRSenderPWM::setFrequency(int frequency)
{
#if defined(__SAM3X8E__) || defined(__SAM3X8H__)
// Arduino Due
pmc_enable_periph_clk(PWM_INTERFACE_ID);
const uint32_t pwmval = (frequency) * 2000;
PWMC_ConfigureClocks(PWM_FREQUENCY * PWM_MAX_DUTY_CYCLE, pwmval, F_CPU);
PIO_Configure(PIOC, PIO_PERIPH_B, IR_USE_PWM_PINMASK, PIO_DEFAULT);
PWMC_ConfigureChannel(PWM_INTERFACE, IR_USE_PWM_CH, PWM_CMR_CPRE_CLKB, 0, 0);
PWMC_SetPeriod(PWM_INTERFACE, IR_USE_PWM_CH, 2);
PWMC_SetDutyCycle(PWM_INTERFACE, IR_USE_PWM_CH, 1);
#else
uint8_t pwmval8 = F_CPU / 2000 / (frequency);
uint16_t pwmval16 = F_CPU / 2000 / (frequency);
@ -73,12 +138,17 @@ void IRSenderPWM::setFrequency(int frequency)
break;
#endif
}
#endif
}
// Send an IR 'mark' symbol, i.e. transmitter ON
void IRSenderPWM::mark(int markLength)
{
#if defined(__SAM3X8E__) || defined(__SAM3X8H__)
// Arduino Due
PWMC_EnableChannel(PWM_INTERFACE, IR_USE_PWM_CH); // Enable pin PWM output
#else
switch (_pin)
{
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
@ -119,7 +189,8 @@ void IRSenderPWM::mark(int markLength)
(TCCR2A |= _BV(COM2A1)); // Enable pin 11 PWM output
break;
#endif
}
}
#endif
delayMicroseconds(markLength);
}
@ -128,6 +199,10 @@ void IRSenderPWM::mark(int markLength)
// Send an IR 'space' symbol, i.e. transmitter OFF
void IRSenderPWM::space(int spaceLength)
{
#if defined(__SAM3X8E__) || defined(__SAM3X8H__)
// Arduino Due
PWMC_DisableChannel(PWM_INTERFACE, IR_USE_PWM_CH); // Disable pin PWM output
#else
switch (_pin)
{
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
@ -166,6 +241,7 @@ void IRSenderPWM::space(int spaceLength)
break;
#endif
}
#endif
// Mitsubishi heatpump uses > 16383us spaces, and delayMicroseconds only works up to 2^14 - 1 us
// Use the less accurate milliseconds delay for longer delays