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(uint8_ti=lex_max7219_displays;i>0;i--){// go though all displays
while(SPI_SR(SPI(LED_MAX7219_SPI))&SPI_SR_BSY);// wait until not busy
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)
}
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
}
voidled_max7219_setup(uint8_tdisplays)
{
// 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)
gpio_set_mode(GPIO(LED_MAX7219_LOAD_PORT),GPIO_MODE_OUTPUT_2_MHZ,GPIO_CNF_OUTPUT_PUSHPULL,GPIO(LED_MAX7219_LOAD_PIN));// set as output
// configure SPI peripheral
rcc_periph_clock_enable(RCC_SPI_SCK_PORT(LED_MAX7219_SPI));// enable clock for GPIO peripheral for clock signal
gpio_set_mode(SPI_SCK_PORT(LED_MAX7219_SPI),GPIO_MODE_OUTPUT_10_MHZ,GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,SPI_SCK_PIN(LED_MAX7219_SPI));// set as output (max clock speed for MAX7219 is 10 MHz)
rcc_periph_clock_enable(RCC_SPI_MOSI_PORT(LED_MAX7219_SPI));// enable clock for GPIO peripheral for MOSI signal
gpio_set_mode(SPI_MOSI_PORT(LED_MAX7219_SPI),GPIO_MODE_OUTPUT_10_MHZ,GPIO_CNF_OUTPUT_ALTFN_PUSHPULL,SPI_MOSI_PIN(LED_MAX7219_SPI));// set as output
rcc_periph_clock_enable(RCC_AFIO);// enable clock for SPI alternate function
rcc_periph_clock_enable(RCC_SPI(LED_MAX7219_SPI));// enable clock for SPI peripheral
spi_reset(SPI(LED_MAX7219_SPI));// clear SPI values to default
spi_init_master(SPI(LED_MAX7219_SPI),SPI_CR1_BAUDRATE_FPCLK_DIV_8,SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE,SPI_CR1_CPHA_CLK_TRANSITION_1,SPI_CR1_DFF_16BIT,SPI_CR1_MSBFIRST);// initialise SPI as master, divide clock by 8 since max MAX7219 clock is 10 MHz and max SPI PCLK clock is 72 Mhz, depending on which SPI is used, set clock polarity to idle low (as in the datasheet of the MAX7219, but not that important), set clock phase to go high when bit is set (depends on polarity) as data is stored on MAX7219 on rising edge), use 16 bits frames (as used by MAX7219), use MSB first
spi_set_unidirectional_mode(SPI(LED_MAX7219_SPI));// we only need to transmit data
spi_enable(SPI(LED_MAX7219_SPI));// enable SPI
}
voidled_max7219_on(uint8_tdisplay)
{
led_max7219_write(0x0C01,display);// put in normal operation more (registers remain as set)
}
voidled_max7219_off(uint8_tdisplay)
{
led_max7219_write(0x0C00,display);// put in shutdown mode (registers remain as set)
}
voidled_max7219_test(booltest,uint8_tdisplay)
{
if(test){
led_max7219_write(0x0F01,display);// go into display test mode
}else{
led_max7219_write(0x0F00,display);// go into normal operation mode