add NEC code controlled power output animations
This commit is contained in:
parent
10c2973ee7
commit
4f7a173e23
125
application.c
125
application.c
|
@ -12,8 +12,8 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/** STM32F1 application example
|
/** STM32F1 application to strobe electricity
|
||||||
* @file application.c
|
* @file
|
||||||
* @author King Kévin <kingkevin@cuvoodoo.info>
|
* @author King Kévin <kingkevin@cuvoodoo.info>
|
||||||
* @date 2016-2018
|
* @date 2016-2018
|
||||||
*/
|
*/
|
||||||
|
@ -43,8 +43,9 @@
|
||||||
#include "usb_cdcacm.h" // USB CDC ACM utilities
|
#include "usb_cdcacm.h" // USB CDC ACM utilities
|
||||||
#include "terminal.h" // handle the terminal interface
|
#include "terminal.h" // handle the terminal interface
|
||||||
#include "menu.h" // menu utilities
|
#include "menu.h" // menu utilities
|
||||||
|
#include "ir_nec.h" // InfraRed NEC decoding utilities
|
||||||
|
|
||||||
#define WATCHDOG_PERIOD 10000 /**< watchdog period in ms */
|
#define WATCHDOG_PERIOD 20000 /**< watchdog period in ms */
|
||||||
|
|
||||||
/** @defgroup main_flags flag set in interrupts to be processed in main task
|
/** @defgroup main_flags flag set in interrupts to be processed in main task
|
||||||
* @{
|
* @{
|
||||||
|
@ -235,6 +236,94 @@ static void process_command(char* str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define STROBE_PORT B /**< GPIO port to control strobe light */
|
||||||
|
#define STROBE_PIN 6 /**< GPIO pin to control strobe light */
|
||||||
|
#define STROBE_ON 0 /**< LED is on when pin is low (open-drain allows 5V on) */
|
||||||
|
|
||||||
|
/* strobe animations (on + off times in ms) */
|
||||||
|
/** single strobe */
|
||||||
|
static const uint16_t strobe_single[] = {100, 0};
|
||||||
|
/** double strobe */
|
||||||
|
static const uint16_t strobe_double[] = {100, 200, 100, 0};
|
||||||
|
|
||||||
|
/** switch strobe power on */
|
||||||
|
static void strobe_on(void)
|
||||||
|
{
|
||||||
|
#if LED_ON
|
||||||
|
gpio_set(GPIO(STROBE_PORT), GPIO(STROBE_PIN));
|
||||||
|
#else
|
||||||
|
gpio_clear(GPIO(STROBE_PORT), GPIO(STROBE_PIN));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** switch strobe power off */
|
||||||
|
static void strobe_off(void)
|
||||||
|
{
|
||||||
|
#if STROBE_ON
|
||||||
|
gpio_clear(GPIO(STROBE_PORT), GPIO(STROBE_PIN));
|
||||||
|
#else
|
||||||
|
gpio_set(GPIO(STROBE_PORT), GPIO(STROBE_PIN));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** toggle strobe power */
|
||||||
|
static void strobe_toggle(void)
|
||||||
|
{
|
||||||
|
gpio_toggle(GPIO(STROBE_PORT), GPIO(STROBE_PIN));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** play strobe animation
|
||||||
|
* @param[in] animation on+off timings (in ms)
|
||||||
|
* @param[in] length animation length
|
||||||
|
*/
|
||||||
|
static void strobe_play(const uint16_t* animation, uint16_t length)
|
||||||
|
{
|
||||||
|
for (uint16_t i = 0; i < length; i++) {
|
||||||
|
iwdg_reset(); // kick the dog
|
||||||
|
if (0 == animation[i]) { // skip animation
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (i % 2) { // odd index if encodes off duration
|
||||||
|
strobe_off();
|
||||||
|
} else {
|
||||||
|
strobe_on();
|
||||||
|
}
|
||||||
|
sleep_ms(animation[i]); // wait for set duration
|
||||||
|
}
|
||||||
|
strobe_off(); // switch off at the end
|
||||||
|
}
|
||||||
|
|
||||||
|
/** perform IR code related action
|
||||||
|
* @warning the codes need to be adjusted to your remote
|
||||||
|
* @param[in] code IR code
|
||||||
|
*/
|
||||||
|
static void ir_action(const struct ir_nec_code_t* code)
|
||||||
|
{
|
||||||
|
if (code->repeat) { // don't handle long button press repeating the code
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (0 != code->address) { // current remote uses this address
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (code->command) {
|
||||||
|
case 0x30: // power button
|
||||||
|
strobe_toggle();
|
||||||
|
printf("toggle strobe\n");
|
||||||
|
break;
|
||||||
|
case 0x88: // 1 button
|
||||||
|
strobe_play(strobe_single, LENGTH(strobe_single));
|
||||||
|
printf("strobe animation 1\n");
|
||||||
|
break;
|
||||||
|
case 0x48: // 2 button
|
||||||
|
strobe_play(strobe_double, LENGTH(strobe_double));
|
||||||
|
printf("strobe animation 2\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("unknown code\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** program entry point
|
/** program entry point
|
||||||
* this is the firmware function started by the micro-controller
|
* this is the firmware function started by the micro-controller
|
||||||
*/
|
*/
|
||||||
|
@ -258,8 +347,17 @@ void main(void)
|
||||||
|
|
||||||
board_setup(); // setup board
|
board_setup(); // setup board
|
||||||
uart_setup(); // setup USART (for printing)
|
uart_setup(); // setup USART (for printing)
|
||||||
usb_cdcacm_setup(); // setup USB CDC ACM (for printing)
|
usb_cdcacm_setup(); // setup USB CDC ACM (for printing and DFU)
|
||||||
printf("\nwelcome to the CuVoodoo STM32F1 example application\n"); // print welcome message
|
// setup strobe pin
|
||||||
|
rcc_periph_clock_enable(RCC_GPIO(STROBE_PORT)); // enable clock for GPIO port peripheral
|
||||||
|
#if STROBE_ON
|
||||||
|
gpio_set_mode(GPIO(STROBE_PORT), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO(STROBE_PIN)); // set pin to output push-pull do drive strobe signal
|
||||||
|
#else
|
||||||
|
gpio_set_mode(GPIO(STROBE_PORT), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO(STROBE_PIN)); // set pin to output open-drain do enable strobe
|
||||||
|
#endif
|
||||||
|
strobe_off(); // switch off strobe per defaulf
|
||||||
|
ir_nec_setup(); // setup ID NEC code decoder
|
||||||
|
printf("\nwelcome to the CuVoodoo STM32F1 spark strober\n"); // print welcome message
|
||||||
|
|
||||||
#if !(DEBUG)
|
#if !(DEBUG)
|
||||||
// show watchdog information
|
// show watchdog information
|
||||||
|
@ -290,13 +388,13 @@ void main(void)
|
||||||
button_flag = false; // reset button flag
|
button_flag = false; // reset button flag
|
||||||
while (true) { // infinite loop
|
while (true) { // infinite loop
|
||||||
iwdg_reset(); // kick the dog
|
iwdg_reset(); // kick the dog
|
||||||
while (user_input_available) { // user input is available
|
if (user_input_available) { // user input is available
|
||||||
action = true; // action has been performed
|
action = true; // action has been performed
|
||||||
led_toggle(); // toggle LED
|
led_toggle(); // toggle LED
|
||||||
char c = user_input_get(); // store receive character
|
char c = user_input_get(); // store receive character
|
||||||
terminal_send(c); // send received character to terminal
|
terminal_send(c); // send received character to terminal
|
||||||
}
|
}
|
||||||
while (button_flag) { // user pressed button
|
if (button_flag) { // user pressed button
|
||||||
action = true; // action has been performed
|
action = true; // action has been performed
|
||||||
printf("button pressed\n");
|
printf("button pressed\n");
|
||||||
led_toggle(); // toggle LED
|
led_toggle(); // toggle LED
|
||||||
|
@ -305,13 +403,22 @@ void main(void)
|
||||||
}
|
}
|
||||||
button_flag = false; // reset flag
|
button_flag = false; // reset flag
|
||||||
}
|
}
|
||||||
while (rtc_internal_tick_flag) { // the internal RTC ticked
|
if (rtc_internal_tick_flag) { // the internal RTC ticked
|
||||||
rtc_internal_tick_flag = false; // reset flag
|
rtc_internal_tick_flag = false; // reset flag
|
||||||
action = true; // action has been performed
|
action = true; // action has been performed
|
||||||
#if !defined(BLUE_PILL) // on the blue pill the LED is close to the 32.768 kHz oscillator and heavily influences it
|
#if !defined(BLUE_PILL) // on the blue pill the LED is close to the 32.768 kHz oscillator and heavily influences it
|
||||||
led_toggle(); // toggle LED (good to indicate if main function is stuck)
|
//led_toggle(); // toggle LED (good to indicate if main function is stuck)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
if (ir_nec_code_received_flag) { // IR code received
|
||||||
|
ir_nec_code_received_flag = false; // reset flag
|
||||||
|
led_on(); // notify user we received a code
|
||||||
|
printf("IR NEC code received: addr=%+02x, cmd=%+02x%s\n", ir_nec_code_received.address, ir_nec_code_received.command, ir_nec_code_received.repeat ? " (repeat)" : "");
|
||||||
|
if (!ir_nec_code_received.repeat) { // ignore repeated codes
|
||||||
|
ir_action(&ir_nec_code_received); // handle IR code
|
||||||
|
}
|
||||||
|
led_off(); // notify user we received a code
|
||||||
|
}
|
||||||
if (action) { // go to sleep if nothing had to be done, else recheck for activity
|
if (action) { // go to sleep if nothing had to be done, else recheck for activity
|
||||||
action = false;
|
action = false;
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue