This commit is contained in:
rogerclarkmelbourne 2015-05-28 14:09:09 +10:00
commit c3428ca861
6 changed files with 223 additions and 148 deletions

View File

@ -253,7 +253,7 @@ void Adafruit_ILI9341::begin(void) {
writedata(0x10); //SAP[2:0];BT[3:0]
writecommand(ILI9341_VMCTR1); //VCM control
writedata(0x3e); //¶Ô±È¶Èµ÷½Ú
writedata(0x3e); //???????
writedata(0x28);
writecommand(ILI9341_VMCTR2); //VCM control2
@ -327,11 +327,9 @@ void Adafruit_ILI9341::begin(void) {
void Adafruit_ILI9341::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1,
uint16_t y1) {
byte buf[4];
writecommand(ILI9341_CASET); // Column addr set
*dcport |= dcpinmask;
*csport &= ~cspinmask;
SPI.write(x0 >> 8);
SPI.write(x0 & 0xFF); // XSTART
SPI.write(x1 >> 8);
@ -340,13 +338,11 @@ void Adafruit_ILI9341::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1,
writecommand(ILI9341_PASET); // Row addr set
*dcport |= dcpinmask;
*csport &= ~cspinmask;
SPI.write(y0>>8);
SPI.write(y0); // YSTART
SPI.write(y1>>8);
SPI.write(y1); // YEND
writecommand(ILI9341_RAMWR); // write to RAM
}
@ -437,58 +433,33 @@ void Adafruit_ILI9341::fillScreen(uint16_t color) {
}
// fill a rectangle
void Adafruit_ILI9341::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) {
void Adafruit_ILI9341::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
uint16_t color) {
int numPixels;
// rudimentary clipping (drawChar w/big text requires this)
if((x >= _width) || (y >= _height)) return;
if((x + w - 1) >= _width) w = _width - x;
if((y + h - 1) >= _height) h = _height - y;
unsigned char *buff;
if (hwSPI) spi_begin();
setAddrWindow(x, y, x+w-1, y+h-1);
// rudimentary clipping (drawChar w/big text requires this)
if((x >= _width) || (y >= _height)) return;
if((x + w - 1) >= _width) w = _width - x;
if((y + h - 1) >= _height) h = _height - y;
uint8_t hi = color >> 8, lo = color;
if (hwSPI) spi_begin();
setAddrWindow(x, y, x+w-1, y+h-1);
uint8_t hi = color >> 8, lo = color;
*dcport |= dcpinmask;
*csport &= ~cspinmask;
*dcport |= dcpinmask;
*csport &= ~cspinmask;
if (true)
for(y=h; y>0; y--)
{
for(x=w; x>0; x--)
{
// Use DMA
byte txBuf[h*2];// Buffer to be sent via DMA
byte rxBuf[h*2];// Buffer to be sent via DMA
// need to build a buffer of the required height (h)
// Note I suspect there is a faster way to do this
for(int i=0;i<h*2;i++)
{
txBuf[i++] = hi&0xff;
txBuf[i] = lo&0xff;
}
// Tansfer each line by DMA
for(int i=0;i<w;i++)
{
//memcpy(rxBuf,txBuf,h*2);
SPI.DMATransfer(txBuf,rxBuf,h*2);
}
}
else
{
// Non DMA method (currently not used)
for(y=h; y>0; y--)
{
for(x=w; x>0; x--)
{
SPI.write(hi);
SPI.write(lo);
}
}
}
if (hwSPI) spi_end();
*csport |= cspinmask;
SPI.write(hi);
SPI.write(lo);
}
}
if (hwSPI) spi_end();
*csport |= cspinmask;
}
@ -658,3 +629,4 @@ uint8_t Adafruit_ILI9341::readcommand8(uint8_t c, uint8_t index) {
}
*/

View File

@ -167,3 +167,4 @@ class Adafruit_ILI9341 : public Adafruit_GFX {
};
#endif

View File

