From 5dae02bbbf083e8b1fb0d2ff3f01dcaaa0c63fbd Mon Sep 17 00:00:00 2001 From: Jochen Hoenicke Date: Wed, 13 Jul 2016 12:51:47 +0200 Subject: [PATCH] Faster SPI communication According to specs, the display can handle up to 10 MHz SPI traffic (minimum cycle time is 100 ns). This patch sets the SPI port to 7.5 MHz (60 MHz clock with divisor 8). In my tests the display works even fine with SPI frequency at 60 MHz. I also minimized the delays (the spec doesn't require a long setup time) and use the registers to check when transfer is done instead of using a fixed delay. This patch also changes the swipe function to swipe pixel by pixel. Otherwise, the swipe would happen too fast to be seen. This changes the display update time from 11 ms to 1.5 ms. --- oled.c | 17 ++++++----------- setup.c | 3 ++- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/oled.c b/oled.c index a63d810..926428e 100644 --- a/oled.c +++ b/oled.c @@ -82,11 +82,12 @@ static bool is_debug_mode = 0; inline void SPISend(uint32_t base, uint8_t *data, int len) { int i; - delay(400); + delay(1); for (i = 0; i < len; i++) { spi_send(base, data[i]); } - delay(800); + while (!(SPI_SR(base) & SPI_SR_TXE)); + while ((SPI_SR(base) & SPI_SR_BSY)); } /* @@ -364,18 +365,12 @@ void oledFrame(int x1, int y1, int x2, int y2) void oledSwipeLeft(void) { int i, j, k; - for (i = 0; i < OLED_WIDTH / 4; i++) { + for (i = 0; i < OLED_WIDTH; i++) { for (j = 0; j < OLED_HEIGHT / 8; j++) { - for (k = OLED_WIDTH / 4 - 1; k > 0; k--) { - _oledbuffer[k * 4 + 3 + j * OLED_WIDTH] = _oledbuffer[k * 4 - 1 + j * OLED_WIDTH]; - _oledbuffer[k * 4 + 2 + j * OLED_WIDTH] = _oledbuffer[k * 4 - 2 + j * OLED_WIDTH]; - _oledbuffer[k * 4 + 1 + j * OLED_WIDTH] = _oledbuffer[k * 4 - 3 + j * OLED_WIDTH]; - _oledbuffer[k * 4 + 0 + j * OLED_WIDTH] = _oledbuffer[k * 4 - 4 + j * OLED_WIDTH]; + for (k = OLED_WIDTH-1; k > 0; k--) { + _oledbuffer[j * OLED_WIDTH + k] = _oledbuffer[j * OLED_WIDTH + k - 1]; } _oledbuffer[j * OLED_WIDTH] = 0; - _oledbuffer[j * OLED_WIDTH + 1] = 0; - _oledbuffer[j * OLED_WIDTH + 2] = 0; - _oledbuffer[j * OLED_WIDTH + 3] = 0; } oledRefresh(); } diff --git a/setup.c b/setup.c index c85bd8d..b91c2d6 100644 --- a/setup.c +++ b/setup.c @@ -55,7 +55,7 @@ void setup(void) gpio_set_af(GPIOA, GPIO_AF5, GPIO5 | GPIO7); // spi_disable_crc(SPI1); - spi_init_master(SPI1, SPI_CR1_BAUDRATE_FPCLK_DIV_64, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST); + spi_init_master(SPI1, SPI_CR1_BAUDRATE_FPCLK_DIV_8, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST); spi_enable_ss_output(SPI1); // spi_enable_software_slave_management(SPI1); // spi_set_nss_high(SPI1); @@ -71,4 +71,5 @@ void setupApp(void) { // hotfix for old bootloader gpio_mode_setup(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO9); + spi_init_master(SPI1, SPI_CR1_BAUDRATE_FPCLK_DIV_8, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST); }