control 7 TM1637 displays using multiplexer
This commit is contained in:
parent
3bc254fd52
commit
6b80135f67
116
main.c
116
main.c
|
@ -65,6 +65,15 @@ volatile uint16_t standby_timer = 0; /**< number of seconds since last wake-up/a
|
||||||
#define FRAME_RATE 25 /**< frame rate */
|
#define FRAME_RATE 25 /**< frame rate */
|
||||||
volatile uint8_t frame_count = 0; /**< number of frames passed */
|
volatile uint8_t frame_count = 0; /**< number of frames passed */
|
||||||
|
|
||||||
|
#define MUX_EN_PORT B
|
||||||
|
#define MUX_EN_PIN 9
|
||||||
|
#define MUX_S0_PORT B
|
||||||
|
#define MUX_S0_PIN 3
|
||||||
|
#define MUX_S1_PORT B
|
||||||
|
#define MUX_S1_PIN 4
|
||||||
|
#define MUX_S2_PORT B
|
||||||
|
#define MUX_S2_PIN 5
|
||||||
|
|
||||||
/** user input command */
|
/** user input command */
|
||||||
static char command[32] = {0};
|
static char command[32] = {0};
|
||||||
/** user input command index */
|
/** user input command index */
|
||||||
|
@ -174,6 +183,58 @@ error:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mux_select(uint8_t output)
|
||||||
|
{
|
||||||
|
if (output>7) { // multiplexer is only controlling 8 outputs
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gpio_clear(GPIO(MUX_EN_PORT), GPIO(MUX_EN_PIN)); // enable multiplexer
|
||||||
|
switch (output) {
|
||||||
|
case 0: // output on channel C0
|
||||||
|
gpio_clear(GPIO(MUX_S0_PORT), GPIO(MUX_S0_PIN));
|
||||||
|
gpio_clear(GPIO(MUX_S1_PORT), GPIO(MUX_S1_PIN));
|
||||||
|
gpio_clear(GPIO(MUX_S2_PORT), GPIO(MUX_S2_PIN));
|
||||||
|
break;
|
||||||
|
case 1: // output on channel C1
|
||||||
|
gpio_set(GPIO(MUX_S0_PORT), GPIO(MUX_S0_PIN));
|
||||||
|
gpio_clear(GPIO(MUX_S1_PORT), GPIO(MUX_S1_PIN));
|
||||||
|
gpio_clear(GPIO(MUX_S2_PORT), GPIO(MUX_S2_PIN));
|
||||||
|
break;
|
||||||
|
case 2: // output on channel C2
|
||||||
|
gpio_clear(GPIO(MUX_S0_PORT), GPIO(MUX_S0_PIN));
|
||||||
|
gpio_set(GPIO(MUX_S1_PORT), GPIO(MUX_S1_PIN));
|
||||||
|
gpio_clear(GPIO(MUX_S2_PORT), GPIO(MUX_S2_PIN));
|
||||||
|
break;
|
||||||
|
case 3: // output on channel C3
|
||||||
|
gpio_set(GPIO(MUX_S0_PORT), GPIO(MUX_S0_PIN));
|
||||||
|
gpio_set(GPIO(MUX_S1_PORT), GPIO(MUX_S1_PIN));
|
||||||
|
gpio_clear(GPIO(MUX_S2_PORT), GPIO(MUX_S2_PIN));
|
||||||
|
break;
|
||||||
|
case 4: // output on channel C4
|
||||||
|
gpio_clear(GPIO(MUX_S0_PORT), GPIO(MUX_S0_PIN));
|
||||||
|
gpio_clear(GPIO(MUX_S1_PORT), GPIO(MUX_S1_PIN));
|
||||||
|
gpio_set(GPIO(MUX_S2_PORT), GPIO(MUX_S2_PIN));
|
||||||
|
break;
|
||||||
|
case 5: // output on channel C5
|
||||||
|
gpio_set(GPIO(MUX_S0_PORT), GPIO(MUX_S0_PIN));
|
||||||
|
gpio_clear(GPIO(MUX_S1_PORT), GPIO(MUX_S1_PIN));
|
||||||
|
gpio_set(GPIO(MUX_S2_PORT), GPIO(MUX_S2_PIN));
|
||||||
|
break;
|
||||||
|
case 6: // output on channel C6
|
||||||
|
gpio_clear(GPIO(MUX_S0_PORT), GPIO(MUX_S0_PIN));
|
||||||
|
gpio_set(GPIO(MUX_S1_PORT), GPIO(MUX_S1_PIN));
|
||||||
|
gpio_set(GPIO(MUX_S2_PORT), GPIO(MUX_S2_PIN));
|
||||||
|
break;
|
||||||
|
case 7: // output on channel C7
|
||||||
|
gpio_set(GPIO(MUX_S0_PORT), GPIO(MUX_S0_PIN));
|
||||||
|
gpio_set(GPIO(MUX_S1_PORT), GPIO(MUX_S1_PIN));
|
||||||
|
gpio_set(GPIO(MUX_S2_PORT), GPIO(MUX_S2_PIN));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
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
|
||||||
*/
|
*/
|
||||||
|
@ -198,6 +259,7 @@ void main(void)
|
||||||
board_setup(); // setup board
|
board_setup(); // setup board
|
||||||
usart_setup(); // setup USART for user communication
|
usart_setup(); // setup USART for user communication
|
||||||
cdcacm_setup(); // setup USB ACM (serial) for user communication
|
cdcacm_setup(); // setup USB ACM (serial) for user communication
|
||||||
|
gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON,0); // disable JTAG (but leave SWD on) since we need most of the GPIOs
|
||||||
printf("welcome to the STM32F1 CuVoodoo clapperboard\n"); // print welcome message
|
printf("welcome to the STM32F1 CuVoodoo clapperboard\n"); // print welcome message
|
||||||
|
|
||||||
#if !(DEBUG)
|
#if !(DEBUG)
|
||||||
|
@ -256,26 +318,45 @@ void main(void)
|
||||||
rtc_ds1307_oscillator_enable(); // enable oscillator again
|
rtc_ds1307_oscillator_enable(); // enable oscillator again
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setup analog multiplexer for TM1637 clock
|
||||||
|
printf("setup multiplexer: ");
|
||||||
|
rcc_periph_clock_enable(RCC_GPIO(MUX_EN_PORT));
|
||||||
|
gpio_set_mode(GPIO(MUX_EN_PORT), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO(MUX_EN_PIN));
|
||||||
|
gpio_set(GPIO(MUX_EN_PORT), GPIO(MUX_EN_PIN)); // disable multiplexer
|
||||||
|
rcc_periph_clock_enable(RCC_GPIO(MUX_S0_PORT));
|
||||||
|
gpio_set_mode(GPIO(MUX_S0_PORT), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO(MUX_S0_PIN));
|
||||||
|
rcc_periph_clock_enable(RCC_GPIO(MUX_S1_PORT));
|
||||||
|
gpio_set_mode(GPIO(MUX_S1_PORT), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO(MUX_S1_PIN));
|
||||||
|
rcc_periph_clock_enable(RCC_GPIO(MUX_S2_PORT));
|
||||||
|
gpio_set_mode(GPIO(MUX_S2_PORT), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO(MUX_S2_PIN));
|
||||||
|
printf("OK\n");
|
||||||
|
|
||||||
// setup TM1637 and MAX7219 7-segments displays
|
// setup TM1637 and MAX7219 7-segments displays
|
||||||
printf("setup 7-segment displays: ");
|
printf("setup 7-segment displays: ");
|
||||||
led_tm1637_setup(); // setup TM1637
|
led_tm1637_setup(); // setup TM1637
|
||||||
|
for (uint8_t tm1637=0; tm1637<7; tm1637++) {
|
||||||
|
mux_select(tm1637);
|
||||||
|
if (!led_tm1637_time(88,88)) { // test TM1637 display
|
||||||
|
printf("could not send time to TM1637 %u\n", tm1637);
|
||||||
|
}
|
||||||
|
if (!led_tm1637_on()) { // switch on TM1637 display
|
||||||
|
printf("could not switch on TM1637 %u\n", tm1637);
|
||||||
|
}
|
||||||
|
}
|
||||||
led_max7219_setup(2); // setup MAX7219
|
led_max7219_setup(2); // setup MAX7219
|
||||||
if (!led_tm1637_time(88,88)) { // test TM1637 display
|
|
||||||
printf("could not send time to TM1637\n");
|
|
||||||
}
|
|
||||||
if (!led_tm1637_on()) { // switch on TM1637 display
|
|
||||||
printf("could not switch on TM1637\n");
|
|
||||||
}
|
|
||||||
led_max7219_intensity(15,8,0xff); // set brightness max and enable all digits
|
led_max7219_intensity(15,8,0xff); // set brightness max and enable all digits
|
||||||
led_max7219_test(true,0xff); // test all MAX7219 displays
|
led_max7219_test(true,0xff); // test all MAX7219 displays
|
||||||
for (uint32_t i=0; i<5000000; i++) { // wait a bit to have the user check the display
|
for (uint32_t i=0; i<5000000; i++) { // wait a bit to have the user check the display
|
||||||
__asm__("nop");
|
__asm__("nop");
|
||||||
}
|
}
|
||||||
if (!led_tm1637_text(" ")) { // clear display
|
for (uint8_t tm1637=0; tm1637<7; tm1637++) {
|
||||||
printf("could not clear\n");
|
mux_select(tm1637);
|
||||||
}
|
if (!led_tm1637_text(" ")) { // clear display
|
||||||
if (!led_tm1637_off()) { // switch off display
|
printf("could not clear on TM1637 %u\n", tm1637);
|
||||||
printf("could not switch off TM1637\n");
|
}
|
||||||
|
if (!led_tm1637_off()) { // switch off display
|
||||||
|
printf("could not switch off TM1637 %u\n", tm1637);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
led_max7219_test(false,0xff); // go back in normal operation
|
led_max7219_test(false,0xff); // go back in normal operation
|
||||||
led_max7219_off(0xff); // switch displays off
|
led_max7219_off(0xff); // switch displays off
|
||||||
|
@ -367,7 +448,7 @@ void main(void)
|
||||||
rtc_tick_flag = false; // reset flag
|
rtc_tick_flag = false; // reset flag
|
||||||
action = true; // action has been performed
|
action = true; // action has been performed
|
||||||
led_toggle(); // toggle LED (good to indicate if main function is stuck)
|
led_toggle(); // toggle LED (good to indicate if main function is stuck)
|
||||||
frame_count = 0; // resync frame counter to second
|
/*
|
||||||
if (standby_timer>=STANDBY_TIMEOUT) { // standby timeout complete
|
if (standby_timer>=STANDBY_TIMEOUT) { // standby timeout complete
|
||||||
// go into standby mode
|
// go into standby mode
|
||||||
printf("standing by\n");
|
printf("standing by\n");
|
||||||
|
@ -376,6 +457,7 @@ void main(void)
|
||||||
SCB_SCR |= SCB_SCR_SLEEPDEEP; // enable deep sleep
|
SCB_SCR |= SCB_SCR_SLEEPDEEP; // enable deep sleep
|
||||||
pwr_set_standby_mode(); // go to deep sleep
|
pwr_set_standby_mode(); // go to deep sleep
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if (rtc_seconds>=60) { // one minute passed
|
if (rtc_seconds>=60) { // one minute passed
|
||||||
rtc_ds1307_time = rtc_ds1307_read_time(); // get time/date from external RTC
|
rtc_ds1307_time = rtc_ds1307_read_time(); // get time/date from external RTC
|
||||||
if (rtc_ds1307_time==NULL) {
|
if (rtc_ds1307_time==NULL) {
|
||||||
|
@ -388,6 +470,15 @@ void main(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (uint8_t tm1637=0; tm1637<7; tm1637++) {
|
||||||
|
mux_select(tm1637);
|
||||||
|
if (!led_tm1637_time(rtc_ds1307_time[1],rtc_seconds+tm1637)) { // test TM1637 display
|
||||||
|
printf("could not send time to TM1637 %u\n", tm1637);
|
||||||
|
}
|
||||||
|
if (!led_tm1637_on()) { // switch on TM1637 display
|
||||||
|
printf("could not switch on TM1637 %u\n", tm1637);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (pwr_get_wakeup_flag()) { // someone is moving the clapperboard
|
while (pwr_get_wakeup_flag()) { // someone is moving the clapperboard
|
||||||
pwr_clear_wakeup_flag(); // clear flag
|
pwr_clear_wakeup_flag(); // clear flag
|
||||||
|
@ -405,6 +496,7 @@ void main(void)
|
||||||
void EXTI_ISR(SQUARE_WAVE_PIN)(void)
|
void EXTI_ISR(SQUARE_WAVE_PIN)(void)
|
||||||
{
|
{
|
||||||
exti_reset_request(EXTI(SQUARE_WAVE_PIN)); // reset interrupt
|
exti_reset_request(EXTI(SQUARE_WAVE_PIN)); // reset interrupt
|
||||||
|
frame_count = 0; // re-sync frame counter to second
|
||||||
rtc_seconds++; // increment number of seconds passed
|
rtc_seconds++; // increment number of seconds passed
|
||||||
if (standby_timer<STANDBY_TIMEOUT) { // timeout countdown not complete
|
if (standby_timer<STANDBY_TIMEOUT) { // timeout countdown not complete
|
||||||
standby_timer++; // continue counting down
|
standby_timer++; // continue counting down
|
||||||
|
|
Loading…
Reference in New Issue