add button press detection

This commit is contained in:
King Kévin 2017-05-06 16:22:44 +02:00
parent b5cc93bfc0
commit 11ccf9aacc
1 changed files with 63 additions and 15 deletions

78
main.c
View File

@ -86,6 +86,17 @@ volatile uint8_t frame_count = 0; /**< number of frames passed */
#define POWER_BUTTON_PORT B /**< port to detect power switching activity (to keep alive) */
#define POWER_BUTTON_PIN 1 /**< pin to detect power switching activity (to keep alive) */
#define BUTTONS_DRIVE_PORT A
#define BUTTONS_DRIVE_PIN0 0
#define BUTTONS_DRIVE_PIN1 1
#define BUTTONS_DRIVE_PIN2 2
#define BUTTONS_DRIVE_PIN3 3
#define BUTTONS_READ_PORT A
#define BUTTONS_READ_PIN0 4
#define BUTTONS_READ_PIN1 5
#define BUTTONS_READ_PIN2 6
#define BUTTONS_READ_PIN3 15
/** user input command */
static char command[32] = {0};
/** user input command index */
@ -259,12 +270,12 @@ static void encode_morse(void)
{
bool not_zero = false;
for (uint8_t digit=0; digit<4; digit++) {
uint16_t number = 40;
uint16_t number = 42;
// get only the digit from the number
for (uint8_t divide=digit; divide<3; divide++) {
number /= 10;
}
number %= 10;
printf("%u: %u\n", digit, number);
// remember when we found the first non-zero digit
if (number!=0 || digit==3) {
not_zero = true;
@ -413,15 +424,6 @@ void main(void)
}
#endif
// disable internal RTC
printf("disable internal RTC: ");
rcc_periph_clock_enable(RCC_PWR); // enable power domain clock
rcc_periph_clock_enable(RCC_BKP); // enable backup domain clock
pwr_disable_backup_domain_write_protect(); // enable write on backup domain (including RTC)
RCC_BDCR &= ~RCC_BDCR_RTCEN; // disable RTC
pwr_enable_backup_domain_write_protect(); // re-enable write protect
printf("OK\n");
// setup external RTC
printf("setup external RTC: ");
rtc_ds1307_setup(); // setup external RTC module
@ -513,7 +515,7 @@ void main(void)
printf("OK\n");
// setup PWM for piezo-buzzer
printf("setup piezo-buzzer timer: ");
printf("setup piezo-buzzer PWM timer: ");
rcc_periph_clock_enable(RCC_GPIO(BUZZER_1_PORT)); // enable clock for GPIO peripheral
rcc_periph_clock_enable(RCC_AFIO); // enable clock for alternate function (PWM)
gpio_primary_remap(AFIO_MAPR_SWJ_MASK, AFIO_MAPR_TIM1_REMAP_PARTIAL_REMAP); // remap TIM1_CH1N to PA7 instead of PB13
@ -534,8 +536,18 @@ void main(void)
timer_generate_event(TIM(BUZZER_TIMER), TIM_EGR_UG); // generate update event to reload registers and reset counter
printf("OK\n");
// setup GPIO for reading buttons
printf("setup button inputs: ");
rcc_periph_clock_enable(RCC_GPIO(BUTTONS_DRIVE_PORT)); // enable clock for GPIO port domain
// no need to configure the driving line modes since this will be done when they need to be driven
rcc_periph_clock_enable(RCC_GPIO(BUTTONS_READ_PORT)); // enable clock for GPIO port domain
gpio_set_mode(GPIO(BUTTONS_READ_PORT), GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO(BUTTONS_READ_PIN0)|GPIO(BUTTONS_READ_PIN1)|GPIO(BUTTONS_READ_PIN2)|GPIO(BUTTONS_READ_PIN3)); // set read lines as input
gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON, 0); // enable PA15 (JTDI per default)
gpio_clear(GPIO(BUTTONS_READ_PORT), GPIO(BUTTONS_READ_PIN0)|GPIO(BUTTONS_READ_PIN1)|GPIO(BUTTONS_READ_PIN2)|GPIO(BUTTONS_READ_PIN3)); // pull read lines low since they will be high when driven and button is pressed
uint16_t buttons = 0;
encode_morse();
bool announce = true;
bool announce = false;
// main loop
printf("command input: ready\n");
@ -577,7 +589,8 @@ void main(void)
while (frame_flag) { // a frame has passed
frame_flag = false; // reset flag
action = true; // action has been performed
if (announce) { // announce the scene and take using Morse code over the buzzer
// announce the scene and take using Morse code over the buzzer
if (announce) {
while (morse_i<LENGTH(morse)) {
if (morse[morse_i]) { // skip empty codes
if (morse_i%2) { // switch buzzer on for odd code
@ -595,6 +608,41 @@ void main(void)
announce = false; // announce finished
}
}
// read button inputs (drive and read each row since they are multiplexed)
uint16_t buttons_new = 0;
gpio_set_mode(GPIO(BUTTONS_DRIVE_PORT), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO(BUTTONS_DRIVE_PIN0));
gpio_set(GPIO(BUTTONS_DRIVE_PORT), GPIO(BUTTONS_DRIVE_PIN0));
gpio_set_mode(GPIO(BUTTONS_DRIVE_PORT), GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO(BUTTONS_DRIVE_PIN1)|GPIO(BUTTONS_DRIVE_PIN2)|GPIO(BUTTONS_DRIVE_PIN3));
buttons_new |= ((gpio_get(GPIO(BUTTONS_READ_PORT), GPIO(BUTTONS_READ_PIN0)) ? 1 : 0)<<0);
buttons_new |= ((gpio_get(GPIO(BUTTONS_READ_PORT), GPIO(BUTTONS_READ_PIN1)) ? 1 : 0)<<1);
buttons_new |= ((gpio_get(GPIO(BUTTONS_READ_PORT), GPIO(BUTTONS_READ_PIN2)) ? 1 : 0)<<2);
buttons_new |= ((gpio_get(GPIO(BUTTONS_READ_PORT), GPIO(BUTTONS_READ_PIN3)) ? 1 : 0)<<3);
gpio_set_mode(GPIO(BUTTONS_DRIVE_PORT), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO(BUTTONS_DRIVE_PIN1));
gpio_set(GPIO(BUTTONS_DRIVE_PORT), GPIO(BUTTONS_DRIVE_PIN1));
gpio_set_mode(GPIO(BUTTONS_DRIVE_PORT), GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO(BUTTONS_DRIVE_PIN0)|GPIO(BUTTONS_DRIVE_PIN2)|GPIO(BUTTONS_DRIVE_PIN3));
buttons_new |= ((gpio_get(GPIO(BUTTONS_READ_PORT), GPIO(BUTTONS_READ_PIN0)) ? 1 : 0)<<4);
buttons_new |= ((gpio_get(GPIO(BUTTONS_READ_PORT), GPIO(BUTTONS_READ_PIN1)) ? 1 : 0)<<5);
buttons_new |= ((gpio_get(GPIO(BUTTONS_READ_PORT), GPIO(BUTTONS_READ_PIN2)) ? 1 : 0)<<6);
buttons_new |= ((gpio_get(GPIO(BUTTONS_READ_PORT), GPIO(BUTTONS_READ_PIN3)) ? 1 : 0)<<7);
gpio_set_mode(GPIO(BUTTONS_DRIVE_PORT), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO(BUTTONS_DRIVE_PIN2));
gpio_set(GPIO(BUTTONS_DRIVE_PORT), GPIO(BUTTONS_DRIVE_PIN2));
gpio_set_mode(GPIO(BUTTONS_DRIVE_PORT), GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO(BUTTONS_DRIVE_PIN0)|GPIO(BUTTONS_DRIVE_PIN1)|GPIO(BUTTONS_DRIVE_PIN3));
buttons_new |= ((gpio_get(GPIO(BUTTONS_READ_PORT), GPIO(BUTTONS_READ_PIN0)) ? 1 : 0)<<8);
buttons_new |= ((gpio_get(GPIO(BUTTONS_READ_PORT), GPIO(BUTTONS_READ_PIN1)) ? 1 : 0)<<9);
buttons_new |= ((gpio_get(GPIO(BUTTONS_READ_PORT), GPIO(BUTTONS_READ_PIN2)) ? 1 : 0)<<10);
buttons_new |= ((gpio_get(GPIO(BUTTONS_READ_PORT), GPIO(BUTTONS_READ_PIN3)) ? 1 : 0)<<11);
gpio_set_mode(GPIO(BUTTONS_DRIVE_PORT), GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO(BUTTONS_DRIVE_PIN3));
gpio_set(GPIO(BUTTONS_DRIVE_PORT), GPIO(BUTTONS_DRIVE_PIN3));
gpio_set_mode(GPIO(BUTTONS_DRIVE_PORT), GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO(BUTTONS_DRIVE_PIN0)|GPIO(BUTTONS_DRIVE_PIN1)|GPIO(BUTTONS_DRIVE_PIN2));
buttons_new |= ((gpio_get(GPIO(BUTTONS_READ_PORT), GPIO(BUTTONS_READ_PIN0)) ? 1 : 0)<<12);
buttons_new |= ((gpio_get(GPIO(BUTTONS_READ_PORT), GPIO(BUTTONS_READ_PIN1)) ? 1 : 0)<<13);
buttons_new |= ((gpio_get(GPIO(BUTTONS_READ_PORT), GPIO(BUTTONS_READ_PIN2)) ? 1 : 0)<<14);
buttons_new |= ((gpio_get(GPIO(BUTTONS_READ_PORT), GPIO(BUTTONS_READ_PIN3)) ? 1 : 0)<<15);
if (buttons_new!=buttons) { // only do something if there is a change
buttons = buttons_new; // save new state
printf("button pressed: %016b\n", buttons);
}
char time[] = "00000000"; // time to display
time[0] += (rtc_ds1307_time[2]/10)%10; // display hours
time[1] += (rtc_ds1307_time[2])%10; // display hours
@ -617,7 +665,7 @@ void main(void)
rtc_tick_flag = false; // reset flag
action = true; // action has been performed
led_toggle(); // toggle LED (good to indicate if main function is stuck)
if (standby_timer>=STANDBY_TIMEOUT) { // standby timeout complete
if (standby_timer>=STANDBY_TIMEOUT && false) { // standby timeout complete
// go into standby mode
printf("shutting down\n");
led_max7219_off(0xff); // switch off MAX7219 displays