Update to V5.1

This commit is contained in:
Agustín Gimenez 2024-05-05 13:17:44 +02:00
parent e99cc31c89
commit c13c6fcbd3
10 changed files with 182 additions and 58 deletions

View File

@ -13,13 +13,14 @@
"type": "cortex-debug", "type": "cortex-debug",
"servertype": "openocd", "servertype": "openocd",
"gdbPath": "arm-none-eabi-gdb", "gdbPath": "arm-none-eabi-gdb",
"openOCDLaunchCommands": ["adapter speed 5000"],
"device": "RP2040", "device": "RP2040",
"configFiles": [ "configFiles": [
"interface/picoprobe.cfg", "interface/cmsis-dap.cfg",
"target/rp2040.cfg" "target/rp2040.cfg"
], ],
"svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd", "svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd",
"runToMain": true, "runToEntryPoint": "main",
// Give restart the same functionality as runToMain // Give restart the same functionality as runToMain
"postRestartCommands": [ "postRestartCommands": [
"break main", "break main",

View File

@ -61,8 +61,6 @@
"cyw43_arch.h": "c", "cyw43_arch.h": "c",
"logicanalyzer_build_settings.h": "c", "logicanalyzer_build_settings.h": "c",
"sync.h": "c", "sync.h": "c",
"flash.h": "c", "flash.h": "c"
"shared_buffers.h": "c",
"logicanalyzer_wifi.h": "c"
}, },
} }

View File

