NanoVNA/ili9431.c

739 lines
16 KiB
C
Raw Normal View History

2016-09-28 15:48:53 +02:00
#include <math.h>
2016-09-26 17:06:00 +02:00
#include "ch.h"
#include "hal.h"
#include "chprintf.h"
2016-09-26 17:06:00 +02:00
#include "nanovna.h"
#define RESET_ASSERT palClearPad(GPIOA, 15)
#define RESET_NEGATE palSetPad(GPIOA, 15)
#define CS_LOW palClearPad(GPIOB, 6)
#define CS_HIGH palSetPad(GPIOB, 6)
#define DC_CMD palClearPad(GPIOB, 7)
#define DC_DATA palSetPad(GPIOB, 7)
2016-10-04 01:16:01 +02:00
#define RGB565(b,r,g) ( (((b)<<8)&0xfc00) | (((r)<<2)&0x03e0) | (((g)>>3)&0x001f) )
2016-09-26 17:06:00 +02:00
uint16_t spi_buffer[1024];
void draw_frequencies(void);
2016-09-26 17:06:00 +02:00
static const SPIConfig spicfg = {
NULL,
GPIOB,
6,
0,
SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0
};
void
ssp_wait(void)
{
while (SPI1->SR & SPI_SR_BSY)
;
}
void
ssp_wait_slot(void)
{
while ((SPI1->SR & 0x1800) == 0x1800)
;
}
void
ssp_senddata(uint8_t x)
{
*(uint8_t*)(&SPI1->DR) = x;
while (SPI1->SR & SPI_SR_BSY)
;
}
void
ssp_senddata16(uint16_t x)
{
ssp_wait_slot();
SPI1->DR = x;
//while (SPI1->SR & SPI_SR_BSY)
// ;
}
void
ssp_databit8(void)
{
SPI1->CR2 = (SPI1->CR2 & 0xf0ff) | 0x0700;
//LPC_SSP1->CR0 = (LPC_SSP1->CR0 & 0xf0) | SSP_DATABIT_8;
}
void
ssp_databit16(void)
{
SPI1->CR2 = (SPI1->CR2 & 0xf0ff) | 0x0f00;
//LPC_SSP1->CR0 = (LPC_SSP1->CR0 & 0xf0) | SSP_DATABIT_16;
}
2016-10-04 01:16:01 +02:00
const stm32_dma_stream_t *dmatx;
uint32_t txdmamode;
static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) {
(void)spip;
(void)flags;
}
2016-09-26 17:06:00 +02:00
void
spi_init(void)
{
rccEnableSPI1(FALSE);
2016-10-04 01:16:01 +02:00
dmatx = STM32_DMA_STREAM(STM32_SPI_SPI1_TX_DMA_STREAM);
txdmamode = STM32_DMA_CR_CHSEL(SPI1_TX_DMA_CHANNEL) |
STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) |
STM32_DMA_CR_DIR_M2P |
STM32_DMA_CR_DMEIE |
STM32_DMA_CR_TEIE |
STM32_DMA_CR_PSIZE_HWORD |
STM32_DMA_CR_MSIZE_HWORD;
dmaStreamAllocate(dmatx,
STM32_SPI_SPI1_IRQ_PRIORITY,
(stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
NULL);
dmaStreamSetPeripheral(dmatx, &SPI1->DR);
2016-09-26 17:06:00 +02:00
//spiStart(&SPID1, &spicfg); /* Setup transfer parameters. */
SPI1->CR1 = 0;
SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_BIDIOE | SPI_CR1_SSM | SPI_CR1_SSI;// | SPI_CR1_BR_1;
2016-10-04 01:16:01 +02:00
SPI1->CR2 = 0x0700 | SPI_CR2_TXDMAEN;
2016-09-26 17:06:00 +02:00
SPI1->CR1 |= SPI_CR1_SPE;
}
#if 0
void
spi_test(void)
{
spiSelect(&SPID1); /* Slave Select assertion. */
spiSend(&SPID1, 512, txbuf); /* Atomic transfer operations. */
spiUnselect(&SPID1); /* Slave Select de-assertion. */
}
#endif
void
send_command(uint8_t cmd, int len, const uint8_t *data)
{
CS_LOW;
DC_CMD;
ssp_databit8();
ssp_senddata(cmd);
DC_DATA;
while (len-- > 0) {
ssp_senddata(*data++);
}
//CS_HIGH;
}
void
send_command16(uint8_t cmd, int data)
{
CS_LOW;
DC_CMD;
ssp_databit8();
ssp_senddata(cmd);
DC_DATA;
ssp_databit16();
ssp_senddata16(data);
CS_HIGH;
}
const uint8_t ili9341_init_seq[] = {
// cmd, len, data...,
// Power control B
0xCF, 3, 0x00, 0x83, 0x30,
// Power on sequence control
0xED, 4, 0x64, 0x03, 0x12, 0x81,
//0xED, 4, 0x55, 0x01, 0x23, 0x01,
// Driver timing control A
0xE8, 3, 0x85, 0x01, 0x79,
//0xE8, 3, 0x84, 0x11, 0x7a,
// Power control A
0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
// Pump ratio control
0xF7, 1, 0x20,
// Driver timing control B
0xEA, 2, 0x00, 0x00,
// POWER_CONTROL_1
0xC0, 1, 0x26,
// POWER_CONTROL_2
0xC1, 1, 0x11,
// VCOM_CONTROL_1
0xC5, 2, 0x35, 0x3E,
// VCOM_CONTROL_2
0xC7, 1, 0xBE,
// MEMORY_ACCESS_CONTROL
//0x36, 1, 0x48, // portlait
0x36, 1, 0x28, // landscape
// COLMOD_PIXEL_FORMAT_SET : 16 bit pixel
0x3A, 1, 0x55,
// Frame Rate
0xB1, 2, 0x00, 0x1B,
// Gamma Function Disable
0xF2, 1, 0x08,
// gamma set for curve 01/2/04/08
0x26, 1, 0x01,
// positive gamma correction
0xE0, 15, 0x1F, 0x1A, 0x18, 0x0A, 0x0F, 0x06, 0x45, 0x87, 0x32, 0x0A, 0x07, 0x02, 0x07, 0x05, 0x00,
// negativ gamma correction
0xE1, 15, 0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3A, 0x78, 0x4D, 0x05, 0x18, 0x0D, 0x38, 0x3A, 0x1F,
// Column Address Set
0x2A, 4, 0x00, 0x00, 0x01, 0x3f, // width 320
// Page Address Set
0x2B, 4, 0x00, 0x00, 0x00, 0xef, // height 240
// entry mode
0xB7, 1, 0x06,
// display function control
0xB6, 4, 0x0A, 0x82, 0x27, 0x00,
// sleep out
0x11, 0,
0 // sentinel
};
void
ili9341_init(void)
{
//spiAcquireBus(&SPID1); /* Acquire ownership of the bus. */
spi_init();
DC_DATA;
RESET_ASSERT;
chThdSleepMilliseconds(10);
RESET_NEGATE;
send_command(0x01, 0, NULL); // SW reset
chThdSleepMilliseconds(5);
send_command(0x28, 0, NULL); // display off
const uint8_t *p;
for (p = ili9341_init_seq; *p; ) {
send_command(p[0], p[1], &p[2]);
p += 2 + p[1];
chThdSleepMilliseconds(5);
}
chThdSleepMilliseconds(100);
send_command(0x29, 0, NULL); // display on
//spiReleaseBus(&SPID1); /* Ownership release. */
}
void ili9341_pixel(int x, int y, int color)
{
uint8_t xx[4] = { x >> 8, x, (x+1) >> 8, (x+1) };
uint8_t yy[4] = { y >> 8, y, (y+1) >> 8, (y+1) };
uint8_t cc[2] = { color >> 8, color };
send_command(0x2A, 4, xx);
send_command(0x2B, 4, yy);
send_command(0x2C, 2, cc);
//send_command16(0x2C, color);
}
2016-09-26 17:06:00 +02:00
void ili9341_fill(int x, int y, int w, int h, int color)
{
2016-09-28 01:47:46 +02:00
uint8_t xx[4] = { x >> 8, x, (x+w-1) >> 8, (x+w-1) };
uint8_t yy[4] = { y >> 8, y, (y+h-1) >> 8, (y+h-1) };
2016-09-26 17:06:00 +02:00
int len = w * h;
send_command(0x2A, 4, xx);
send_command(0x2B, 4, yy);
send_command(0x2C, 0, NULL);
while (len-- > 0)
ssp_senddata16(color);
}
2016-10-04 01:16:01 +02:00
#if 0
2016-09-28 01:47:46 +02:00
void ili9341_bulk(int x, int y, int w, int h)
{
uint8_t xx[4] = { x >> 8, x, (x+w-1) >> 8, (x+w-1) };
uint8_t yy[4] = { y >> 8, y, (y+h-1) >> 8, (y+h-1) };
uint16_t *buf = spi_buffer;
int len = w * h;
send_command(0x2A, 4, xx);
send_command(0x2B, 4, yy);
send_command(0x2C, 0, NULL);
while (len-- > 0)
ssp_senddata16(*buf++);
}
2016-10-04 01:16:01 +02:00
#else
void ili9341_bulk(int x, int y, int w, int h)
{
uint8_t xx[4] = { x >> 8, x, (x+w-1) >> 8, (x+w-1) };
uint8_t yy[4] = { y >> 8, y, (y+h-1) >> 8, (y+h-1) };
int len = w * h;
send_command(0x2A, 4, xx);
send_command(0x2B, 4, yy);
send_command(0x2C, 0, NULL);
dmaStreamSetMemory0(dmatx, spi_buffer);
dmaStreamSetTransactionSize(dmatx, len);
dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_MINC);
dmaStreamEnable(dmatx);
dmaWaitCompletion(dmatx);
}
#endif
#define SWAP(x,y) do { int z=x; x = y; y = z; } while(0)
void
ili9341_line(int x0, int y0, int x1, int y1, uint16_t fg)
{
if (x0 > x1) {
SWAP(x0, x1);
SWAP(y0, y1);
}
while (x0 <= x1) {
int dx = x1 - x0 + 1;
int dy = y1 - y0;
if (dy >= 0) {
dy++;
if (dy > dx) {
dy /= dx; dx = 1;
} else {
dx /= dy; dy = 1;
}
} else {
dy--;
if (-dy > dx) {
dy /= dx; dx = 1;
} else {
dx /= -dy; dy = -1;
}
}
if (dy > 0)
ili9341_fill(x0, y0, dx, dy, fg);
else
ili9341_fill(x0, y0+dy, dx, -dy, fg);
x0 += dx;
y0 += dy;
}
}
2016-09-28 01:47:46 +02:00
2016-09-26 17:06:00 +02:00
typedef struct {
uint16_t width;
uint16_t height;
uint16_t scaley;
uint16_t slide;
const uint32_t *bitmap;
} font_t;
const font_t NF20x24 = { 20, 24, 1, 24, (const uint32_t *)numfont20x24 };
//const font_t NF32x24 = { 32, 24, 1, 24, (const uint32_t *)numfont32x24 };
//const font_t NF32x48 = { 32, 48, 2, 24, (const uint32_t *)numfont32x24 };
void
ili9341_drawfont(uint8_t ch, const font_t *font, int x, int y, uint16_t fg, uint16_t bg)
{
int ex = x + font->width-1;
int ey = y + font->height-1;
uint8_t xx[4] = { x >> 8, x, ex >> 8, ex };
uint8_t yy[4] = { y >> 8, y, ey >> 8, ey };
uint16_t *buf = spi_buffer;
uint32_t bits;
const uint32_t *bitmap = &font->bitmap[font->slide * ch];
int len;
int c, r, j;
for (c = 0; c < font->slide; c++) {
for (j = 0; j < font->scaley; j++) {
bits = bitmap[c];
for (r = 0; r < font->width; r++) {
*buf++ = (0x80000000UL & bits) ? fg : bg;
bits <<= 1;
}
}
}
send_command(0x2A, 4, xx);
send_command(0x2B, 4, yy);
send_command(0x2C, 0, NULL);
len = buf - spi_buffer;
buf = spi_buffer;
while (len-- > 0)
ssp_senddata16(*buf++);
}
2016-09-28 01:47:46 +02:00
2016-10-04 01:16:01 +02:00
#if 0
2016-09-28 01:47:46 +02:00
void
draw_grid(int n, int m, int w, int h, int x, int y, uint16_t fg, uint16_t bg)
{
int ww = w*n+1;
int hh = h*m+1;
int xx = x;
int yy = y;
int i;
ili9341_fill(x, y, ww, hh, bg);
for (i = 0; i <= n; i++) {
ili9341_fill(xx, y, 1, hh, fg);
xx += w;
}
for (i = 0; i <= m; i++) {
ili9341_fill(x, yy, ww, 1, fg);
yy += h;
}
}
2016-10-04 01:16:01 +02:00
#endif
2016-09-28 01:47:46 +02:00
2016-09-26 17:06:00 +02:00
const uint16_t colormap[] = {
RGB565(255,0,0), RGB565(0,255,0), RGB565(0,0,255),
RGB565(255,255,0), RGB565(0,255,255), RGB565(255,0,255)
};
void
ili9341_test(int mode)
{
int x, y;
int i;
switch (mode) {
default:
#if 1
ili9341_fill(0, 0, 320, 240, 0);
for (y = 0; y < 240; y++) {
ili9341_fill(0, y, 320, 1, RGB565(y, (y + 120) % 256, 240-y));
}
break;
case 1:
ili9341_fill(0, 0, 320, 240, 0);
for (y = 0; y < 240; y++) {
for (x = 0; x < 320; x++) {
ili9341_pixel(x, y, (y<<8)|x);
}
}
break;
case 2:
//send_command16(0x55, 0xff00);
ili9341_pixel(64, 64, 0xaa55);
break;
#endif
#if 1
case 3:
for (i = 0; i < 10; i++)
ili9341_drawfont(i, &NF20x24, i*20, 120, colormap[i%6], 0x0000);
break;
#endif
2016-10-04 01:16:01 +02:00
#if 0
2016-09-28 01:47:46 +02:00
case 4:
draw_grid(10, 8, 29, 29, 15, 0, 0xffff, 0);
break;
2016-10-04 01:16:01 +02:00
#endif
case 4:
ili9341_line(0, 0, 15, 100, 0xffff);
ili9341_line(0, 0, 100, 100, 0xffff);
ili9341_line(0, 15, 100, 0, 0xffff);
ili9341_line(0, 100, 100, 0, 0xffff);
break;
2016-09-28 01:47:46 +02:00
}
}
int prev_x;
int32_t fstart = 0;
2016-09-30 02:42:49 +02:00
int32_t fstop = 300000000;
int32_t fspan = 300000000;
int32_t fgrid = 50000000;
2016-10-04 01:16:01 +02:00
int grid_offset;
int grid_width;
2016-09-28 01:47:46 +02:00
#define OFFSETX 15
#define OFFSETY 0
#define WIDTH 291
#define HEIGHT 233
//#define GRID_COLOR 0x0863
uint16_t grid_color = 0x1084;
2016-09-30 02:42:49 +02:00
void set_sweep(int32_t start, int stop)
{
int32_t gdigit = 100000000;
int32_t grid;
fstart = start;
fstop = stop;
fspan = stop - start;
while (gdigit > 100) {
grid = 5 * gdigit;
if (fspan / grid >= 4)
2016-09-30 02:42:49 +02:00
break;
grid = 2 * gdigit;
if (fspan / grid >= 4)
2016-09-30 02:42:49 +02:00
break;
grid = gdigit;
if (fspan / grid >= 4)
2016-09-30 02:42:49 +02:00
break;
gdigit /= 10;
}
fgrid = grid;
2016-10-04 01:16:01 +02:00
grid_offset = (WIDTH-1) * ((fstart % fgrid) / 100) / (fspan / 100);
grid_width = (WIDTH-1) * (fgrid / 100) / (fspan / 100);
draw_frequencies();
2016-09-30 02:42:49 +02:00
}
2016-09-28 01:47:46 +02:00
int
2016-09-30 02:42:49 +02:00
circle_inout(int x, int y, int r)
2016-09-28 01:47:46 +02:00
{
int d = x*x + y*y - r*r;
if (d <= -r)
return 1;
2016-09-30 02:42:49 +02:00
if (d > r)
2016-09-28 01:47:46 +02:00
return -1;
return 0;
}
int
smith_grid(int x, int y)
{
2016-09-30 02:42:49 +02:00
int d = circle_inout(x-146, y-116, 116);
int c = grid_color;
2016-09-28 01:47:46 +02:00
if (d < 0)
return 0;
else if (d == 0)
return c;
x -= 146+116;
y -= 116;
2016-09-30 02:42:49 +02:00
if (circle_inout(x, y+58, 58) == 0)
2016-09-28 01:47:46 +02:00
return c;
2016-09-30 02:42:49 +02:00
if (circle_inout(x, y-58, 58) == 0)
2016-09-28 01:47:46 +02:00
return c;
2016-09-30 02:42:49 +02:00
d = circle_inout(x+29, y, 29);
2016-09-28 01:47:46 +02:00
if (d > 0) return 0;
if (d == 0) return c;
2016-09-30 02:42:49 +02:00
if (circle_inout(x, y+116, 116) == 0)
2016-09-28 01:47:46 +02:00
return c;
2016-09-30 02:42:49 +02:00
if (circle_inout(x, y-116, 116) == 0)
2016-09-28 01:47:46 +02:00
return c;
2016-09-30 02:42:49 +02:00
d = circle_inout(x+58, y, 58);
2016-09-28 01:47:46 +02:00
if (d > 0) return 0;
if (d == 0) return c;
2016-09-30 02:42:49 +02:00
if (circle_inout(x, y+232, 232) == 0)
2016-09-28 01:47:46 +02:00
return c;
2016-09-30 02:42:49 +02:00
if (circle_inout(x, y-232, 232) == 0)
2016-09-28 01:47:46 +02:00
return c;
2016-09-30 02:42:49 +02:00
if (circle_inout(x+87, y, 87) == 0)
2016-09-28 01:47:46 +02:00
return c;
return 0;
}
int
rectangular_grid(int x, int y)
{
2016-09-30 02:42:49 +02:00
#define FREQ(x) (((x) * (fspan / 1000) / (WIDTH-1)) * 1000 + fstart)
int c = grid_color;
2016-10-04 01:16:01 +02:00
//int32_t n = FREQ(x-1) / fgrid;
//int32_t m = FREQ(x) / fgrid;
//if ((m - n) > 0)
2016-09-30 02:42:49 +02:00
//if (((x * 6) % (WIDTH-1)) < 6)
2016-10-04 01:16:01 +02:00
if (((x - grid_offset) % grid_width) == 0)
2016-09-28 01:47:46 +02:00
return c;
if (x == 0 || x == (WIDTH-1))
return c;
2016-09-28 01:47:46 +02:00
if ((y % 29) == 0)
return c;
return 0;
}
int
set_strut_grid(int x)
{
uint16_t *buf = spi_buffer;
int y;
for (y = 0; y < HEIGHT; y++) {
int c = rectangular_grid(x, y);
2016-09-28 01:47:46 +02:00
c |= smith_grid(x, y);
*buf++ = c;
2016-09-26 17:06:00 +02:00
}
2016-09-28 01:47:46 +02:00
return y;
2016-09-26 17:06:00 +02:00
}
2016-09-28 01:47:46 +02:00
void
2016-09-28 16:33:43 +02:00
draw_on_strut(int v0, int d, int color)
2016-09-28 01:47:46 +02:00
{
2016-09-28 16:33:43 +02:00
int v;
int v1 = v0 + d;
2016-09-28 01:47:46 +02:00
if (v0 < 0) v0 = 0;
if (v1 < 0) v1 = 0;
if (v0 >= HEIGHT) v0 = HEIGHT-1;
if (v1 >= HEIGHT) v1 = HEIGHT-1;
if (v0 == v1) {
2016-09-30 02:42:49 +02:00
v = v0; d = 2;
2016-09-28 01:47:46 +02:00
} else if (v0 < v1) {
2016-09-30 02:42:49 +02:00
v = v0; d = v1 - v0 + 1;
2016-09-28 01:47:46 +02:00
} else {
2016-09-30 02:42:49 +02:00
v = v1; d = v0 - v1 + 1;
2016-09-28 01:47:46 +02:00
}
while (d-- > 0)
2016-10-04 01:16:01 +02:00
spi_buffer[v++] |= color;
2016-09-28 01:47:46 +02:00
}
2016-10-04 01:16:01 +02:00
#define TRACES_MAX 4
2016-09-28 16:33:43 +02:00
struct {
2016-10-04 01:16:01 +02:00
int enabled;
2016-09-28 16:33:43 +02:00
float value;
float prev_value;
float d;
uint16_t color;
2016-10-04 01:16:01 +02:00
} trace[TRACES_MAX] = {
{ 1, 0, 0, 0, RGB565(0,255,255) },
{ 1, 0, 0, 0, RGB565(255,0,40) },
{ 0, 0, 0, 0, RGB565(0,0,255) },
{ 0, 0, 0, 0, RGB565(0,255,0) }
2016-09-28 16:33:43 +02:00
};
float logmag(float *v)
{
return 11 - log10f(v[0]*v[0] + v[1]*v[1]);
}
2016-10-04 01:16:01 +02:00
float phase(float *v)
{
return 4 + 2 * atan2f(v[1], v[0]) / M_PI;
}
void sweep_plot(int32_t freq, int first, float *measured)
2016-09-28 01:47:46 +02:00
{
2016-09-30 02:42:49 +02:00
int curr_x = ((float)WIDTH * (freq - fstart) / fspan);
2016-10-04 01:16:01 +02:00
int i;
if (trace[0].enabled)
trace[0].value = logmag(&measured[0]) * 29;
if (trace[1].enabled)
trace[1].value = logmag(&measured[2]) * 29;
if (trace[2].enabled)
trace[2].value = phase(&measured[0]) * 29;
if (trace[3].enabled)
trace[3].value = phase(&measured[2]) * 29;
2016-09-28 01:47:46 +02:00
if (first) {
prev_x = 0;
while (prev_x < curr_x) {
int len = set_strut_grid(prev_x);
ili9341_bulk(OFFSETX + prev_x, OFFSETY, 1, len);
prev_x++;
}
} else {
int w = curr_x - prev_x;
2016-10-04 01:16:01 +02:00
for (i = 0; i < TRACES_MAX; i++)
if (trace[i].enabled)
trace[i].d = (trace[i].value - trace[i].prev_value) / w;
2016-09-28 01:47:46 +02:00
while (prev_x < curr_x) {
int len = set_strut_grid(prev_x);
2016-10-04 01:16:01 +02:00
for (i = 0; i < TRACES_MAX; i++)
if (trace[i].enabled) {
draw_on_strut(trace[i].prev_value, trace[i].d, trace[i].color);
trace[i].prev_value += trace[i].d;
}
2016-09-28 01:47:46 +02:00
ili9341_bulk(OFFSETX + prev_x, OFFSETY, 1, len);
prev_x++;
}
}
2016-10-04 01:16:01 +02:00
for (i = 0; i < TRACES_MAX; i++)
if (trace[i].enabled)
trace[i].prev_value = trace[i].value;
2016-09-28 01:47:46 +02:00
}
void sweep_tail()
{
while (prev_x < WIDTH) {
int len = set_strut_grid(prev_x);
ili9341_bulk(OFFSETX + prev_x, OFFSETY, 1, len);
prev_x++;
}
}
2016-10-04 01:16:01 +02:00
void
cartesian_scale(float re, float im, int *xp, int *yp)
{
float scale = 4e-3;
int x = WIDTH / 2 - re * scale;
int y = HEIGHT / 2 + im * scale;
if (x < 0) x = 0;
if (y < 0) y = 0;
if (x > WIDTH) x = WIDTH;
if (y > HEIGHT) y = HEIGHT;
*xp = OFFSETX + x;
*yp = OFFSETY + y;
}
void polar_plot(float measured[101][4])
{
int x0, y0;
int i;
cartesian_scale(measured[0][1], measured[0][0], &x0, &y0);
for (i = 1; i < 101; i++) {
int x1, y1;
cartesian_scale(measured[i][1], measured[i][0], &x1, &y1);
ili9341_line(x0, y0, x1, y1, trace[2].color);
x0 = x1;
y0 = y1;
}
}
2016-09-26 17:06:00 +02:00
void
ili9341_drawchar_5x7(uint8_t ch, int x, int y, uint16_t fg, uint16_t bg)
2016-09-26 17:06:00 +02:00
{
uint16_t *buf = spi_buffer;
uint16_t bits;
int c, r;
for(c = 0; c < 7; c++) {
bits = x5x7_bits[(ch * 7) + c];
for (r = 0; r < 5; r++) {
*buf++ = (0x8000 & bits) ? fg : bg;
bits <<= 1;
}
2016-09-26 17:06:00 +02:00
}
ili9341_bulk(x, y, 5, 7);
2016-09-26 17:06:00 +02:00
}
void
ili9341_drawstring_5x7(char *str, int x, int y, uint16_t fg, uint16_t bg)
2016-09-26 17:06:00 +02:00
{
while (*str) {
ili9341_drawchar_5x7(*str, x, y, fg, bg);
x += 5;
str++;
}
2016-09-26 17:06:00 +02:00
}
void
draw_frequencies(void)
2016-09-26 17:06:00 +02:00
{
char buf[24];
chsnprintf(buf, 24, "START%3d.%03d %03d MHz",
(int)(fstart / 1000000),
(int)((fstart / 1000) % 1000),
(int)(fstart % 1000));
ili9341_drawstring_5x7(buf, OFFSETX, 233, 0xffff, 0x0000);
chsnprintf(buf, 24, "STOP %3d.%03d %03d MHz",
(int)(fstop / 1000000),
(int)((fstop / 1000) % 1000),
(int)(fstop % 1000));
ili9341_drawstring_5x7(buf, 205, 233, 0xffff, 0x0000);
2016-09-26 17:06:00 +02:00
}
void
redraw(void)
2016-09-26 17:06:00 +02:00
{
ili9341_fill(0, 0, 320, 240, 0);
draw_frequencies();
2016-09-26 17:06:00 +02:00
}