precalculate all spi data
This commit is contained in:
parent
486d80f00d
commit
94664bafad
124
lib/vfd.c
124
lib/vfd.c
@ -305,12 +305,9 @@ static const uint8_t pict5x7[][5] = {
|
||||
|
||||
/* the 32 bits values to be shifted out to the VFD driver
|
||||
* split into 16 bit for SPI transfer */
|
||||
static uint32_t vfd_data[VFD_DRIVERS] = {0};
|
||||
static uint16_t vfd_spi[VFD_DRIVERS*2] = {0};
|
||||
static volatile uint8_t vfd_spi_i = 0;
|
||||
|
||||
char vfd_digits[VFD_DIGITS] = {0};
|
||||
char vfd_matrixs[VFD_MATRIX] = {0};
|
||||
static uint16_t vfd_spi[VFD_DIGITS+VFD_MATRIX][VFD_DRIVERS*2] = {0};
|
||||
static volatile uint8_t vfd_spi_i = 0; // which driver data is being transmitted
|
||||
static volatile uint8_t vfd_mux = 0; // which part to output
|
||||
|
||||
/* set digit <nb> to ASCII character <c>
|
||||
* use the MSB of <c> to enable the dot */
|
||||
@ -319,11 +316,8 @@ void vfd_digit(uint8_t nb, char c)
|
||||
if (!(nb<VFD_DIGITS)) { // check the digit exists
|
||||
return;
|
||||
}
|
||||
|
||||
// clear data
|
||||
for (uint8_t i=0; i<LENGTH(vfd_data); i++) {
|
||||
vfd_data[i] = 0;
|
||||
}
|
||||
|
||||
uint32_t vfd_data[VFD_DRIVERS] = {0}; // the data to be shifted out for the driver
|
||||
|
||||
vfd_data[1] = 1<<(4+(9-nb)); // select digit
|
||||
/* encode segment
|
||||
@ -350,6 +344,12 @@ void vfd_digit(uint8_t nb, char c)
|
||||
vfd_data[1] |= (ascii_7segments[i]<<(17)); // add encoded segments to memory
|
||||
}
|
||||
}
|
||||
|
||||
// prepare the data for SPI to shift it out
|
||||
for (uint8_t i=0; i<LENGTH(vfd_data); i++) {
|
||||
vfd_spi[nb][i*2] = vfd_data[i];
|
||||
vfd_spi[nb][i*2+1] = vfd_data[i]>>16;
|
||||
}
|
||||
}
|
||||
|
||||
/* set dot matrix <nb> to ASCII character <c>
|
||||
@ -361,10 +361,7 @@ void vfd_matrix(uint8_t nb, char c)
|
||||
return;
|
||||
}
|
||||
|
||||
// clear data
|
||||
for (uint8_t i=0; i<LENGTH(vfd_data); i++) {
|
||||
vfd_data[i] = 0;
|
||||
}
|
||||
uint32_t vfd_data[VFD_DRIVERS] = {0}; // the data to be shifted out for the driver
|
||||
|
||||
// select matrix
|
||||
if (nb<4) {
|
||||
@ -392,46 +389,11 @@ void vfd_matrix(uint8_t nb, char c)
|
||||
vfd_data[2] |= pict5x7[i][4]<<24;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* shift out the VFD data */
|
||||
void vfd_shift(void)
|
||||
{
|
||||
// prepare SPI data
|
||||
for (uint8_t i=0; i<LENGTH(vfd_data) && (uint8_t)(i*2+1)<LENGTH(vfd_spi); i++) {
|
||||
vfd_spi[i*2] = vfd_data[i];
|
||||
vfd_spi[i*2+1] = vfd_data[i]>>16;
|
||||
}
|
||||
vfd_spi_i = 0;
|
||||
|
||||
// enable SPI (the tx empty interrupt will trigger)
|
||||
spi_enable(VFD_SPI);
|
||||
}
|
||||
|
||||
/* transmit every digit and matrix */
|
||||
void vfd_transmit(void)
|
||||
{
|
||||
for (uint8_t i=0; i<LENGTH(vfd_digits); i++) {
|
||||
if (vfd_digits[i]==0) {
|
||||
continue; // skip unused digits
|
||||
}
|
||||
vfd_digit(i,vfd_digits[i]); // set digit
|
||||
vfd_shift(); // shift out data
|
||||
// let the fluorescence glow up a bit
|
||||
for (uint32_t j = 0; j < 0x2000; j++) {
|
||||
__asm__("nop");
|
||||
}
|
||||
}
|
||||
for (uint8_t i=0; i<LENGTH(vfd_matrixs); i++) {
|
||||
if (vfd_matrixs[i]==0) {
|
||||
continue; // skip unused matrix
|
||||
}
|
||||
vfd_matrix(i,vfd_matrixs[i]); // set matrix
|
||||
vfd_shift(); // shift out data
|
||||
// let the fluorescence glow up a bit
|
||||
for (uint32_t j = 0; j < 0x2000; j++) {
|
||||
__asm__("nop");
|
||||
}
|
||||
// prepare the data for SPI to shift it out
|
||||
for (uint8_t i=0; i<LENGTH(vfd_data); i++) {
|
||||
vfd_spi[nb+VFD_DIGITS][i*2] = vfd_data[i];
|
||||
vfd_spi[nb+VFD_DIGITS][i*2+1] = vfd_data[i]>>16;
|
||||
}
|
||||
}
|
||||
|
||||
@ -439,14 +401,10 @@ void vfd_transmit(void)
|
||||
* the data has to be transmitted separately */
|
||||
void vfd_clear(void)
|
||||
{
|
||||
for (uint8_t i=0; i<LENGTH(vfd_digits); i++) {
|
||||
vfd_digits[i] = 0;
|
||||
}
|
||||
for (uint8_t i=0; i<LENGTH(vfd_matrixs); i++) {
|
||||
vfd_matrixs[i] = 0;
|
||||
}
|
||||
for (uint8_t i=0; i<LENGTH(vfd_data); i++) {
|
||||
vfd_data[i] = 0;
|
||||
for (uint8_t i=0; i<LENGTH(vfd_spi); i++) {
|
||||
for (uint8_t j=0; j<LENGTH(vfd_spi[0]); j++) {
|
||||
vfd_spi[i][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -454,14 +412,10 @@ void vfd_clear(void)
|
||||
* the data has to be transmitted separately */
|
||||
void vfd_test(void)
|
||||
{
|
||||
for (uint8_t i=0; i<LENGTH(vfd_digits); i++) {
|
||||
vfd_digits[i] = '8';
|
||||
}
|
||||
for (uint8_t i=0; i<LENGTH(vfd_matrixs); i++) {
|
||||
vfd_matrixs[i] = 0x80+LENGTH(pict5x7)-1;
|
||||
}
|
||||
for (uint8_t i=0; i<LENGTH(vfd_data); i++) {
|
||||
vfd_data[i] = ~0;
|
||||
for (uint8_t i=0; i<LENGTH(vfd_spi); i++) {
|
||||
for (uint8_t j=0; j<LENGTH(vfd_spi[0]); j++) {
|
||||
vfd_spi[i][j] = ~0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -526,8 +480,8 @@ void vfd_setup(void)
|
||||
spi_enable_software_slave_management(VFD_SPI);
|
||||
spi_set_nss_high(VFD_SPI); // set NSS high
|
||||
|
||||
spi_enable_tx_buffer_empty_interrupt(VFD_SPI); // enable TX empty interrupt
|
||||
nvic_enable_irq(VFD_SPI_IRQ); // enable SPI interrupt
|
||||
spi_enable(VFD_SPI); // enable SPI (the tx empty interrupt will trigger)
|
||||
|
||||
/* setup timer to refresh display */
|
||||
rcc_periph_clock_enable(VFD_TIMER_RCC); // enable clock for timer block
|
||||
@ -548,11 +502,14 @@ void spi2_isr(void)
|
||||
#endif
|
||||
{
|
||||
if (SPI_SR(VFD_SPI) & SPI_SR_TXE) { // transmission buffer empty
|
||||
if (vfd_spi_i<LENGTH(vfd_spi)) { // check if data is available
|
||||
if (vfd_spi_i<LENGTH(vfd_spi[0])) { // check if data is available
|
||||
gpio_clear(VFD_PORT, VFD_NLE); // slave select to latch data
|
||||
spi_send(VFD_SPI, vfd_spi[vfd_spi_i++]); // send next data
|
||||
spi_send(VFD_SPI, vfd_spi[vfd_mux][vfd_spi_i++]); // send next data
|
||||
} else { // all data transmitted
|
||||
spi_clean_disable(VFD_SPI); // wait for transmission to complete
|
||||
spi_disable_tx_buffer_empty_interrupt(VFD_SPI); // no need to wait for new data
|
||||
while (SPI_SR(VFD_SPI) & SPI_SR_BSY); // wait for data to be shifted out
|
||||
spi_disable_tx_buffer_empty_interrupt(VFD_SPI); // no need to wait for new data
|
||||
gpio_set(VFD_PORT, VFD_NLE); // output latched data
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -567,21 +524,12 @@ void tim4_isr(void)
|
||||
void tim5_isr(void)
|
||||
#endif
|
||||
{
|
||||
static uint8_t vfd_mux = 0; // which part to output
|
||||
|
||||
//gpio_toggle(LED_PORT, LED_PIN);
|
||||
if (timer_get_flag(VFD_TIMER, TIM_SR_UIF)) { // overflow even happened
|
||||
gpio_toggle(LED_PORT, LED_PIN);
|
||||
timer_clear_flag(VFD_TIMER, TIM_SR_UIF); // clear flag
|
||||
if (vfd_mux<LENGTH(vfd_digits)) {
|
||||
if (vfd_digits[vfd_mux]!=0) { // skip unused digits
|
||||
vfd_digit(vfd_mux,vfd_digits[vfd_mux]); // set digit
|
||||
vfd_shift(); // shift out data
|
||||
}
|
||||
} else if (vfd_mux<LENGTH(vfd_digits)+LENGTH(vfd_matrixs)) {
|
||||
if (vfd_matrixs[vfd_mux-LENGTH(vfd_digits)]!=0) { // skip unused matrix
|
||||
vfd_matrix(vfd_mux-LENGTH(vfd_digits),vfd_matrixs[vfd_mux-LENGTH(vfd_digits)]); // set matrix
|
||||
vfd_shift(); // shift out data
|
||||
}
|
||||
}
|
||||
vfd_mux = (vfd_mux+1)%(LENGTH(vfd_digits)+LENGTH(vfd_matrixs)); // got to next segment
|
||||
vfd_spi_i = 0; // set the register to shift out
|
||||
spi_enable_tx_buffer_empty_interrupt(VFD_SPI); // enable TX empty interrupt
|
||||
vfd_mux = (vfd_mux+1)%LENGTH(vfd_spi); // got to next segment
|
||||
}
|
||||
}
|
||||
|
@ -31,8 +31,6 @@ void vfd_digit(uint8_t nb, char c);
|
||||
/* set dot matrix <nb> to ASCII character <c>
|
||||
* non ASCII characters are used for pictures */
|
||||
void vfd_matrix(uint8_t nb, char c);
|
||||
/* shift out the VFD data */
|
||||
void vfd_shift(void);
|
||||
/* clear VFD display
|
||||
* the data has to be transmitted separately */
|
||||
void vfd_clear(void);
|
||||
@ -40,8 +38,6 @@ void vfd_clear(void);
|
||||
* the data has to be transmitted separately */
|
||||
void vfd_test(void);
|
||||
/* transmit every digit and matrix */
|
||||
void vfd_transmit(void);
|
||||
/* switch VFD display on */
|
||||
void vfd_on(void);
|
||||
/* switch VFD display off */
|
||||
void vfd_off(void);
|
||||
|
19
main.c
19
main.c
@ -82,23 +82,20 @@ int main(void)
|
||||
|
||||
|
||||
vfd_on(); // switch on VFD
|
||||
vfd_refresh_on();
|
||||
vfd_test();
|
||||
vfd_shift();
|
||||
for (uint32_t i = 0; i < 0x800000; i++) {
|
||||
__asm__("nop");
|
||||
}
|
||||
vfd_clear();
|
||||
vfd_shift();
|
||||
vfd_digit(0,'0');
|
||||
vfd_shift();
|
||||
|
||||
|
||||
bool vfd_flag = false;
|
||||
bool refresh = true;
|
||||
for (uint8_t i=0; i<LENGTH(vfd_digits); i++) {
|
||||
vfd_digits[i] = '0'+i;
|
||||
vfd_digit(i,'0'+i);
|
||||
}
|
||||
for (uint8_t i=0; i<LENGTH(vfd_matrixs); i++) {
|
||||
vfd_matrixs[i] = 'A'+i;
|
||||
vfd_matrix(i,'A'+i);
|
||||
}
|
||||
while (true) {
|
||||
while (usart_received) { // echo every received character
|
||||
@ -112,7 +109,13 @@ int main(void)
|
||||
while (vfd_flag) {
|
||||
vfd_flag = false;
|
||||
gpio_toggle(LED_PORT, LED_PIN); // toggle LED
|
||||
refresh ? vfd_refresh_on() : vfd_refresh_off();
|
||||
if (refresh) {
|
||||
printf("on\n");
|
||||
vfd_refresh_on();
|
||||
} else {
|
||||
printf("off\n");
|
||||
vfd_refresh_off();
|
||||
}
|
||||
refresh = !refresh;
|
||||
}
|
||||
__WFI(); // go to sleep
|
||||
|
Loading…
Reference in New Issue
Block a user