@ -5,6 +5,8 @@ cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
# set(PICO_BOARD pico_w)
# Initialise pico_sdk from installed location # Initialise pico_sdk from installed location
# (note this can come from environment, CMake cache etc) # (note this can come from environment, CMake cache etc)
set(PICO_SDK_PATH "F:/PicoSDK/Pico/pico-sdk") set(PICO_SDK_PATH "F:/PicoSDK/Pico/pico-sdk")
@ -30,7 +32,7 @@ pico_generate_pio_header(${PROJECT_NAME}
) )
pico_set_program_name(LogicAnalyzer "LogicAnalyzer") pico_set_program_name(LogicAnalyzer "LogicAnalyzer")
pico_set_program_version(LogicAnalyzer "4.5") pico_set_program_version(LogicAnalyzer "5.1")
pico_enable_stdio_uart(LogicAnalyzer 0) pico_enable_stdio_uart(LogicAnalyzer 0)
@ -50,6 +52,7 @@ target_link_libraries(LogicAnalyzer
hardware_pio hardware_pio
hardware_clocks hardware_clocks
hardware_flash hardware_flash
hardware_adc
pico_multicore pico_multicore
pico_base_headers pico_base_headers
pico_multicore pico_multicore

View File

@ -153,6 +153,41 @@ void sendResponse(const char* response, bool toWiFi)
printf(response); printf(response);
} }
/// @brief Transfer a buffer of data through USB using the TinyUSB CDC functions
/// @param data Buffer of data to transfer
/// @param len Length of the buffer
void cdc_transfer(unsigned char* data, int len)
{
int left = len;
int pos = 0;
while(left > 0)
{
int avail = (int) tud_cdc_write_available();
if(avail > left)
avail = left;
if(avail)
{
int transferred = (int) tud_cdc_write(data + pos, avail);
tud_task();
tud_cdc_write_flush();
pos += transferred;
left -= transferred;
}
else
{
tud_task();
tud_cdc_write_flush();
if (!tud_cdc_connected())
break;
}
}
}
/// @brief Processes data received from the host application /// @brief Processes data received from the host application
/// @param data The received data /// @param data The received data
/// @param length Length of the data /// @param length Length of the data
@ -229,7 +264,7 @@ void processData(uint8_t* data, uint length, bool fromWiFi)
break; break;
} }
else else
started = startCaptureSimple(req->frequency, req->preSamples, req->postSamples, (uint8_t*)&req->channels, req->channelCount, req->trigger, req->inverted, req->captureMode); started = startCaptureSimple(req->frequency, req->preSamples, req->postSamples, req->loopCount, (uint8_t*)&req->channels, req->channelCount, req->trigger, req->inverted, req->captureMode);
#endif #endif
@ -245,7 +280,7 @@ void processData(uint8_t* data, uint length, bool fromWiFi)
#ifdef USE_CYGW_WIFI #ifdef USE_CYGW_WIFI
case 2: case 2: //Update WiFi settings
wReq = (WIFI_SETTINGS_REQUEST*)&messageBuffer[3]; wReq = (WIFI_SETTINGS_REQUEST*)&messageBuffer[3];
WIFI_SETTINGS settings; WIFI_SETTINGS settings;
@ -279,6 +314,27 @@ void processData(uint8_t* data, uint length, bool fromWiFi)
break; break;
case 3: //Read power status
if(!fromWiFi)
sendResponse("ERR_UNSUPPORTED\n", fromWiFi);
else
{
EVENT_FROM_FRONTEND powerEvent;
powerEvent.event = GET_POWER_STATUS;
event_push(&frontendToWifi, &powerEvent);
}
break;
#else
case 2:
case 3:
sendResponse("ERR_UNSUPPORTED\n", fromWiFi);
break;
#endif #endif
default: default:
@ -312,41 +368,6 @@ void processData(uint8_t* data, uint length, bool fromWiFi)
//have any data, but the capture request has a CAPTURE_REQUEST struct as data. //have any data, but the capture request has a CAPTURE_REQUEST struct as data.
} }
/// @brief Transfer a buffer of data through USB using the TinyUSB CDC functions
/// @param data Buffer of data to transfer
/// @param len Length of the buffer
void cdc_transfer(unsigned char* data, int len)
{
int left = len;
int pos = 0;
while(left > 0)
{
int avail = (int) tud_cdc_write_available();
if(avail > left)
avail = left;
if(avail)
{
int transferred = (int) tud_cdc_write(data + pos, avail);
tud_task();
tud_cdc_write_flush();
pos += transferred;
left -= transferred;
}
else
{
tud_task();
tud_cdc_write_flush();
if (!tud_cdc_connected())
break;
}
}
}
/// @brief Receive and process USB data from the host application /// @brief Receive and process USB data from the host application
/// @param skipProcessing If true the received data is not processed (used for cleanup) /// @param skipProcessing If true the received data is not processed (used for cleanup)
/// @return True if anything is received, false if not /// @return True if anything is received, false if not
@ -376,6 +397,19 @@ void purgeUSBData()
while(getchar_timeout_us(0) != PICO_ERROR_TIMEOUT); while(getchar_timeout_us(0) != PICO_ERROR_TIMEOUT);
} }
/// @brief Send a string response with the power status
/// @param status Status received from the WiFi core
void sendPowerStatus(POWER_STATUS* status)
{
char buffer[32];
memset(buffer, 0, 32);
int len = sprintf(buffer, "%.2f", status->vsysVoltage);
buffer[len++] = '_';
buffer[len++] = status->vbusConnected ? '1' : '0';
buffer[len] = '\n';
sendResponse(buffer, true);
}
/// @brief Callback for the WiFi event queue /// @brief Callback for the WiFi event queue
/// @param event Received event /// @param event Received event
void wifiEvent(void* event) void wifiEvent(void* event)
@ -402,6 +436,13 @@ void wifiEvent(void* event)
else else
processData(wEvent->data, wEvent->dataLength, true); processData(wEvent->data, wEvent->dataLength, true);
break; break;
case POWER_STATUS_DATA:
{
POWER_STATUS status;
memcpy(&status, wEvent->data, sizeof(POWER_STATUS));
sendPowerStatus(&status);
}
break;
} }
} }
@ -603,7 +644,9 @@ int main()
else else
{ {
LED_ON(); LED_ON();
#ifdef SUPPORTS_COMPLEX_TRIGGER
check_fast_interrupt(); check_fast_interrupt();
#endif
sleep_ms(1000); sleep_ms(1000);
} }
} }

View File

@ -199,6 +199,7 @@ static bool captureFinished;
static bool captureProcessed; static bool captureProcessed;
//Pin mapping, used to map the channels to the PIO program //Pin mapping, used to map the channels to the PIO program
//COMPLEX_TRIGGER_IN_PIN is added at the end of the array to support the chained mode
#if defined (BUILD_PICO) #if defined (BUILD_PICO)
const uint8_t pinMap[] = {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,27,28,COMPLEX_TRIGGER_IN_PIN}; const uint8_t pinMap[] = {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,26,27,28,COMPLEX_TRIGGER_IN_PIN};
#elif defined (BUILD_PICO_W) #elif defined (BUILD_PICO_W)
@ -212,16 +213,18 @@ static bool captureProcessed;
//Main capture buffer, aligned at a 32k boundary, to use the maxixmum ring size supported by DMA channels //Main capture buffer, aligned at a 32k boundary, to use the maxixmum ring size supported by DMA channels
static uint8_t captureBuffer[CAPTURE_BUFFER_SIZE] __attribute__((aligned(32768))); static uint8_t captureBuffer[CAPTURE_BUFFER_SIZE] __attribute__((aligned(32768)));
//-----------------------------------------------------------------------------
//--------------Complex trigger PIO program------------------------------------
//-----------------------------------------------------------------------------
#define COMPLEX_TRIGGER_wrap_target 0
#define COMPLEX_TRIGGER_wrap 8
#define CAPTURE_TYPE_SIMPLE 0 #define CAPTURE_TYPE_SIMPLE 0
#define CAPTURE_TYPE_COMPLEX 1 #define CAPTURE_TYPE_COMPLEX 1
#define CAPTURE_TYPE_FAST 2 #define CAPTURE_TYPE_FAST 2
//-----------------------------------------------------------------------------
//--------------Complex trigger PIO program------------------------------------
//-----------------------------------------------------------------------------
#ifdef SUPPORTS_COMPLEX_TRIGGER
#define COMPLEX_TRIGGER_wrap_target 0
#define COMPLEX_TRIGGER_wrap 8
uint16_t COMPLEX_TRIGGER_program_instructions[] = { uint16_t COMPLEX_TRIGGER_program_instructions[] = {
// .wrap_target // .wrap_target
0x80a0, // 0: pull block 0x80a0, // 0: pull block
@ -247,6 +250,7 @@ static inline pio_sm_config COMPLEX_TRIGGER_program_get_default_config(uint offs
sm_config_set_wrap(&c, offset + COMPLEX_TRIGGER_wrap_target, offset + COMPLEX_TRIGGER_wrap); sm_config_set_wrap(&c, offset + COMPLEX_TRIGGER_wrap_target, offset + COMPLEX_TRIGGER_wrap);
return c; return c;
} }
#endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//--------------Complex trigger PIO program END-------------------------------- //--------------Complex trigger PIO program END--------------------------------
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -254,6 +258,8 @@ static inline pio_sm_config COMPLEX_TRIGGER_program_get_default_config(uint offs
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//--------------Fast trigger PIO program--------------------------------------- //--------------Fast trigger PIO program---------------------------------------
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifdef SUPPORTS_COMPLEX_TRIGGER
#define FAST_TRIGGER_wrap_target 0 #define FAST_TRIGGER_wrap_target 0
#define FAST_TRIGGER_wrap 31 #define FAST_TRIGGER_wrap 31
@ -295,6 +301,7 @@ uint8_t create_fast_trigger_program(uint8_t pattern, uint8_t length)
return first; return first;
} }
#endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//--------------Fast trigger PIO program END----------------------------------- //--------------Fast trigger PIO program END-----------------------------------
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -370,8 +377,10 @@ uint32_t find_capture_tail()
//Disable the trigger GPIOs to avoid triggering again a chained device //Disable the trigger GPIOs to avoid triggering again a chained device
void disable_gpios() void disable_gpios()
{ {
#ifdef SUPPORTS_COMPLEX_TRIGGER
gpio_deinit(COMPLEX_TRIGGER_OUT_PIN); gpio_deinit(COMPLEX_TRIGGER_OUT_PIN);
gpio_deinit(COMPLEX_TRIGGER_IN_PIN); gpio_deinit(COMPLEX_TRIGGER_IN_PIN);
#endif
for(uint8_t i = 0; i < lastCapturePinCount; i++) for(uint8_t i = 0; i < lastCapturePinCount; i++)
gpio_deinit(lastCapturePins[i]); gpio_deinit(lastCapturePins[i]);
@ -590,6 +599,8 @@ void stopCapture()
{ {
uint32_t int_status = save_and_disable_interrupts(); uint32_t int_status = save_and_disable_interrupts();
#ifdef SUPPORTS_COMPLEX_TRIGGER
if(lastCaptureType == CAPTURE_TYPE_SIMPLE) if(lastCaptureType == CAPTURE_TYPE_SIMPLE)
simple_capture_completed(); simple_capture_completed();
else if(lastCaptureType == CAPTURE_TYPE_COMPLEX) else if(lastCaptureType == CAPTURE_TYPE_COMPLEX)
@ -597,6 +608,12 @@ void stopCapture()
else if(lastCaptureType == CAPTURE_TYPE_FAST) else if(lastCaptureType == CAPTURE_TYPE_FAST)
fast_capture_completed(); fast_capture_completed();
#else
simple_capture_completed();
#endif
restore_interrupts(int_status); restore_interrupts(int_status);
} }
} }

