Merged DiSlord optimizations

Removed_REF_marker
erikkaashoek 5 years ago
parent 7a7bfd838d
commit 74017052d5

@ -26,11 +26,6 @@
#include "spi.h"
// Allow enable DMA for read display data
#ifdef TINYSA4
#define __USE_DISPLAY_DMA_RX__
#endif
// Pin macros for LCD
#ifdef TINYSA4
#define LCD_CS_LOW palClearPad(GPIO_LCD_CS_PORT, GPIO_LCD_CS)
@ -48,12 +43,31 @@
#define LCD_DC_DATA palSetPad(GPIOB, GPIOB_LCD_CD)
#endif
// LCD display SPI bus
#define LCD_SPI SPI1
// Custom display definition
#ifdef LCD_DRIVER_ILI9341
// Set SPI bus speed for LCD
#define LCD_SPI_SPEED SPI_BR_DIV2
//Not define if need use some as Tx speed
#ifdef TINYSA4
// Read speed, need more slow, not define if need use some as Tx speed
//#define LCD_SPI_RX_SPEED SPI_BR_DIV4
// Allow enable DMA for read display data (can not stable on full speed, on less speed slower)
#define __USE_DISPLAY_DMA_RX__
#endif
#ifdef LCD_DRIVER_ST7796S
// Set SPI bus speed for LCD
#define LCD_SPI_SPEED SPI_BR_DIV2
// Read speed, need more slow, not define if need use some as Tx speed
#define LCD_SPI_RX_SPEED SPI_BR_DIV4
// Allow enable DMA for read display data
#define __USE_DISPLAY_DMA_RX__
#endif
// Disable DMA rx on disabled DMA tx
#ifndef __USE_DISPLAY_DMA__
#undef __USE_DISPLAY_DMA_RX__
#endif
pixel_t spi_buffer[SPI_BUFFER_SIZE];
@ -167,6 +181,50 @@ pixel_t background_color = 0;
#define DISPLAY_ROTATION_180 (ILI9341_MADCTL_MX | ILI9341_MADCTL_MY \
| ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR)
//*****************************************************
// SPI bus functions, data
//*****************************************************
// SPI transmit byte to SPI (no wait complete transmit)
void spi_TxByte(uint8_t data) {
SPI_WRITE_8BIT(LCD_SPI, data);
}
// Transmit word to SPI bus (if SPI in 8 bit mode LSB send first!!!!!)
void spi_TxWord(uint16_t data) {
SPI_WRITE_16BIT(LCD_SPI, data);
}
// Transmit buffer to SPI bus (len should be > 0)
void spi_TxBuffer(uint8_t *buffer, uint16_t len) {
do {
while (SPI_TX_IS_NOT_EMPTY(LCD_SPI));
SPI_WRITE_8BIT(LCD_SPI, *buffer++);
}while(--len);
}
// Receive byte from SPI bus
uint8_t spi_RxByte(void) {
// Start RX clock (by sending data)
SPI_WRITE_8BIT(LCD_SPI, 0xFF);
while (SPI_RX_IS_EMPTY(LCD_SPI)||SPI_IS_BUSY(LCD_SPI));
return SPI_READ_8BIT(LCD_SPI);
}
// Receive buffer from SPI bus (len should be > 0)
void spi_RxBuffer(uint8_t *buffer, uint16_t len) {
do{
SPI_WRITE_8BIT(LCD_SPI, 0xFF);
while (SPI_RX_IS_EMPTY(LCD_SPI));
*buffer++ = SPI_READ_8BIT(LCD_SPI);
}while(--len);
}
void spi_DropRx(void){
// Drop Rx buffer after tx and wait tx complete
while (SPI_RX_IS_NOT_EMPTY(LCD_SPI)||SPI_IS_BUSY(LCD_SPI))
(void)SPI_READ_8BIT(LCD_SPI);
}
//*****************************************************
// SPI DMA settings and data
//*****************************************************
@ -187,7 +245,6 @@ static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags)
}
#endif
#ifdef __USE_DISPLAY_DMA_RX__
static const stm32_dma_stream_t *dmarx = STM32_DMA_STREAM(STM32_SPI_SPI1_RX_DMA_STREAM);
static const uint32_t rxdmamode =
STM32_DMA_CR_CHSEL(SPI1_RX_DMA_CHANNEL) // Select SPI1 Rx DMA
@ -202,7 +259,6 @@ static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags)
(void)flags;
}
#endif
#endif
// Send prepared DMA data, and wait completion
static void dmaStreamFlush(uint32_t len)
@ -216,60 +272,16 @@ static void dmaStreamFlush(uint32_t len)
dmaWaitCompletion(dmatx);
}
}
#endif
// SPI transmit byte to SPI (no wait complete transmit)
void spi_TxByte(uint8_t data) {
SPI_WRITE_8BIT(LCD_SPI, data);
}
// Transmit word to SPI bus (if SPI in 8 bit mode LSB send first!!!!!)
void spi_TxWord(uint16_t data) {
SPI_WRITE_16BIT(LCD_SPI, data);
}
// Transmit buffer to SPI bus (len should be > 0)
void spi_TxBuffer(uint8_t *buffer, uint16_t len) {
do {
while (SPI_TX_IS_NOT_EMPTY(LCD_SPI));
SPI_WRITE_8BIT(LCD_SPI, *buffer++);
}while(--len);
}
// Receive byte from SPI bus
uint8_t spi_RxByte(void) {
// Start RX clock (by sending data)
SPI_WRITE_8BIT(LCD_SPI, 0xFF);
while (SPI_RX_IS_EMPTY(LCD_SPI)||SPI_IS_BUSY(LCD_SPI));
return SPI_READ_8BIT(LCD_SPI);
}
// Receive buffer from SPI bus (len should be > 0)
void spi_RxBuffer(uint8_t *buffer, uint16_t len) {
do{
SPI_WRITE_8BIT(LCD_SPI, 0xFF);
while (SPI_RX_IS_EMPTY(LCD_SPI));
*buffer++ = SPI_READ_8BIT(LCD_SPI);
}while(--len);
}
void spi_DropRx(void){
// Drop Rx buffer after tx and wait tx complete
while (SPI_RX_IS_NOT_EMPTY(LCD_SPI)||SPI_IS_BUSY(LCD_SPI))
(void)SPI_READ_8BIT(LCD_SPI);
}
#ifdef __USE_DISPLAY_DMA__
// SPI receive byte buffer use DMA
void spi_DMATxBuffer(uint8_t *buffer, uint16_t len) {
dmaStreamSetMemory0(dmatx, buffer);
dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_MINC);
dmaStreamFlush(len);
}
#ifdef __USE_DISPLAY_DMA_RX__
#if 0 // Not used
// SPI transmit byte buffer use DMA
static void spi_DMARxBuffer(uint8_t *buffer, uint16_t len) {
void spi_DMARxBuffer(uint8_t *buffer, uint16_t len) {
uint8_t dummy_tx = 0xFF;
// Init Rx DMA buffer, size, mode (spi and mem data size is 8 bit)
dmaStreamSetMemory0(dmarx, buffer);
@ -288,9 +300,7 @@ static void spi_DMARxBuffer(uint8_t *buffer, uint16_t len) {
dmaWaitCompletion(dmatx);
dmaWaitCompletion(dmarx);
}
#endif // 0
#endif // __USE_DISPLAY_DMA_RX__
#endif // __USE_DISPLAY_DMA__
#endif // __USE_DISPLAY_DMA__
static void spi_init(void)
{
@ -375,7 +385,7 @@ static void send_command(uint8_t cmd, uint8_t len, const uint8_t *data)
//LCD_CS_HIGH;
}
#ifdef TINYSA4
#ifdef LCD_DRIVER_ST7796S
static const uint8_t ST7796S_init_seq[] = {
// SW reset
ILI9341_SOFTWARE_RESET, 0,
@ -419,7 +429,10 @@ static const uint8_t ST7796S_init_seq[] = {
ILI9341_DISPLAY_ON, 0,
0 // sentinel
};
#else
#define LCD_INIT ST7796S_init_seq
#endif
#ifdef LCD_DRIVER_ILI9341
static const uint8_t ili9341_init_seq[] = {
// cmd, len, data...,
// SW reset
@ -462,9 +475,9 @@ static const uint8_t ili9341_init_seq[] = {
// negativ gamma correction
ILI9341_NEGATIVE_GAMMA_CORRECTION, 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F,
// Column Address Set
//ILI9341_COLUMN_ADDRESS_SET, 4, 0x00, 0x00, 0x01, 0x3f, // width 320
// ILI9341_COLUMN_ADDRESS_SET, 4, 0x00, 0x00, 0x01, 0x3f, // width 320
// Page Address Set
//ILI9341_PAGE_ADDRESS_SET, 4, 0x00, 0x00, 0x00, 0xef, // height 240
// ILI9341_PAGE_ADDRESS_SET, 4, 0x00, 0x00, 0x00, 0xef, // height 240
// entry mode
ILI9341_ENTRY_MODE_SET, 1, 0x06,
// display function control
@ -477,7 +490,7 @@ static const uint8_t ili9341_init_seq[] = {
ILI9341_DISPLAY_ON, 0,
0 // sentinel
};
#define LCD_INIT ili9341_init_seq
#endif
void ili9341_init(void)
@ -488,22 +501,16 @@ void ili9341_init(void)
chThdSleepMilliseconds(10);
LCD_RESET_NEGATE;
const uint8_t *p;
#ifdef TINYSA4
p = ST7796S_init_seq;
#else
p = ili9341_init_seq;
#endif
while (*p) {
for (p = LCD_INIT; *p; ) {
send_command(p[0], p[1], &p[2]);
p += 2 + p[1];
chThdSleepMilliseconds(5);
}
#ifdef TINYSA4
// ili9341_clear_screen();
LCD_CS_HIGH;
#endif
}
static void ili9341_setWindow(int x, int y, int w, int h){
static void ili9341_setWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t 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) };
uint32_t xx = __REV16(x | ((x + w - 1) << 16));
@ -512,49 +519,20 @@ static void ili9341_setWindow(int x, int y, int w, int h){
send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t *)&yy);
}
#if 0
// Test code for palette mode
void ili9341_bulk_8bit(int x, int y, int w, int h, pixel_t *palette)
{
ili9341_setWindow(x, y ,w, h);
send_command(ILI9341_MEMORY_WRITE, 0, NULL);
uint8_t *buf = (uint8_t *)spi_buffer;
int32_t len = w * h;
while (len-- > 0)
spi_TxWord(palette[*buf++]);
// LCD_CS_HIGH;
}
#endif
#if DISPLAY_CELL_BUFFER_COUNT != 1
#define LCD_BUFFER_1 0x01
#define LCD_DMA_RUN 0x02
static uint8_t LCD_dma_status = 0;
#endif
pixel_t *ili9341_get_cell_buffer(void){
#if DISPLAY_CELL_BUFFER_COUNT == 1
return spi_buffer;
#else
return &spi_buffer[(LCD_dma_status&LCD_BUFFER_1) ? SPI_BUFFER_SIZE/2 : 0];
#endif
}
#ifndef __USE_DISPLAY_DMA__
void ili9341_fill(int x, int y, int w, int h, pixel_t color)
void ili9341_fill(int x, int y, int w, int h)
{
ili9341_setWindow(x, y ,w, h);
ili9341_setWindow(x, y, w, h);
send_command(ILI9341_MEMORY_WRITE, 0, NULL);
uint32_t len = w * h;
do {
while (SPI_TX_IS_NOT_EMPTY(LCD_SPI))
;
SPI_WRITE_16BIT(LCD_SPI, color);
SPI_WRITE_16BIT(LCD_SPI, background_color);
}while(--len);
#ifdef __REMOTE_DESKTOP__
if (auto_capture) {
send_region("fill", x,y,w,h);
send_region("fill", x, y, w, h);
send_buffer((uint8_t *)&background_color, 2);
}
#endif
@ -562,26 +540,18 @@ void ili9341_fill(int x, int y, int w, int h, pixel_t color)
void ili9341_bulk(int x, int y, int w, int h)
{
ili9341_setWindow(x, y ,w, h);
ili9341_setWindow(x, y, w, h);
send_command(ILI9341_MEMORY_WRITE, 0, NULL);
spi_TxBuffer((uint8_t *)spi_buffer, w * h * sizeof(pixel_t));
#ifdef __REMOTE_DESKTOP__
if (auto_capture) {
send_region("bulk", x,y,w,h);
send_buffer((uint8_t *)buffer, w *h * sizeof(pixel_t));
send_region("bulk", x, y, w, h);
send_buffer((uint8_t *)buffer, w * h * sizeof(pixel_t));
}
#endif
}
void ili9341_bulk_continue(int x, int y, int w, int h){
ili9341_bulk(x, y, w, h);
}
void ili9341_bulk_finish(void){
while (SPI_IS_BUSY(LCD_SPI)); // Wait tx
}
#else
#else // LCD DMA mode
//
// Use DMA for send data
//
@ -602,12 +572,7 @@ void ili9341_fill(int x, int y, int w, int h)
dmaStreamFlush(w * h);
}
void ili9341_bulk_finish(void){
dmaWaitCompletion(dmatx); // Wait DMA
while (SPI_IN_TX_RX(LCD_SPI)); // Wait tx
}
static void ili9341_DMA_bulk(int x, int y, int w, int h, pixel_t *buffer){
static void ili9341_DMA_bulk(uint16_t x, uint16_t y, uint16_t w, uint16_t h, pixel_t *buffer){
ili9341_setWindow(x, y ,w, h);
send_command(ILI9341_MEMORY_WRITE, 0, NULL);
@ -626,28 +591,46 @@ static void ili9341_DMA_bulk(int x, int y, int w, int h, pixel_t *buffer){
// Copy spi_buffer to region
void ili9341_bulk(int x, int y, int w, int h)
{
ili9341_DMA_bulk(x, y ,w, h, spi_buffer); // Send data
ili9341_bulk_finish(); // Wait
ili9341_DMA_bulk(x, y, w, h, spi_buffer); // Send data
dmaWaitCompletion(dmatx);
}
// Used only in double buffer mode
#ifndef ili9341_get_cell_buffer
#define LCD_BUFFER_1 0x01
#define LCD_DMA_RUN 0x02
static uint8_t LCD_dma_status = 0;
// Return free buffer for render
pixel_t *ili9341_get_cell_buffer(void){
return &spi_buffer[(LCD_dma_status&LCD_BUFFER_1) ? SPI_BUFFER_SIZE/2 : 0];
}
#endif
// Wait completion before next data send
#ifndef ili9341_bulk_finish
void ili9341_bulk_finish(void){
dmaWaitCompletion(dmatx); // Wait DMA
//while (SPI_IN_TX_RX(LCD_SPI)); // Wait tx
}
#endif
// Copy part of spi_buffer to region, no wait completion after if buffer count !=1
#ifndef ili9341_bulk_continue
void ili9341_bulk_continue(int x, int y, int w, int h)
{
#if DISPLAY_CELL_BUFFER_COUNT == 1
ili9341_bulk(x, y, w, h);
#else
ili9341_bulk_finish(); // Wait DMA
ili9341_DMA_bulk(x, y , w, h, ili9341_get_cell_buffer()); // Send new cell data
LCD_dma_status^=LCD_BUFFER_1; // Switch buffer
#endif
ili9341_bulk_finish(); // Wait DMA
ili9341_DMA_bulk(x, y, w, h, ili9341_get_cell_buffer()); // Send new cell data
LCD_dma_status^=LCD_BUFFER_1; // Switch buffer
}
#endif
#endif // end LCD DMA mode
#ifndef __USE_DISPLAY_DMA_RX__
void ili9341_read_memory(int x, int y, int w, int h, int len, pixel_t *out)
#ifdef LCD_DRIVER_ILI9341
// ILI9341 send data in RGB888 format, need parse it
// Copy ILI9341 screen data to buffer
void ili9341_read_memory(int x, int y, int w, int h, uint16_t *out)
{
ili9341_setWindow(x, y ,w, h);
uint16_t len = w * h;
ili9341_setWindow(x, y, w, h);
send_command(ILI9341_MEMORY_READ, 0, NULL);
// Skip data from rx buffer
spi_DropRx();
@ -657,87 +640,58 @@ void ili9341_read_memory(int x, int y, int w, int h, int len, pixel_t *out)
#endif
// require 8bit dummy clock
spi_RxByte();
#ifdef TINYSA4
// receive pixel data to buffer
spi_RxBuffer((uint8_t *)out, len * 2);
#ifndef __USE_DISPLAY_DMA_RX__
spi_RxBuffer((uint8_t *)out, len * 3);
#else
while (len-- > 0) {
uint8_t r, g, b;
// read data is always 18bit
r = spi_RxByte();
g = spi_RxByte();
b = spi_RxByte();
*out++ = RGB565(r, g, b);
}
spi_DMARxBuffer((uint8_t *)out, len * 3);
#endif
// restore speed if need
#ifdef LCD_SPI_RX_SPEED
SPI_BR_SET(LCD_SPI, LCD_SPI_SPEED);
#endif
LCD_CS_HIGH;
// Parse received data to RGB565 format
uint8_t *rgbbuf = (uint8_t *)out;
while (len-- > 0) {
uint8_t r, g, b;
// read data is always 18bit
r = rgbbuf[0];
g = rgbbuf[1];
b = rgbbuf[2];
*out++ = RGB565(r, g, b);
rgbbuf += 3;
}
}
#endif
#else
// Copy screen data to buffer
// Warning!!! buffer size must be greater then 3*len + 1 bytes
void ili9341_read_memory(int x, int y, int w, int h, int len, pixel_t *out)
#ifdef LCD_DRIVER_ST7796S
// ST7796S send data in RGB565 format, not need parse it
// Copy ST7796S screen data to buffer
void ili9341_read_memory(int x, int y, int w, int h, uint16_t *out)
{
uint16_t dummy_tx = 0;
uint8_t *rgbbuf = (uint8_t *)out;
#ifdef TINYSA4
uint16_t data_size = len * 2;
//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) };
uint32_t xx = __REV16(x | ((x + w - 1) << 16));
uint32_t yy = __REV16(y | ((y + h - 1) << 16));
send_command(ILI9341_COLUMN_ADDRESS_SET, 4, (uint8_t *)&xx);
send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t *)&yy);
#else
uint16_t data_size = len * 3;
ili9341_setWindow(x, y ,w, h);
#endif
uint16_t len = w * h;
ili9341_setWindow(x, y, w, h);
send_command(ILI9341_MEMORY_READ, 0, NULL);
// Init Rx DMA buffer, size, mode (spi and mem data size is 8 bit)
dmaStreamSetMemory0(dmarx, rgbbuf);
dmaStreamSetTransactionSize(dmarx, data_size);
dmaStreamSetMode(dmarx, rxdmamode | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_MINC);
// Init dummy Tx DMA (for rx clock), size, mode (spi and mem data size is 8 bit)
dmaStreamSetMemory0(dmatx, &dummy_tx);
dmaStreamSetTransactionSize(dmatx, data_size);
dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE);
// Skip SPI rx buffer
// Skip data from rx buffer
spi_DropRx();
// Set read speed (if need different)
#ifdef LCD_SPI_RX_SPEED
SPI_BR_SET(LCD_SPI, LCD_SPI_RX_SPEED);
#endif
#endif
// require 8bit dummy clock
spi_RxByte();
// Start DMA exchange
dmaStreamEnable(dmarx);
dmaStreamEnable(dmatx);
// Wait DMA completion
dmaWaitCompletion(dmatx);
dmaWaitCompletion(dmarx);
// receive pixel data to buffer
#ifndef __USE_DISPLAY_DMA_RX__
spi_RxBuffer((uint8_t *)out, len * 2);
#else
spi_DMARxBuffer((uint8_t *)out, len * 2);
#endif
// restore speed if need
#ifdef LCD_SPI_RX_SPEED
SPI_BR_SET(LCD_SPI, LCD_SPI_SPEED);
#endif
LCD_CS_HIGH;
#ifndef TINYSA4
// Parce recived data
while (len-- > 0) {
uint8_t r, g, b;
// read data is always 18bit
r = rgbbuf[0];
g = rgbbuf[1];
b = rgbbuf[2];
*out++ = RGB565(r, g, b);
rgbbuf += 3;
}
#endif
}
#endif
@ -746,23 +700,15 @@ void ili9341_clear_screen(void)
ili9341_fill(0, 0, ILI9341_WIDTH, ILI9341_HEIGHT);
}
#ifndef ili9341_set_foreground
void ili9341_set_foreground(uint16_t fg_idx)
{
if (fg_idx >= 32)
foreground_color = fg_idx;
else
foreground_color = GET_PALTETTE_COLOR(fg_idx);
foreground_color = GET_PALTETTE_COLOR(fg_idx);
}
#endif
#ifndef ili9341_set_background
void ili9341_set_background(uint16_t bg_idx)
{
// if (bg_idx >= 32) bg_idx = 0;
background_color = GET_PALTETTE_COLOR(bg_idx);
}
#endif
void ili9341_set_rotation(uint8_t r)
{
@ -771,11 +717,9 @@ void ili9341_set_rotation(uint8_t r)
send_command(ILI9341_MEMORY_ACCESS_CONTROL, 1, &r);
}
static uint8_t bit_align = 0;
void ili9341_blitBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height,
const uint8_t *b)
void ili9341_blitBitmap(int x, int y, int width, int height, const uint8_t *b)
{
uint16_t *buf = spi_buffer;
pixel_t *buf = spi_buffer;
uint8_t bits = 0;
for (uint16_t c = 0; c < height; c++) {
for (uint16_t r = 0; r < width; r++) {
@ -783,7 +727,6 @@ void ili9341_blitBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height,
*buf++ = (0x80 & bits) ? foreground_color : background_color;
bits <<= 1;
}
if (bit_align) b+=bit_align;
}
ili9341_bulk(x, y, width, height);
}
@ -828,11 +771,9 @@ void ili9341_drawstring_10x14(const char *str, int x, int y)
if (ch == '\n') {x = x_pos; y+=wFONT_STR_HEIGHT; continue;}
const uint8_t *char_buf = wFONT_GET_DATA(ch);
uint16_t w = wFONT_GET_WIDTH(ch);
bit_align = (w<=8) ? 1 : 0;
ili9341_blitBitmap(x, y, w, wFONT_GET_HEIGHT, char_buf);
ili9341_blitBitmap(x, y, (w<=8) ? 9 : w, wFONT_GET_HEIGHT, char_buf);
x += w;
}
bit_align = 0;
#else
ili9341_drawstring_size(str, x, y, 2);
#endif

