Squashed commit of the following:

commit d9f1514b26
Merge: 6148013 6210a57
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Sun Dec 11 13:54:00 2022 +0300

    Merge branch 'DiSlord_browser' of https://github.com/erikkaashoek/tinySA into DiSlord_browser

commit 6148013c54
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Sun Dec 11 13:53:42 2022 +0300

    Rewrite progress bar update/remove dead code/use buffering in cmd_scanraw
    cmd_vbat now run in sweep thread

commit 6210a57304
Author: erikkaashoek <erik@kaashoek.com>
Date:   Fri Dec 9 12:06:01 2022 +0100

    Level error + above 4.4GHz

commit 63a26eb112
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Wed Dec 7 18:59:45 2022 +0300

    Less code size and remove variable

commit e46a7423ee
Author: erikkaashoek <erik@kaashoek.com>
Date:   Mon Dec 5 10:36:20 2022 +0100

    Fix keyboard

commit 519af36d93
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Sat Dec 3 21:49:32 2022 +0300

    Add Enter button

commit a1eeae37f3
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Sat Dec 3 21:49:05 2022 +0300

    Not need clear text

commit 1d9c85c7c3
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Sat Dec 3 20:04:37 2022 +0300

    Replace

commit 400175ed48
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Sat Dec 3 19:57:16 2022 +0300

    Fix

commit dc01db6e8a
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Sat Dec 3 19:52:11 2022 +0300

    Add lcd_set_font function
    Allow lcd_printf print by selected font
    Fix text position in browser

commit bb860080de
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Sat Dec 3 17:53:47 2022 +0300

    Add SWEEP_UI_MODE flag for console command
    This allow run command if active thread in UI mode

commit 31e4d72a46
Merge: 18b4b94 f832809
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Sat Dec 3 16:15:39 2022 +0300

    Merge branch 'DiSlord_browser' of https://github.com/erikkaashoek/tinySA into DiSlord_browser

commit f8328093f1
Author: erikkaashoek <erik@kaashoek.com>
Date:   Sat Dec 3 13:16:53 2022 +0100

    Removed compile warnings on 072

commit 18b4b94875
Merge: 80dfb6e d99d679
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Sat Dec 3 15:05:50 2022 +0300

    Merge branch 'V4.3' of https://github.com/erikkaashoek/tinySA into DiSlord_browser

commit 80dfb6e6bc
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Sat Dec 3 14:01:05 2022 +0300

    Fix warnings

commit a61de95423
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Sat Dec 3 13:51:47 2022 +0300

    Fix f072 compile

commit 467f300b3d
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Sat Dec 3 12:50:26 2022 +0300

    Add *.cmd files browse and execute
    Added some useful functions

commit f2752f1200
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Sat Dec 3 12:48:52 2022 +0300

    Fix clean frequency area

commit ab35aadde3
Merge: 6fcdc8b 68a5114
Author: erikkaashoek <erik@kaashoek.com>
Date:   Sat Dec 3 09:59:06 2022 +0100

    Merge branch 'DiSlord_browser' of https://github.com/erikkaashoek/tinySA into DiSlord_browser

commit 6fcdc8b7af
Author: erikkaashoek <erik@kaashoek.com>
Date:   Sat Dec 3 09:56:58 2022 +0100

    UI updated with STORAGE menu

commit 68a5114048
Merge: fae9a43 afb59b8
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Sat Dec 3 11:22:42 2022 +0300

    Merge branch 'V4.3' of https://github.com/erikkaashoek/tinySA into DiSlord_browser

commit fae9a43825
Merge: ba7a3dc 768ecf0
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Fri Dec 2 18:23:14 2022 +0300

    Merge branch 'DiSlord_browser' of https://github.com/erikkaashoek/tinySA into DiSlord_browser

    # Conflicts:
    #	ui.c

commit ba7a3dc941
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Fri Dec 2 18:19:11 2022 +0300

    Add autofilename option
    Ask for filename on save

commit 0c0ac98140
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Fri Dec 2 18:17:48 2022 +0300

    Add Enter symbol
    Update fonts

commit 768ecf01ca
Author: erikkaashoek <erik@kaashoek.com>
Date:   Fri Dec 2 08:20:25 2022 +0100

    Old compiler can't use "string"[0]

commit c4563d6efc
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Thu Dec 1 23:56:06 2022 +0300

    Keyboard size and position definition

commit e63db4f2df
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Thu Dec 1 23:55:32 2022 +0300

    Refactoring keyboard code, prepare for text input keyboard

commit 597b4e300f
Merge: c43b8c1 7b602fc
Author: erikkaashoek <erik@kaashoek.com>
Date:   Thu Dec 1 09:53:05 2022 +0100

    Merge branch 'V4.3' into DiSlord_browser

commit c43b8c1005
Author: erikkaashoek <erik@kaashoek.com>
Date:   Thu Dec 1 09:23:27 2022 +0100

    Added preset load/store SD card

commit a0b0351a7e
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Wed Nov 30 23:03:04 2022 +0300

    Disable battery and cal state update in browser mode

commit 9b3d077942
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Wed Nov 30 22:56:55 2022 +0300

    Use big font for browser

commit 01e87fc27b
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Wed Nov 30 22:24:40 2022 +0300

    Add browser option

commit be63b81b1b
Merge: 5d22b2f 1543296
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Wed Nov 30 21:19:45 2022 +0300

    Merge branch 'DiSlord_browser' of https://github.com/erikkaashoek/tinySA into DiSlord_browser

commit 5d22b2fcce
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Wed Nov 30 21:18:39 2022 +0300

    Add dump firmware option

commit 154329698d
Merge: d31a599 b9b9ea1
Author: erikkaashoek <erik@kaashoek.com>
Date:   Wed Nov 30 19:17:58 2022 +0100

    Merge pull request #42 from erikkaashoek/V4.3

    Add c and h commands

commit d31a599b1d
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Wed Nov 30 21:17:36 2022 +0300

    Fix typo

commit 517428bd01
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Wed Nov 30 20:43:38 2022 +0300

    Allow read/write more then one sector (512 bytes) in one time

commit 84342fbd43
Author: DiSlord Live <dislordlive@gmail.com>
Date:   Wed Nov 30 20:28:37 2022 +0300

    Update save to card part