View File

@ -1,7 +1,7 @@
#ifndef __BUILD_SETTINGS__ #ifndef __BUILD_SETTINGS__
#define __BUILD_SETTINGS__ #define __BUILD_SETTINGS__
#define FIRMWARE_VERSION "V5_0" #define FIRMWARE_VERSION "V5_1"
//Select the board type to build the firmware for //Select the board type to build the firmware for
#define BUILD_PICO #define BUILD_PICO

View File

@ -66,7 +66,8 @@
CYW_READY, CYW_READY,
CONNECTED, CONNECTED,
DISCONNECTED, DISCONNECTED,
DATA_RECEIVED DATA_RECEIVED,
POWER_STATUS_DATA
} WIFI_EVENT; } WIFI_EVENT;
@ -75,7 +76,8 @@
LED_ON, LED_ON,
LED_OFF, LED_OFF,
CONFIG_RECEIVED, CONFIG_RECEIVED,
SEND_DATA SEND_DATA,
GET_POWER_STATUS
} FRONTEND_EVENT; } FRONTEND_EVENT;
@ -95,6 +97,13 @@
} EVENT_FROM_FRONTEND; } EVENT_FROM_FRONTEND;
typedef struct _POWER_STATUS
{
float vsysVoltage;
bool vbusConnected;
} POWER_STATUS;
#endif #endif
#endif #endif

View File

@ -11,6 +11,8 @@
#include "pico/stdlib.h" #include "pico/stdlib.h"
#include "pico/cyw43_arch.h" #include "pico/cyw43_arch.h"
#include "pico/multicore.h" #include "pico/multicore.h"
#include "hardware/adc.h"
#include "hardware/gpio.h"
#include "hardware/flash.h" #include "hardware/flash.h"
#include "lwip/pbuf.h" #include "lwip/pbuf.h"
#include "lwip/tcp.h" #include "lwip/tcp.h"
@ -27,6 +29,39 @@ bool boot = false;
#define LED_ON() cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1) #define LED_ON() cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1)
#define LED_OFF() cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0) #define LED_OFF() cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0)
void getPowerStatus()
{
EVENT_FROM_WIFI evtPower;
evtPower.event = POWER_STATUS_DATA;
evtPower.dataLength = sizeof(POWER_STATUS);
POWER_STATUS* status = (POWER_STATUS*)&evtPower.data;
adc_init();
uint32_t oldInt = save_and_disable_interrupts();
uint32_t old_pad = padsbank0_hw->io[29];
uint32_t old_ctrl = iobank0_hw->io[29].ctrl;
adc_gpio_init(29);
adc_select_input(3);
sleep_ms(100);
const float conversion_factor = 3.3f / (1 << 12);
status->vsysVoltage = adc_read() * conversion_factor * 3;
gpio_init(29);
padsbank0_hw->io[29] = old_pad;
iobank0_hw->io[29].ctrl = old_ctrl;
restore_interrupts(oldInt);
status->vbusConnected = cyw43_arch_gpio_get(2);
event_push(&wifiToFrontend, &evtPower);
}
void readSettings() void readSettings()
{ {
wifiSettings = *((volatile WIFI_SETTINGS*)(FLASH_SETTINGS_ADDRESS)); wifiSettings = *((volatile WIFI_SETTINGS*)(FLASH_SETTINGS_ADDRESS));
@ -87,7 +122,9 @@ err_t serverReceiveData(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t e
//Client disconnected //Client disconnected
if(!p || p->tot_len == 0) if(!p || p->tot_len == 0)
{ {
pbuf_free(p); if(p)
pbuf_free(p);
killClient(); killClient();
evt.event = DISCONNECTED; evt.event = DISCONNECTED;
event_push(&wifiToFrontend, &evt); event_push(&wifiToFrontend, &evt);
@ -227,6 +264,7 @@ void frontendEvent(void* event)
case LED_ON: case LED_ON:
LED_ON(); LED_ON();
break; break;
case LED_OFF: case LED_OFF:
LED_OFF(); LED_OFF();
break; break;
@ -241,6 +279,10 @@ void frontendEvent(void* event)
case SEND_DATA: case SEND_DATA:
sendData(evt->data, evt->dataLength); sendData(evt->data, evt->dataLength);
break; break;
case GET_POWER_STATUS:
getPowerStatus();
break;
} }
} }
@ -262,4 +304,5 @@ void runWiFiCore()
cyw43_arch_poll(); cyw43_arch_poll();
} }
} }
#endif #endif

