Last active
October 14, 2015 06:04
-
-
Save vk2tds/c6048fd65b4e82087396 to your computer and use it in GitHub Desktop.
This is a snippet of code that allows IR to be sent using PWM on the Spark Core.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void setup() { | |
} | |
void loop(){ | |
unsigned int ir[] = {8576,4224,640,1664,640,640,640,640,640,640,640,1664,640,640,640,640,640,640,640,640,640,640, | |
640,640,640,640,640,640,640,1664,640,640,640,640,640,1664,640,640,640,640,640,640,640,640, | |
640,640,640,640,640,640,640,1664,640,1664,640,640,640,640,640}; | |
send (ir, 59, 36000); | |
} | |
// From https://github.com/zoellner/IRLib/blob/master/IRLib.cpp and also | |
// based on https://gist.github.com/technobly/8313449 | |
uint16_t TIM_ARR = (uint16_t)(24000000 / 38000) - 1; // 38 KHz Init | |
// User defined analogWrite() to gain control of PWM initialization | |
void analogWrite2(uint16_t pin, uint8_t value) { | |
TIM_OCInitTypeDef TIM_OCInitStructure; | |
if (pin >= TOTAL_PINS || PIN_MAP[pin].timer_peripheral == NULL) { | |
return; | |
} | |
// SPI safety check | |
if (SPI.isEnabled() == true && (pin == SCK || pin == MOSI || pin == MISO)) { | |
return; | |
} | |
// I2C safety check | |
if (Wire.isEnabled() == true && (pin == SCL || pin == SDA)) { | |
return; | |
} | |
// Serial1 safety check | |
if (Serial1.isEnabled() == true && (pin == RX || pin == TX)) { | |
return; | |
} | |
if (PIN_MAP[pin].pin_mode != OUTPUT && PIN_MAP[pin].pin_mode != AF_OUTPUT_PUSHPULL) { | |
return; | |
} | |
// Don't re-init PWM and cause a glitch if already setup, just update duty cycle and return. | |
if (PIN_MAP[pin].pin_mode == AF_OUTPUT_PUSHPULL) { | |
TIM_OCInitStructure.TIM_Pulse = (uint16_t)(value * (TIM_ARR + 1) / 255); | |
if (PIN_MAP[pin].timer_ch == TIM_Channel_1) { | |
PIN_MAP[pin].timer_peripheral-> CCR1 = TIM_OCInitStructure.TIM_Pulse; | |
} else if (PIN_MAP[pin].timer_ch == TIM_Channel_2) { | |
PIN_MAP[pin].timer_peripheral-> CCR2 = TIM_OCInitStructure.TIM_Pulse; | |
} else if (PIN_MAP[pin].timer_ch == TIM_Channel_3) { | |
PIN_MAP[pin].timer_peripheral-> CCR3 = TIM_OCInitStructure.TIM_Pulse; | |
} else if (PIN_MAP[pin].timer_ch == TIM_Channel_4) { | |
PIN_MAP[pin].timer_peripheral-> CCR4 = TIM_OCInitStructure.TIM_Pulse; | |
} | |
return; | |
} | |
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; | |
//PWM Frequency : PWM_FREQ (Hz) | |
uint16_t TIM_Prescaler = (uint16_t)(SystemCoreClock / 24000000) - 1; //TIM Counter clock = 24MHz | |
// TIM Channel Duty Cycle(%) = (TIM_CCR / TIM_ARR + 1) * 100 | |
uint16_t TIM_CCR = (uint16_t)(value * (TIM_ARR + 1) / 255); | |
// AFIO clock enable | |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); | |
//pinMode(pin, AF_OUTPUT_PUSHPULL); // we need to do this manually else we get a glitch | |
// TIM clock enable | |
if (PIN_MAP[pin].timer_peripheral == TIM2) | |
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); | |
else if (PIN_MAP[pin].timer_peripheral == TIM3) | |
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); | |
else if (PIN_MAP[pin].timer_peripheral == TIM4) | |
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); | |
// Time base configuration | |
TIM_TimeBaseStructure.TIM_Period = TIM_ARR; | |
TIM_TimeBaseStructure.TIM_Prescaler = TIM_Prescaler; | |
TIM_TimeBaseStructure.TIM_ClockDivision = 0; | |
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; | |
TIM_TimeBaseInit(PIN_MAP[pin].timer_peripheral, & TIM_TimeBaseStructure); | |
// PWM1 Mode configuration | |
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; | |
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; | |
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; | |
TIM_OCInitStructure.TIM_Pulse = TIM_CCR; | |
if (PIN_MAP[pin].timer_ch == TIM_Channel_1) { | |
// PWM1 Mode configuration: Channel1 | |
TIM_OC1Init(PIN_MAP[pin].timer_peripheral, & TIM_OCInitStructure); | |
TIM_OC1PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); | |
} else if (PIN_MAP[pin].timer_ch == TIM_Channel_2) { | |
// PWM1 Mode configuration: Channel2 | |
TIM_OC2Init(PIN_MAP[pin].timer_peripheral, & TIM_OCInitStructure); | |
TIM_OC2PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); | |
} else if (PIN_MAP[pin].timer_ch == TIM_Channel_3) { | |
// PWM1 Mode configuration: Channel3 | |
TIM_OC3Init(PIN_MAP[pin].timer_peripheral, & TIM_OCInitStructure); | |
TIM_OC3PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); | |
} else if (PIN_MAP[pin].timer_ch == TIM_Channel_4) { | |
// PWM1 Mode configuration: Channel4 | |
TIM_OC4Init(PIN_MAP[pin].timer_peripheral, & TIM_OCInitStructure); | |
TIM_OC4PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); | |
} | |
TIM_ARRPreloadConfig(PIN_MAP[pin].timer_peripheral, ENABLE); | |
// TIM enable counter | |
TIM_Cmd(PIN_MAP[pin].timer_peripheral, ENABLE); | |
} | |
void enableIROut (unsigned int hz){ | |
pinMode (A5, OUTPUT); | |
TIM_ARR = (uint16_t)(24000000 / hz) - 1; | |
analogWrite2 (A5,128); // 50% Duty Cycle | |
pinMode(A5, AF_OUTPUT_PUSHPULL); | |
space(0); // And turn off the PWM output until we need it | |
delay(100); | |
} | |
void My_delay_uSecs(unsigned int T) { | |
if(T){if(T>16000) {delayMicroseconds(T % 1000); delay(T/1000); } else delayMicroseconds(T);}; | |
} | |
void mark(unsigned int time) { | |
//pinMode(A5, AF_OUTPUT_PUSHPULL); | |
analogWrite2 (A5,128); | |
My_delay_uSecs(time); | |
} | |
void space(unsigned int time) { | |
//pinMode(A5, OUTPUT); | |
analogWrite2 (A5,0); | |
My_delay_uSecs(time); | |
} | |
void send(unsigned short buf[], unsigned char len, unsigned int hz) | |
{ | |
if (hz == 0){ | |
enableIROut(38000); | |
} else { | |
enableIROut(hz); | |
} | |
for (unsigned char i = 0; i < len; i++) { | |
if (i & 1) { | |
space(buf[i]); | |
} | |
else { | |
mark(buf[i]); | |
} | |
} | |
space(0); // Just to be sure | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment