diff --git a/lib/led_max7219.c b/lib/led_max7219.c index 8623505..b594580 100644 --- a/lib/led_max7219.c +++ b/lib/led_max7219.c @@ -155,24 +155,38 @@ static const uint8_t ascii_7segments[] = { 0x78, // } ([) 0x01, // ~ }; + +/** number of display in the chain */ +uint8_t lex_max7219_displays = 0; + /** write data on SPI bus and handle load signal * @param[in] data bytes to write */ static void led_max7219_write(uint16_t data, uint8_t display) { + if (lex_max7219_displays<=display && 0xff!=display) { // display no in chain + return; + } + gpio_clear(GPIO(LED_MAX7219_LOAD_PORT), GPIO(LED_MAX7219_LOAD_PIN)); // ensure load pin is low (data is put in MAX7219 register on rising edge) - for (uint16_t i=0; i<=display; i++) { // go though all displays + for (uint8_t i=lex_max7219_displays; i>0; i--) { // go though all displays while (SPI_SR(SPI(LED_MAX7219_SPI))&SPI_SR_BSY); // wait until not busy - spi_send(SPI(LED_MAX7219_SPI), data); // send data + if (0xff==display || i==(display+1)) { // right display or broadcast message + spi_send(SPI(LED_MAX7219_SPI), data); // send data + } else { + spi_send(SPI(LED_MAX7219_SPI), 0x0000); // send no-op command to shift command to correct display or out + } while (!(SPI_SR(SPI(LED_MAX7219_SPI))&SPI_SR_TXE)); // wait until Tx is empty (reference manual says BSY should also cover this, but it doesn't) while (SPI_SR(SPI(LED_MAX7219_SPI))&SPI_SR_BSY); // wait until not busy (= transmission completed) - data = 0x0000; // send no-op command to shift initial command to correct display } gpio_set(GPIO(LED_MAX7219_LOAD_PORT), GPIO(LED_MAX7219_LOAD_PIN)); // create rising edge on load pin for data to be set in MAX7219 register } -void led_max7219_setup(void) +void led_max7219_setup(uint8_t displays) { + // saved number of displays + lex_max7219_displays = displays; + // configure GPIO for load line rcc_periph_clock_enable(RCC_GPIO(LED_MAX7219_LOAD_PORT)); // enable clock for GPIO peripheral gpio_clear(GPIO(LED_MAX7219_LOAD_PORT), GPIO(LED_MAX7219_LOAD_PIN)); // idle low (load on rising edge) diff --git a/lib/led_max7219.h b/lib/led_max7219.h index 129e61d..8a1207e 100644 --- a/lib/led_max7219.h +++ b/lib/led_max7219.h @@ -22,30 +22,36 @@ #pragma once /** setup communication with MAX7219 IC + * @param[in] displays number of displays in the chain */ -void led_max7219_setup(void); +void led_max7219_setup(uint8_t displays); +/** do nothing (no operation) + * @param[in] display display number in chain (0xff for all) + * @note send it to the last display in the chain to clear the previous command from the chain + */ +void led_max7219_nop(uint8_t display); /** switch display on - * @param[in] display display number in chain + * @param[in] display display number in chain (0xff for all) */ void led_max7219_on(uint8_t display); /** switch display off - * @param[in] display display number in chain + * @param[in] display display number in chain (0xff for all) */ void led_max7219_off(uint8_t display); /** switch display in test or normal operation mode * @param[in] test switch in test mode (else normal operation) - * @param[in] display display number in chain + * @param[in] display display number in chain (0xff for all) */ void led_max7219_test(bool test, uint8_t display); /** set display intensity * @param[in] intensity level to set (0-15) * @param[in] digits number of digits to display (1-8) - * @param[in] display display number in chain + * @param[in] display display number in chain (0xff for all) */ void led_max7219_intensity(uint8_t intensity, uint8_t digits, uint8_t display); /** display text * @param[in] text text to display (8 characters) - * @param[in] display display number in chain + * @param[in] display display number in chain (0xff for all) * @note use first bit of each character to enable dot * @return false if string has unsupported characters */ @@ -53,6 +59,6 @@ bool led_max7219_text(char* text, uint8_t display); /** display number * @param[in] number number to display (8 digits max) * @param[in] dots set bit if dot on corresponding digit should be displayed - * @param[in] display display number in chain + * @param[in] display display number in chain (0xff for all) */ void led_max7219_number(uint32_t number, uint8_t dots, uint8_t display);