Add font scaling, fix trouble with sprites, fix trouble with blocking SPI read (DMA read non-fixing without reset SPI)

This commit is contained in:
Edward Emelianov 2023-05-11 23:16:56 +03:00
parent d88de360d0
commit e63b29435c
8 changed files with 70 additions and 64 deletions

View File

@ -590,6 +590,7 @@ const uint8_t font14_table[] = {
________,________, ________,________,
________,________, ________,________,
________,________, ________,________,
________,________,
XX______,________, XX______,________,
XX______,________, XX______,________,
________,________, ________,________,
@ -600,8 +601,7 @@ const uint8_t font14_table[] = {
XX______,________, XX______,________,
_X______,________, _X______,________,
_X______,________, _X______,________,
X_______,________, X_______,________
________,________
// 0x3C // 0x3C
, ,
9, 9,
@ -1516,21 +1516,21 @@ const uint8_t font14_table[] = {
________,________ ________,________
// 0x6C // 0x6C
, ,
3, 5,
________,________, ________,________,
________,________, ________,________,
XX______,________, XXX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, __XX____,________,
________,________, ________,________,
________,________ ________,________
// 0x6D // 0x6D
@ -1820,22 +1820,22 @@ const uint8_t font14_table[] = {
________,________ ________,________
// 0x7C // 0x7C
, ,
3, 4,
________,________, ________,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
XX______,________, _XX_____,________,
________,________ ________,________
// 0x7D // 0x7D
, ,

View File

@ -219,12 +219,8 @@ int ili9341_readregdma(uint8_t reg, uint8_t *data, uint32_t N){
do{ do{
if(!spi_write(&reg, 1)) break; if(!spi_write(&reg, 1)) break;
if(!spi_waitbsy()) break; if(!spi_waitbsy()) break;
SCRN_Data(); r = dmardwr(data, data, N);
if(!dmardwr(data, data, N)) break;
r = 1;
}while(0); }while(0);
SCRN_Command();
SCRN_RST_set(1);
return r; return r;
} }

View File

@ -241,7 +241,7 @@ static int scrnrdwr4(const char *cmd, int parno, const char *c, int32_t i){
static int scrnrdn(const char *cmd, int parno, const char *c, int32_t i){ static int scrnrdn(const char *cmd, int parno, const char *c, int32_t i){
if(parno < 0 || parno > 255) return RET_WRONGPARNO; if(parno < 0 || parno > 255) return RET_WRONGPARNO;
if(!c || i < 1 || i > COLORBUFSZ*2) return RET_WRONGARG; if(!c || i < 1 || i > COLORBUFSZ*2) return RET_WRONGARG;
if(!ili9341_readregdma(parno, (uint8_t*)colorbuf, i)) return RET_BAD; if(!(i = ili9341_readregdma(parno, (uint8_t*)colorbuf, i))) return RET_BAD;
sendkey(cmd, parno, i); sendkey(cmd, parno, i);
hexdump(USB_sendstr, (uint8_t*)colorbuf, i); hexdump(USB_sendstr, (uint8_t*)colorbuf, i);
return RET_GOOD; return RET_GOOD;
@ -346,7 +346,8 @@ static int sputstr(const char _U_ *cmd, int parno, const char *c, int32_t _U_ i)
if(parno < 0) parno = 0; if(parno < 0) parno = 0;
if(parno > SCRNH-1) parno = SCRNH-1; if(parno > SCRNH-1) parno = SCRNH-1;
PutStringAt(0, parno, c); PutStringAt(0, parno, c);
UpdateScreen(parno - 14, parno+2); int fs = SetFontScale(0); // get font scale
UpdateScreen(parno-13*fs, parno+3*fs);
USB_sendstr("put string: '"); USB_sendstr(c); USB_sendstr("'\n"); USB_sendstr("put string: '"); USB_sendstr(c); USB_sendstr("'\n");
return RET_GOOD; return RET_GOOD;
} }
@ -375,6 +376,11 @@ static int sstate(const char _U_ *cmd, int _U_ parno, const char _U_ *c, int32_t
USB_sendstr("ScreenState="); USB_sendstr(s); newline(); USB_sendstr("ScreenState="); USB_sendstr(s); newline();
return RET_GOOD; return RET_GOOD;
} }
static int sfscale(const char *cmd, int _U_ parno, const char _U_ *c, int32_t i){
sendkeyu(cmd, -1, SetFontScale((uint8_t)i));
return RET_GOOD;
}
typedef struct{ typedef struct{
int (*fn)(const char*, int, const char*, int32_t); int (*fn)(const char*, int, const char*, int32_t);
@ -418,6 +424,7 @@ commands cmdlist[] = {
{scolor, "Scolor", "seg color fg=bg"}, {scolor, "Scolor", "seg color fg=bg"},
{sputstr, "Sstr", "put string y=string"}, {sputstr, "Sstr", "put string y=string"},
{sstate, "Sstate", "current screen state"}, {sstate, "Sstate", "current screen state"},
{sfscale, "Sfscale", "set/get =font scale"},
{NULL, "ADC commands", NULL}, {NULL, "ADC commands", NULL},
{adcval, "ADC", "get ADCx value (without x - for all)"}, {adcval, "ADC", "get ADCx value (without x - for all)"},
{adcvoltage, "ADCv", "get ADCx voltage (without x - for all)"}, {adcvoltage, "ADCv", "get ADCx voltage (without x - for all)"},

View File

@ -56,6 +56,8 @@ static int uy0, uy1;
static int updidx = 0; // ==-1 to initialize update static int updidx = 0; // ==-1 to initialize update
// next data portion size (in bytes!), total amount of bytes in update buffer // next data portion size (in bytes!), total amount of bytes in update buffer
static int portionsz = 0, updbuffsz; static int portionsz = 0, updbuffsz;
// font scale
static uint8_t fontscale = 1;
static uint16_t fgColor = 0xff, bgColor = 0; // foreground and background colors static uint16_t fgColor = 0xff, bgColor = 0; // foreground and background colors
void setBGcolor(uint16_t c){bgColor = c;} void setBGcolor(uint16_t c){bgColor = c;}
@ -84,14 +86,11 @@ void UpdateScreen(int y0, int y1){
*/ */
void ClearScreen(){ void ClearScreen(){
memset(screenbuf, 0, SCREENBUF_SZ); memset(screenbuf, 0, SCREENBUF_SZ);
int i; for(int i = 0; i < SPRITE_SZ; ++i){
for(i = 0; i < SPRITE_SZ; ++i){
foreground[i] = fgColor; foreground[i] = fgColor;
background[i] = bgColor; background[i] = bgColor;
} }
USB_sendstr("total spsz="); USB_sendstr(i2str(i)); newline(); for(int i = SPRITE_SZ-40; i < SPRITE_SZ; ++i) foreground[i] = i;
foreground[SPRITE_SZ-5] = 0x1234;
foreground[SPRITE_SZ-21] = 0x4321;
UpdateScreen(0, SCRNH-1); UpdateScreen(0, SCRNH-1);
} }
@ -103,7 +102,7 @@ void ClearScreen(){
void DrawPix(int X, int Y, uint8_t pix){ void DrawPix(int X, int Y, uint8_t pix){
if(X < 0 || X > SCRNW-1 || Y < 0 || Y > SCRNH-1) return; // outside of screen if(X < 0 || X > SCRNW-1 || Y < 0 || Y > SCRNH-1) return; // outside of screen
// now calculate coordinate of pixel // now calculate coordinate of pixel
int16_t spritex = X/SPRITEWD, spriteidx = spritex + SCRNSPRITEW * Y / SPRITEHT; int16_t spritex = X/SPRITEWD, spriteidx = spritex + SCRNSPRITEW * (Y / SPRITEHT);
uint8_t *ptr = &screenbuf[Y*SCRNSPRITEW + spritex]; // pointer to byte with 8 pixels uint8_t *ptr = &screenbuf[Y*SCRNSPRITEW + spritex]; // pointer to byte with 8 pixels
if(pix) *ptr |= 1 << (7 - (X%8)); if(pix) *ptr |= 1 << (7 - (X%8));
else *ptr &= ~(1 << (7 - (X%8))); else *ptr &= ~(1 << (7 - (X%8)));
@ -135,6 +134,11 @@ void invertSpriteColor(int xmin, int xmax, int ymin, int ymax){
} }
} }
uint8_t SetFontScale(uint8_t scale){
if(scale > 0 && scale <= FONTSCALEMAX) fontscale = scale;
return fontscale;
}
// TODO in case of low speed: draw at once full line? // TODO in case of low speed: draw at once full line?
/** /**
* @brief DrawCharAt - draws character @ position X,Y (this point is left baseline corner of char!) * @brief DrawCharAt - draws character @ position X,Y (this point is left baseline corner of char!)
@ -147,18 +151,20 @@ uint8_t DrawCharAt(int X, int Y, uint8_t Char){
const uint8_t *curchar = font_char(Char); const uint8_t *curchar = font_char(Char);
if(!curchar) return 0; if(!curchar) return 0;
// now change Y coordinate to left upper corner of font // now change Y coordinate to left upper corner of font
Y += curfont->baseline - curfont->height + 1; Y += fontscale*(curfont->baseline - curfont->height + 1);
// height and width of letter in pixels // height and width of letter in pixels
uint8_t h = curfont->height, w = *curchar++; // now curchar is pointer to bits array uint8_t h = curfont->height, w = *curchar++; // now curchar is pointer to bits array
uint8_t lw = curfont->bytes / h; // width of letter in bytes uint8_t lw = curfont->bytes / h; // width of letter in bytes
for(uint8_t row = 0; row < h; ++row){ for(uint8_t row = 0; row < h; ++row){
int Y1 = Y + row; int Y1 = Y + fontscale * row;
for(uint8_t col = 0; col < w; ++col){ for(uint8_t col = 0; col < w; ++col){
register uint8_t pix = curchar[row*lw + (col/8)] & (1 << (7 - (col%8))); register uint8_t pix = curchar[row*lw + (col/8)] & (1 << (7 - (col%8)));
DrawPix(X + col, Y1, pix); int xx = X + fontscale * col;
for(int y = 0; y < fontscale; ++y) for(int x = 0; x < fontscale; ++x)
DrawPix(xx + x, Y1 + y, pix);
} }
} }
return w; return w * fontscale;
} }
/** /**
@ -215,11 +221,8 @@ static int convbuf(){
uint16_t *fg = foreground + spidx, *bg = background + spidx; uint16_t *fg = foreground + spidx, *bg = background + spidx;
for(int X = 0; X < SCRNSPRITEW; ++X, ++fg, ++bg, ++i){ for(int X = 0; X < SCRNSPRITEW; ++X, ++fg, ++bg, ++i){
// prepare colors for SPI transfer // prepare colors for SPI transfer
uint16_t f = __builtin_bswap16(*fg++), b = __builtin_bswap16(*bg++); uint16_t f = __builtin_bswap16(*fg), b = __builtin_bswap16(*bg);
uint8_t pix = *i; uint8_t pix = *i;
if(Y==239){
USB_sendstr("X="); USB_sendstr(i2str(X)); newline();
USB_sendstr("f="); USB_sendstr(uhex2str(f)); newline();}
for(int idx = 0; idx < SPRITEWD; ++idx){ // now check bits in pixels mask for(int idx = 0; idx < SPRITEWD; ++idx){ // now check bits in pixels mask
*o++ = (pix & 0x80) ? f : b; *o++ = (pix & 0x80) ? f : b;
pix <<= 1; pix <<= 1;

View File

@ -39,6 +39,9 @@ typedef enum{ // screen states
#define SPRITEWD (8) #define SPRITEWD (8)
#define SPRITEHT (8) #define SPRITEHT (8)
// maximal font scale
#define FONTSCALEMAX (10)
screen_state getScreenState(); screen_state getScreenState();
void ClearScreen(); void ClearScreen();
void UpdateScreen(int y0, int y1); void UpdateScreen(int y0, int y1);
@ -46,6 +49,7 @@ void setBGcolor(uint16_t c);
void setFGcolor(uint16_t c); void setFGcolor(uint16_t c);
void invertSpriteColor(int xmin, int xmax, int ymin, int ymax); void invertSpriteColor(int xmin, int xmax, int ymin, int ymax);
void DrawPix(int X, int Y, uint8_t pix); void DrawPix(int X, int Y, uint8_t pix);
uint8_t SetFontScale(uint8_t scale);
uint8_t DrawCharAt(int X, int Y, uint8_t Char); uint8_t DrawCharAt(int X, int Y, uint8_t Char);
int PutStringAt(int X, int Y, const char *str); int PutStringAt(int X, int Y, const char *str);
int CenterStringAt(int Y, const char *str); int CenterStringAt(int Y, const char *str);

View File

@ -24,7 +24,7 @@
#include "strfunc.h" #include "strfunc.h"
#endif #endif
#define SPIDR *((uint8_t*)&SPI2->DR) #define SPIDR *((volatile uint8_t*)&SPI2->DR)
spiStatus spi_status = SPI_NOTREADY; spiStatus spi_status = SPI_NOTREADY;
volatile uint32_t wctr; volatile uint32_t wctr;
@ -40,11 +40,12 @@ static uint32_t rxbuflen = 0;
// Channel 5 - SPI2 Tx // Channel 5 - SPI2 Tx
void spi_setup(){ void spi_setup(){
SPI2->CR1 = 0; // clear EN SPI2->CR1 = 0; // clear EN
//RCC->APB1RSTR = RCC_APB1RSTR_SPI2RST; // reset SPI RCC->APB1RSTR = RCC_APB1RSTR_SPI2RST; // reset SPI
RCC->APB1RSTR = 0; // clear reset
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
RCC->AHBENR |= RCC_AHBENR_DMA1EN; RCC->AHBENR |= RCC_AHBENR_DMA1EN;
// Baudrate = 0b011 - fpclk/16 = 2MHz; software slave management (without hardware NSS pin) // Baudrate = 0b011 - fpclk/4 = 8MHz; software slave management (without hardware NSS pin)
SPI2->CR1 = SPI_CR1_MSTR | SPI_CR1_BR_0 | SPI_CR1_BR_1 | SPI_CR1_SSM | SPI_CR1_SSI; SPI2->CR1 = SPI_CR1_MSTR | /*SPI_CR1_BR_0 |*/ SPI_CR1_SSM | SPI_CR1_SSI;
// 8bit; RXNE generates after 8bit of data in FIFO // 8bit; RXNE generates after 8bit of data in FIFO
SPI2->CR2 = SPI_CR2_FRXTH | SPI_CR2_DS_2|SPI_CR2_DS_1|SPI_CR2_DS_0 | SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN; SPI2->CR2 = SPI_CR2_FRXTH | SPI_CR2_DS_2|SPI_CR2_DS_1|SPI_CR2_DS_0 | SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN;
// setup SPI2 DMA // setup SPI2 DMA
@ -94,14 +95,10 @@ int spi_write(const uint8_t *data, uint32_t n){
*/ */
int spi_write_dma(const uint8_t *data, uint8_t *rxbuf, uint32_t n){ int spi_write_dma(const uint8_t *data, uint8_t *rxbuf, uint32_t n){
if(spi_status != SPI_READY) return 0; if(spi_status != SPI_READY) return 0;
if(!spi_waitbsy()) return 0;
rxbufptr = rxbuf; rxbufptr = rxbuf;
rxbuflen = n; rxbuflen = n;
if(!spi_waitbsy()) return 0; // spi_setup(); - only so we can clear Rx FIFO!
// clear SPI Rx FIFO
(void) SPI2->DR;
while(SPI2->SR & SPI_SR_RXNE) (void) SPI2->DR;
//DMA1_Channel4->CCR &= ~DMA_CCR_EN; // turn off to reconfigure
//DMA1_Channel5->CCR &= ~DMA_CCR_EN;
DMA1_Channel5->CMAR = (uint32_t) data; DMA1_Channel5->CMAR = (uint32_t) data;
DMA1_Channel5->CNDTR = n; DMA1_Channel5->CNDTR = n;
// check if user want to receive data // check if user want to receive data
@ -130,8 +127,7 @@ int spi_read(uint8_t *data, uint32_t n){
} }
if(!spi_waitbsy()) return 0; if(!spi_waitbsy()) return 0;
// clear SPI Rx FIFO // clear SPI Rx FIFO
(void) SPI2->DR; for(int i = 0; i < 4; ++i) (void) SPI2->DR;
while(SPI2->SR & SPI_SR_RXNE) (void) SPI2->DR;
for(uint32_t x = 0; x < n; ++x){ for(uint32_t x = 0; x < n; ++x){
WAITX(!(SPI2->SR & SPI_SR_TXE)); WAITX(!(SPI2->SR & SPI_SR_TXE));
SPIDR = 0; SPIDR = 0;

View File

@ -1,2 +1,2 @@
#define BUILD_NUMBER "217" #define BUILD_NUMBER "242"
#define BUILD_DATE "2023-05-11" #define BUILD_DATE "2023-05-11"