View File

@ -18,6 +18,7 @@
} WIFI_STATE_MACHINE; } WIFI_STATE_MACHINE;
void runWiFiCore(); void runWiFiCore();
bool getVsysState();
#endif #endif
#endif #endif

View File

@ -11,6 +11,10 @@ namespace SharedDriver
{ {
public class LogicAnalyzerDriver : IDisposable, IAnalizerDriver public class LogicAnalyzerDriver : IDisposable, IAnalizerDriver
{ {
const int MAJOR_VERSION = 5;
const int MINOR_VERSION = 1;
Regex regVersion = new Regex(".*?(V([0-9]+)_([0-9]+))$"); Regex regVersion = new Regex(".*?(V([0-9]+)_([0-9]+))$");
Regex regAddressPort = new Regex("([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)\\:([0-9]+)"); Regex regAddressPort = new Regex("([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)\\:([0-9]+)");
StreamReader readResponse; StreamReader readResponse;
@ -85,15 +89,22 @@ namespace SharedDriver
if (verMatch == null || !verMatch.Success || !verMatch.Groups[2].Success) if (verMatch == null || !verMatch.Success || !verMatch.Groups[2].Success)
{ {
Dispose(); Dispose();
throw new DeviceConnectionException($"Invalid device version V{ (string.IsNullOrWhiteSpace(verMatch?.Value) ? "(unknown)" : verMatch?.Value) }, minimum supported version: V5_0"); throw new DeviceConnectionException($"Invalid device version V{ (string.IsNullOrWhiteSpace(verMatch?.Value) ? "(unknown)" : verMatch?.Value) }, minimum supported version: V{MAJOR_VERSION}_{MINOR_VERSION}");
} }
int majorVer = int.Parse(verMatch.Groups[2].Value); int majorVer = int.Parse(verMatch.Groups[2].Value);
int minorVer = int.Parse(verMatch.Groups[3].Value);
if (majorVer < 5) if (majorVer < MAJOR_VERSION)
{ {
Dispose(); Dispose();
throw new DeviceConnectionException($"Invalid device version V{verMatch.Value}, minimum supported version: V5_0"); throw new DeviceConnectionException($"Invalid device version V{verMatch.Value}, minimum supported version: V{MAJOR_VERSION}_{MINOR_VERSION}");
}
if (majorVer == MAJOR_VERSION && minorVer < MINOR_VERSION)
{
Dispose();
throw new DeviceConnectionException($"Invalid device version V{verMatch.Value}, minimum supported version: V{MAJOR_VERSION}_{MINOR_VERSION}");
} }
baseStream.ReadTimeout = Timeout.Infinite; baseStream.ReadTimeout = Timeout.Infinite;
@ -456,8 +467,6 @@ namespace SharedDriver
public string? GetVoltageStatus() public string? GetVoltageStatus()
{ {
return "UNSUPPORTED";
if (!isNetwork) if (!isNetwork)
return "UNSUPPORTED"; return "UNSUPPORTED";