add command flushing and broadcast

This commit is contained in:
King Kévin 2017-04-02 13:42:25 +02:00
parent 9246317c4d
commit 6922cf655b
2 changed files with 31 additions and 11 deletions

View File

@ -155,24 +155,38 @@ static const uint8_t ascii_7segments[] = {
0x78, // } ([) 0x78, // } ([)
0x01, // ~ 0x01, // ~
}; };
/** number of display in the chain */
uint8_t lex_max7219_displays = 0;
/** write data on SPI bus and handle load signal /** write data on SPI bus and handle load signal
* @param[in] data bytes to write * @param[in] data bytes to write
*/ */
static void led_max7219_write(uint16_t data, uint8_t display) 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) 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 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_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) 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 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 // configure GPIO for load line
rcc_periph_clock_enable(RCC_GPIO(LED_MAX7219_LOAD_PORT)); // enable clock for GPIO peripheral 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) gpio_clear(GPIO(LED_MAX7219_LOAD_PORT), GPIO(LED_MAX7219_LOAD_PIN)); // idle low (load on rising edge)

View File

@ -22,30 +22,36 @@
#pragma once #pragma once
/** setup communication with MAX7219 IC /** 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 /** 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); void led_max7219_on(uint8_t display);
/** switch display off /** 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); void led_max7219_off(uint8_t display);
/** switch display in test or normal operation mode /** switch display in test or normal operation mode
* @param[in] test switch in test mode (else normal operation) * @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); void led_max7219_test(bool test, uint8_t display);
/** set display intensity /** set display intensity
* @param[in] intensity level to set (0-15) * @param[in] intensity level to set (0-15)
* @param[in] digits number of digits to display (1-8) * @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); void led_max7219_intensity(uint8_t intensity, uint8_t digits, uint8_t display);
/** display text /** display text
* @param[in] text text to display (8 characters) * @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 * @note use first bit of each character to enable dot
* @return false if string has unsupported characters * @return false if string has unsupported characters
*/ */
@ -53,6 +59,6 @@ bool led_max7219_text(char* text, uint8_t display);
/** display number /** display number
* @param[in] number number to display (8 digits max) * @param[in] number number to display (8 digits max)
* @param[in] dots set bit if dot on corresponding digit should be displayed * @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); void led_max7219_number(uint32_t number, uint8_t dots, uint8_t display);