Updated to use new DMA functions.

Previous version will not work anymore due to conflict of variable name
(dma1_ch3_active
This commit is contained in:
victorpv 2015-05-24 00:21:15 -05:00
parent 66b3a0394e
commit 84ff52b49d
2 changed files with 193 additions and 91 deletions

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;