Created
February 12, 2014 05:10
-
-
Save technobly/8950366 to your computer and use it in GitHub Desktop.
SPARK CORE RUBE GOLDBERG LED TOGGLE CHALLENGE
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
/* | |
* ================================= | |
* RUBE GOLDBERG LED TOGGLE | |
* --------------------------------- | |
* BDub / Technobly - Feb 11th, 2014 | |
* ================================= | |
* | |
*/ | |
uint16_t TIM_ARR = (uint16_t)(65535/6); // Calc PWM period. | |
void setup() { | |
pinMode(D1, INPUT); // sets D1 as an input | |
pinMode(D0, OUTPUT); // sets D0 as an output | |
pinMode(D7, OUTPUT); // sets D7 as an output | |
attachInterrupt(D1, updateD7, CHANGE); // call updateD7() everytime D1's input changes | |
analogWrite2(D0, 128); // Set D0 output as a 0.1Hz 50% duty cycle PWM (5s on, 5s off) | |
} | |
void loop() { | |
// Jumper D0 to D1 to control D7 for 5 seconds on, and 5 seconds off | |
// in the most convolutedly awexome way I could think of, for now ;) | |
// look Ma, no hands! | |
} | |
void updateD7() { | |
digitalWrite(D7,digitalRead(D1)); // translate PWM to LED output | |
} | |
// 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)65535; // largest prescaler! | |
// 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); | |
// 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); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment