diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d16386367f7cd7dd3c1842c484239e9e82a25efc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/ \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000000000000000000000000000000000000..630290e9e2a7f266b8eafc30a990c9b86eed5fe4 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,26 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**", + "/usr/include/opencv4/**" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "c17", + "cppStandard": "gnu++17", + "intelliSenseMode": "linux-gcc-x64" + }, + { + "name": "docker", + "includePath": [ + "${workspaceFolder}/**", + "/opt/pico-sdk/1.5.1/src/**" + ], + "intelliSenseMode": "linux-gcc-arm" + + } + ], + "version": 4 +} \ No newline at end of file diff --git a/firmware/README.md b/firmware/README.md index f7dcdcfe1b0b7f087c6b4beedb0336afe361ca3e..9b8346e668445ed5be595d8c4d605444d5bcf923 100644 --- a/firmware/README.md +++ b/firmware/README.md @@ -12,8 +12,8 @@ Documents found that could be useful. Program that run to the PC to configure the camera and acquire images. ## uc -Code of the Raspberry Pi Pico which generates trigger signal and flashs. -Can be controlled via UART. +Code of the Raspberry Pi Pico which generates trigger signal and flash. +Can be controlled via UART. ## ui -Graphical interface for easy control of the Raspberry Pi Pico. +Graphical interface for easy control of the Raspberry Pi Pico. diff --git a/firmware/imageProc/code/CMakeLists.txt b/firmware/imageProc/code/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..16da0273f6c720266e917dbbeebd470e4fdb464e --- /dev/null +++ b/firmware/imageProc/code/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.20) + +project(imageproc LANGUAGES CXX) + +find_package(OpenCV REQUIRED) + +include_directories(${OpenCV_INCLUDE_DIRS}) + +add_subdirectory(src) \ No newline at end of file diff --git a/firmware/imageProc/code/src/CMakeLists.txt b/firmware/imageProc/code/src/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..6412c450344fcdc630d951b511c8e54dc4b7cf1b --- /dev/null +++ b/firmware/imageProc/code/src/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.20) + +project(app) + +file(GLOB SRC *.cpp) + +link_directories("/opt/SVS/SVCamKit/SDK/Linux64_x64/") + +add_executable(${PROJECT_NAME} ${SRC}) +target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS} SVGenSDK64) \ No newline at end of file diff --git a/firmware/imageProc/code/src/main.cpp b/firmware/imageProc/code/src/main.cpp index 7ca793a9078c1de02d058d35b2496c740d31ee09..86686c8ae1306b13f933a44e2075f789e41cc7cb 100644 --- a/firmware/imageProc/code/src/main.cpp +++ b/firmware/imageProc/code/src/main.cpp @@ -53,7 +53,7 @@ void * AcquisitionThread(SV_STREAM_HANDLE context) continue; } - printf("Image Received FrameId:%lld Info Ptr:0x%p Width:%zd Height:%zd\n", bufferInfo.iImageId, bufferInfo.pImagePtr, bufferInfo.iSizeX, bufferInfo.iSizeY); + printf("Image Received FrameId:%ld Info Ptr:0x%p Width:%zd Height:%zd\n", bufferInfo.iImageId, bufferInfo.pImagePtr, bufferInfo.iSizeX, bufferInfo.iSizeY); printf("----------------------------------------------\n"); cv::Mat img(bufferInfo.iSizeY, bufferInfo.iSizeX, CV_8UC1, bufferInfo.pImagePtr); @@ -69,7 +69,8 @@ void * AcquisitionThread(SV_STREAM_HANDLE context) } char filename_png[1024]; - sprintf(filename_png, "img/image_%lld.png", bufferInfo.iImageId); + sprintf(filename_png, "img/image_%ld.png", bufferInfo.iImageId); + printf("filename: %s\n", filename_png); cv::imwrite(filename_png, new_image); diff --git a/firmware/uc/.devcontainer/devcontainer.json b/firmware/uc/.devcontainer/devcontainer.json new file mode 100644 index 0000000000000000000000000000000000000000..2a36bc75459db092fbcc0477c8cd85a04f5f57f7 --- /dev/null +++ b/firmware/uc/.devcontainer/devcontainer.json @@ -0,0 +1,20 @@ +{ + "image" : "labinfo.ing.he-arc.ch:5050/igib/shared/ci-docker/pico-sdk:latest", + "runArgs": ["--name", "pico-sdk-container"], + "name": "pi-etat-marche-sdk", + "privileged": true, + "updateRemoteUserUID": true, + "postStartCommand": "sudo service ssh start && /bin/bash", + "postAttachCommand": "/bin/bash", + "customizations": { + "vscode": { + "extensions": [ + "ms-vscode.cpptools-extension-pack", + "ms-vscode.cmake-tools", + "mcu-debug.debug-tracker-vscode", + "marus25.cortex-debug" + ] + } + + } +} \ No newline at end of file diff --git a/firmware/uc/.vscode/c_cpp_properties.json b/firmware/uc/.vscode/c_cpp_properties.json new file mode 100644 index 0000000000000000000000000000000000000000..053854d68ea02f3e28a2634a655f964b759f6781 --- /dev/null +++ b/firmware/uc/.vscode/c_cpp_properties.json @@ -0,0 +1,16 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**", + "/opt/pico-sdk/1.5.1/src/**" + ], + "cStandard": "c11", + "cppStandard": "c++17", + "intelliSenseMode": "linux-gcc-arm" + + } + ], + "version": 4 +} \ No newline at end of file diff --git a/firmware/uc/.vscode/launch.json b/firmware/uc/.vscode/launch.json new file mode 100644 index 0000000000000000000000000000000000000000..6739f6c46cbb27c5b7eba4fd6466f8fb0a2672be --- /dev/null +++ b/firmware/uc/.vscode/launch.json @@ -0,0 +1,37 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "cwd": "${workspaceRoot}", + "executable": "${workspaceRoot}/code/build/PI_ContrHorlo.elf", + "name": "Debug with OpenOCD", + "request": "launch", + "type": "cortex-debug", + "servertype": "openocd", + "gdbPath": "arm-none-eabi-gdb", + "device": "RP2040", + "interface": "swd", + "configFiles": [ + "interface/cmsis-dap.cfg", + "target/rp2040.cfg" + ], + "svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd", + "searchDir": [ + "/usr/local/share/openocd/scripts/", + ], + "runToEntryPoint": "main", + // Work around for stopping at main on restart + "postRestartCommands": [ + "break main", + "continue" + ], + "openOCDLaunchCommands": [ + "adapter speed 5000" + ], + "showDevDebugOutput": "vscode" + } + ] +} \ No newline at end of file diff --git a/firmware/uc/README.md b/firmware/uc/README.md index c3b46533b5b5e1416ffb7bcfcf40ac318d18c62f..8f6c13a6d0db0a04fe069857b6b08356c1abe733 100644 --- a/firmware/uc/README.md +++ b/firmware/uc/README.md @@ -1,71 +1,64 @@ +# Uc Code created on the Raspberry Pi Pico platform. It generates a trigger signal and a series of flashes of light. It can be controlled via UART commands. + # Installation -## Pi Debug -Download and install the OpenOCD dependencies: +To use the provided container simply login to gitlab with docker: ```bash -sudo apt install automake autoconf build-essential texinfo libtool libftdi-dev libusb-1.0-0-dev +docker login labinfo.ing.he-arc.ch:5050 ``` -Clone, build and install OpenOCD: + +And then open the folder in the container. + +## Build and flash + +The container has a build and deploy script already installed. ```bash -cd /tmp/ -git clone https://github.com/raspberrypi/openocd.git --branch rp2040-v0.12.0 --depth=1 --no-single-branch -cd openocd -./bootstrap -./configure -make -j4 -sudo make install +Build Raspberry Pi Pico projects + +Syntax: /usr/bin/pico_build [-b|c|d|f|h|p] +[ -b ] Build project. +[ -c ] Clean +[ -d ] Launch debugger +[ -f ] Flash board +[ -h ] Help +[ -p PATH ] Set project path ``` -Check OpenOCD version: +Example to build and deploy the firmware: ```bash -openocd --version +pico_build -p code -bf ``` -Output: +To build without the script: ```bash -Open On-Chip Debugger 0.12.0-g4d87f6d (2024-01-08-14:31) -Licensed under GNU GPL v2 -For bug reports, read - http://openocd.org/doc/doxygen/bugs.html - +cd code +mkdir -p build +cmake .. +make -j4 ``` +## Pi Debug + +**This most be done on the host machine.** Create a file with any name (ex. pico_openocd.rules) under /etc/udev/rules.d and put this line inside. ```bash ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000c", MODE="660", GROUP="plugdev", TAG+="uaccess" ``` -## SDK Config -1. Clone repository https://labinfo.ing.he-arc.ch/gitlab/igib/public/raspberry-pi-pico/raspberry-pi-pico-sdk -2. Go in the folder and init it: - ``` - cd raspberry-pi-pico-sdk - git submodule update --recursive --init pico-sdk - ``` -3. Clone this git into the folder raspberry-pi-pico-sdk. - +Then recompile and deploy your code with debug tags: -## Create docker image -It is possible to directly create the docker image in the raspberry-pi-pico-sdk folder: -``` -docker build -t pico-dev . +```bash +cd code/build +cmake -DCMAKE_BUILD_TYPE=DEBUG +pico_build -p code -bf ``` -## Build and flash - -- Build only : ```./build.sh -b -p PI_ContrHorlo/uc/``` -- Build and flash : ```./build.sh -bf -p PI_ContrHorlo/uc/``` - - -## Configuration -- Raspberry Pi Pico -- Raspberry Pi Debug -- Ubuntu 22.04.4 LTS \ No newline at end of file +Using VScode debug tab lanuch a new debug session. \ No newline at end of file diff --git a/firmware/uc/code/.config b/firmware/uc/code/.config index 068bd6d19d6d7f6f4226726b446fe478c4ce7bff..f58d12c0d0e6105198ef50a06778aa1debd2bb9d 100644 --- a/firmware/uc/code/.config +++ b/firmware/uc/code/.config @@ -1,3 +1,2 @@ -BOARD_TYPE=grove_pico_w -SRC_PATH=. - +BOARD_TYPE=pico +SRC_PATH=. \ No newline at end of file diff --git a/firmware/uc/code/CMakeLists.txt b/firmware/uc/code/CMakeLists.txt index b81ae4401bdee7f7a374fa08f79f347db639316d..91ae99d729ab4c66481efc45c1370f021bbd5d66 100644 --- a/firmware/uc/code/CMakeLists.txt +++ b/firmware/uc/code/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 3.13) +set(PICO_SDK_FETCH_FROM_GIT ON) include(pico_sdk_import.cmake) project(PI_ContrHorlo C CXX ASM) @@ -20,4 +21,4 @@ pico_enable_stdio_uart(${PROJECT_NAME} 1) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}) target_link_libraries(${PROJECT_NAME} pico_stdlib pico_multicore) -pico_add_extra_outputs(${PROJECT_NAME}) +pico_add_extra_outputs(${PROJECT_NAME}) \ No newline at end of file diff --git a/firmware/uc/code/grove_pico_w.h b/firmware/uc/code/grove_pico_w.h deleted file mode 100644 index c7c15e24665fb9d5ea4d091a5ff08b5e0032ed50..0000000000000000000000000000000000000000 --- a/firmware/uc/code/grove_pico_w.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2022 Raspberry Pi (Trading) Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -// ----------------------------------------------------- -// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO -// SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES -// ----------------------------------------------------- - -// This header may be included by other board headers as "boards/pico.h" - -#ifndef _BOARDS_GROVE_W_H -#define _BOARDS_GROVE_W_H - -// For board detection -#define RASPBERRYPI_PICO_W - -// --- UART --- -#ifndef PICO_DEFAULT_UART -#define PICO_DEFAULT_UART 0 -#endif -#ifndef PICO_DEFAULT_UART_TX_PIN -#define PICO_DEFAULT_UART_TX_PIN 0 -#endif -#ifndef PICO_DEFAULT_UART_RX_PIN -#define PICO_DEFAULT_UART_RX_PIN 1 -#endif - -// --- LED --- -// no PICO_DEFAULT_LED_PIN - LED is on Wireless chip -// no PICO_DEFAULT_WS2812_PIN - -// --- I2C --- - -#ifndef PICO_DEFAULT_I2C -#define PICO_DEFAULT_I2C 0 -#endif -#ifndef PICO_DEFAULT_I2C_SDA_PIN -#define PICO_DEFAULT_I2C_SDA_PIN 8 -#endif -#ifndef PICO_DEFAULT_I2C_SCL_PIN -#define PICO_DEFAULT_I2C_SCL_PIN 9 -#endif - -#ifndef PICO_I2C0 -#define PICO_I2C0 0 -#endif -#ifndef PICO_I2C0_SDA_PIN -#define PICO_I2C0_SDA_PIN 8 -#endif -#ifndef PICO_I2C0_SCL_PIN -#define PICO_I2C0_SCL_PIN 9 -#endif - -#ifndef PICO_I2C1 -#define PICO_I2C1 1 -#endif -#ifndef PICO_I2C1_SDA_PIN -#define PICO_I2C1_SDA_PIN 6 -#endif -#ifndef PICO_I2C1_SCL_PIN -#define PICO_I2C1_SCL_PIN 7 -#endif - -// --- SPI --- -#ifndef PICO_DEFAULT_SPI -#define PICO_DEFAULT_SPI 0 -#endif -#ifndef PICO_DEFAULT_SPI_SCK_PIN -#define PICO_DEFAULT_SPI_SCK_PIN 18 -#endif -#ifndef PICO_DEFAULT_SPI_TX_PIN -#define PICO_DEFAULT_SPI_TX_PIN 19 -#endif -#ifndef PICO_DEFAULT_SPI_RX_PIN -#define PICO_DEFAULT_SPI_RX_PIN 16 -#endif -#ifndef PICO_DEFAULT_SPI_CSN_PIN -#define PICO_DEFAULT_SPI_CSN_PIN 17 -#endif - -// --- FLASH --- - -#define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 - -#ifndef PICO_FLASH_SPI_CLKDIV -#define PICO_FLASH_SPI_CLKDIV 2 -#endif - -#ifndef PICO_FLASH_SIZE_BYTES -#define PICO_FLASH_SIZE_BYTES (2 * 1024 * 1024) -#endif - -// note the SMSP mode pin is on WL_GPIO1 -// #define PICO_SMPS_MODE_PIN - -#ifndef PICO_RP2040_B0_SUPPORTED -#define PICO_RP2040_B0_SUPPORTED 0 -#endif - -#ifndef PICO_RP2040_B1_SUPPORTED -#define PICO_RP2040_B1_SUPPORTED 0 -#endif - -#ifndef CYW43_PIN_WL_HOST_WAKE -#define CYW43_PIN_WL_HOST_WAKE 24 -#endif - -#ifndef CYW43_PIN_WL_REG_ON -#define CYW43_PIN_WL_REG_ON 23 -#endif - -#ifndef CYW43_WL_GPIO_COUNT -#define CYW43_WL_GPIO_COUNT 3 -#endif - -#ifndef CYW43_WL_GPIO_LED_PIN -#define CYW43_WL_GPIO_LED_PIN 0 -#endif - -// If CYW43_WL_GPIO_VBUS_PIN is defined then a CYW43 GPIO has to be used to read VBUS. -// This can be passed to cyw43_arch_gpio_get to determine if the device is battery powered. -// PICO_VBUS_PIN and CYW43_WL_GPIO_VBUS_PIN should not both be defined. -#ifndef CYW43_WL_GPIO_VBUS_PIN -#define CYW43_WL_GPIO_VBUS_PIN 2 -#endif - -// If CYW43_USES_VSYS_PIN is defined then CYW43 uses the VSYS GPIO (defined by PICO_VSYS_PIN) for other purposes. -// If this is the case, to use the VSYS GPIO it's necessary to ensure CYW43 is not using it. -// This can be achieved by wrapping the use of the VSYS GPIO in cyw43_thread_enter / cyw43_thread_exit. -#ifndef CYW43_USES_VSYS_PIN -#define CYW43_USES_VSYS_PIN 1 -#endif - -// The GPIO Pin used to monitor VSYS. Typically you would use this with ADC. -// There is an example in adc/read_vsys in pico-examples. -#ifndef PICO_VSYS_PIN -#define PICO_VSYS_PIN 29 -#endif - -#endif diff --git a/firmware/uc/code/hw.cpp b/firmware/uc/code/hw.cpp index a70d0dcd977f59f5db934e176f4d2c0086498e82..2b5fc24aa6936fd330a5a516548888fb307184f3 100644 --- a/firmware/uc/code/hw.cpp +++ b/firmware/uc/code/hw.cpp @@ -36,7 +36,7 @@ void on_uart_rx() { // Can we send it back? if (uart_is_writable(UART_ID)) { uartCb(c); - //uart_putc(UART_ID, c); + // uart_putc(UART_ID, c); } } } @@ -46,8 +46,8 @@ void init_uart(){ // Set up our UART with a basic baud rate. uart_init(UART_ID, 2400); - // Set the TX and RX pins by USing the function select on the GPIO - // Set datasheet for more information on function select + // // Set the TX and RX pins by USing the function select on the GPIO + // // Set datasheet for more information on function select gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART); gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART); diff --git a/firmware/uc/code/hw.h b/firmware/uc/code/hw.h index 2dd34d16b866a9d13ec34bdbdb7b18cfe23012f3..10e065310ee375a1151d778bff5a4603e2d07d96 100644 --- a/firmware/uc/code/hw.h +++ b/firmware/uc/code/hw.h @@ -21,8 +21,8 @@ #define UART_TX_PIN 0 #define UART_RX_PIN 1 -#define TRIG_PIN 14 -#define LED_PIN 13 +#define TRIG_PIN 19 +#define LED_PIN 21 typedef void (*uart_callback_t)(char); diff --git a/firmware/uc/code/main.cpp b/firmware/uc/code/main.cpp index 1631b01f7ef80cdf64abcceed074a4892c88a24c..2e8aa747e99d4656a922e2e3cce717cb3423f836 100644 --- a/firmware/uc/code/main.cpp +++ b/firmware/uc/code/main.cpp @@ -339,6 +339,10 @@ int main() { init(); // Common to both cores + gpio_init(PICO_DEFAULT_LED_PIN); + gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); + gpio_put(PICO_DEFAULT_LED_PIN, 1); + multicore_launch_core1(ui_task); queue_ui_in_entry_t ui_in_entry; diff --git a/firmware/uc/code/ui.cpp b/firmware/uc/code/ui.cpp index d6d07fc0219e0da0137d4f749263e06adfc7460d..a3cd2ad7838a08dc02ed6c6cf665f864d4d9ed7c 100644 --- a/firmware/uc/code/ui.cpp +++ b/firmware/uc/code/ui.cpp @@ -133,8 +133,12 @@ void ui_task(){ queue_ui_in_entry_t entry; - while(1){ + while(1) { + queue_remove_blocking(&queue_ui_in, &entry); + + gpio_put(PICO_DEFAULT_LED_PIN, 0); + if(entry.type == LOG_MARCHE){ printf("[LOG] Marche : %f\n", entry.data.float64); }else if(entry.type == LOG_STRING){ @@ -153,6 +157,8 @@ void ui_task(){ }else if(entry.type == LOG_FLASH_ON_TIME){ printf("[LOG] New flash on time : %dus\n", entry.data.uint32); } + + gpio_put(PICO_DEFAULT_LED_PIN, 1); } } diff --git a/firmware/uc/deploy.bat b/firmware/uc/deploy.bat new file mode 100644 index 0000000000000000000000000000000000000000..703ed14f39f8d940783a2688efc5c401a3355b24 --- /dev/null +++ b/firmware/uc/deploy.bat @@ -0,0 +1,109 @@ +@echo off + +@REM Get current path +for %%i in ("%~dp0.") do SET "currentPath=%%~fi" + +SET "CONFIG_FILE=%currentPath%\code\.config" +SET "BUILD_DIR=%currentPath%\code\build" +SET _BUILD=0 +SET _FLASH=0 + +IF NOT EXIST %CONFIG_FILE% ( + @echo BUILD_TYPE=Debug> %CONFIG_FILE% +) + +@REM I Made it static change the path if you need. This scripts load all the Pico SDK environnement +CALL "C:\\Program Files\\Raspberry Pi\\Pico SDK v1.5.1\\pico-env.cmd" > nul 2>&1 + +GOTO :GETOPS + +:BUILD +REM Load variables +FOR /F "delims=" %%A IN (%CONFIG_FILE%) DO SET "%%A" + +mkdir +cmake -G Ninja -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -B %BUILD_DIR%/%BUILD_TYPE% -S . +cmake --build %BUILD_DIR%/%BUILD_TYPE% + +EXIT /b 0 + +:FLASH +ECHO ***Flashing*** +REM Load variables +FOR /F "delims=" %%A IN (%CONFIG_FILE%) DO SET "%%A" + +set "BINARY_DIR=%BUILD_DIR%" +@REM Find executable +FOR /R %BINARY_DIR% %%x in (*.elf) do ( + set PROGRAM=%%x +) + +@REM SET PROGRAM=%PROGRAM:\=\\% +SET PROGRAM=%BINARY_DIR%\PI_ContrHorlo.elf +@REM SET PROGRAM=%PROGRAM:\=\\% +SET PROGRAM=%PROGRAM:\=\\% + +ECHO Loading executable %PROGRAM% + +openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" -c "program %PROGRAM% verify reset exit" + +EXIT /b 0 + +:GETOPS +SET LAST_OPT=%1 + +@REM Check args +IF [%LAST_OPT%]==[] GOTO :USAGE +IF [%LAST_OPT%]==[-h] GOTO :USAGE +IF [%LAST_OPT%]==[--help] GOTO :USAGE + +@REM Check build +IF [%LAST_OPT%]==[--build] SET LAST_OPT=-b +IF [%LAST_OPT%]==[-b] ( + SET _BUILD=1 +) + +@REM Check flash +IF [%LAST_OPT%]==[--flash] SET LAST_OPT=-f +IF [%LAST_OPT%]==[-f] ( + SET _FLASH=1 +) + +@REM Check Type +IF [%LAST_OPT%]==[-t] ( + SHIFT + IF ["%2"]==["Debug"] ( + @ECHO BUILD_TYPE=Debug> %CONFIG_FILE% + ) ELSE IF ["%2"]==["Release"] ( + @ECHO BUILD_TYPE=Release> %CONFIG_FILE% + ) ELSE ( + ECHO Build type can be either Debug or Release + EXIT 1 + ) +) + +SHIFT +IF NOT "%1" == "" GOTO GETOPS + +IF [%_BUILD%] == [1] ( + CALL :BUILD +) + +IF [%_FLASH%] == [1] ( + CALL :FLASH +) + +EXIT 0 + +:USAGE + +ECHO: Usage %SCRIPTFILE% [OPTIONS] [PARAMS] ^ +ECHO. +ECHO OPTIONS: +ECHO. +ECHO [-b ^| --build] : Build project +ECHO [-c ^| --clean] : Clean +ECHO [-f ^| --flash] : Upload application to Raspberry Pi Pico +ECHO [-h ^| --help] : Help +ECHO [-t ^] : ^Set build ^type. Debug^|Release +EXIT 1 diff --git a/firmware/ui/README.md b/firmware/ui/README.md index 11fb548154a7b5ebd99b00122ffb2ca3afff9fc2..9a7ac386f0a217c9a5320810e83984a05d9cc80e 100644 --- a/firmware/ui/README.md +++ b/firmware/ui/README.md @@ -1,11 +1,20 @@ +# UI Graphical interface for controlling the various signals generated by the Raspberry Pi Pico. This eliminates the need for the user to enter commands on the UART. -# Prerequisites -The interface is developed in Python with PyQt6. Both must be installed beforehand. +# Install + +This project uses [Poetry][1]. To install the environnement run: + +```bash +poetry install +``` # Usage -```python3 main.py DEVICE_NAME``` + +```bash +poetry run python main.py +``` DEVICE_NAME is on Linux generally ttyACM0. @@ -18,4 +27,6 @@ All messages received by the device are displayed. - Ubuntu 22.04.4 LTS - Python 3.10.12 - Raspberry Pi Pico -- Raspberry Pi Debug \ No newline at end of file +- Raspberry Pi Debug + +[1]:https://python-poetry.org/ \ No newline at end of file diff --git a/firmware/ui/main.py b/firmware/ui/main.py index 6ddb00c2b5a986fe470f0de1ec61e4f1f46c1f3e..682783edc91d47f04be1ec19e65fa7cf4c1b6c5d 100644 --- a/firmware/ui/main.py +++ b/firmware/ui/main.py @@ -1,14 +1,23 @@ # Quentin Rod for PI - MSE Computer Science import sys -from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout, QVBoxLayout, QPushButton, QSlider, QLineEdit, QGroupBox, QTextEdit, QLabel -from PyQt6.QtCore import Qt +from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout, QVBoxLayout, QPushButton, QSlider, QLineEdit, QGroupBox, QTextEdit, QLabel +from PySide6.QtCore import Qt import serial import os import threading -from PyQt6.QtCore import pyqtSignal -from PyQt6.QtGui import QIcon +from PySide6.QtCore import Signal as pyqtSignal +from PySide6.QtGui import QIcon, QCloseEvent import time +import serial.tools +import serial.tools.list_ports + +DEFAULT_TRIG_OFF_TIME=92000 +DEFAULT_MIN_EXP_TIME=19 +DEFAULT_FLASH_OFF=15000 +DEFAULT_FLASH_ON=1000 +DEFAULT_TRIG_SHIFT_TIME=1000 + class SerialLogger(QWidget): sig_recv = pyqtSignal(str) def __init__(self, ser): @@ -70,7 +79,6 @@ class Flasher(): def flash_off(self, val): self._send_cmd("flash.off:" + str(val) +";") - flasher = None class CommandWidget(QWidget): @@ -140,6 +148,14 @@ class MainWindow(QMainWindow): self.on_button.clicked.connect(self.on_button_clicked) self.on_button.setChecked(False) self.on_button_clicked() + + self.reset_button = QPushButton("Reset", self) + self.reset_button.setGeometry(200, 150, 100, 40) + self.reset_button.setCheckable(True) + self.reset_button.setMaximumWidth(50) + self.reset_button.clicked.connect(self.reset_button_clicked) + self.reset_button.setChecked(False) + # self.on_button_clicked() #self.on_button.setChecked(False) self.trig_expo_widget = CommandWidget('Minimal exposure time (us)', self.trig_expo_cb, 0, 200, 19) @@ -156,6 +172,7 @@ class MainWindow(QMainWindow): layout_cmd = QVBoxLayout() layout_cmd.addWidget(self.on_button, alignment= Qt.AlignmentFlag.AlignCenter) + layout_cmd.addWidget(self.reset_button, alignment=Qt.AlignmentFlag.AlignCenter) layout_cmd.addWidget(self.trig_off_widget) layout_cmd.addWidget(self.flash_off_widget) layout_cmd.addWidget(self.flash_on_widget) @@ -180,6 +197,24 @@ class MainWindow(QMainWindow): else: self.flasher.off() self.on_button.setText("On") + + def reset_button_clicked(self): + + self.trig_off_widget_cb(DEFAULT_TRIG_OFF_TIME) + self.trig_off_widget.update_val(DEFAULT_TRIG_OFF_TIME) + + self.flash_off_widget_cb(DEFAULT_FLASH_OFF) + self.flash_off_widget.update_val(DEFAULT_FLASH_OFF) + + self.flash_on_widget_cb(DEFAULT_FLASH_ON) + self.flash_on_widget.update_val(DEFAULT_FLASH_ON) + + self.trig_shift_cb(DEFAULT_TRIG_SHIFT_TIME) + self.trig_shift_widget.update_val(DEFAULT_TRIG_SHIFT_TIME) + + self.trig_expo_cb(DEFAULT_MIN_EXP_TIME) + self.trig_expo_widget.update_val(DEFAULT_MIN_EXP_TIME) + def trig_off_widget_cb(self, value): self.flasher.trig_off(value) def flash_off_widget_cb(self, value): @@ -191,17 +226,27 @@ class MainWindow(QMainWindow): def trig_expo_cb(self, value): self.flasher.trig_expo(value) + def closeEvent(self, ev=None): + self.flasher.off() + if __name__ == "__main__": + + import os + + os.chdir(os.path.dirname(__file__)) + if len(sys.argv) != 2: print("Please use : " + sys.argv[0] + " " + "[DEV_UART]") - exit(0) + exit(1) - filename = sys.argv[1] - if not os.path.exists(filename): - print("File doesn't exist") - exit(0) - - ser = serial.Serial(filename, 115200) + port = sys.argv[1] + ports = serial.tools.list_ports.comports() + + if port not in [_port for _port, _, _ in ports]: + print(f"Port {port} not found") + exit(1) + + ser = serial.Serial(port, 115200) app = QApplication(sys.argv) window = MainWindow(ser) diff --git a/firmware/ui/poetry.lock b/firmware/ui/poetry.lock new file mode 100644 index 0000000000000000000000000000000000000000..98206fb04efe1084c9a8330af1ec763827000c45 --- /dev/null +++ b/firmware/ui/poetry.lock @@ -0,0 +1,89 @@ +[[package]] +name = "pyserial" +version = "3.5" +description = "Python Serial Port Extension" +category = "main" +optional = false +python-versions = "*" + +[package.extras] +cp2110 = ["hidapi"] + +[[package]] +name = "PySide6" +version = "6.7.2" +description = "Python bindings for the Qt cross-platform application and UI framework" +category = "main" +optional = false +python-versions = "<3.13,>=3.9" + +[package.dependencies] +PySide6-Addons = "6.7.2" +PySide6-Essentials = "6.7.2" +shiboken6 = "6.7.2" + +[[package]] +name = "PySide6-Addons" +version = "6.7.2" +description = "Python bindings for the Qt cross-platform application and UI framework (Addons)" +category = "main" +optional = false +python-versions = "<3.13,>=3.9" + +[package.dependencies] +PySide6-Essentials = "6.7.2" +shiboken6 = "6.7.2" + +[[package]] +name = "PySide6-Essentials" +version = "6.7.2" +description = "Python bindings for the Qt cross-platform application and UI framework (Essentials)" +category = "main" +optional = false +python-versions = "<3.13,>=3.9" + +[package.dependencies] +shiboken6 = "6.7.2" + +[[package]] +name = "shiboken6" +version = "6.7.2" +description = "Python/C++ bindings helper module" +category = "main" +optional = false +python-versions = "<3.13,>=3.9" + +[metadata] +lock-version = "1.1" +python-versions = ">=3.10,<3.13" +content-hash = "0f12e425a2789ff40a16c23f004e133a89e13b2091c2c549decd38f957bf5a65" + +[metadata.files] +pyserial = [ + {file = "pyserial-3.5-py2.py3-none-any.whl", hash = "sha256:c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0"}, + {file = "pyserial-3.5.tar.gz", hash = "sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb"}, +] +PySide6 = [ + {file = "PySide6-6.7.2-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:602debef9ec159b0db48f83b38a0e43e2dad3961f7d99f708d98620f04e9112b"}, + {file = "PySide6-6.7.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:15e7696a09072ee977f6e6179ab1e48184953df8417bcaa83cfadf0b79747242"}, + {file = "PySide6-6.7.2-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:6e0acb471535de303f56e3077aa86f53496b4de659b99ecce80520bcee508a63"}, + {file = "PySide6-6.7.2-cp39-abi3-win_amd64.whl", hash = "sha256:f73ae0de77d67f51ca3ce8207b12d3a5fa0107d3d5b6e4aeb3b53ee842b0927a"}, +] +PySide6-Addons = [ + {file = "PySide6_Addons-6.7.2-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:90b995efce61058d995c603ea480a9a3054fe8206739dcbc273fc3b53d40650f"}, + {file = "PySide6_Addons-6.7.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:94b9bf6a2a4a7ac671e1776633e50d51326c86f4184f1c6e556f4dd5498fd52a"}, + {file = "PySide6_Addons-6.7.2-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:22979b1aa09d9cf1d7a86c8a9aa0cb4791d6bd1cc94f96c5b6780c5ef8a9e34e"}, + {file = "PySide6_Addons-6.7.2-cp39-abi3-win_amd64.whl", hash = "sha256:ebf549eb25998665d8e4ec24014fbbd37bebc5ecdcb050b34db1e1c03e1bf81d"}, +] +PySide6-Essentials = [ + {file = "PySide6_Essentials-6.7.2-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:4d13666e796ec140ecfb432c4f3d7baef6dfafc11929985a83b22c0025532fb7"}, + {file = "PySide6_Essentials-6.7.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a1a4c09f1e916b9cfe53151fe4a503a6acb1f6621ba28204d1bfe636f80d6780"}, + {file = "PySide6_Essentials-6.7.2-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:9135513e1c4c6e2fbb1e4f9afcb3d42e54708b0d9ed870cb3213ea4874cafa1e"}, + {file = "PySide6_Essentials-6.7.2-cp39-abi3-win_amd64.whl", hash = "sha256:0111d5fa8cf826de3ca9d82fed54726cce116d57f454f88a6467578652032d69"}, +] +shiboken6 = [ + {file = "shiboken6-6.7.2-cp39-abi3-macosx_11_0_universal2.whl", hash = "sha256:50c33ac6317b673a1eb97a9abaafccb162c4ba0c9ca658a8e449c49a8aadc379"}, + {file = "shiboken6-6.7.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:70e80737b27cd5d83504b373013b55e70462bd4a27217d919ff9a83958731990"}, + {file = "shiboken6-6.7.2-cp39-abi3-manylinux_2_31_aarch64.whl", hash = "sha256:98bedf9a15f1d8ba1af3e4d1e7527f7946ce36da541e08074fd9dc9ab5ff1adf"}, + {file = "shiboken6-6.7.2-cp39-abi3-win_amd64.whl", hash = "sha256:9024e6afb2af1568ebfc8a5d07e4ff6c8829f40923eeb28901f535463e2b6b65"}, +] diff --git a/firmware/ui/pyproject.toml b/firmware/ui/pyproject.toml new file mode 100644 index 0000000000000000000000000000000000000000..6db175fb43c4ea7d8ac6e287d77645a5b81680eb --- /dev/null +++ b/firmware/ui/pyproject.toml @@ -0,0 +1,15 @@ +[tool.poetry] +name = "ui" +version = "0.1.0" +description = "" +authors = ["mattia.gallacchi "] +readme = "README.md" + +[tool.poetry.dependencies] +python = ">=3.10,<3.13" +PySide6 = "^6.7.2" +pyserial = "^3.5" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api"