2022-01-18 12:42:57 +00:00
# ifndef _RA8875_T4_H
# define _RA8875_T4_H
# include <Arduino.h>
# include <SPI.h>
# include <DMAChannel.h>
# include <stdint.h>
2022-01-26 18:49:28 +00:00
# include "basedisplay.h"
2022-01-18 12:42:57 +00:00
# define RA8875_WIDTH 800
# define RA8875_HEIGHT 480
# define _RA8875_WAITPOLL_TIMEOUT_DCR_LINESQUTRI_STATUS 20
enum {
RA8875_DMA_INIT = 0x01 ,
RA8875_DMA_EVER_INIT = 0x08 ,
RA8875_DMA_CONT = 0x02 ,
RA8875_DMA_FINISH = 0x04 ,
RA8875_DMA_ACTIVE = 0x80
} ;
2022-01-26 18:49:28 +00:00
class RA8875_t4 : public BaseDisplay {
2022-01-18 12:42:57 +00:00
public :
2022-01-30 20:30:11 +00:00
RA8875_t4 ( uint8_t cs_pin , uint8_t rst_pin , uint8_t mosi_pin , uint8_t sck_pin , uint8_t miso_pin , uint8_t dc_pin = 255 ) ; // dc pin is unused for this display but it's needed for the ILI and base class.
2022-01-26 18:49:28 +00:00
2022-01-18 12:42:57 +00:00
~ RA8875_t4 ( ) ;
2022-01-26 18:49:28 +00:00
virtual void begin ( uint32_t spi_clock = 30000000u , uint32_t spi_clock_read = 2000000 ) ;
2022-01-18 12:42:57 +00:00
2022-01-26 18:49:28 +00:00
virtual void fillWindow ( uint16_t color = 0x0000 ) ;
2022-01-18 12:42:57 +00:00
2022-01-26 18:49:28 +00:00
virtual void setFrameBuffer ( uint8_t * frame_buffer ) ;
2022-01-18 12:42:57 +00:00
2022-01-26 18:49:28 +00:00
virtual bool asyncUpdateActive ( ) ;
virtual bool updateScreenAsync ( bool update_cont = false ) ;
virtual void drawPixel ( int16_t x , int16_t y , uint16_t color ) ;
2022-01-31 01:26:12 +00:00
virtual void cacheApplePixel ( uint16_t x , uint16_t y , uint16_t color16 ) ;
virtual void cacheDoubleWideApplePixel ( uint16_t x , uint16_t y , uint16_t color16 ) ;
2022-01-26 18:49:28 +00:00
virtual uint32_t frameCount ( ) ;
2022-01-18 12:42:57 +00:00
2022-01-18 23:22:21 +00:00
uint8_t color16To8bpp ( uint16_t color ) __attribute__ ( ( always_inline ) ) {
return ( ( color & 0xe000 ) > > 8 ) | ( ( color & 0x700 ) > > 6 ) | ( ( color & 0x18 ) > > 3 ) ;
}
2022-01-18 12:42:57 +00:00
private :
void _initializeTFT ( ) ;
2022-01-19 23:40:10 +00:00
void initDMASettings ( ) ;
2022-01-18 12:42:57 +00:00
// These are the old style RA8875 calls -- replace them ***
void writeCommand ( const uint8_t d ) ;
void writeData16 ( uint16_t data ) ;
void _writeData ( uint8_t data ) ;
void _writeRegister ( const uint8_t reg , uint8_t val ) ;
uint8_t _readData ( bool stat ) ;
uint8_t _readRegister ( const uint8_t reg ) ;
2022-01-18 22:13:12 +00:00
void _waitBusy ( uint8_t res ) ;
2022-01-18 12:42:57 +00:00
boolean _waitPoll ( uint8_t regname , uint8_t waitflag , uint8_t timeout ) ;
2022-01-19 23:40:10 +00:00
void maybeUpdateTCR ( uint32_t requested_tcr_state ) ;
static void dmaInterrupt ( void ) ;
void process_dma_interrupt ( void ) ;
2022-01-18 12:42:57 +00:00
protected :
uint8_t _cs , _miso , _mosi , _sck , _rst ;
SPIClass * _pspi ;
IMXRT_LPSPI_t * _pimxrt_spi ;
SPIClass : : SPI_Hardware_t * _spi_hardware ;
uint32_t _spi_clock ; // desired clock
uint32_t _spi_clock_read ;
uint32_t _clock ; // current clock, used in starting transactions (b/c we have to slow down sometimes)
2022-02-02 12:17:05 +00:00
// DMA stuff. The _dmasettings[] and _dmatx can't be member
// variables. If they are, then the object will work if it's
// statically allocated; but dynamically allocated RA8875_t4 objects
// would be malloc()'d in RAM2, which is a problem for DMA.
// So instead they're static globals in the module.
// DMASetting _dmasettings[12];
// DMAChannel _dmatx;
2022-01-19 23:40:10 +00:00
uint32_t _spi_fcr_save ;
uint8_t * _pfbtft ;
volatile uint8_t _dma_state ;
uint32_t _spi_tcr_current ;
volatile uint32_t _dma_frame_count ;
2022-01-18 12:42:57 +00:00
protected :
void DIRECT_WRITE_LOW ( volatile uint32_t * base , uint32_t mask ) __attribute__ ( ( always_inline ) ) {
* ( base + 34 ) = mask ;
}
void DIRECT_WRITE_HIGH ( volatile uint32_t * base , uint32_t mask ) __attribute__ ( ( always_inline ) ) {
* ( base + 33 ) = mask ;
}
/* These are old-style function names, but with new-style contents */
void _startSend ( ) __attribute__ ( ( always_inline ) ) {
_pspi - > beginTransaction ( SPISettings ( _clock , MSBFIRST , SPI_MODE3 ) ) ;
2022-01-19 23:40:10 +00:00
_spi_tcr_current = _pimxrt_spi - > TCR ;
2022-01-18 12:42:57 +00:00
// DIRECT_WRITE_LOW(_csport, _cspinmask);
2022-01-18 22:13:12 +00:00
digitalWriteFast ( _cs , LOW ) ;
2022-01-18 12:42:57 +00:00
}
void _endSend ( ) __attribute__ ( ( always_inline ) ) {
// DIRECT_WRITE_HIGH(_csport, _cspinmask);
2022-01-18 22:13:12 +00:00
digitalWriteFast ( _cs , HIGH ) ;
2022-01-18 12:42:57 +00:00
_pspi - > endTransaction ( ) ;
}
} ;
# endif