@ -184,13 +184,11 @@ static THD_FUNCTION(Thread1, arg)
// Process collected data, calculate trace coordinates and plot only if scan
// completed
if (/* sweep_mode & SWEEP_ENABLE && */ completed) {
#ifdef __VNA__
if ((domain_mode & DOMAIN_MODE) == DOMAIN_TIME) transform_domain();
#endif
// START_PROFILE;
// Prepare draw graphics, cache all lines, mark screen cells for redraw
plot_into_index(measured);
redraw_request |= REDRAW_CELLS | REDRAW_BATTERY;
// STOP_PROFILE;
if (uistat.marker_tracking) {
int i = marker_search_max();
if (i != -1 && active_marker != MARKER_INVALID) {
@ -358,6 +356,39 @@ int shell_serial_printf(const char *fmt, ...)
return formatted_bytes;
}
#endif
//
// Function used for search substring v in list
// Example need search parameter "center" in "start|stop|center|span|cw" getStringIndex return 2
// If not found return -1
// Used for easy parse command arguments
static int get_str_index(const char *v, const char *list)
{
int i = 0;
while (1) {
const char *p = v;
while (1) {
char c = *list;
if (c == '|') c = 0;
if (c == *p++) {
// Found, return index
if (c == 0) return i;
list++; // Compare next symbol
continue;
}
break; // Not equal, break
}
// Set new substring ptr
while (1) {
// End of string, not found
if (*list == 0) return -1;
if (*list++ == '|') break;
}
i++;
}
return -1;
}
VNA_SHELL_FUNCTION(cmd_pause)
{
(void)argc;
@ -386,7 +417,7 @@ VNA_SHELL_FUNCTION(cmd_reset)
(void)argv;
if (argc == 1) {
if (strcmp(argv[0], "dfu") == 0) {
if (get_str_index(argv[0], "dfu") == 0) {
shell_printf("Performing reset to DFU mode\r\n");
enter_dfu();
return;
@ -550,37 +581,6 @@ my_atof(const char *p)
return x;
}
//
// Function used for search substring v in list
// Example need search parameter "center" in "start|stop|center|span|cw" getStringIndex return 2
// If not found return -1
// Used for easy parse command arguments
static int get_str_index(char *v, const char *list)
{
int i = 0;
while (1) {
char *p = v;
while (1) {
char c = *list;
if (c == '|') c = 0;
if (c == *p++) {
// Found, return index
if (c == 0) return i;
list++; // Compare next symbol
continue;
}
break; // Not equal, break
}
// Set new substring ptr
while (1) {
// End of string, not found
if (*list == 0) return -1;
if (*list++ == '|') break;
}
i++;
}
return -1;
}
#ifdef __VNA__
VNA_SHELL_FUNCTION(cmd_offset)
{
@ -692,7 +692,7 @@ VNA_SHELL_FUNCTION(cmd_clearconfig)
return;
}
if (strcmp(argv[0], "1234") != 0) {
if (get_str_index(argv[0], "1234") != 0) {
shell_printf("Key unmatched.\r\n");
return;
}
@ -802,10 +802,11 @@ VNA_SHELL_FUNCTION(cmd_data)
if (argc == 1)
sel = my_atoi(argv[0]);
if (sel >= 0 && sel <= MAX_DATA) {
static const uint8_t sel_conv[]={TRACE_TEMP, TRACE_STORED, TRACE_ACTUAL};
float *data = measured[sel_conv[sel]];
for (i = 0; i < sweep_points; i++)
shell_printf("%f\r\n", value(measured[sel][i]));
shell_printf("%f\r\n", value(data[i]));
return;
}
shell_printf("usage: data [0-2]\r\n");
@ -888,8 +889,8 @@ VNA_SHELL_FUNCTION(cmd_capture)
for (y = 0; y < LCD_HEIGHT; y += 2) {
// use uint16_t spi_buffer[2048] (defined in ili9341) for read buffer
uint8_t *buf = (uint8_t *)spi_buffer;
ili9341_read_memory(0, y, LCD_WIDTH, 2, 2 * LCD_WIDTH, spi_buffer);
streamWrite(shell_stream, (void*)buf, 2 * 2 * LCD_WIDTH);
ili9341_read_memory(0, y, LCD_WIDTH, 2, spi_buffer);
streamWrite(shell_stream, (void*)buf, 2 * LCD_WIDTH * sizeof(uint16_t));
}
}
@ -1176,9 +1177,9 @@ VNA_SHELL_FUNCTION(cmd_scan)
if (mask) {
for (i = 0; i < points; i++) {
if (mask & 1) shell_printf("%U ", frequencies[i]);
if (mask & 2) shell_printf("%f %f ", value(measured[2][i]), 0.0);
if (mask & 4) shell_printf("%f %f ", value(measured[1][i]), 0.0);
if (mask & 8) shell_printf("%f %f ", value(measured[0][i]), 0.0);
if (mask & 2) shell_printf("%f %f ", value(measured[TRACE_ACTUAL][i]), 0.0);
if (mask & 4) shell_printf("%f %f ", value(measured[TRACE_STORED][i]), 0.0);
if (mask & 8) shell_printf("%f %f ", value(measured[TRACE_TEMP][i]), 0.0);
shell_printf("\r\n");
}
}
@ -1883,7 +1884,7 @@ VNA_SHELL_FUNCTION(cmd_trace)
if (argc == 2) {
switch (get_str_index(argv[0], cmd_scale_ref_list)) {
case 0:
if (strcmp(argv[1],"auto") == 0) {
if (get_str_index(argv[1],"auto") == 0) {
set_auto_reflevel(true);
} else {
user_set_scale(my_atof(argv[1]));
@ -1891,7 +1892,7 @@ VNA_SHELL_FUNCTION(cmd_trace)
goto update;
case 1:
//trace[t].refpos = my_atof(argv[2]);
if (strcmp(argv[1],"auto") == 0) {
if (get_str_index(argv[1],"auto") == 0) {
set_auto_reflevel(true);
} else {
user_set_reflevel(my_atof(argv[1]));
@ -1950,7 +1951,7 @@ VNA_SHELL_FUNCTION(cmd_marker)
return;
}
redraw_request |= REDRAW_MARKER;
if (strcmp(argv[0], "off") == 0) {
if (get_str_index(argv[0], "off") == 0) {
active_marker = MARKER_INVALID;
for (t = 0; t < MARKERS_MAX; t++)
markers[t].enabled = FALSE;
@ -2670,7 +2671,7 @@ static void VNAShell_executeLine(char *line)
// Execute line
const VNAShellCommand *scp;
for (scp = commands; scp->sc_name != NULL; scp++) {
if (strcmp(scp->sc_name, shell_args[0]) == 0) {
if (get_str_index(scp->sc_name, shell_args[0]) == 0) {
if (scp->flags & CMD_WAIT_MUTEX) {
shell_function = scp->sc_function;
operation_requested|=OP_CONSOLE;

@ -711,7 +711,7 @@ extern volatile uint8_t redraw_request;
// Set display buffers count for cell render (if use 2 and DMA, possible send data and prepare new in some time)
#ifdef __USE_DISPLAY_DMA__
// Cell size = sizeof(spi_buffer), but need wait while cell cata send to LCD
// Cell size = sizeof(spi_buffer), but need wait while cell data send to LCD
//#define DISPLAY_CELL_BUFFER_COUNT 1
// Cell size = sizeof(spi_buffer)/2, while one cell send to LCD by DMA, CPU render to next cell
#define DISPLAY_CELL_BUFFER_COUNT 2
@ -727,7 +727,7 @@ typedef uint16_t pixel_t;
#define CELLHEIGHT (32)
// Define size of screen buffer in pixels (one pixel 16bit size)
#define SPI_BUFFER_SIZE (CELLWIDTH*CELLHEIGHT*DISPLAY_CELL_BUFFER_COUNT)
#define SPI_BUFFER_SIZE (CELLWIDTH * CELLHEIGHT * DISPLAY_CELL_BUFFER_COUNT)
// SPI bus revert byte order
// 16-bit gggBBBbb RRRrrGGG
@ -735,11 +735,13 @@ typedef uint16_t pixel_t;
#define RGBHEX(hex) ( (((hex)&0x001c00)<<3) | (((hex)&0x0000f8)<<5) | (((hex)&0xf80000)>>16) | (((hex)&0x00e000)>>13) )
#define HEXRGB(hex) ( (((hex)>>3)&0x001c00) | (((hex)>>5)&0x0000f8) | (((hex)<<16)&0xf80000) | (((hex)<<13)&0x00e000) )
// Define LCD display driver and screen size
#ifdef TINYSA4
#define LCD_DRIVER_ST7796S
#define LCD_WIDTH 480
#define LCD_HEIGHT 320
#else
#define LCD_DRIVER_ILI9341
#define LCD_WIDTH 320
#define LCD_HEIGHT 240
#endif
@ -813,7 +815,7 @@ typedef uint16_t pixel_t;
extern uint16_t foreground_color;
extern uint16_t background_color;
extern uint16_t spi_buffer[SPI_BUFFER_SIZE];
extern pixel_t spi_buffer[SPI_BUFFER_SIZE];
// Used for easy define big Bitmap as 0bXXXXXXXXX image
#define _BMP8(d) ((d)&0xFF)
@ -824,16 +826,24 @@ extern uint16_t spi_buffer[SPI_BUFFER_SIZE];
void ili9341_init(void);
void ili9341_test(int mode);
void ili9341_bulk(int x, int y, int w, int h); // send data to display, in DMA mode use it, but wait DMA complete
void ili9341_bulk_continue(int x, int y, int w, int h); // send data to display, in DMA mode use it, no wait DMA complete
void ili9341_bulk_finish(void); // wait DMA complete (need call at end)
void ili9341_fill(int x, int y, int w, int h);
// Double buffer mode parser
#if DISPLAY_CELL_BUFFER_COUNT == 1
#define ili9341_get_cell_buffer() spi_buffer
#define ili9341_bulk_continue ili9341_bulk
#define ili9341_bulk_finish() {}
#else
pixel_t *ili9341_get_cell_buffer(void); // get buffer for cell render
void ili9341_bulk_continue(int x, int y, int w, int h); // send data to display, in DMA mode use it, no wait DMA complete
void ili9341_bulk_finish(void); // wait DMA complete (need call at end)
#endif
void ili9341_set_foreground(uint16_t fg_idx);
void ili9341_set_background(uint16_t bg_idx);
void ili9341_clear_screen(void);
void ili9341_blitBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *bitmap);
void ili9341_blitBitmap(int x, int y, int width, int height, const uint8_t *bitmap);
void ili9341_drawchar(uint8_t ch, int x, int y);
void ili9341_drawstring(const char *str, int x, int y);
void ili9341_drawstring_7x13(const char *str, int x, int y);
@ -842,7 +852,7 @@ void ili9341_drawstringV(const char *str, int x, int y);
int ili9341_drawchar_size(uint8_t ch, int x, int y, uint8_t size);
void ili9341_drawstring_size(const char *str, int x, int y, uint8_t size);
void ili9341_drawfont(uint8_t ch, int x, int y);
void ili9341_read_memory(int x, int y, int w, int h, int len, pixel_t* out);
void ili9341_read_memory(int x, int y, int w, int h, uint16_t* out);
void ili9341_line(int x0, int y0, int x1, int y1);
void show_version(void);

@ -111,7 +111,9 @@ char marker_letter[5] =
'T'
};
//#define float2int(v) ((int)(v))
#if 1
#define float2int(v) ((int)(v))
#else
static int
float2int(float v)
{
@ -119,6 +121,7 @@ float2int(float v)
if (v > 0) return v + 0.5;
return 0;
}
#endif
void update_grid(void)
{
@ -287,7 +290,8 @@ draw_on_strut(int v0, int d, int color)
#define POW_SQRT ((float)0.2236067950725555419921875)
#define LOG_10_SQRT_50_x20_plus30 ((float)46.98970004336)
#define LOG_10_SQRT_50_x20_plus90 ((float)106.98970004336)
#define LOG_DIV_10 ((float)0.2302585093)
#define LOG_DIV_20 ((float)0.11512925465)
/*
* calculate log10f(abs(gamma))
*/
@ -304,20 +308,17 @@ value(const float v)
{
case U_DBMV:
// return v + 30.0 + 20.0*log10f(sqrtf(50));
return v + LOG_10_SQRT_50_x20_plus30; // + 30.0 + 20.0*LOG_10_SQRT_50; //TODO convert constants to single float number as GCC compiler does runtime calculation
break;
return v + LOG_10_SQRT_50_x20_plus30; // + 30.0 + 20.0*LOG_10_SQRT_50;
case U_DBUV:
// return v + 90.0 + 20.0*log10f(sqrtf(50.0)); //TODO convert constants to single float number as GCC compiler does runtime calculation
// return v + 90.0 + 20.0*log10f(sqrtf(50.0));
return v + LOG_10_SQRT_50_x20_plus90; // 90.0 + 20.0*LOG_10_SQRT_50;
break;
case U_VOLT:
// return powf(10.0, (v-30.0)/20.0) * sqrtf(50.0);
// return powf(10.0, (v-30.0)/20.0) * SQRT_50; //
return powf(10.0, v/20) * POW_SQRT; // powf(10.0,v/20.0) * powf(10, -30.0/20.0) * sqrtf(50)
break;
// return powf(10.0, (v-30.0)/20.0) * SQRT_50; // powf(10.0,v/20.0) * powf(10, -30.0/20.0) * sqrtf(50)
return expf(v*LOG_DIV_20) * POW_SQRT; // expf(v*logf(10.0)/20.0) * powf(10, -30.0/20.0) * sqrtf(50)
case U_WATT:
return powf((float)10.0, v/10.0)/1000.0; //
break;
// return powf(10.0, v/10.0)/1000.0; // powf(10, v/10.0)/1000.0 = expf(v*logf(10.0)/10.0)/1000.0
return expf(v*LOG_DIV_10)/1000.0; //
}
// case U_DBM:
return v; // raw data is in logmag*10 format
@ -331,18 +332,14 @@ to_dBm(const float v)
case U_DBMV:
// return v - 30.0 - 20.0*log10f(sqrtf(50));
return v - LOG_10_SQRT_50_x20_plus30; // (30.0 + 20.0*LOG_10_SQRT_50);
break;
case U_DBUV:
// return v - 90.0 - 20.0*log10f(sqrtf(50.0)); //TODO convert constants to single float number as GCC compiler does runtime calculation
return v - LOG_10_SQRT_50_x20_plus90; // (90.0 + 20.0*LOG_10_SQRT_50);
break;
case U_VOLT:
// return log10f( v / (sqrtf(50.0))) * 20.0 + 30.0 ;
return log10f( v / SQRT_50) * 20.0 + 30.0 ;
break;
case U_WATT:
return log10f(v*1000.0)*10.0;
break;
}
// case U_DBM:
return v; // raw data is in logmag*10 format
@ -1293,7 +1290,8 @@ static void cell_draw_marker_info(int x0, int y0)
float level = (actual_t[markers[1].index] + actual_t[markers[2].index])/2.0 - actual_t[markers[0].index];
if (level < -70 || level > 0)
break;
int depth =(int) (powf((float)10.0, 2.0 + (level + 6.02) /20.0));
// int depth =(int) (powf((float)10.0, 2.0 + (level + 6.02) /20.0));
int depth = expf((2.0 + (level + 6.02))*LOG_DIV_20);
#endif
plot_printf(buf, sizeof buf, "DEPTH: %3d%%", depth);
goto show_computed;
@ -1527,7 +1525,7 @@ int display_test(void)
for (int w = 0; w < LCD_WIDTH; w++) {
spi_buffer[w] = 0;
}
ili9341_read_memory(0, h, LCD_WIDTH, 1, LCD_WIDTH, spi_buffer);
ili9341_read_memory(0, h, LCD_WIDTH, 1, spi_buffer);
for (int w = 0; w < LCD_WIDTH; w++) {
if (spi_buffer[w] != ((w*h) & 0xfff))
return false;
@ -1544,12 +1542,10 @@ int display_test(void)
static void update_waterfall(void){
int i;
int w_width = area_width < WIDTH ? area_width : WIDTH;
// Waterfall only in 290 or 145 points
// if (!(sweep_points == 290 || sweep_points == 145))
// return;
// START_PROFILE;
for (i = CHART_BOTTOM-1; i >=graph_bottom+1; i--) { // Scroll down
ili9341_read_memory(OFFSETX, i , w_width, 1, w_width*1, spi_buffer);
ili9341_bulk(OFFSETX, i+1, w_width, 1);
ili9341_read_memory(OFFSETX, i, w_width, 1, spi_buffer);
ili9341_bulk(OFFSETX, i+1, w_width, 1);
}
index_y_t *index;
if (setting.average == AV_OFF)
@ -1605,6 +1601,7 @@ static void update_waterfall(void){
}
}
ili9341_bulk(OFFSETX, graph_bottom+1, w_width, 1);
// STOP_PROFILE;
}
int get_waterfall(void)

@ -144,19 +144,6 @@ VNA_SHELL_FUNCTION(cmd_ultra)
VNA_SHELL_FUNCTION(cmd_output)
{
#if 0
if (argc != 1) {
usage:
shell_printf("usage: output on|off\r\n");
return;
}
if (strcmp(argv[0],"on") == 0) {
setting.mute = false;
} else if (strcmp(argv[0],"off") == 0) {
setting.mute = true;
} else
goto usage;
#endif
int m = generic_option_cmd("output", "on|off", argc, argv[0]);
if (m>=0) {
setting.mute = m;
@ -166,19 +153,17 @@ VNA_SHELL_FUNCTION(cmd_output)
VNA_SHELL_FUNCTION(cmd_load)
{
if (argc != 1) {
usage:
shell_printf("usage: load 0..4\r\n");
if (argc != 1)
goto usage;
uint16_t a = my_atoui(argv[0]);
if (a <= 4) {
caldata_recall(a);
return;
}
int a = my_atoi(argv[0]);
if (0 <= a && a <= 4) {
caldata_recall(a);
} else
goto usage;
usage:
shell_printf("usage: load 0..4\r\n");
}
VNA_SHELL_FUNCTION(cmd_attenuate)
{
if (argc != 1) {
@ -186,7 +171,7 @@ VNA_SHELL_FUNCTION(cmd_attenuate)
shell_printf("usage: attenuate 0..31|auto\r\n");
return;
}
if (strcmp(argv[0],"auto") == 0) {
if (get_str_index(argv[0],"auto") == 0) {
if (!setting.auto_attenuation)
set_auto_attenuation();
} else {
@ -249,6 +234,8 @@ VNA_SHELL_FUNCTION(cmd_levelchange)
VNA_SHELL_FUNCTION(cmd_leveloffset)
{
// 0 1 2
static const char cmd_mode_list[] = "low|high|switch";
if (argc == 0) {
const char *p = "leveloffset %s %.1f\r\n";
shell_printf(p, "low", config.low_level_offset);
@ -257,30 +244,25 @@ VNA_SHELL_FUNCTION(cmd_leveloffset)
shell_printf(p, "high output", config.high_level_output_offset);
shell_printf(p, "switch", config.switch_offset);
return;
} else if (argc == 2) {
float v = my_atof(argv[1]);
if (strcmp(argv[0],"low") == 0)
config.low_level_offset = v;
else if (strcmp(argv[0],"high") == 0)
config.high_level_offset = v;
else if (strcmp(argv[0],"switch") == 0)
config.switch_offset = v;
else
goto usage;
dirty = true;
} else if (argc == 3 && strcmp(argv[1],"output") == 0) {
float v = my_atof(argv[2]);
if (strcmp(argv[0],"low") == 0)
config.low_level_output_offset = v;
else if (strcmp(argv[0],"high") == 0)
config.high_level_output_offset = v;
else
goto usage;
dirty = true;
} else {
usage:
shell_printf("leveloffset [low|high|switch] {output} [-20..+20]\r\n");
}
int mode = get_str_index(argv[0], cmd_mode_list);
float v;
if (argc == 2)
v = my_atof(argv[1]);
else if (argc == 3 && get_str_index(argv[1], "output") == 0)
v = my_atof(argv[2]);
else
goto usage;
switch (mode){
case 0: config.low_level_offset = v; break;
case 1: config.high_level_offset = v; break;
case 2: config.switch_offset = v; break;
default: goto usage;
}
dirty = true;
return;
usage:
shell_printf("leveloffset [%s] {output} [-20..+20]\r\n", cmd_mode_list);
}
VNA_SHELL_FUNCTION(cmd_deviceid)
@ -781,7 +763,7 @@ VNA_SHELL_FUNCTION(cmd_correction)
}
return;
}
if (argc == 1 && (strcmp(argv[0],"reset") == 0)) {
if (argc == 1 && (get_str_index(argv[0],"reset") == 0)) {
for (int i=0; i<CORRECTION_POINTS; i++) {
setting.correction_value[i] = 0.0;
}

38
ui.c

@ -2590,44 +2590,8 @@ keypad_click(int key)
scale /= 1000000000.0;
}
/* numeric input done */
double value = my_atof(kp_buf) * scale;
#if 1
uistat.value = value;
uistat.value = my_atof(kp_buf) * scale;
set_numeric_value();
#else
switch (keypad_mode) {
case KM_START:
set_sweep_frequency(ST_START, value);
break;
case KM_STOP:
set_sweep_frequency(ST_STOP, value);
break;
case KM_CENTER:
set_sweep_frequency(ST_CENTER, value);
break;
case KM_SPAN:
set_sweep_frequency(ST_SPAN, value);
break;
case KM_CW:
set_sweep_frequency(ST_CW, value);
break;
case KM_SCALE:
set_trace_scale(uistat.current_trace, value);
break;
case KM_REFPOS:
set_trace_refpos(uistat.current_trace, value);
break;
case KM_EDELAY:
set_electrical_delay(value); // pico seconds
break;
case KM_VELOCITY_FACTOR:
velocity_factor = value / 100.0;
break;
case KM_SCALEDELAY:
set_trace_scale(uistat.current_trace, value * 1e-12); // pico second
break;
}
#endif
return KP_DONE;
} else if (c <= 9 && kp_index < NUMINPUT_LEN) {
kp_buf[kp_index++] = '0' + c;

Loading…
Cancel
Save

Powered by TurnKey Linux.