@ -1,6 +1,7 @@
/*
See rights and use declaration in License.h
This library has been modified for the Maple Mini
This library has been modified for the Maple Mini.
Includes DMA transfers on DMA1 CH2 and CH3.
*/
#include <Adafruit_ILI9341_STM.h>
#include <avr/pgmspace.h>
@ -10,10 +11,6 @@ This library has been modified for the Maple Mini
#include "wiring_private.h"
#include <SPI.h> // Using library SPI in folder: D:\Documents\Arduino\hardware\STM32\STM32F1XX\libraries\SPI
//Used for DMA transfers in STM32F1XX
#if defined (__STM32F1__)
volatile bool dma1_ch3_Active = false;
#endif
// Constructor when using software SPI. All output pins are configurable.
Adafruit_ILI9341_STM::Adafruit_ILI9341_STM(int8_t cs, int8_t dc, int8_t mosi,
@ -38,10 +35,6 @@ Adafruit_ILI9341_STM::Adafruit_ILI9341_STM(int8_t cs, int8_t dc, int8_t rst) : A
_mosi = _sclk = 0;
}
inline void DMA1_CH3_Event() {
dma1_ch3_Active = 0;
dma_disable(DMA1, DMA_CH3);
}
void Adafruit_ILI9341_STM::spiwrite(uint8_t c) {
@ -58,7 +51,7 @@ void Adafruit_ILI9341_STM::spiwrite(uint8_t c) {
#elif defined(TEENSYDUINO)
SPI.transfer(c);
#elif defined (__STM32F1__)
SPI.transfer(c);
SPI.write(c);
#elif defined (__arm__)
SPI.setClockDivider(11); // 8-ish MHz (full! speed!)
SPI.setBitOrder(MSBFIRST);
@ -87,30 +80,20 @@ void Adafruit_ILI9341_STM::spiwrite(uint8_t c) {
void Adafruit_ILI9341_STM::writecommand(uint8_t c) {
*dcport &= ~dcpinmask;
//digitalWrite(_dc, LOW);
//*clkport &= ~clkpinmask; // clkport is a NULL pointer when hwSPI==true
//digitalWrite(_sclk, LOW);
*csport &= ~cspinmask;
//digitalWrite(_cs, LOW);
spiwrite(c);
*csport |= cspinmask;
//digitalWrite(_cs, HIGH);
}
void Adafruit_ILI9341_STM::writedata(uint8_t c) {
*dcport |= dcpinmask;
//digitalWrite(_dc, HIGH);
//*clkport &= ~clkpinmask; // clkport is a NULL pointer when hwSPI==true
//digitalWrite(_sclk, LOW);
*csport &= ~cspinmask;
//digitalWrite(_cs, LOW);
spiwrite(c);
//digitalWrite(_cs, HIGH);
*csport |= cspinmask;
}
@ -195,13 +178,6 @@ void Adafruit_ILI9341_STM::begin(void) {
SPI.setClockDivider(SPI_CLOCK_DIV2);
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
// DMA setup stuff. We use a line buffer and usa DMA for filling lines and blocks.
spi_tx_dma_enable(SPI1);
dma_init(DMA1);
dma_attach_interrupt(DMA1, DMA_CH3, DMA1_CH3_Event);
dma_setup_transfer(DMA1, DMA_CH3, &SPI1->regs->DR, DMA_SIZE_8BITS,
lineBuffer, DMA_SIZE_8BITS, (DMA_MINC_MODE | DMA_FROM_MEM | DMA_TRNS_CMPLT));
#elif defined (__arm__)
SPI.begin();
@ -361,7 +337,26 @@ void Adafruit_ILI9341_STM::begin(void) {
void Adafruit_ILI9341_STM::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1,
uint16_t y1) {
#if defined (__STM32F1__)
writecommand(ILI9341_CASET); // Column addr set
*dcport |= dcpinmask;
*csport &= ~cspinmask;
SPI.setDataSize (SPI_CR1_DFF);
SPI.write(x0);
SPI.write(x1);
// SPI.setDataSize (0);
writecommand(ILI9341_PASET); // Row addr set
*dcport |= dcpinmask;
*csport &= ~cspinmask;
// SPI.setDataSize (SPI_CR1_DFF);
SPI.write(y0);
SPI.write(y1);
SPI.setDataSize (0);
writecommand(ILI9341_RAMWR); // write to RAM
#else
writecommand(ILI9341_CASET); // Column addr set
writedata(x0 >> 8);
writedata(x0 & 0xFF); // XSTART
@ -375,6 +370,7 @@ void Adafruit_ILI9341_STM::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1,
writedata(y1); // YEND
writecommand(ILI9341_RAMWR); // write to RAM
#endif
}
@ -400,16 +396,13 @@ void Adafruit_ILI9341_STM::drawPixel(int16_t x, int16_t y, uint16_t color) {
if (hwSPI) spi_begin();
setAddrWindow(x, y, x + 1, y + 1);
//digitalWrite(_dc, HIGH);
*dcport |= dcpinmask;
//digitalWrite(_cs, LOW);
*csport &= ~cspinmask;
spiwrite(color >> 8);
spiwrite(color);
*csport |= cspinmask;
//digitalWrite(_cs, HIGH);
if (hwSPI) spi_end();
}
@ -422,37 +415,30 @@ void Adafruit_ILI9341_STM::drawFastVLine(int16_t x, int16_t y, int16_t h,
if ((y + h - 1) >= _height)
h = _height - y;
if (h < 2 ) {
drawPixel(x, y, color);
return;
}
// if (hwSPI) spi_begin();
setAddrWindow(x, y, x, y + h - 1);
uint8_t hi = color >> 8, lo = color;
*dcport |= dcpinmask;
//digitalWrite(_dc, HIGH);
*csport &= ~cspinmask;
//digitalWrite(_cs, LOW);
#if defined (__STM32F1__)
for (int i = 0; i < (h * 2) - 1 ; i = i + 2)
{
lineBuffer[i] = hi;
lineBuffer[i + 1] = lo;
}
dma_set_num_transfers(DMA1, DMA_CH3, h * 2); // 2 bytes per pixel
dma1_ch3_Active = true;
dma_enable(DMA1, DMA_CH3);
while (dma1_ch3_Active);
SPI.setDataSize (SPI_CR1_DFF); // Set SPI 16bit mode
lineBuffer[0] = color;
SPI.dmaSend(lineBuffer, h, 0);
SPI.setDataSize (0);
#else
while (h--) {
spiwrite(hi);
spiwrite(lo);
}
uint8_t hi = color >> 8, lo = color;
while (h--) {
spiwrite(hi);
spiwrite(lo);
}
#endif
*csport |= cspinmask;
//digitalWrite(_cs, HIGH);
// if (hwSPI) spi_end();
}
@ -463,27 +449,23 @@ void Adafruit_ILI9341_STM::drawFastHLine(int16_t x, int16_t y, int16_t w,
// Rudimentary clipping
if ((x >= _width) || (y >= _height || w < 1)) return;
if ((x + w - 1) >= _width) w = _width - x;
if (hwSPI) spi_begin();
setAddrWindow(x, y, x + w - 1, y);
if (w < 2 ) {
drawPixel(x, y, color);
return;
}
uint8_t hi = color >> 8, lo = color;
// if (hwSPI) spi_begin();
setAddrWindow(x, y, x + w - 1, y);
*dcport |= dcpinmask;
*csport &= ~cspinmask;
//digitalWrite(_dc, HIGH);
//digitalWrite(_cs, LOW);
#if defined (__STM32F1__)
for (int i = 0; i < (w * 2) - 1 ; i = i + 2)
{
lineBuffer[i] = hi;
lineBuffer[i + 1] = lo;
}
dma_set_num_transfers(DMA1, DMA_CH3, w * 2); // 2 bytes per pixel
dma1_ch3_Active = true;
dma_enable(DMA1, DMA_CH3);
while (dma1_ch3_Active) delayMicroseconds(1);
#if defined (__STM32F1__)
SPI.setDataSize (SPI_CR1_DFF); // Set spi 16bit mode
lineBuffer[0] = color;
SPI.dmaSend(lineBuffer, w, 0);
SPI.setDataSize (0);
#else
uint8_t hi = color >> 8, lo = color;
while (w--) {
spiwrite(hi);
spiwrite(lo);
@ -491,11 +473,23 @@ void Adafruit_ILI9341_STM::drawFastHLine(int16_t x, int16_t y, int16_t w,
#endif
*csport |= cspinmask;
//digitalWrite(_cs, HIGH);
if (hwSPI) spi_end();
// if (hwSPI) spi_end();
}
void Adafruit_ILI9341_STM::fillScreen(uint16_t color) {
#if defined (__STM32F1__)
setAddrWindow(0, 0, _width - 1, _height - 1);
*dcport |= dcpinmask;
*csport &= ~cspinmask;
SPI.setDataSize (SPI_CR1_DFF); // Set spi 16bit mode
lineBuffer[0] = color;
SPI.dmaSend(lineBuffer, (65535), 0);
SPI.dmaSend(lineBuffer, ((_width * _height) - 65535), 0);
SPI.setDataSize (0);
#else
fillRect(0, 0, _width, _height, color);
#endif
}
// fill a rectangle
@ -506,36 +500,29 @@ void Adafruit_ILI9341_STM::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
if ((x >= _width) || (y >= _height || h < 1 || w < 1)) return;
if ((x + w - 1) >= _width) w = _width - x;
if ((y + h - 1) >= _height) h = _height - y;
if (w == 1 && h == 1) {
drawPixel(x, y, color);
return;
}
if (hwSPI) spi_begin();
setAddrWindow(x, y, x + w - 1, y + h - 1);
uint8_t hi = color >> 8, lo = color;
*dcport |= dcpinmask;
//digitalWrite(_dc, HIGH);
*csport &= ~cspinmask;
//digitalWrite(_cs, LOW);
#if defined (__STM32F1__)
//moved this loop outside as we can fill the buffer once and send it multiple times.
for (int i = 0; i < (w * 2) - 1 ; i = i + 2)
{
lineBuffer[i] = hi;
lineBuffer[i + 1] = lo;
SPI.setDataSize (SPI_CR1_DFF); // Set spi 16bit mode
lineBuffer[0] = color;
if (w*h <= 65535) {
SPI.dmaSend(lineBuffer, (w*h), 0);
}
for (y = h; y > 0; y--) {
// for(x=w; x>0; x--) {
// spiwrite(hi);
// spiwrite(lo);
// }
dma_set_num_transfers(DMA1, DMA_CH3, w * 2); // 2 bytes per pixel
dma1_ch3_Active = true;
dma_enable(DMA1, DMA_CH3);
while (dma1_ch3_Active) delayMicroseconds(1);
else {
SPI.dmaSend(lineBuffer, (65535), 0);
SPI.dmaSend(lineBuffer, ((w*h) - 65535), 0);
}
SPI.setDataSize (0);
#else
uint8_t hi = color >> 8, lo = color;
for(y=h; y>0; y--)
{
for(x=w; x>0; x--)
@ -545,12 +532,124 @@ void Adafruit_ILI9341_STM::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,
}
}
#endif
//digitalWrite(_cs, HIGH);
*csport |= cspinmask;
if (hwSPI) spi_end();
}
/*
* Draw lines faster by calculating straight sections and drawing them with fastVline and fastHline.
*/
#if defined (__STM32F1__)
void Adafruit_ILI9341_STM::drawLine(int16_t x0, int16_t y0,int16_t x1, int16_t y1, uint16_t color)
{
if ((y0 < 0 && y1 <0) || (y0 > _height && y1 > _height)) return;
if ((x0 < 0 && x1 <0) || (x0 > _width && x1 > _width)) return;
if (x0 < 0) x0 = 0;
if (x1 < 0) x1 = 0;
if (y0 < 0) y0 = 0;
if (y1 < 0) y1 = 0;
if (y0 == y1) {
if (x1 > x0) {
drawFastHLine(x0, y0, x1 - x0 + 1, color);
}
else if (x1 < x0) {
drawFastHLine(x1, y0, x0 - x1 + 1, color);
}
else {
drawPixel(x0, y0, color);
}
return;
}
else if (x0 == x1) {
if (y1 > y0) {
drawFastVLine(x0, y0, y1 - y0 + 1, color);
}
else {
drawFastVLine(x0, y1, y0 - y1 + 1, color);
}
return;
}
bool steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) {
swap(x0, y0);
swap(x1, y1);
}
if (x0 > x1) {
swap(x0, x1);
swap(y0, y1);
}
int16_t dx, dy;
dx = x1 - x0;
dy = abs(y1 - y0);
int16_t err = dx / 2;
int16_t ystep;
if (y0 < y1) {
ystep = 1;
}
else {
ystep = -1;
}
int16_t xbegin = x0;
lineBuffer[0] = color;
*csport &= ~cspinmask;
if (steep) {
for (; x0 <= x1; x0++) {
err -= dy;
if (err < 0) {
int16_t len = x0 - xbegin;
if (len) {
drawFastVLine (y0, xbegin, len + 1, color);
//writeVLine_cont_noCS_noFill(y0, xbegin, len + 1);
}
else {
drawPixel(y0, x0, color);
//writePixel_cont_noCS(y0, x0, color);
}
xbegin = x0 + 1;
y0 += ystep;
err += dx;
}
}
if (x0 > xbegin + 1) {
//writeVLine_cont_noCS_noFill(y0, xbegin, x0 - xbegin);
drawFastVLine(y0, xbegin, x0 - xbegin, color);
}
}
else {
for (; x0 <= x1; x0++) {
err -= dy;
if (err < 0) {
int16_t len = x0 - xbegin;
if (len) {
drawFastHLine(xbegin, y0, len + 1, color);
//writeHLine_cont_noCS_noFill(xbegin, y0, len + 1);
}
else {
drawPixel(x0, y0, color);
//writePixel_cont_noCS(x0, y0, color);
}
xbegin = x0 + 1;
y0 += ystep;
err += dx;
}
}
if (x0 > xbegin + 1) {
//writeHLine_cont_noCS_noFill(xbegin, y0, x0 - xbegin);
drawFastHLine(xbegin, y0, x0 - xbegin, color);
}
}
*csport |= cspinmask;
}
#endif
// Pass 8-bit (each) R,G,B, get back 16-bit packed color
uint16_t Adafruit_ILI9341_STM::color565(uint8_t r, uint8_t g, uint8_t b) {

View File

@ -104,6 +104,9 @@ class Adafruit_ILI9341_STM : public Adafruit_GFX {
setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1),
pushColor(uint16_t color),
fillScreen(uint16_t color),
#if defined (__STM32F1__)
drawLine(int16_t x0, int16_t y0,int16_t x1, int16_t y1, uint16_t color),
#endif
drawPixel(int16_t x, int16_t y, uint16_t color),
drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color),
drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color),
@ -145,7 +148,7 @@ class Adafruit_ILI9341_STM : public Adafruit_GFX {
volatile uint32 *mosiport, *clkport, *dcport, *rsport, *csport;
uint32_t _cs, _dc, _rst, _mosi, _miso, _sclk;
uint32_t mosipinmask, clkpinmask, cspinmask, dcpinmask;
volatile byte lineBuffer[640];
uint16_t lineBuffer[ILI9341_TFTHEIGHT]; // DMA buffer. 16bit color data per pixel
#elif defined (__arm__)
volatile RwReg *mosiport, *clkport, *dcport, *rsport, *csport;
uint32_t _cs, _dc, _rst, _mosi, _miso, _sclk;

View File

@ -324,7 +324,7 @@ void SPIClass::write(uint16 data) {
while (spi_is_busy(this->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
}
void SPIClass::write(uint8 byte) {
//void SPIClass::write(uint8 byte) {
// this->write(&byte, 1);
/* Roger Clark
@ -333,10 +333,10 @@ void SPIClass::write(uint8 byte) {
* This almost doubles the speed of this function.
*/
spi_tx_reg(this->spi_d, byte); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
while (spi_is_tx_empty(this->spi_d) == 0); // "5. Wait until TXE=1 ..."
while (spi_is_busy(this->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
}
// spi_tx_reg(this->spi_d, byte); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
// while (spi_is_tx_empty(this->spi_d) == 0); // "5. Wait until TXE=1 ..."
// while (spi_is_busy(this->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
//}
void SPIClass::write(const uint8 *data, uint32 length) {
uint32 txed = 0;

View File

@ -215,7 +215,7 @@ public:
* @brief Transmit a byte.
* @param data Byte to transmit.
*/
void write(uint8 data);
// void write(uint8 data);
/**
* @brief Transmit a half word.