pull/51/head
erikkaashoek 3 years ago
parent eac5904cd9
commit d4fcab1e7b

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019-2020, written by DiSlord dislordlive@gmail.com * Copyright (c) 2019-2020, Dmitry (DiSlord) dislordlive@gmail.com
* All rights reserved. * All rights reserved.
* *
* This is free software; you can redistribute it and/or modify * This is free software; you can redistribute it and/or modify
@ -28,7 +28,7 @@
* Check 1 byte of bitmap data for get width * Check 1 byte of bitmap data for get width
*/ */
#define wFONT_START_CHAR 0x17 #define wFONT_START_CHAR 0x16
#define wFONT_MAX_WIDTH 12 #define wFONT_MAX_WIDTH 12
#define wFONT_GET_HEIGHT 14 #define wFONT_GET_HEIGHT 14
#define wFONT_STR_HEIGHT 16 #define wFONT_STR_HEIGHT 16
@ -50,6 +50,22 @@
// for less 8 width used 9 but next char draw at correct place // for less 8 width used 9 but next char draw at correct place
const uint8_t x10x14_bits[(127-wFONT_START_CHAR)*wFONT_GET_HEIGHT*2] = const uint8_t x10x14_bits[(127-wFONT_START_CHAR)*wFONT_GET_HEIGHT*2] =
{ {
//S_DELTA "\029" // 0x17
_BMP16(0b0000000000000000|CW_13), // | |
_BMP16(0b0000000001110000), // | *** |
_BMP16(0b0000000001110000), // | *** |
_BMP16(0b0000000001110000), // | *** |
_BMP16(0b0000000001110000), // | *** |
_BMP16(0b0000000001110000), // | *** |
_BMP16(0b0000000001110000), // | *** |
_BMP16(0b0001000001110000), // | * *** |
_BMP16(0b0011000001110000), // | ** *** |
_BMP16(0b0111111111110000), // | *********** |
_BMP16(0b1111111111110000), // |************ |
_BMP16(0b0111111111110000), // | *********** |
_BMP16(0b0011000000000000), // | ** |
_BMP16(0b0001000000000000), // | * |
//S_DELTA "\029" // 0x17 //S_DELTA "\029" // 0x17
_BMP16(0b0000000000000000|CW_13), // | | _BMP16(0b0000000000000000|CW_13), // | |
_BMP16(0b0000011000000000), // | ** | _BMP16(0b0000011000000000), // | ** |

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -64,7 +64,7 @@ void flash_unlock(void)
FLASH->KEYR = 0xCDEF89AB; FLASH->KEYR = 0xCDEF89AB;
} }
static uint32_t uint32_t
checksum(const void *start, size_t len) checksum(const void *start, size_t len)
{ {
uint32_t *p = (uint32_t*)start; uint32_t *p = (uint32_t*)start;

@ -827,7 +827,7 @@ typedef struct {
int16_t y; int16_t y;
} lcdPrintStream; } lcdPrintStream;
static msg_t lcd_put(void *ip, uint8_t ch) { static msg_t lcd_put5x7(void *ip, uint8_t ch) {
lcdPrintStream *ps = ip; lcdPrintStream *ps = ip;
if (ch == '\n') {ps->x = ps->start_x; ps->y+=FONT_STR_HEIGHT; return MSG_OK;} if (ch == '\n') {ps->x = ps->start_x; ps->y+=FONT_STR_HEIGHT; return MSG_OK;}
uint16_t w = FONT_GET_WIDTH(ch); uint16_t w = FONT_GET_WIDTH(ch);
@ -836,23 +836,25 @@ static msg_t lcd_put(void *ip, uint8_t ch) {
return MSG_OK; return MSG_OK;
} }
#if 0 static msg_t lcd_put_7x11b(void *ip, uint8_t ch) {
static msg_t lcd_put_7x13(void *ip, uint8_t ch) {
lcdPrintStream *ps = ip; lcdPrintStream *ps = ip;
if (ch == '\n') {ps->x = ps->start_x; ps->y+=FONT_STR_HEIGHT; return MSG_OK;} if (ch == '\n') {ps->x = ps->start_x; ps->y+=bFONT_STR_HEIGHT; return MSG_OK;}
uint16_t w = FONT_GET_WIDTH(ch); uint16_t w = bFONT_GET_WIDTH(ch);
ili9341_blitBitmap(ps->x, ps->y, w, FONT_GET_HEIGHT, FONT_GET_DATA(ch)); ili9341_blitBitmap(ps->x, ps->y, w, bFONT_GET_HEIGHT, bFONT_GET_DATA(ch));
ps->x+= w; ps->x+= w;
return MSG_OK; return MSG_OK;
} }
#endif
typedef msg_t (*font_put_t)(void *ps, uint8_t ch);
static font_put_t put_char = lcd_put5x7;
void lcd_set_font(int type) {put_char = type == FONT_SMALL ? lcd_put5x7 : lcd_put_7x11b;}
// Simple print in buffer function // Simple print in buffer function
int lcd_printf(int16_t x, int16_t y, const char *fmt, ...) { int lcd_printf(int16_t x, int16_t y, const char *fmt, ...) {
// Init small lcd print stream // Init small lcd print stream
struct lcd_printStreamVMT { struct lcd_printStreamVMT {
_base_sequential_stream_methods _base_sequential_stream_methods
} lcd_vmt = {NULL, NULL, lcd_put, NULL}; } lcd_vmt = {NULL, NULL, put_char, NULL};
lcdPrintStream ps = {&lcd_vmt, x, y, x, y}; lcdPrintStream ps = {&lcd_vmt, x, y, x, y};
// Performing the print operation using the common code. // Performing the print operation using the common code.
va_list ap; va_list ap;
@ -1351,7 +1353,7 @@ static bool SD_RxDataBlock(uint8_t *buff, uint16_t len, uint8_t token) {
} }
// Transmit data block to SD // Transmit data block to SD
static bool SD_TxDataBlock(const uint8_t *buff, uint8_t token) { static bool SD_TxDataBlock(const uint8_t *buff, uint16_t len, uint8_t token) {
uint8_t resp; uint8_t resp;
// Transmit token // Transmit token
spi_TxByte(token); spi_TxByte(token);
@ -1361,13 +1363,13 @@ static bool SD_TxDataBlock(const uint8_t *buff, uint8_t token) {
#endif #endif
#ifdef __USE_SDCARD_DMA__ #ifdef __USE_SDCARD_DMA__
spi_DMATxBuffer((uint8_t*)buff, SD_SECTOR_SIZE, true); spi_DMATxBuffer((uint8_t*)buff, len, true);
#else #else
spi_TxBuffer((uint8_t*)buff, SD_SECTOR_SIZE); spi_TxBuffer((uint8_t*)buff, len);
#endif #endif
// Send CRC // Send CRC
#ifdef SD_USE_DATA_CRC #ifdef SD_USE_DATA_CRC
uint16_t bcrc = crc16(buff, SD_SECTOR_SIZE); uint16_t bcrc = crc16(buff, len);
spi_TxWord(bcrc); spi_TxWord(bcrc);
#else #else
spi_TxWord(0xFFFF); spi_TxWord(0xFFFF);
@ -1580,7 +1582,7 @@ DSTATUS disk_status(BYTE pdrv) {
// diskio.c - Read sector // diskio.c - Read sector
DRESULT disk_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { DRESULT disk_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) {
// No disk or wrong block count // No disk or wrong block count
if (pdrv != 0 || count != 1 || (Stat & STA_NOINIT)) return RES_NOTRDY; if (pdrv != 0 || (Stat & STA_NOINIT)) return RES_NOTRDY;
// convert to byte address // convert to byte address
if (!(CardType & CT_BLOCK)) sector *= SD_SECTOR_SIZE; if (!(CardType & CT_BLOCK)) sector *= SD_SECTOR_SIZE;
@ -1590,14 +1592,18 @@ DRESULT disk_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) {
#endif #endif
SD_Select_SPI(); SD_Select_SPI();
// READ_SINGLE_BLOCK uint8_t cmd = count == 1 ? CMD17 : CMD18;
uint8_t cnt = SD_READ_WRITE_REPEAT; // read repeat count // convert to byte address
do{ if (!(CardType & CT_BLOCK)) sector*= SD_SECTOR_SIZE;
if ((SD_SendCmd(CMD17, sector) == 0) && SD_RxDataBlock(buff, SD_SECTOR_SIZE, SD_TOKEN_START_BLOCK)){ // Read single / multiple block
count = 0; if (SD_SendCmd(cmd, sector) == 0) {
break; do {
} if (SD_RxDataBlock(buff, SD_SECTOR_SIZE, SD_TOKEN_START_BLOCK))
}while (--cnt); buff+= SD_SECTOR_SIZE;
else break;
} while(--count);
}
if (cmd == CMD18) SD_SendCmd(CMD12, 0); // Finish multiple block transfer
SD_Unselect_SPI(); SD_Unselect_SPI();
#if DEBUG == 1 #if DEBUG == 1
@ -1622,12 +1628,9 @@ DRESULT disk_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) {
// diskio.c - Write sector // diskio.c - Write sector
DRESULT disk_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { DRESULT disk_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) {
// No disk or wrong count // No disk or wrong count
if (pdrv != 0 || count != 1 || (Stat & STA_NOINIT)) return RES_NOTRDY; if (pdrv != 0 || (Stat & STA_NOINIT)) return RES_NOTRDY;
// Write protection // Write protection
if (Stat & STA_PROTECT) return RES_WRPRT; if (Stat & STA_PROTECT) return RES_WRPRT;
// Convert to byte address if no Block mode
if (!(CardType & CT_BLOCK)) sector*= SD_SECTOR_SIZE;
#if DEBUG == 1 #if DEBUG == 1
#if 0 #if 0
DEBUG_PRINT("Sector write 0x%08X, %d\r\n", sector, count); DEBUG_PRINT("Sector write 0x%08X, %d\r\n", sector, count);
@ -1642,14 +1645,14 @@ DRESULT disk_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) {
#endif #endif
SD_Select_SPI(); SD_Select_SPI();
// WRITE_SINGLE_BLOCK do {
uint8_t cnt = SD_READ_WRITE_REPEAT; // write repeat count // WRITE_SINGLE_BLOCK * count
do{ uint32_t sect = (CardType & CT_BLOCK) ? sector : sector * SD_SECTOR_SIZE;
if ((SD_SendCmd(CMD24, sector) == 0) && SD_TxDataBlock(buff, SD_TOKEN_START_BLOCK)){ if ((SD_SendCmd(CMD24, sect) == 0) && SD_TxDataBlock(buff, SD_SECTOR_SIZE, SD_TOKEN_START_BLOCK)) {
count = 0; sector++;
break; buff+= SD_SECTOR_SIZE;
} } else break;
} while (--cnt); } while (--count);
SD_Unselect_SPI(); SD_Unselect_SPI();
#if DEBUG == 1 #if DEBUG == 1

102
main.c

@ -226,8 +226,11 @@ static THD_FUNCTION(Thread1, arg)
} }
// START_PROFILE // START_PROFILE
// Process UI inputs // Process UI inputs
if (!(sweep_mode & SWEEP_SELFTEST)) if (!(sweep_mode & SWEEP_SELFTEST)) {
sweep_mode|= SWEEP_UI_MODE;
ui_process(); ui_process();
sweep_mode&=~SWEEP_UI_MODE;
}
// Process collected data, calculate trace coordinates and plot only if scan // Process collected data, calculate trace coordinates and plot only if scan
// completed // completed
if (completed) { if (completed) {
@ -961,7 +964,7 @@ config_t config = {
#ifdef TINYSA4 #ifdef TINYSA4
.touch_cal = { 278, 513, 115, 154 }, // 4 inch panel .touch_cal = { 278, 513, 115, 154 }, // 4 inch panel
#endif #endif
._mode = _MODE_USB, ._mode = _MODE_USB | _MODE_AUTO_FILENAME,
._serial_speed = SERIAL_DEFAULT_BITRATE, ._serial_speed = SERIAL_DEFAULT_BITRATE,
.lcd_palette = LCD_DEFAULT_PALETTE, .lcd_palette = LCD_DEFAULT_PALETTE,
#ifdef TINYSA3 #ifdef TINYSA3
@ -2019,6 +2022,7 @@ typedef struct {
// Some commands can executed only in sweep thread, not in main cycle // Some commands can executed only in sweep thread, not in main cycle
#define CMD_WAIT_MUTEX 1 #define CMD_WAIT_MUTEX 1
#define CMD_RUN_IN_LOAD 2 #define CMD_RUN_IN_LOAD 2
#define CMD_RUN_IN_UI 4
static const VNAShellCommand commands[] = static const VNAShellCommand commands[] =
{ {
{"version" , cmd_version , 0}, {"version" , cmd_version , 0},
@ -2067,13 +2071,13 @@ static const VNAShellCommand commands[] =
{"usart" , cmd_usart , CMD_WAIT_MUTEX}, {"usart" , cmd_usart , CMD_WAIT_MUTEX},
{"usart_cfg" , cmd_usart_cfg , CMD_WAIT_MUTEX | CMD_RUN_IN_LOAD}, {"usart_cfg" , cmd_usart_cfg , CMD_WAIT_MUTEX | CMD_RUN_IN_LOAD},
#endif #endif
{"capture" , cmd_capture , CMD_WAIT_MUTEX}, {"capture" , cmd_capture , CMD_WAIT_MUTEX | CMD_RUN_IN_UI},
#ifdef __REMOTE_DESKTOP__ #ifdef __REMOTE_DESKTOP__
{"refresh" , cmd_refresh , 0}, {"refresh" , cmd_refresh , 0},
{"touch" , cmd_touch , 0}, {"touch" , cmd_touch , 0},
{"release" , cmd_release , 0}, {"release" , cmd_release , 0},
#endif #endif
{"vbat" , cmd_vbat , 0}, // Uses same adc as touch!!!!! {"vbat" , cmd_vbat , CMD_WAIT_MUTEX}, // Uses same adc as touch!!!!!
#ifdef ENABLE_VBAT_OFFSET_COMMAND #ifdef ENABLE_VBAT_OFFSET_COMMAND
{"vbat_offset" , cmd_vbat_offset , CMD_RUN_IN_LOAD}, {"vbat_offset" , cmd_vbat_offset , CMD_RUN_IN_LOAD},
#endif #endif
@ -2322,37 +2326,48 @@ static void shell_init_connection(void){
bool global_abort = false; bool global_abort = false;
static const VNAShellCommand *VNAShell_parceLine(char *line){ static inline char* vna_strpbrk(char *s1, const char *s2) {
// Parse and execute line do {
char *lp = line, *ep; const char *s = s2;
shell_nargs = 0; do {
shell_args[0] = line; // shell_args[0] is used in error message, must be initialized if (*s == *s1) return s1;
// DEBUG_LOG(0, lp); // debug console log s++;
while (*lp != 0) { } while (*s);
// Skipping white space and tabs at string begin. s1++;
while (*lp == ' ' || *lp == '\t') lp++; } while(*s1);
// If an argument starts with a double quote then its delimiter is another quote, else return s1;
// delimiter is white space. }
ep = (*lp == '"') ? strpbrk(++lp, "\"") : strpbrk(lp, " \t");
// Store in args string /*
shell_args[shell_nargs++] = lp; * Split line by arguments, return arguments count
// Stop, end of input string */
if ((lp = ep) == NULL) break; int parse_line(char *line, char* args[], int max_cnt) {
// Argument limits check char *lp = line, c;
if (shell_nargs > VNA_SHELL_MAX_ARGUMENTS) { const char *brk;
shell_printf("too many arguments, max " define_to_STR(VNA_SHELL_MAX_ARGUMENTS) "" VNA_SHELL_NEWLINE_STR); uint16_t nargs = 0;
return NULL; while ((c = *lp) != 0) { // While not end
if (c != ' ' && c != '\t') { // Skipping white space and tabs.
if (c == '"') {lp++; brk = "\""; } // string end is next quote or end
else { brk = " \t";} // string end is tab or space or end
if (nargs < max_cnt) args[nargs] = lp; // Put pointer in args buffer (if possible)
nargs++; // Substring count
lp = vna_strpbrk(lp, brk); // search end
if (*lp == 0) break; // Stop, end of input string
*lp = 0; // Set zero at the end of substring
} }
// Set zero at the end of string and continue check lp++;
*lp++ = 0;
} }
if (shell_nargs){ return nargs;
if (shell_args[0][0] == '.') { }
global_abort = true;
return NULL;
}
global_abort = false;
static const VNAShellCommand *VNAShell_parceLine(char *line){
// Parse and execute line
shell_nargs = parse_line(line, shell_args, ARRAY_COUNT(shell_args));
if (shell_nargs > ARRAY_COUNT(shell_args)) {
shell_printf("too many arguments, max " define_to_STR(VNA_SHELL_MAX_ARGUMENTS) "" VNA_SHELL_NEWLINE_STR);
return NULL;
}
if (shell_nargs > 0) {
const VNAShellCommand *scp; const VNAShellCommand *scp;
for (scp = commands; scp->sc_name != NULL; scp++) for (scp = commands; scp->sc_name != NULL; scp++)
if (get_str_index(scp->sc_name, shell_args[0]) == 0) if (get_str_index(scp->sc_name, shell_args[0]) == 0)
@ -2401,14 +2416,16 @@ static void VNAShell_executeLine(char *line)
// Execute line // Execute line
const VNAShellCommand *scp = VNAShell_parceLine(line); const VNAShellCommand *scp = VNAShell_parceLine(line);
if (scp) { if (scp) {
if (scp->flags & CMD_WAIT_MUTEX) { uint16_t cmd_flag = scp->flags;
// Skip wait mutex if process UI
if ((cmd_flag & CMD_RUN_IN_UI) && (sweep_mode&SWEEP_UI_MODE)) cmd_flag&=~CMD_WAIT_MUTEX;
if (cmd_flag & CMD_WAIT_MUTEX) {
shell_function = scp->sc_function; shell_function = scp->sc_function;
operation_requested|=OP_CONSOLE; // this will abort current sweep to give priority to the new request operation_requested|=OP_CONSOLE; // this will abort current sweep to give priority to the new request
// Wait execute command in sweep thread // Wait execute command in sweep thread
osalThreadEnqueueTimeoutS(&shell_thread, TIME_INFINITE); do {
// do { osalThreadEnqueueTimeoutS(&shell_thread, TIME_INFINITE);
// osalThreadSleepMilliseconds(10); } while (shell_function);
// } while (shell_function);
} else { } else {
operation_requested = false; // otherwise commands will be aborted operation_requested = false; // otherwise commands will be aborted
scp->sc_function(shell_nargs - 1, &shell_args[1]); scp->sc_function(shell_nargs - 1, &shell_args[1]);
@ -2425,6 +2442,15 @@ static void VNAShell_executeLine(char *line)
shell_printf("%s?" VNA_SHELL_NEWLINE_STR, shell_args[0]); shell_printf("%s?" VNA_SHELL_NEWLINE_STR, shell_args[0]);
} }
void shell_executeCMDLine(char *line) {
// Disable shell output (not allow shell_printf write, but not block other output!!)
shell_stream = NULL;
const VNAShellCommand *scp = VNAShell_parceLine(line);
if (scp && (scp->flags & CMD_RUN_IN_LOAD))
scp->sc_function(shell_nargs - 1, &shell_args[1]);
PREPARE_STREAM;
}
#ifdef __SD_CARD_LOAD__ #ifdef __SD_CARD_LOAD__
#ifndef __USE_SD_CARD__ #ifndef __USE_SD_CARD__
#error "Need enable SD card support __USE_SD_CARD__ in nanovna.h, for use ENABLE_SD_CARD_CMD" #error "Need enable SD card support __USE_SD_CARD__ in nanovna.h, for use ENABLE_SD_CARD_CMD"
@ -2630,7 +2656,7 @@ int main(void)
#ifdef TINYSA4 #ifdef TINYSA4
ili9341_set_foreground(LCD_FG_COLOR); ili9341_set_foreground(LCD_FG_COLOR);
PULSE PULSE
ili9341_drawstring("Starting...", 0,0); ili9341_drawstring_7x13("Starting...", 0, 0);
PULSE PULSE
#ifdef __DISABLE_HOT_INSERT__ #ifdef __DISABLE_HOT_INSERT__
sd_card_inserted_at_boot = SD_Inserted(); sd_card_inserted_at_boot = SD_Inserted();

@ -90,7 +90,9 @@
#define __ULTRA__ #define __ULTRA__
#define __USE_RTC__ // Enable RTC clock #define __USE_RTC__ // Enable RTC clock
#define __USE_SD_CARD__ // Enable SD card support #define __USE_SD_CARD__ // Enable SD card support
#define __SD_CARD_LOAD__ // Allow run commands from SD card (config.ini in root) //#define __SD_CARD_LOAD__ // Allow run commands from SD card (config.ini in root), if enabled __SD_FILE_BROWSER__ scripts run from *.cmd in it
#define __SD_CARD_DUMP_FIRMWARE__ // Allow dump firmware to SD card
#define __SD_FILE_BROWSER__
#define __LCD_BRIGHTNESS__ // LCD or hardware allow change brightness, add menu item for this #define __LCD_BRIGHTNESS__ // LCD or hardware allow change brightness, add menu item for this
#define __HARMONIC__ #define __HARMONIC__
#define __NOISE_FIGURE__ #define __NOISE_FIGURE__
@ -322,6 +324,7 @@ enum {
#define SWEEP_CALIBRATE_HARMONIC 0x40 #define SWEEP_CALIBRATE_HARMONIC 0x40
//#define SWEEP_FACTORY 0x20 //#define SWEEP_FACTORY 0x20
#endif #endif
#define SWEEP_UI_MODE 0x80
extern uint8_t sweep_mode; extern uint8_t sweep_mode;
extern uint8_t completed; extern uint8_t completed;
@ -584,6 +587,14 @@ extern uint16_t graph_bottom;
#define MENU_BUTTON_HEIGHT_N(n) (LCD_HEIGHT/(n)-1) #define MENU_BUTTON_HEIGHT_N(n) (LCD_HEIGHT/(n)-1)
#define BROWSER_BUTTON_BORDER 1
// Browser window settings
#define FILES_COLUMNS (LCD_WIDTH/160) // columns in browser
#define FILES_ROWS 10 // rows in browser
#define FILES_PER_PAGE (FILES_COLUMNS*FILES_ROWS) // FILES_ROWS * FILES_COLUMNS
#define FILE_BOTTOM_HEIGHT 20 // Height of bottom buttons (< > X)
#define FILE_BUTTON_HEIGHT ((LCD_HEIGHT - FILE_BOTTOM_HEIGHT)/FILES_ROWS) // Height of file buttons
// Define message box width // Define message box width
#ifdef TINYSA4 #ifdef TINYSA4
#define MESSAGE_BOX_WIDTH 300 #define MESSAGE_BOX_WIDTH 300
@ -612,7 +623,10 @@ extern const uint8_t x7x11b_bits [];
extern const uint8_t x10x14_bits[]; extern const uint8_t x10x14_bits[];
extern const uint8_t numfont16x22[]; extern const uint8_t numfont16x22[];
#define FONT_START_CHAR 0x17 #define FONT_SMALL 0
#define FONT_NORMAL 1
#define FONT_START_CHAR 0x16
#define FONT_MAX_WIDTH 7 #define FONT_MAX_WIDTH 7
#define FONT_WIDTH 5 #define FONT_WIDTH 5
#define FONT_GET_HEIGHT 7 #define FONT_GET_HEIGHT 7
@ -620,7 +634,7 @@ extern const uint8_t numfont16x22[];
#define FONT_GET_DATA(ch) ( &x5x7_bits[(ch-FONT_START_CHAR)*FONT_GET_HEIGHT]) #define FONT_GET_DATA(ch) ( &x5x7_bits[(ch-FONT_START_CHAR)*FONT_GET_HEIGHT])
#define FONT_GET_WIDTH(ch) (8-(x5x7_bits[(ch-FONT_START_CHAR)*FONT_GET_HEIGHT]&7)) #define FONT_GET_WIDTH(ch) (8-(x5x7_bits[(ch-FONT_START_CHAR)*FONT_GET_HEIGHT]&7))
#define bFONT_START_CHAR 0x17 #define bFONT_START_CHAR 0x16
#define bFONT_MAX_WIDTH 8 #define bFONT_MAX_WIDTH 8
#define bFONT_WIDTH 7 #define bFONT_WIDTH 7
#define bFONT_GET_HEIGHT 11 #define bFONT_GET_HEIGHT 11
@ -629,7 +643,7 @@ extern const uint8_t numfont16x22[];
#define bFONT_GET_WIDTH(ch) (8-(x7x11b_bits[(ch-bFONT_START_CHAR)*bFONT_GET_HEIGHT]&7)) #define bFONT_GET_WIDTH(ch) (8-(x7x11b_bits[(ch-bFONT_START_CHAR)*bFONT_GET_HEIGHT]&7))
#ifdef __NICE_BIG_FONT__ #ifdef __NICE_BIG_FONT__
#define wFONT_START_CHAR 0x17 #define wFONT_START_CHAR 0x16
#define wFONT_MAX_WIDTH 12 #define wFONT_MAX_WIDTH 12
#define wFONT_GET_HEIGHT 14 #define wFONT_GET_HEIGHT 14
#define wFONT_STR_HEIGHT 16 #define wFONT_STR_HEIGHT 16
@ -644,20 +658,16 @@ extern const uint8_t numfont16x22[];
#define NUM_FONT_GET_HEIGHT 22 #define NUM_FONT_GET_HEIGHT 22
#define NUM_FONT_GET_DATA(ch) (&numfont16x22[ch*2*NUM_FONT_GET_HEIGHT]) #define NUM_FONT_GET_DATA(ch) (&numfont16x22[ch*2*NUM_FONT_GET_HEIGHT])
#if 1 #define KP_WIDTH (LCD_WIDTH / 4) // numeric keypad button width
#define KP_WIDTH ((LCD_WIDTH) / 4)// numeric keypad button width #define KP_HEIGHT ((LCD_HEIGHT - NUM_INPUT_HEIGHT) / 4) // numeric keypad button height
#define KP_HEIGHT ((LCD_HEIGHT - NUM_INPUT_HEIGHT) / 4) // numeric keypad button height #define KP_X_OFFSET 0 // numeric keypad X offset
// Key x, y position (0 - 15) on screen #define KP_Y_OFFSET 0 // numeric keypad Y offset
#define KP_GET_X(posx) ((posx) * KP_WIDTH) // numeric keypad left #define KPF_WIDTH (LCD_WIDTH / 10) // text keypad button width
#define KP_GET_Y(posy) ((posy) * KP_HEIGHT) // numeric keypad top #define KPF_HEIGHT KPF_WIDTH // text keypad button height
#else #define KPF_X_OFFSET 0 // text keypad X offset
#define KP_WIDTH (LCD_HEIGHT/5) #define KPF_Y_OFFSET (LCD_HEIGHT - NUM_INPUT_HEIGHT - 4 * KPF_HEIGHT) // text keypad Y offset
#define KP_HEIGHT (LCD_HEIGHT/5)
// Key x, y position (0 - 15) on screen
#define KP_GET_X(posx) ((posx)*KP_WIDTH + (LCD_WIDTH-MENU_BUTTON_WIDTH-5-KP_WIDTH*4))
#define KP_GET_Y(posy) ((posy)*KP_HEIGHT + 12 )
#endif
#define S_ENTER "\026" // 0x16
#define S_DELTA "\027" // 0x17 #define S_DELTA "\027" // 0x17
#define S_SARROW "\030" // 0x18 #define S_SARROW "\030" // 0x18
#define S_INFINITY "\031" // 0x19 #define S_INFINITY "\031" // 0x19
@ -668,6 +678,10 @@ extern const uint8_t numfont16x22[];
#define S_OHM "\036" // 0x1E #define S_OHM "\036" // 0x1E
#define S_DEGREE "\037" // 0x1F #define S_DEGREE "\037" // 0x1F
#define C_ENTER 0x16 // 0x16
#define C_LARROW 0x1A // 0x1A
#define C_RARROW 0x1B // 0x1B
// String prefix for select font size (use not printable chars) // String prefix for select font size (use not printable chars)
#define FONT_s "\001" #define FONT_s "\001"
#define _FONT_s 1 #define _FONT_s 1
@ -712,14 +726,17 @@ float marker_to_value(const int i);
#define FREQ_MODE_START_STOP 0x0 #define FREQ_MODE_START_STOP 0x0
#define FREQ_MODE_CENTER_SPAN 0x1 #define FREQ_MODE_CENTER_SPAN 0x1
#define FREQ_MODE_DOTTED_GRID 0x2 //#define FREQ_MODE_DOTTED_GRID 0x2
// Connection flag // Connection flag
#define _MODE_CONNECTION_MASK 0x04 #define _MODE_CONNECTION_MASK 0x04
#define _MODE_SERIAL 0x04 #define _MODE_SERIAL 0x04
#define _MODE_USB 0x00 #define _MODE_USB 0x00
// don't save state
#define _MODE_DONT_SAVE_STATE 0x08 #define _MODE_DONT_SAVE_STATE 0x08
// auto name
#define _MODE_AUTO_FILENAME 0x10
#pragma pack(push, 4) #pragma pack(push, 4)
typedef struct config { typedef struct config {
@ -819,6 +836,7 @@ extern void clear_marker_cache(void);
void shell_update_speed(void); void shell_update_speed(void);
void shell_reset_console(void); void shell_reset_console(void);
int shell_serial_printf(const char *fmt, ...); int shell_serial_printf(const char *fmt, ...);
void shell_executeCMDLine(char *line);
// marker // marker
enum { enum {
@ -1098,6 +1116,7 @@ void ili9341_drawchar(uint8_t ch, int x, int y);
void ili9341_drawstring(const char *str, 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); void ili9341_drawstring_7x13(const char *str, int x, int y);
void ili9341_drawstring_10x14(const char *str, int x, int y); void ili9341_drawstring_10x14(const char *str, int x, int y);
void lcd_set_font(int type);
int lcd_printf(int16_t x, int16_t y, const char *fmt, ...); int lcd_printf(int16_t x, int16_t y, const char *fmt, ...);
void ili9341_drawstringV(const char *str, int x, int y); void ili9341_drawstringV(const char *str, int x, int y);
int ili9341_drawchar_size(uint8_t ch, int x, int y, uint8_t size, int x_max); int ili9341_drawchar_size(uint8_t ch, int x, int y, uint8_t size, int x_max);
@ -1277,6 +1296,7 @@ extern int linear_averaging;
#else #else
#define SAVEAREA_MAX 5 #define SAVEAREA_MAX 5
#endif #endif
// STM32 minimum page size for write // STM32 minimum page size for write
#define FLASH_PAGESIZE 0x800 #define FLASH_PAGESIZE 0x800
// config save area (flash7 addr) // config save area (flash7 addr)
@ -1284,12 +1304,16 @@ extern int linear_averaging;
#define SAVE_CONFIG_ADDR 0x0801D000 #define SAVE_CONFIG_ADDR 0x0801D000
#define SAVE_CONFIG_SIZE FLASH_PAGESIZE #define SAVE_CONFIG_SIZE FLASH_PAGESIZE
#define FLASH_END 0x08020000 #define FLASH_END 0x08020000
#define FLASH_START_ADDRESS 0x08000000
#define FLASH_TOTAL_SIZE (128*1024)
#endif #endif
#ifdef TINYSA4 #ifdef TINYSA4
#define SAVE_CONFIG_ADDR 0x0803C000 #define SAVE_CONFIG_ADDR 0x0803C000
#define SAVE_CONFIG_SIZE FLASH_PAGESIZE*2 #define SAVE_CONFIG_SIZE FLASH_PAGESIZE*2
#define FLASH_END 0x08040000 #define FLASH_END 0x08040000
#define FLASH_START_ADDRESS 0x08000000
#define FLASH_TOTAL_SIZE (256*1024)
#endif #endif
typedef char assert_config[sizeof(config_t)> SAVE_CONFIG_SIZE ? -1 : 1]; // Check config size typedef char assert_config[sizeof(config_t)> SAVE_CONFIG_SIZE ? -1 : 1]; // Check config size
@ -1407,6 +1431,7 @@ int caldata_save(uint16_t id);
int config_save(void); int config_save(void);
int config_recall(void); int config_recall(void);
setting_t * caldata_pointer(uint16_t id); setting_t * caldata_pointer(uint16_t id);
uint32_t checksum(const void *start, size_t len);
void clear_all_config_prop_data(void); void clear_all_config_prop_data(void);
@ -1445,7 +1470,8 @@ int invoke_quick_menu(int);
bool ui_process_listen_lever(void); bool ui_process_listen_lever(void);
void refresh_sweep_menu(int i); void refresh_sweep_menu(int i);
void save_to_sd(int mask); void save_to_sd(int mask);
void drawMessageBox(char *header, char *text, uint32_t delay); void drawMessageBox(const char *header, char *text, uint32_t delay);
bool isFullScreenMode(void);
// Irq operation process set // Irq operation process set
#define OP_NONE 0x00 #define OP_NONE 0x00
@ -1583,8 +1609,6 @@ void SD_PowerOff(void);
#define fs_volume (FATFS *)(((uint8_t*)(&spi_buffer[SPI_BUFFER_SIZE])) - sizeof(FATFS)) #define fs_volume (FATFS *)(((uint8_t*)(&spi_buffer[SPI_BUFFER_SIZE])) - sizeof(FATFS))
// FatFS file object (at the end of spi_buffer) // FatFS file object (at the end of spi_buffer)
#define fs_file ( FIL*)(((uint8_t*)(&spi_buffer[SPI_BUFFER_SIZE])) - sizeof(FATFS) - sizeof(FIL)) #define fs_file ( FIL*)(((uint8_t*)(&spi_buffer[SPI_BUFFER_SIZE])) - sizeof(FATFS) - sizeof(FIL))
// Filename object (at the end of spi_buffer)
#define fs_filename ( char*)(((uint8_t*)(&spi_buffer[SPI_BUFFER_SIZE])) - sizeof(FATFS) - sizeof(FIL) - FF_LFN_BUF - 4)
#endif #endif
void testLog(void); // debug log void testLog(void); // debug log
void sd_card_load_config(char *filename); void sd_card_load_config(char *filename);
@ -1631,6 +1655,7 @@ typedef struct {
/* /*
* misclinous * misclinous
*/ */
int parse_line(char *line, char* args[], int max_cnt);
int plot_printf(char *str, int, const char *fmt, ...); int plot_printf(char *str, int, const char *fmt, ...);
#define PULSE do { palClearPad(GPIOC, GPIOC_LED); palSetPad(GPIOC, GPIOC_LED);} while(0) #define PULSE do { palClearPad(GPIOC, GPIOC_LED); palSetPad(GPIOC, GPIOC_LED);} while(0)
//extern int setting_attenuate; //extern int setting_attenuate;

@ -599,4 +599,28 @@ const uint8_t numfont16x22[] = {
_BMP16(0b1111000000000000), _BMP16(0b1111000000000000),
_BMP16(0b1111000000000000), _BMP16(0b1111000000000000),
_BMP16(0b1111000000000000), _BMP16(0b1111000000000000),
_BMP16(0b1111010001011111), // ENTER
_BMP16(0b1000011001000100),
_BMP16(0b1111010101000100),
_BMP16(0b1000010011000100),
_BMP16(0b1111010001000100),
_BMP16(0b0000000000000000),
_BMP16(0b0000000000000000),
_BMP16(0b0000000000001111),
_BMP16(0b0000000000001111),
_BMP16(0b0000000000001111),
_BMP16(0b0000000000001111),
_BMP16(0b0000000000001111),
_BMP16(0b0000000000001111),
_BMP16(0b0000000000001111),
_BMP16(0b0001100000001111),
_BMP16(0b0011100000001111),
_BMP16(0b0111111111111111),
_BMP16(0b1111111111111111),
_BMP16(0b1111111111111111),
_BMP16(0b0111111111111111),
_BMP16(0b0011100000000000),
_BMP16(0b0001100000000000),
}; };

@ -1252,6 +1252,7 @@ draw_all_cells(bool flush_markmap)
void void
draw_all(bool flush) draw_all(bool flush)
{ {
if (isFullScreenMode()) return;
#ifdef __LEVEL_METER__ #ifdef __LEVEL_METER__
level_text[0] = 0; // Clear level text level_text[0] = 0; // Clear level text
#endif #endif
@ -1830,7 +1831,7 @@ draw_frequencies(void)
} }
ili9341_set_foreground(LCD_FG_COLOR); ili9341_set_foreground(LCD_FG_COLOR);
ili9341_set_background(LCD_BG_COLOR); ili9341_set_background(LCD_BG_COLOR);
ili9341_fill(FREQUENCIES_XPOS1, FREQUENCIES_YPOS, LCD_WIDTH - FREQUENCIES_XPOS1, LCD_HEIGHT - FREQUENCIES_YPOS); ili9341_fill(FREQUENCIES_XPOS1, CHART_BOTTOM + 1, LCD_WIDTH - FREQUENCIES_XPOS1, LCD_HEIGHT - CHART_BOTTOM - 1);
if (uistat.lever_mode == LM_CENTER) if (uistat.lever_mode == LM_CENTER)
buf1[0] = S_SARROW[0]; buf1[0] = S_SARROW[0];
if (uistat.lever_mode == LM_SPAN) if (uistat.lever_mode == LM_SPAN)
@ -1845,8 +1846,8 @@ draw_frequencies(void)
#ifdef TINYSA4 #ifdef TINYSA4
if (get_sweep_frequency(ST_STOP) > 2000000000ULL && setting.attenuate_x2 >= 16 ) { if (get_sweep_frequency(ST_STOP) > 2000000000ULL && setting.attenuate_x2 >= 16 ) {
ili9341_drawstring("REDUCED LINEARITY", p2 - 18*7, FREQUENCIES_YPOS); ili9341_drawstring("REDUCED LINEARITY", p2 - 18*7, FREQUENCIES_YPOS);
} else }// else
ili9341_drawstring(" ", p2 - 18*7, FREQUENCIES_YPOS); // ili9341_drawstring(" ", p2 - 18*7, FREQUENCIES_YPOS);
#endif #endif
} }

@ -1245,37 +1245,39 @@ VNA_SHELL_FUNCTION(cmd_scanraw)
float f_step = (stop-start)/ points; float f_step = (stop-start)/ points;
setting.frequency_step = (freq_t)f_step; setting.frequency_step = (freq_t)f_step;
streamPut(shell_stream, '{');
static freq_t old_start=0, old_stop=0;
static uint32_t old_points=0;
if (old_start != start || old_stop != stop || old_points != points) { // To prevent dirty for every sweep
dirty = true;
old_start = start;
old_stop = stop;
old_points = points;
}
operation_requested = false; operation_requested = false;
dirty = true; dirty = true;
// adc_stop_analog_watchdog();
for (uint32_t i = 0; i<points; i++) { int oldpos = 0;
ili9341_set_background(LCD_BG_COLOR);
ili9341_fill(OFFSETX, CHART_BOTTOM+1, WIDTH, 1);
ili9341_set_background(LCD_SWEEP_LINE_COLOR);
#define BUFFER_SIZE 64
uint8_t buf[BUFFER_SIZE];
int idx = 0;
buf[idx++] = '{';
for (uint32_t i = 0; i < points; i++) {
int val = perform(false, i, start +(freq_t)(f_step * i), false) + float_TO_PURE_RSSI(config.ext_zero_level); int val = perform(false, i, start +(freq_t)(f_step * i), false) + float_TO_PURE_RSSI(config.ext_zero_level);
if (operation_requested || SDU1.config->usbp->state != USB_ACTIVE) // break on operation in perform if (operation_requested || SDU1.config->usbp->state != USB_ACTIVE) // break on operation in perform
break; break;
streamPut(shell_stream, 'x'); buf[idx++] = 'x';
streamPut(shell_stream, (uint8_t)(val & 0xFF)); buf[idx++] = (uint8_t)(val & 0xFF);
streamPut(shell_stream, (uint8_t)((val>>8) & 0xFF)); buf[idx++] = (uint8_t)((val>>8) & 0xFF);
if ((i & 0x07) == 0) { // if required if (idx >= BUFFER_SIZE - 4) {
int pos = i * (WIDTH+1) / points; streamWrite(shell_stream, buf, idx);
ili9341_set_background(LCD_SWEEP_LINE_COLOR); idx = 0;
ili9341_fill(OFFSETX, CHART_BOTTOM+1, pos, 1); // update sweep progress bar }
ili9341_set_background(LCD_BG_COLOR); int pos = i * (WIDTH+1) / points;
ili9341_fill(OFFSETX+pos, CHART_BOTTOM+1, WIDTH-pos, 1); if (pos - oldpos > 8) {
ili9341_fill(OFFSETX + oldpos, CHART_BOTTOM+1, pos - oldpos, 1); // update sweep progress bar
oldpos = pos;
} }
} }
buf[idx++] = '}';
streamWrite(shell_stream, buf, idx);
// adc_start_analog_watchdog();
ili9341_set_background(LCD_BG_COLOR); ili9341_set_background(LCD_BG_COLOR);
ili9341_fill(OFFSETX, CHART_BOTTOM+1, WIDTH, 1); ili9341_fill(OFFSETX, CHART_BOTTOM+1, WIDTH, 1);
streamPut(shell_stream, '}');
setting.frequency_step = old_step; setting.frequency_step = old_step;
dirty = true; dirty = true;
redraw_request = 0; // disable screen update in this mode redraw_request = 0; // disable screen update in this mode

@ -492,7 +492,10 @@ void update_min_max_freq(void)
minFreq = 0; minFreq = 0;
#ifdef TINYSA4 #ifdef TINYSA4
#ifdef __ULTRA_OUT__ #ifdef __ULTRA_OUT__
maxFreq = ULTRA_MAX_FREQ+60000000; // Add 60MHz to go to 5.40GHz if (setting.mixer_output)
maxFreq = ULTRA_MAX_FREQ+60000000; // Add 60MHz to go to 5.40GHz
else
maxFreq = 4400000000ULL; // 4.4GHz
#else #else
maxFreq = MAX_LOW_OUTPUT_FREQ; maxFreq = MAX_LOW_OUTPUT_FREQ;
#endif #endif
@ -4413,6 +4416,25 @@ again: // Spur redu
my_microsecond_delay(200); // To prevent lockup of SI4432 my_microsecond_delay(200); // To prevent lockup of SI4432
#endif #endif
} }
// Calculate the RSSI correction for later use
if (MODE_INPUT(setting.mode)){ // only cases where the value can change on 0 point of sweep
if (setting.frequency_step != 0 || (i==0 && scandirty)) {
correct_RSSI_freq = get_frequency_correction(lf);
}
}
// #define DEBUG_CORRECTION
#ifdef DEBUG_CORRECTION
if (SDU1.config->usbp->state == USB_ACTIVE) {
shell_printf ("%d:%Q %f\r\n", i, lf, PURE_TO_float(correct_RSSI_freq));
osalThreadSleepMilliseconds(2);
}
#endif
#ifdef TINYSA4 #ifdef TINYSA4
if (debug_frequencies ) { if (debug_frequencies ) {
@ -4437,46 +4459,33 @@ again: // Spur redu
} }
char spur = ' '; char spur = ' ';
int delta=0; int delta=0;
freq_t f = (LO_mirrored ? f_high : f_low); freq_t tf = (LO_mirrored ? f_high : f_low);
if ( f * 4 < real_old_freq[SI4463_RX] + real_offset) { if ( tf * 4 < real_old_freq[SI4463_RX] + real_offset) {
delta = real_old_freq[SI4463_RX] + real_offset - 4*f; delta = real_old_freq[SI4463_RX] + real_offset - 4*tf;
if (delta < actual_rbw_x10*100) if (delta < actual_rbw_x10*100)
spur = '!'; spur = '!';
} else { } else {
delta = 4*f - real_old_freq[SI4463_RX] + real_offset; delta = 4*tf - real_old_freq[SI4463_RX] + real_offset;
if (delta < actual_rbw_x10*100) if (delta < actual_rbw_x10*100)
spur = '!'; spur = '!';
} }
char shifted = ( LO_spur_shifted ? '>' : ' '); char shifted = ( LO_spur_shifted ? '>' : ' ');
if (SDU1.config->usbp->state == USB_ACTIVE) if (SDU1.config->usbp->state == USB_ACTIVE)
shell_printf ("%d:%c%c%c%cLO=%11.6Lq:%11.6Lq\tIF=%11.6Lq:%11.6Lq\tOF=%11.6d\tF=%11.6Lq:%11.6Lq\tD=%.2f:%.2f %c%c%c\r\n", shell_printf ("%d:%c%c%c%cLO=%11.6Lq:%11.6Lq\tIF=%11.6Lq:%11.6Lq\tOF=%11.6d\tF=%11.6Lq:%11.6Lq\tD=%.2f:%.2f %c%c%c %d\r\n",
i, spur, shifted,(LO_mirrored ? 'm' : ' '), (LO_harmonic ? 'h':' ' ), i, spur, shifted,(LO_mirrored ? 'm' : ' '), (LO_harmonic ? 'h':' ' ),
old_freq[ADF4351_LO],real_old_freq[ADF4351_LO], old_freq[ADF4351_LO],real_old_freq[ADF4351_LO],
old_freq[SI4463_RX], real_old_freq[SI4463_RX], (int32_t)real_offset, f_low, f_high , f_error_low, f_error_high, old_freq[SI4463_RX], real_old_freq[SI4463_RX], (int32_t)real_offset, f_low, f_high , f_error_low, f_error_high,
(ADF4351_frequency_changed? 'A' : ' '), (ADF4351_frequency_changed? 'A' : ' '),
(SI4463_frequency_changed? 'S' : ' '), (SI4463_frequency_changed? 'S' : ' '),
(SI4463_offset_changed? 'O' : ' ') (SI4463_offset_changed? 'O' : ' '),
); correct_RSSI_freq
);
osalThreadSleepMilliseconds(100); osalThreadSleepMilliseconds(100);
} }
#endif #endif
// ------------------------- end of processing when in output mode ------------------------------------------------ // ------------------------- end of processing when in output mode ------------------------------------------------
// Calculate the RSSI correction for later use
if (MODE_INPUT(setting.mode)){ // only cases where the value can change on 0 point of sweep
if (setting.frequency_step != 0 || (i==0 && scandirty)) {
correct_RSSI_freq = get_frequency_correction(f);
}
}
// #define DEBUG_CORRECTION
#ifdef DEBUG_CORRECTION
if (SDU1.config->usbp->state == USB_ACTIVE) {
shell_printf ("%d:%Q %f\r\n", i, f, PURE_TO_float(correct_RSSI_freq));
osalThreadSleepMilliseconds(2);
}
#endif
skip_LO_setting: skip_LO_setting:
if (i == 0 && t == 0) // if first point in scan (here is get 1 point data) if (i == 0 && t == 0) // if first point in scan (here is get 1 point data)
@ -4613,7 +4622,7 @@ again: // Spur redu
#ifdef TINYSA4 #ifdef TINYSA4
if (SI4432_step_delay && (ADF4351_frequency_changed || SI4463_frequency_changed)) { if (SI4432_step_delay && (ADF4351_frequency_changed || SI4463_frequency_changed)) {
int my_step_delay = SI4432_step_delay; int my_step_delay = SI4432_step_delay;
if (f < LOW_SHIFT_FREQ && actual_rbw_x10 == 3 && !in_step_test) if (lf < LOW_SHIFT_FREQ && actual_rbw_x10 == 3 && !in_step_test)
my_step_delay = my_step_delay * 2; my_step_delay = my_step_delay * 2;
// if (LO_spur_shifted) // || SI4463_offset_changed) // if (LO_spur_shifted) // || SI4463_offset_changed)
// my_step_delay = my_step_delay * 2; // my_step_delay = my_step_delay * 2;
@ -4676,6 +4685,11 @@ again: // Spur redu
if (LO_shifting) if (LO_shifting)
pureRSSI += float_TO_PURE_RSSI(actual_rbw_x10>USE_SHIFT2_RBW ? config.shift2_level_offset : (lf < LOW_SHIFT_FREQ ? config.shift1_level_offset: 0.0)); pureRSSI += float_TO_PURE_RSSI(actual_rbw_x10>USE_SHIFT2_RBW ? config.shift2_level_offset : (lf < LOW_SHIFT_FREQ ? config.shift1_level_offset: 0.0));
} }
if (setting.unit == U_RAW)
pureRSSI += - float_TO_PURE_RSSI(120); // don't add correction;
else
pureRSSI += correct_RSSI + correct_RSSI_freq; // add correction
//#define __DEBUG_FREQUENCY_SETTING__ //#define __DEBUG_FREQUENCY_SETTING__
#ifdef __DEBUG_FREQUENCY_SETTING__ // For debugging the frequency calculation #ifdef __DEBUG_FREQUENCY_SETTING__ // For debugging the frequency calculation
stored_t[i] = -60.0 + (real_old_freq[ADF4351_LO] - f - old_freq[2])/10; stored_t[i] = -60.0 + (real_old_freq[ADF4351_LO] - f - old_freq[2])/10;
@ -4687,7 +4701,7 @@ again: // Spur redu
// i = i + 1; // i = i + 1;
// } // }
#ifdef __ULTRA__ #ifdef __ULTRA__
float debug_rssi = PURE_TO_float(pureRSSI+ correct_RSSI + correct_RSSI_freq); float debug_rssi = PURE_TO_float(pureRSSI);
#endif #endif
#ifdef __SPUR__ #ifdef __SPUR__
static pureRSSI_t spur_RSSI = -1; // Initialization only to avoid warning. static pureRSSI_t spur_RSSI = -1; // Initialization only to avoid warning.
@ -4733,11 +4747,7 @@ again: // Spur redu
// } // }
#define IGNORE_RSSI 30000 #define IGNORE_RSSI 30000
// pureRSSI_t rssi = (RSSI>0 ? RSSI + correct_RSSI + correct_RSSI_freq : IGNORE_RSSI); // add correction // pureRSSI_t rssi = (RSSI>0 ? RSSI + correct_RSSI + correct_RSSI_freq : IGNORE_RSSI); // add correction
pureRSSI_t rssi; pureRSSI_t rssi = RSSI;
if (setting.unit == U_RAW)
rssi = RSSI - float_TO_PURE_RSSI(120); // don't add correction;
else
rssi = RSSI + correct_RSSI + correct_RSSI_freq; // add correction
if (false) { if (false) {
abort: abort:
rssi = 0; rssi = 0;
@ -7405,7 +7415,7 @@ void calibrate_harmonic(void)
test_acquire(TEST_JUMP_HARMONIC); // Acquire test test_acquire(TEST_JUMP_HARMONIC); // Acquire test
if (peakLevel < -50) { if (peakLevel < -50) {
ili9341_set_foreground(LCD_BRIGHT_COLOR_RED); ili9341_set_foreground(LCD_BRIGHT_COLOR_RED);
ili9341_drawstring_7x13("Signal level too low", 30, 200); ili9341_drawstring_7x13("Signal level too low or not on frequency", 30, 200);
goto quit; goto quit;
} }
set_jump_config(i, get_jump_config(i) + measure_jump(i)); set_jump_config(i, get_jump_config(i) + measure_jump(i));

925
ui.c

File diff suppressed because it is too large Load Diff

@ -0,0 +1,369 @@
static uint16_t file_count;
static uint16_t page_count;
static uint16_t current_page;
static uint16_t sel_mode;
// Buttons in browser
enum {FILE_BUTTON_LEFT = 0, FILE_BUTTON_RIGHT, FILE_BUTTON_EXIT, FILE_BUTTON_DEL, FILE_BUTTON_FILE};
// Button position on screen
typedef struct {
uint16_t x;
uint16_t y;
uint16_t w;
uint8_t h;
uint8_t ofs;
} browser_btn_t;
static const browser_btn_t browser_btn[] = {
[FILE_BUTTON_LEFT] = { 0 + 40, LCD_HEIGHT - FILE_BOTTOM_HEIGHT, LCD_WIDTH/2 - 80, FILE_BOTTOM_HEIGHT, (LCD_WIDTH/2 - 80 - FONT_WIDTH)/2}, // < previous
[FILE_BUTTON_RIGHT]= {LCD_WIDTH/2 + 40, LCD_HEIGHT - FILE_BOTTOM_HEIGHT, LCD_WIDTH/2 - 80, FILE_BOTTOM_HEIGHT, (LCD_WIDTH/2 - 80 - FONT_WIDTH)/2}, // > next
[FILE_BUTTON_EXIT] = {LCD_WIDTH - 40, LCD_HEIGHT - FILE_BOTTOM_HEIGHT, 40, FILE_BOTTOM_HEIGHT, ( 40 - FONT_WIDTH)/2}, // X exit
[FILE_BUTTON_DEL] = { 0 + 0, LCD_HEIGHT - FILE_BOTTOM_HEIGHT, 40, FILE_BOTTOM_HEIGHT, ( 40 - 3*FONT_WIDTH)/2}, // DEL
// File button, only size and start position, must be idx = FILE_BUTTON_FILE
[FILE_BUTTON_FILE] = { 0, 0, LCD_WIDTH/FILES_COLUMNS, FILE_BUTTON_HEIGHT, 5},
};
static void browser_get_button_pos(int idx, browser_btn_t *b) {
int n = idx >= FILE_BUTTON_FILE ? FILE_BUTTON_FILE : idx;
#if 0
memcpy(b, &browser_btn[n], sizeof(browser_btn_t));
#else
b->x = browser_btn[n].x;
b->y = browser_btn[n].y;
b->w = browser_btn[n].w;
b->h = browser_btn[n].h;
b->ofs = browser_btn[n].ofs;
#endif
if (idx > FILE_BUTTON_FILE) { // for file buttons use multiplier from start offset
idx-= FILE_BUTTON_FILE;
b->x+= b->w * (idx / FILES_ROWS);
b->y+= b->h * (idx % FILES_ROWS);
}
}
static void browser_draw_button(int idx, const char *txt) {
if (idx < 0) return;
ui_button_t b;
browser_btn_t btn;
browser_get_button_pos(idx, &btn);
// Mark DEL button in file delete mode
b.bg = (idx == FILE_BUTTON_DEL && sel_mode) ? LCD_LOW_BAT_COLOR : LCD_MENU_COLOR;
b.fg = LCD_MENU_TEXT_COLOR;
b.border = (idx == selection) ? BROWSER_BUTTON_BORDER|BUTTON_BORDER_FALLING : BROWSER_BUTTON_BORDER|BUTTON_BORDER_RISE;
if (txt == NULL) b.border|= BUTTON_BORDER_NO_FILL;
draw_button(btn.x, btn.y, btn.w, btn.h, &b);
if (txt) ili9341_drawstring_7x13(txt, btn.x + btn.ofs, btn.y + (btn.h - bFONT_STR_HEIGHT) / 2);
}
static char to_lower(char c) {return (c >='A' && c <= 'Z') ? c - 'A' + 'a' : c;}
static bool strcmpi(const char *t1, const char *t2) {
int i = 0;
while (1) {
char ch1 = to_lower(t1[i]), ch2 = to_lower(t2[i]);
if (ch1 != ch2) return false;
if (ch1 == 0) return true;
i++;
}
}
static bool compare_ext(const char *name, const char *ext) {
int i = 0, j = 0;
while (name[i]) if (name[i++] == '.') j = i; // Get last '.' position + 1
return j == 0 ? false : strcmpi(&name[j], ext); // Compare text after '.' and ext
}
static FRESULT sd_findnext(DIR* dp, FILINFO* fno) {
while (f_readdir(dp, fno) == FR_OK && fno->fname[0]) {
if (fno->fattrib & AM_DIR) continue;
if (compare_ext(fno->fname, dp->pat)) return FR_OK;
//#if FF_USE_LFN && FF_USE_FIND == 2
// if (compare_ext(fno->altname, dp->pat)) return FR_OK;
//#endif
}
return FR_NO_FILE;
}
static FRESULT sd_open_dir(DIR* dp, const TCHAR* path, const TCHAR* pattern) {
dp->pat = pattern;
return f_opendir(dp, path);
}
static void browser_open_file(int sel) {
FILINFO fno;
FRESULT res;
DIR dj;
int cnt;
if ((uint16_t)sel >= file_count) return;
if (f_mount(fs_volume, "", 1) != FR_OK) return;
repeat:
cnt = sel;
if (sd_open_dir(&dj, "", file_ext[keypad_mode]) != FR_OK) return; // open dir
while (sd_findnext(&dj, &fno) == FR_OK && cnt != 0) cnt--; // skip cnt files
f_closedir(&dj);
if (cnt != 0) return;
// Delete file if in delete mode
if (sel_mode) {f_unlink(fno.fname); return;}
const char *error = NULL;
bool leave_show = true;
UINT size;
if (f_open(fs_file, fno.fname, FA_READ) != FR_OK) return;
ili9341_set_foreground(LCD_FG_COLOR);
ili9341_set_background(LCD_BG_COLOR);
switch (keypad_mode) {
case FMT_CMD_FILE:
{
const int buffer_size = 256;
const int line_size = 128;
char *buf_8 = (char *)spi_buffer; // must be greater then buffer_size + line_size
char *line = buf_8 + buffer_size;
uint16_t j = 0, i;
while (f_read(fs_file, buf_8, buffer_size, &size) == FR_OK && size > 0) {
for (i = 0; i < size; i++) {
uint8_t c = buf_8[i];
if (c == '\r') { // New line (Enter)
line[j] = 0; j = 0;
shell_executeCMDLine(line);
}
else if (c < 0x20) continue; // Others (skip)
else if (j < line_size) line[j++] = (char)c; // Store
}
}
break;
}
/*
* BMP file load procedure, load only device screenshots
*/
case FMT_BMP_FILE:
{
int y;
leave_show = false; // allow step up/down load bitmap
uint16_t *buf_16 = spi_buffer; // prepare buffer
res = f_read(fs_file, (void *)buf_16, sizeof(bmp_header_v4), &size); // read heaser
if (res != FR_OK || buf_16[9] != LCD_WIDTH || buf_16[11] != LCD_HEIGHT || buf_16[14] != 16) {error = "Format err"; break;}
for (y = LCD_HEIGHT-1; y >=0 && res == FR_OK; y--) {
res = f_read(fs_file, (void *)buf_16, LCD_WIDTH * sizeof(uint16_t), &size);
swap_bytes(buf_16, LCD_WIDTH);
ili9341_bulk(0, y, LCD_WIDTH, 1);
}
ili9341_drawstring_7x13(fno.fname, 0, LCD_HEIGHT - 3*bFONT_STR_HEIGHT);
}
break;
/*
* Load calibration
*/
// case FMT_CAL_FILE:
// {
// uint32_t magic;
// char *src = (char*)&current_props + sizeof(magic);
// uint32_t total = sizeof(current_props) - sizeof(magic);
// // Compare file size and try read magic header, if all OK load it
// if (fno.fsize == sizeof(current_props) && f_read(fs_file, &magic, sizeof(magic), &size) == FR_OK &&
// magic == PROPS_MAGIC && f_read(fs_file, src, total, &size) == FR_OK)
// load_properties(NO_SAVE_SLOT);
// else error = "Format err";
// }
// break;
/*
* Load preset
*/
case FMT_PRS_FILE:
{
uint32_t magic;
char *src = (char*)&setting + sizeof(magic);
uint32_t total = sizeof(setting_t) - sizeof(magic);
// Compare file size and try read magic header, if all OK load it
if (fno.fsize == sizeof(setting) && f_read(fs_file, &magic, sizeof(magic), &size) == FR_OK &&
magic == CONFIG_MAGIC && f_read(fs_file, src, total, &size) == FR_OK) {
// TODO remove code duplication with flash.c
update_min_max_freq();
update_frequencies();
set_scale(setting.scale);
set_reflevel(setting.reflevel);
set_waterfall();
set_level_meter();
}
else error = "Format err";
}
break;
default: break;
}
f_close(fs_file);
if (error) {
ili9341_clear_screen();
drawMessageBox(error, fno.fname, leave_show ? 2000 : 0);
}
if (leave_show) return;
// Process input
while (1) {
uint16_t status = btn_check();
int key = -1;
if (status & EVT_DOWN) key = 0;
if (status & EVT_UP ) key = 1;
if (status & EVT_BUTTON_SINGLE_CLICK) key = 2;
status = touch_check();
if (status == EVT_TOUCH_PRESSED || status == EVT_TOUCH_DOWN) {
int touch_x, touch_y;
touch_position(&touch_x, &touch_y);
if (touch_x < LCD_WIDTH *1/3) key = 0;
else if (touch_x < LCD_WIDTH *2/3) key = 2;
else key = 1;
touch_wait_release();
}
chThdSleepMilliseconds(100);
int old_sel = sel;
if (key == 0) {if (--sel < 0) sel = file_count - 1;}
else if (key == 1) {if (++sel > file_count - 1) sel = 0;}
else if (key == 2) break;
if (old_sel != sel) goto repeat;
}
}
static void browser_draw_buttons(void) {
browser_draw_button(FILE_BUTTON_DEL, "DEL");
browser_draw_button(FILE_BUTTON_LEFT, "<");
browser_draw_button(FILE_BUTTON_RIGHT, ">");
browser_draw_button(FILE_BUTTON_EXIT, "X");
}
static void browser_draw_page(int page) {
FILINFO fno;
DIR dj;
// Mount SD card and open directory
if (f_mount(fs_volume, "", 1) != FR_OK ||
sd_open_dir(&dj, "", file_ext[keypad_mode]) != FR_OK) {
drawMessageBox("ERROR", "NO CARD", 2000);
ui_mode_normal();
return;
}
// Draw Browser UI
int cnt = 0;
uint16_t start_file = (page - 1) * FILES_PER_PAGE;
ili9341_set_background(LCD_MENU_COLOR);
ili9341_clear_screen();
lcd_set_font(FONT_NORMAL);
while (sd_findnext(&dj, &fno) == FR_OK) {
if (cnt >= start_file && cnt < (start_file + FILES_PER_PAGE)) {
//uint16_t sec = ((fno.ftime<<1) & 0x3F);
//uint16_t min = ((fno.ftime>>5) & 0x3F);
//uint16_t h = ((fno.ftime>>11) & 0x1F);
//uint16_t d = ((fno.fdate>>0) & 0x1F);
//uint16_t m = ((fno.fdate>>5) & 0x0F);
//uint16_t year= ((fno.fdate>>9) & 0x3F) + 1980;
//lcd_printf(x, y, "%2d %s %u - %u/%02u/%02u %02u:%02u:%02u", cnt, fno.fname, fno.fsize, year, m, d, h, min, sec);
browser_draw_button(cnt - start_file + FILE_BUTTON_FILE, fno.fname);
}
cnt++;
if (file_count && (start_file + FILES_PER_PAGE == cnt)) break;
}
f_closedir(&dj);
// Calculate page and file count on first run
if (file_count == 0) {
file_count = cnt;
page_count = cnt == 0 ? 1 : (file_count + FILES_PER_PAGE - 1) / FILES_PER_PAGE;
}
browser_draw_buttons();
lcd_printf(LCD_WIDTH / 2 - 3 * bFONT_WIDTH, LCD_HEIGHT - (FILE_BOTTOM_HEIGHT + bFONT_STR_HEIGHT) / 2, "- %u | %u -", page, page_count);
lcd_set_font(FONT_SMALL);
return;
}
static void browser_key_press(int key) {
int page;
switch (key) {
case FILE_BUTTON_LEFT:
case FILE_BUTTON_RIGHT: // Switch page on left / right change
page = current_page;
if (key == FILE_BUTTON_LEFT && --current_page < 1) current_page = page_count;
if (key == FILE_BUTTON_RIGHT && ++current_page > page_count) current_page = 1;
if (page != current_page)
browser_draw_page(current_page);
break;
case FILE_BUTTON_EXIT: //Exit
ui_mode_normal();
break;
case FILE_BUTTON_DEL: // Toggle delete mode
sel_mode^= 1;
browser_draw_buttons();
break;
case FILE_BUTTON_FILE: // Open or delete file
default:
browser_open_file(key - FILE_BUTTON_FILE + (current_page - 1) * FILES_PER_PAGE);
if (sel_mode) {
file_count = 0; // Reeset file count (recalculate on draw page)
selection = -1; // Reset delection
sel_mode = 0; // Exit file delete mode
browser_draw_page(current_page);
return;
}
ui_mode_normal(); // Exit
break;
}
}
static int browser_get_max(void) {
// get max buttons depend from page and file count
int max = current_page == page_count ? (file_count % FILES_PER_PAGE) : FILES_PER_PAGE;
if (file_count > 0 && max == 0) max = FILES_PER_PAGE;
return max + FILE_BUTTON_FILE - 1;
}
// Process UI input for browser
static void browser_apply_touch(int touch_x, int touch_y) {
browser_btn_t btn;
int old = selection;
int max = browser_get_max();
for (int idx = 0; idx <= max; idx++) {
browser_get_button_pos(idx, &btn);
if (touch_x < btn.x || touch_x >= btn.x + btn.w ||
touch_y < btn.y || touch_y >= btn.y + btn.h) continue;
// Found button under touch
browser_draw_button(selection = idx, NULL); // draw new selection
browser_draw_button(old, NULL); // clear old
touch_wait_release();
selection = -1;
browser_draw_button(idx, NULL); // clear selection
browser_key_press(idx);
return;
}
}
static void ui_process_browser_lever(void) {
uint16_t status = btn_check();
if (status == 0) return;
if (status == EVT_BUTTON_SINGLE_CLICK) {
if (selection >= 0) browser_key_press(selection); // Process click
return;
}
int max = browser_get_max();
do {
int old = selection;
if((status & EVT_DOWN) && --selection < 0) selection = max;
if((status & EVT_UP) && ++selection > max) selection = 0;
if (old != selection) {
browser_draw_button(old, NULL); // clear old selection
browser_draw_button(selection, NULL); // draw new selection
}
chThdSleepMilliseconds(100);
} while ((status = btn_wait_release()) != 0);
}
static UI_FUNCTION_CALLBACK(menu_sdcard_browse_cb) {
(void)item;
if (ui_mode == UI_BROWSER)
return;
area_width = 0;
area_height = 0;
ui_mode = UI_BROWSER;
keypad_mode = data;
current_page = 1;
file_count = 0;
selection = -1;
sel_mode = 0;
browser_draw_page(current_page);
}
Loading…
Cancel
Save

Powered by TurnKey Linux.