From ecedeac7afffc040064085f5c0bbba9e12452ee8 Mon Sep 17 00:00:00 2001 From: Scott Allen Date: Wed, 3 Aug 2016 20:46:34 -0400 Subject: [PATCH] Fix paintScreen() for IDE 1.6.10 paintScreen() used instruction padding for a delay to allow a byte to be sent to the display using SPI. This delay became to short with the new gcc version in Arduino IDE 1.6.10 The function has been changed to test for the serial transfer to complete before sending the next byte. --- src/ArduboyCore.cpp | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/ArduboyCore.cpp b/src/ArduboyCore.cpp index ab8a3a0..923d1d2 100644 --- a/src/ArduboyCore.cpp +++ b/src/ArduboyCore.cpp @@ -244,20 +244,26 @@ void ArduboyCore::paintScreen(const uint8_t *image) // will be used by any buffer based subclass void ArduboyCore::paintScreen(uint8_t image[]) { - for (int i = 0; i < (HEIGHT*WIDTH)/8; i++) - { - // SPI.transfer(image[i]); + uint8_t c; + int i = 0; - // we need to burn 18 cycles between sets of SPDR - // 4 clock cycles - SPDR = image[i]; - // 7 clock cycles - asm volatile( - "mul __zero_reg__, __zero_reg__ \n" // 2 cycles - "mul __zero_reg__, __zero_reg__ \n" // 2 cycles - "mul __zero_reg__, __zero_reg__ \n" // 2 cycles - ); + SPDR = image[i++]; // set the first SPI data byte to get things started + + // the code to iterate the loop and get the next byte from the buffer is + // executed while the previous byte is being sent out by the SPI controller + while (i < (HEIGHT * WIDTH) / 8) + { + // get the next byte. It's put in a local variable so it can be sent as + // as soon as possible after the sending of the previous byte has completed + c = image[i++]; + + while (!(SPSR & _BV(SPIF))) { } // wait for the previous byte to be sent + + // put the next byte in the SPI data register. The SPI controller will + // clock it out while the loop continues and gets the next byte ready + SPDR = c; } + while (!(SPSR & _BV(SPIF))) { } // wait for the last byte to be sent } void ArduboyCore::blank()