diff --git a/90-eismultiplexer.rules b/90-eismultiplexer.rules deleted file mode 100644 index 0a7412b0e9a339ae08ed44d8accb4f928d67dcbc..0000000000000000000000000000000000000000 --- a/90-eismultiplexer.rules +++ /dev/null @@ -1 +0,0 @@ -SUBSYSTEM=="usb", ATTRS{idVendor}=="fe17", GROUP="uucp" diff --git a/CMakeLists.txt b/CMakeLists.txt index 19cc3a106a8d904c02fe4a6912c4c231fddc8957..481cb3d50913ef8bca5ae0dbfcad55a960559b96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.0) -project(eismultiplexer) +project(coincellhell) find_package(PkgConfig REQUIRED) find_package(Doxygen) @@ -10,7 +10,7 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "..." FORCE) endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) -set(SRC_FILES eismultiplexer.c usbshm.c) +set(SRC_FILES coincellhell.c usbshm.c) message("Platform " ${CMAKE_SYSTEM_NAME}) if(WIN32) @@ -27,7 +27,7 @@ target_link_libraries(${PROJECT_NAME} ${LIBUSB_LIBRARIES}) target_include_directories(${PROJECT_NAME} PUBLIC ${LIBUSB_INCLUDE_DIRS}) add_definitions("-std=c17 -Wall -O2 -fno-strict-aliasing") install(TARGETS ${PROJECT_NAME} DESTINATION lib) -install(FILES ./eismultiplexer.h DESTINATION include) +install(FILES ./coincellhell.c DESTINATION include) link_directories(${CMAKE_CURRENT_BINARY_DIR}) add_executable(${PROJECT_NAME}_cli main.c) @@ -56,5 +56,5 @@ endif (DOXYGEN_FOUND) if(CMAKE_SYSTEM_NAME MATCHES "^Linux") set(UDEV_RULES_INSTALL_DIR /lib/udev/rules.d CACHE PATH "install directory for linux udev config") - install(FILES 90-eismultiplexer.rules DESTINATION ${UDEV_RULES_INSTALL_DIR}) + install(FILES 90-coincellhell.rules DESTINATION ${UDEV_RULES_INSTALL_DIR}) endif() diff --git a/EisMultiplexerWinDriver/7ZDP_LZMA.sfx b/EisMultiplexerWinDriver/7ZDP_LZMA.sfx deleted file mode 100755 index 51982ec7e9a8d561209f14816d3b96bc8f995e18..0000000000000000000000000000000000000000 Binary files a/EisMultiplexerWinDriver/7ZDP_LZMA.sfx and /dev/null differ diff --git a/EisMultiplexerWinDriver/7zDP_LZMA.cfg b/EisMultiplexerWinDriver/7zDP_LZMA.cfg deleted file mode 100755 index 2edad7cfa87baad8008e23b30d4899d65169a24b..0000000000000000000000000000000000000000 --- a/EisMultiplexerWinDriver/7zDP_LZMA.cfg +++ /dev/null @@ -1,6 +0,0 @@ -;!@Install@!UTF-8! -RunProgram="dpscat.exe" -RunProgram="x86:dpinst32.exe" -RunProgram="x64:dpinst64.exe" -GUIMode="2" -;!@InstallEnd@! \ No newline at end of file diff --git a/EisMultiplexerWinDriver/7za.exe b/EisMultiplexerWinDriver/7za.exe deleted file mode 100755 index 7f6bf86bc43ed71decf8b03f54dcb9b2be143a24..0000000000000000000000000000000000000000 Binary files a/EisMultiplexerWinDriver/7za.exe and /dev/null differ diff --git a/EisMultiplexerWinDriver/EisMultiplexerWinDriver.inf b/EisMultiplexerWinDriver/EisMultiplexerWinDriver.inf deleted file mode 100755 index cc92de8ef1b595cbd4e0a7b63db0407dbaf65b73..0000000000000000000000000000000000000000 Binary files a/EisMultiplexerWinDriver/EisMultiplexerWinDriver.inf and /dev/null differ diff --git a/EisMultiplexerWinDriver/InstallDriver.exe b/EisMultiplexerWinDriver/InstallDriver.exe deleted file mode 100755 index 53ffd16342c59a2a9701df65edc5b8e54482fafc..0000000000000000000000000000000000000000 Binary files a/EisMultiplexerWinDriver/InstallDriver.exe and /dev/null differ diff --git a/EisMultiplexerWinDriver/_DriverFiles.7z b/EisMultiplexerWinDriver/_DriverFiles.7z deleted file mode 100755 index 32adf29e50bf53a54e6ab9c899c735a576040ffb..0000000000000000000000000000000000000000 Binary files a/EisMultiplexerWinDriver/_DriverFiles.7z and /dev/null differ diff --git a/EisMultiplexerWinDriver/amd64/WdfCoInstaller01009.dll b/EisMultiplexerWinDriver/amd64/WdfCoInstaller01009.dll deleted file mode 100755 index 1731b962d68d52030b32b19d6f0f913cbc47729e..0000000000000000000000000000000000000000 Binary files a/EisMultiplexerWinDriver/amd64/WdfCoInstaller01009.dll and /dev/null differ diff --git a/EisMultiplexerWinDriver/amd64/libusbK.dll b/EisMultiplexerWinDriver/amd64/libusbK.dll deleted file mode 100755 index 4497c2ac373522899d4047ce3aa72a089b717ea8..0000000000000000000000000000000000000000 Binary files a/EisMultiplexerWinDriver/amd64/libusbK.dll and /dev/null differ diff --git a/EisMultiplexerWinDriver/amd64/winusbcoinstaller2.dll b/EisMultiplexerWinDriver/amd64/winusbcoinstaller2.dll deleted file mode 100755 index 30e55025b2fb6455a18165ad9df1ba1a3aa90566..0000000000000000000000000000000000000000 Binary files a/EisMultiplexerWinDriver/amd64/winusbcoinstaller2.dll and /dev/null differ diff --git a/EisMultiplexerWinDriver/dpinst.xml b/EisMultiplexerWinDriver/dpinst.xml deleted file mode 100755 index cc2988e669c6585798b3b01e6806089eec3b716b..0000000000000000000000000000000000000000 --- a/EisMultiplexerWinDriver/dpinst.xml +++ /dev/null @@ -1,19 +0,0 @@ -<!-- -Summary of the DPInst XML Elements: - http://msdn.microsoft.com/en-us/library/windows/hardware/ff553383%28v=vs.85%29.aspx - -Enabling Language Customization: - http://msdn.microsoft.com/en-us/library/windows/hardware/ff544886%28v=vs.85%29.aspx - -Customizing the Items That Appear on the Wizard Pages: - http://msdn.microsoft.com/en-us/library/windows/hardware/ff540265%28v=vs.85%29.aspx - -Dpinst.xml Example: - http://msdn.microsoft.com/en-us/library/windows/hardware/ff544778%28v=vs.85%29.aspx ---> - -<?xml version="1.0"?> -<dpinst> - <forceIfDriverIsNotBetter>1</forceIfDriverIsNotBetter> - <installAllOrNone>1</installAllOrNone> -</dpinst> diff --git a/EisMultiplexerWinDriver/dpinst32.exe b/EisMultiplexerWinDriver/dpinst32.exe deleted file mode 100755 index 410a135a5d3b0ef0e018d9fc0cdd84475a5fe5f2..0000000000000000000000000000000000000000 Binary files a/EisMultiplexerWinDriver/dpinst32.exe and /dev/null differ diff --git a/EisMultiplexerWinDriver/dpinst64.exe b/EisMultiplexerWinDriver/dpinst64.exe deleted file mode 100755 index 00964418a06b9e4e066b6831f8f1ee986b21af89..0000000000000000000000000000000000000000 Binary files a/EisMultiplexerWinDriver/dpinst64.exe and /dev/null differ diff --git a/EisMultiplexerWinDriver/dpscat.exe b/EisMultiplexerWinDriver/dpscat.exe deleted file mode 100755 index 848a16e097d4b0e9fe787d6629f80cf21ed61bf6..0000000000000000000000000000000000000000 Binary files a/EisMultiplexerWinDriver/dpscat.exe and /dev/null differ diff --git a/EisMultiplexerWinDriver/re-pack-files.cmd b/EisMultiplexerWinDriver/re-pack-files.cmd deleted file mode 100755 index dff6c747c3761bab3a28903e6c2e429ad6955167..0000000000000000000000000000000000000000 --- a/EisMultiplexerWinDriver/re-pack-files.cmd +++ /dev/null @@ -1,73 +0,0 @@ -@ECHO OFF -SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION - -SET FILES_TO_PACK=*.inf dpinst* dpscat.* .\data* .\x86* .\amd64* -SET SFX_MODULE=7zDP_LZMA.sfx -SET SFX_MODULE_CFG=7zDP_LZMA.cfg -SET INSTALL_DRIVER_EXE=InstallDriver.exe -SET DRIVER_FILES_7Z=_DriverFiles.7z -SET 7Z_SWITCHES=-air0 -mx - -SET CMD_EXIT_CODE=0 - -IF EXIST "!7ZA_EXE!" (SET 7Z_RUN="!7ZA_EXE!") ELSE CALL :Find7Zip 7za.exe 7z.exe 7zan.exe -IF !7Z_RUN! EQU "" ( - ECHO 7Zip is required to re-pack this installer. - ECHO 1] Download and install 7Zip. http://www.7-zip.org/ - ECHO 2] Add the bin folder to the PATH environment variable. - ECHO "Control Panel->System->Advanced->Environment Variables..." - SET CMD_EXIT_CODE=1 - GOTO Error -) - -IF EXIST "!INSTALL_DRIVER_EXE!" DEL /Q "!INSTALL_DRIVER_EXE!" -IF NOT "!ERRORLEVEL!" EQU "0" ( - ECHO Access denied or file in-use "!INSTALL_DRIVER_EXE!" - SET CMD_EXIT_CODE=2 - GOTO Error -) - -IF EXIST "!DRIVER_FILES_7Z!" DEL /Q "!DRIVER_FILES_7Z!" -IF NOT "!ERRORLEVEL!" EQU "0" ( - ECHO Access denied or file in-use "!DRIVER_FILES_7Z!" - SET CMD_EXIT_CODE=3 - GOTO Error -) - -!7Z_RUN! a "!DRIVER_FILES_7Z!" !FILES_TO_PACK! !7Z_SWITCHES! -IF NOT "!ERRORLEVEL!" EQU "0" ( - ECHO Failed re-packing. Check your 7Zip installation at - ECHO !7Z_RUN! - SET CMD_EXIT_CODE=4 - GOTO Error -) - -COPY /B "!SFX_MODULE!"+"!SFX_MODULE_CFG!"+"!DRIVER_FILES_7Z!" "!INSTALL_DRIVER_EXE!" - -ECHO. -ECHO Done. -ECHO "!INSTALL_DRIVER_EXE!" re-packed! -GOTO :EOF - -:Find7Zip - IF EXIST "%~dp0\%~1" ( - SET 7Z_RUN="%~dp0\%~1" - ECHO 7Zip found at: !7Z_RUN! - GOTO :EOF - ) - - SET 7Z_RUN="%~$PATH:1" - IF NOT !7Z_RUN! EQU "" ( - ECHO 7Zip found at: !7Z_RUN! - SET 7Z_RUN="%~1" - GOTO :EOF - ) - SHIFT /1 - IF "%~1" EQU "" GOTO :EOF - GOTO Find7Zip -GOTO :EOF - -:Error - IF NOT DEFINED NO_REPACK_ERROR_WAIT PAUSE - EXIT %CMD_EXIT_CODE% -GOTO :EOF \ No newline at end of file diff --git a/EisMultiplexerWinDriver/x86/WdfCoInstaller01009.dll b/EisMultiplexerWinDriver/x86/WdfCoInstaller01009.dll deleted file mode 100755 index 30e81af6202448f1f81fb8423af5fa97fa4a110a..0000000000000000000000000000000000000000 Binary files a/EisMultiplexerWinDriver/x86/WdfCoInstaller01009.dll and /dev/null differ diff --git a/EisMultiplexerWinDriver/x86/libusbK_x86.dll b/EisMultiplexerWinDriver/x86/libusbK_x86.dll deleted file mode 100755 index 0a9b1c89b23402072ed4c2ca7a1df6e2fec64904..0000000000000000000000000000000000000000 Binary files a/EisMultiplexerWinDriver/x86/libusbK_x86.dll and /dev/null differ diff --git a/EisMultiplexerWinDriver/x86/winusbcoinstaller2.dll b/EisMultiplexerWinDriver/x86/winusbcoinstaller2.dll deleted file mode 100755 index fc450d2b25d0f8069454cc0bde5ba9c13927fe4d..0000000000000000000000000000000000000000 Binary files a/EisMultiplexerWinDriver/x86/winusbcoinstaller2.dll and /dev/null differ diff --git a/coincellhell.c b/coincellhell.c new file mode 100644 index 0000000000000000000000000000000000000000..bec0af7bb21d05268c54566fd4407c8cd722f167 --- /dev/null +++ b/coincellhell.c @@ -0,0 +1,171 @@ +/* * Copyright (c) 2023 Carl Klemm <carl@uvos.xyz> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * * Neither the name of %ORGANIZATION% nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define _POSIX_C_SOURCE 199309L + +#include <stdint.h> +#include <stdlib.h> +#include <time.h> +#include <stdio.h> +#include <assert.h> + +#include "coincellhell.h" +#include "usbshm.h" +#include "usbcommands.h" + +#define VID 0xfe17 +#define PID 0x08dc + +static void usleep(uint64_t microseconds) +{ + struct timespec ts; + ts.tv_sec = microseconds / 1000000; + ts.tv_nsec = (microseconds % 1000000) * 1000; + nanosleep(&ts, NULL); +} + +int coincellhell_connect(struct coincellhell* hell, uint16_t serial) +{ + int ret; + hell->priv = malloc(sizeof(*hell->priv)); + if(!hell->priv) + return -1; + + ret = usbshm_init(hell->priv, NULL, hell); + if(ret) + return -2; + + unsigned char serialStr[5]; + snprintf((char*)serialStr, sizeof(serialStr), "%04hu", serial); + + ret = usbshm_open(hell->priv, VID, PID , serial == 0 ? NULL : serialStr); + if(ret) + return -3; + return 0; +} + +int coincellhell_get_temperature(struct coincellhell* hell, uint8_t heater, temperature_sensor_location_t location, float* temperature) +{ + int16_t temperatureRaw = 0; + uint8_t *dataPtr = (uint8_t*)&temperatureRaw; + int ret; + while((ret = usbshm_readControlTransferSync(hell->priv, COMMAND_GET_TEMPERATURE, location, heater, dataPtr, 2)) == USBSHM_ERROR_AGAIN) + usleep(1000000); + *temperature = temperatureRaw/10.0f; + return ret; +} + +int coincellhell_set_temperature(struct coincellhell* hell, uint8_t heater, float temperature) +{ + if(temperature*10.0f > INT16_MAX || temperature*10.0f < INT16_MIN) + return -6; + int ret; + while((ret = usbshm_writeControlTransfer(hell->priv, COMMAND_SET_TEMPERATURE, NULL, 0, temperature*10.0f, heater)) == USBSHM_ERROR_AGAIN) + usleep(100000); + return ret; +} + +int coincellhell_get_temperature_setpoint(struct coincellhell* hell, uint8_t heater, float* temperature) +{ + int16_t temperatureRaw = 0; + uint8_t *dataPtr = (uint8_t*)&temperatureRaw; + int ret; + while((ret = usbshm_readControlTransferSync(hell->priv, COMMAND_GET_TEMPERATURE_SETPOINT, 0, heater, dataPtr, 2)) == USBSHM_ERROR_AGAIN) + usleep(100000); + *temperature = temperatureRaw/10.0f; + return ret; +} + +int coincellhell_check_ready(struct coincellhell* hell, bool* ready) +{ + *ready = false; + int ret; + while((ret = usbshm_readControlTransferSync(hell->priv, COMMAND_READY, 0, 0, (uint8_t*)ready, 1)) == USBSHM_ERROR_AGAIN) + usleep(100000); + return ret; +} + +int coincellhell_set_temperature_ramp(struct coincellhell* hell, uint8_t heater, time_t end_time, float temperature) +{ + return -1; +} + +int coincellhell_cancle_ramp(struct coincellhell* hell, uint8_t heater) +{ + return -1; +} + +int coincellhell_get_ramping(struct coincellhell* hell, uint8_t heater, bool* ramping) +{ + return -1; +} + +int coincellhell_set_led(struct coincellhell* hell, bool on) +{ + int ret; + while((ret = usbshm_writeControlTransfer(hell->priv, on ? COMMAND_LED_ON : COMMAND_LED_OFF, NULL, 0, 0, 0)) == USBSHM_ERROR_AGAIN) + usleep(100000); + return ret; +} + +int coincellhell_write_eeprom(struct coincellhell* hell, uint16_t addr, uint16_t value) +{ + int ret; + while((ret = usbshm_writeControlTransfer(hell->priv, COMMAND_WRITE_EEPROM, NULL, 0, value, addr)) == USBSHM_ERROR_AGAIN) + usleep(100000); + return ret; +} + +uint16_t coincellhell_read_eeprom(struct coincellhell* hell, uint16_t addr) +{ + uint8_t buffer[2] = {}; + usbshm_readControlTransferSync(hell->priv, COMMAND_READ_EEPROM, 0, addr, buffer, 2); + return *((uint16_t*)buffer); +} + + +uint8_t coincellhell_read_oscal(struct coincellhell* hell) +{ + uint8_t oscal; + usbshm_readControlTransferSync(hell->priv, COMMAND_READ_OSCAL, 0, 0, &oscal, 1); + return oscal; +} + +uint32_t coincellhell_get_seconds(struct coincellhell* hell) +{ + uint32_t seconds; + usbshm_readControlTransferSync(hell->priv, COMMAND_GET_SECONDS, 0, 0, (uint8_t*)&seconds, 4); + return seconds; +} + +void coincellhell_disconnect(struct coincellhell* hell) +{ + usbshm_distroy(hell->priv); + free(hell->priv); + hell->priv = NULL; +} + diff --git a/coincellhell.h b/coincellhell.h new file mode 100644 index 0000000000000000000000000000000000000000..da3e85aab430358f1eb09dfad44504453329decf --- /dev/null +++ b/coincellhell.h @@ -0,0 +1,139 @@ +/* * Copyright (c) 2023 Carl Klemm <carl@uvos.xyz> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * * Neither the name of %ORGANIZATION% nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <stdint.h> +#include <semaphore.h> +#include <stdbool.h> + +#include "usbcommands.h" + +/** +Api to controll EISmultiplexer devices. +* @defgroup API User API +* This api allows you to controll the EISmultiplexer device. +* @{ +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +struct coincellhell { + struct usbshm* priv; +}; + +/** + * @brief Attempts to connect to a EISmultiplexer device and initalizes a coincellhell struct + * @param hell pointer to a coincellhell struct to initalize + * @param serial The serial number of the device to connect to, or 0 for any + * @return 0 on sucess and < 0 on failure + */ +int coincellhell_connect(struct coincellhell* hell, uint16_t serial); + +/** + * @brief Reads the current temperature of the given heater at given location + * @param heater heater from which to get the temperature + * @param location Place where temperature shal be mesured + * @param temperature A float where the temperature in degrees celcius will be stored + * @return 0 on sucess and < 0 on failure + */ +int coincellhell_get_temperature(struct coincellhell* hell, uint8_t heater, temperature_sensor_location_t location, float* temperature); + +/** + * @brief Sets the target temperature of the given heater + * @param heater heater for which to set the temperature + * @param temperature temperature to set + * @return 0 on sucess and < 0 on failure + */ +int coincellhell_set_temperature(struct coincellhell* hell, uint8_t heater, float temperature); + +/** + * @brief Gets the target temperature of the given heater + * @param heater heater for which to set the temperature + * @param temperature A float where the temperature in degrees celcius will be stored + * @return 0 on sucess and < 0 on failure + */ +int coincellhell_get_temperature_setpoint(struct coincellhell* hell, uint8_t heater, float* temperature); + +/** + * @brief Checks if all temperatures are close to thair setpoins and all ramps have compleated + * @param ready a pointer to a bool where the result will be stored, true if all temperatures have been reatch, false otherwise + * @return 0 on sucess and < 0 on failure + */ +int coincellhell_check_ready(struct coincellhell* hell, bool* ready); + +/** + * @brief Will linearly ramp the temperature to the one provided from now until end_time + * @param heater heater for which to set the ramp + * @param temperature temperature to ramp to + * @return 0 on sucess and < 0 on failure + */ +int coincellhell_set_temperature_ramp(struct coincellhell* hell, uint8_t heater, time_t end_time, float temperature); + +/** + * @brief Cancles any previously set ramp, the setpoint of the heater will hold the current temperature + * @param heater heater for which to cancle the ramp + * @return 0 on sucess and < 0 on failure + */ +int coincellhell_cancle_ramp(struct coincellhell* hell, uint8_t heater); + +/** + * @brief Checks wather the the given heater is currenly executeing a ramp + * @param ramping a pointer to a bool where the ramping state will be stored + * @param heater heater for which to cancle the ramp + * @return 0 on sucess and < 0 on failure + */ +int coincellhell_get_ramping(struct coincellhell* hell, uint8_t heater, bool* ramping); + +/** + * @brief Turns the led on the pcb on or off + * @param hell pointer to a coincellhell struct + * @param on true to turn the led on, false to turn it off + * @return 0 on sucess and < 0 on failure + */ +int coincellhell_set_led(struct coincellhell* hell, bool on); + +/** + * @brief Disconnects from the coincellhell + */ +void coincellhell_disconnect(struct coincellhell* hell); + +int coincellhell_write_eeprom(struct coincellhell* hell, uint16_t addr, uint16_t value); +uint16_t coincellhell_read_eeprom(struct coincellhell* hell, uint16_t addr); +uint8_t coincellhell_read_oscal(struct coincellhell* hell); +uint32_t coincellhell_get_seconds(struct coincellhell* hell); + +#ifdef __cplusplus +} +#endif + +/** +.... +* @} +*/ diff --git a/doc/mainpage.txt.bak b/doc/mainpage.txt.bak new file mode 100644 index 0000000000000000000000000000000000000000..e0cdde23dfc56adf77f24eb800d8da243e9f2ad1 --- /dev/null +++ b/doc/mainpage.txt.bak @@ -0,0 +1,44 @@ +/*! \mainpage libeismultiplexer manual + +libeismultiplexer is a shared library that allows you to control EISmultiplexer devices + +An API reference can be found here: \subpage API + +## Example usage: + +_______ + +@code +#include <stdio.h> +#include "eismultiplexer.h" + +int main(int argc, char* argv[]) +{ + // Each connection to a device is required to have a corresponding eismultiplexer struct + struct eismultiplexer multiplexer; + + // Connect to the first device found + int ret = eismultiplexer_connect(&multiplexer, 0); + if(ret != 0) + { + printf("Can not connect to EISmultiplexer device\n"); + return 1; + } + + // Connect channels A and C to the common output + ret = eismultiplexer_connect_channel(&multiplexer, CHANNEL_A | CHANNEL_C); + if(ret != 0) + { + printf("Failure to communicate with the device\n"); + return 1; + } + + // Disconnect from device + eismultiplexer_disconnect(&multiplexer); + return 0; +} +@endcode +//----------------------------------------------------------- + +librelaxisloader is licenced to you under the Apache License, Version 2.0 +*/ diff --git a/eismultiplexer.c b/eismultiplexer.c deleted file mode 100644 index 1a0eec7bc59a51096b1a6db93cac7bb3c630dc65..0000000000000000000000000000000000000000 --- a/eismultiplexer.c +++ /dev/null @@ -1,131 +0,0 @@ -/* * Copyright (c) 2023 Carl Klemm <carl@uvos.xyz> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * * Neither the name of %ORGANIZATION% nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define _POSIX_C_SOURCE 199309L - -#include <stdint.h> -#include "eismultiplexer.h" -#include "usbshm.h" -#include <stdlib.h> -#include <time.h> -#include <stdio.h> - -static void usleep(uint64_t microseconds) -{ - struct timespec ts; - ts.tv_sec = microseconds / 1000000; - ts.tv_nsec = (microseconds % 1000000) * 1000; - nanosleep(&ts, NULL); -} - -int eismultiplexer_connect(struct eismultiplexer* muliplexer, uint16_t serial) -{ - int ret; - muliplexer->priv = malloc(sizeof(*muliplexer->priv)); - if(!muliplexer->priv) - return -1; - - ret = usbshm_init(muliplexer->priv, NULL, muliplexer); - if(ret) - return -2; - - unsigned char serialStr[5]; - snprintf((char*)serialStr, sizeof(serialStr), "%04hu", serial); - - ret = usbshm_open(muliplexer->priv, 0xfe17, 0x07dc , serial == 0 ? NULL : serialStr); - if(ret) - return -3; - return 0; -} - -int eismultiplexer_connect_channel_exclusive(struct eismultiplexer* muliplexer, channel_t channel) -{ - uint16_t wValue; - // we compile with fno-strict-aliasing - uint8_t* wValChar = (uint8_t*)&wValue; - wValChar[0] = channel; - wValChar[1] = 0; - int ret; - while((ret = usbshm_writeControlTransfer(muliplexer->priv, 2, NULL, 0, wValue, 0)) == USBSHM_ERROR_AGAIN) - usleep(1000000); - return ret; -} - -int eismultiplexer_connect_channel(struct eismultiplexer* muliplexer, channel_t channel) -{ - channel_t channels = eismultiplexer_get_connected(muliplexer); - channels |= channel; - return eismultiplexer_connect_channel_exclusive(muliplexer, channels); -} - -int eismultiplexer_disconnect_channel(struct eismultiplexer* muliplexer, channel_t channel) -{ - channel_t channels = CHANNEL_NONE; - if(channel != CHANNEL_NONE) - { - channels = eismultiplexer_get_connected(muliplexer); - channels &= ~channel; - } - return eismultiplexer_connect_channel_exclusive(muliplexer, channels); -} - -channel_t eismultiplexer_get_connected(struct eismultiplexer* muliplexer) -{ - uint8_t buffer[2] = {}; - usbshm_readControlTransferSync(muliplexer->priv, 3, 0, 0, buffer, 1); - return buffer[0]; -} - -int eismultiplexer_set_led(struct eismultiplexer* muliplexer, bool on) -{ - int ret; - while((ret = usbshm_writeControlTransfer(muliplexer->priv, on, NULL, 0, 0, 0)) == USBSHM_ERROR_AGAIN) - usleep(1000000); - return ret; -} - -int eismultiplexer_write_eeprom(struct eismultiplexer* muliplexer, uint16_t addr, uint16_t value) -{ - int ret; - while((ret = usbshm_writeControlTransfer(muliplexer->priv, 5, NULL, 0, value, addr)) == USBSHM_ERROR_AGAIN) - usleep(1000000); - return ret; -} - -uint16_t eismultiplexer_read_eeprom(struct eismultiplexer* muliplexer, uint16_t addr) -{ - uint8_t buffer[2] = {}; - usbshm_readControlTransferSync(muliplexer->priv, 4, 0, addr, buffer, 2); - return *((uint16_t*)buffer); -} - -void eismultiplexer_disconnect(struct eismultiplexer* muliplexer) -{ - usbshm_distroy(muliplexer->priv); - free(muliplexer->priv); - muliplexer->priv = NULL; -} diff --git a/eismultiplexer.h b/eismultiplexer.h deleted file mode 100644 index a6a9f7fe5703fbe55c64c50960bfee835fc60227..0000000000000000000000000000000000000000 --- a/eismultiplexer.h +++ /dev/null @@ -1,123 +0,0 @@ -/* * Copyright (c) 2023 Carl Klemm <carl@uvos.xyz> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * * Neither the name of %ORGANIZATION% nor the names of its contributors may be - * used to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -#include <stdint.h> -#include <semaphore.h> -#include <stdbool.h> - -/** -Api to controll EISmultiplexer devices. -* @defgroup API User API -* This api allows you to controll the EISmultiplexer device. -* @{ -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - CHANNEL_A = (1 << 0), - CHANNEL_B = (1 << 1), - CHANNEL_C = (1 << 2), - CHANNEL_D = (1 << 3), - CHANNEL_E = (1 << 4), - CHANNEL_F = (1 << 5), - CHANNEL_G = (1 << 6), - CHANNEL_NONE = 0, -} channel_t; - -struct eismultiplexer { - struct usbshm* priv; -}; - -/** - * @brief Attempts to connect to a EISmultiplexer device and initalizes a eismultiplexer struct - * @param muliplexer pointer to a eismultiplexer struct to initalize - * @param serial The serial number of the device to connect to, or 0 for any - * @return 0 on sucess and < 0 on failure - */ -int eismultiplexer_connect(struct eismultiplexer* muliplexer, uint16_t serial); - -/** - * @brief Conects the given channel(s) to the common inputs - * @param muliplexer pointer to a eismultiplexer struct - * @param channel A channel to connect, multiple channels can be specified by or'ing together the chanel flags e.g. (CHANNEL_A | CHANNEL_B) - * @return 0 on sucess and < 0 on failure - */ -int eismultiplexer_connect_channel(struct eismultiplexer* muliplexer, channel_t channel); - -/** - * @brief Conects the given channel(s) to the common inputs disconnecting all others - * @param muliplexer pointer to a eismultiplexer struct - * @param channel A channel to connect, multiple channels can be specified by or'ing together the chanel flags e.g. (CHANNEL_A | CHANNEL_B) - * @return 0 on sucess and < 0 on failure - */ -int eismultiplexer_connect_channel_exclusive(struct eismultiplexer* muliplexer, channel_t channel); - -/** - * @brief Disconnect the given channel(s) to the common inputs disconnecting all others - * @param muliplexer pointer to a eismultiplexer struct - * @param channel A channel to connect, multiple channels can be specified by or'ing together the chanel flags e.g. (CHANNEL_A | CHANNEL_B) - * All channels can be dissconnected by passing CHANNEL_NONE - * @return 0 on sucess and < 0 on failure - */ -int eismultiplexer_disconnect_channel(struct eismultiplexer* muliplexer, channel_t channel); - -/** - * @brief Returns the channels currently connected - * @param muliplexer pointer to a eismultiplexer struct - * @return channels connected as a bitfield - */ -channel_t eismultiplexer_get_connected(struct eismultiplexer* muliplexer); - -/** - * @brief Turns the led on the pcb on or off - * @param muliplexer pointer to a eismultiplexer struct - * @param on true to turn the led on, false to turn it off - * @return 0 on sucess and < 0 on failure - */ -int eismultiplexer_set_led(struct eismultiplexer* muliplexer, bool on); - -/** - * @brief Disconnects from the eismultiplexer - */ -void eismultiplexer_disconnect(struct eismultiplexer* muliplexer); - -int eismultiplexer_write_eeprom(struct eismultiplexer* muliplexer, uint16_t addr, uint16_t value); -uint16_t eismultiplexer_read_eeprom(struct eismultiplexer* muliplexer, uint16_t addr); - -#ifdef __cplusplus -} -#endif - -/** -.... -* @} -*/ diff --git a/main.c b/main.c index 2544d3841f4c69a2629cd29e0c7c914d24ee100f..2a77a90945e9005b252adee141ec69c88327c846 100644 --- a/main.c +++ b/main.c @@ -30,67 +30,169 @@ #include <stdlib.h> #include <string.h> #include <signal.h> -#include "eismultiplexer.h" + +#include "coincellhell.h" #include "options.h" +#include "float.h" +#include "usbcommands.h" -static channel_t char_to_channel(char ch) +static void print_commands(void) { - switch(ch) + puts("Valid commands:"); + puts("set [HEATER] [TEMPERATURE]\t | set the temperature setpoint of the given heater"); + puts("get [HEATER] [LOCATION]\t | get the temperature of the given heater"); + puts("get_setpoint [HEATER]\t | get the temperature setpoint of the given heater"); + puts("ready\t | check the ready state of all heaters"); + puts("read [ADDRESS] [LENGTH]\t | read from the device eeprom at address"); + puts("write [ADDRESS] [LENGTH] | write to the device eeprom at address"); +} + +static int convert_string_to_heater_id(const char* str) +{ + char* str_end; + long id = strtol(str, &str_end, 10); + if(str == str_end || id < 0 || id > 0) { - case 'a': - case 'A': - case '1': - return CHANNEL_A; - case 'b': - case 'B': - case '2': - return CHANNEL_B; - case 'c': - case 'C': - case '3': - return CHANNEL_C; - case 'd': - case 'D': - case '4': - return CHANNEL_D; - case 'e': - case 'E': - case '5': - return CHANNEL_E; - case 'f': - case 'F': - case '6': - return CHANNEL_F; - case 'g': - case 'G': - case '7': - return CHANNEL_G; - default: - return CHANNEL_NONE; + puts("HEATER must be a whole nummber between 0 and 3"); + return -1; } + return id; } -void print_commands(void) +static float convert_string_to_temperature(const char* str) { - puts("Valid commands:"); - puts("connect [CHANNEL]\t | connect a channels"); - puts("disconnect [CHANNEL]\t | disconnect a channels"); - puts("clear\t\t\t | disconnect all channels"); - puts("connect_all\t\t | connect all channels"); - puts("get\t\t\t | get the state of all channels"); - puts("read [ADDRESS] [LENGTH]\t | read from the device eeprom at address"); - puts("write [ADDRESS] [LENGTH] | write to the device eeprom at address"); + char* str_end; + float temperature = strtof(str, &str_end); + if(str == str_end || temperature < 0 || temperature > 100) + { + puts("TEMPERATURE must be a float between 0 and 100"); + return FLT_MIN; + } + return temperature; +} + +static temperature_sensor_location_t convert_string_to_location(const char* str) +{ + if(strcmp(str, "both") == 0) + return TEMP_LOCATION_BOTH; + if(strcmp(str, "front") == 0) + return TEMP_LOCATION_FRONT; + if(strcmp(str, "side") == 0) + return TEMP_LOCATION_SIDE; + return TEMP_LOCATION_INVALID; } -static int process_commands(char** commands, size_t command_count, struct eismultiplexer* multiplexer, char* name) +static int process_commands(char** commands, size_t command_count, struct coincellhell* hell, char* name) { - if(strcmp(commands[0], "clear") == 0) + int ret = 0; + + if(strcmp(commands[0], "help") == 0) { - eismultiplexer_disconnect_channel(multiplexer, CHANNEL_NONE); + print_commands(); } - else if(strcmp(commands[0], "help") == 0) + else if(strcmp(commands[0], "set") == 0) { - print_commands(); + if(command_count < 3) + printf("Usage %s %s [HEATER] [TEMPERATURE]\n", name, commands[0]); + + int id = convert_string_to_heater_id(commands[1]); + if(id < 0) + return 1; + + float temperature = convert_string_to_temperature(commands[2]); + if(temperature == FLT_MIN) + return 2; + + ret = coincellhell_set_temperature(hell, id, temperature); + } + else if(strcmp(commands[0], "get") == 0) + { + if(command_count == 1) + { + for(uint8_t i = 0; i < 4; ++i) + { + float front = 0; + float side = 0; + int err = 0; + err |= coincellhell_get_temperature(hell, i, TEMP_LOCATION_FRONT, &front); + err |= coincellhell_get_temperature(hell, i, TEMP_LOCATION_SIDE, &side); + + if(!err) + printf("Heater %i: front temperature %f, side temperature %f, avg temperature %f\n", i, front, side, (front+side)/2); + else + printf("Heater %i: UNABLE TO READ\n", i); + + } + } + else if(command_count < 3) + { + printf("Usage %s %s [HEATER] [LOCATION]\n", name, commands[0]); + ret = 1; + } + else + { + int id = convert_string_to_heater_id(commands[1]); + if(id < 0) + return 1; + temperature_sensor_location_t location = convert_string_to_location(commands[2]); + if(location == TEMP_LOCATION_INVALID) + return 2; + + float temperature; + ret = coincellhell_get_temperature(hell, id, location, &temperature); + if(ret == 0) + printf("%f\n", temperature); + } + } + else if(strcmp(commands[0], "get_setpoint") == 0) + { + if(command_count == 1) + { + for(uint8_t i = 0; i < 4; ++i) + { + float setpoint = 0; + int err = coincellhell_get_temperature_setpoint(hell, i, &setpoint); + if(!err) + printf("Heater %i: setpoint %f\n", i, setpoint); + else + printf("Heater %i: UNABLE TO READ\n", i); + + } + } + else + { + int id = convert_string_to_heater_id(commands[1]); + if(id < 0) + return 1; + + float temperature; + ret = coincellhell_get_temperature_setpoint(hell, id, &temperature); + if(ret == 0) + printf("%f\n", temperature); + } + } + else if(strcmp(commands[0], "ready") == 0) + { + if(command_count == 1) + { + for(uint8_t i = 0; i < 4; ++i) + { + float setpoint = 0; + coincellhell_get_temperature_setpoint(hell, i, &setpoint); + printf("Heater %i: setpoint %f", i, setpoint); + } + } + else + { + int id = convert_string_to_heater_id(commands[1]); + if(id < 0) + return 1; + + float temperature; + ret = coincellhell_get_temperature_setpoint(hell, id, &temperature); + if(ret == 0) + printf("%f\n", temperature); + } } else if(strcmp(commands[0], "write") == 0) { @@ -111,7 +213,7 @@ static int process_commands(char** commands, size_t command_count, struct eismul puts("Address must be a even number, 16 bits are written at a time"); return 2; } - eismultiplexer_write_eeprom(multiplexer, address, value); + coincellhell_write_eeprom(hell, address, value); } else if(strcmp(commands[0], "read") == 0) { @@ -126,8 +228,8 @@ static int process_commands(char** commands, size_t command_count, struct eismul length = strtol(commands[2], NULL, 10); if(address > UINT16_MAX || address < 0 || length < 0 || length > UINT16_MAX) { - return 2; puts("Value or address is out of range"); + return 2; } if(address % 2 == 1) { @@ -142,62 +244,24 @@ static int process_commands(char** commands, size_t command_count, struct eismul for(uint16_t i = address; i - address < length; i+=2) { - uint16_t value = eismultiplexer_read_eeprom(multiplexer, i); + uint16_t value = coincellhell_read_eeprom(hell, i); printf("%u: %u\n", i, value); } } - else if(strcmp(commands[0], "connect_all") == 0) + else if(strcmp(commands[0], "oscal") == 0) { - eismultiplexer_connect_channel(multiplexer, 0xff); + printf("OSCAL: %u\n", coincellhell_read_oscal(hell)); } - else if(strcmp(commands[0], "get") == 0) + else if(strcmp(commands[0], "seconds") == 0) { - channel_t channels = eismultiplexer_get_connected(multiplexer); - for(size_t i = 0; i < 7; ++i) - { - bool connected = channels & (1 << i); - printf("Channel %c: %s\n", (char)('A'+i), connected ? "on" : "off"); - } + printf("Seconds: %u\n", coincellhell_get_seconds(hell)); } else { - if(command_count != 2) - { - puts("A channel is required"); - return 2; - } - - channel_t channel = char_to_channel(commands[1][0]); - if(channel == CHANNEL_NONE) - { - printf("%c is not a valid channel\n", commands[1][0]); - return 2; - } - - if(strcmp(commands[0], "connect") == 0) - { - if(eismultiplexer_connect_channel(multiplexer, channel)) - { - printf("could not connect channel %c\n", commands[1][0]); - return 3; - } - } - else if(strcmp(commands[0], "disconnect") == 0) - { - if(eismultiplexer_disconnect_channel(multiplexer, channel)) - { - printf("could not disconnect channel %c\n", commands[1][0]); - return 3; - } - } - else - { - printf("%s is not a valid command\n", commands[0]); - print_commands(); - return 3; - } + printf("%s is not a valid command!", commands[0]); + print_commands(); } - return 0; + return ret; } enum @@ -249,12 +313,12 @@ int main(int argc, char* argv[]) return 2; } - struct eismultiplexer multiplexer; - if(eismultiplexer_connect(&multiplexer, config.serialSet ? config.serial : 0)) + struct coincellhell hell; + if(coincellhell_connect(&hell, config.serialSet ? config.serial : 0)) { char serialStr[5]; snprintf(serialStr, sizeof(serialStr), "%04hu", config.serial); - printf("Can not connect to EISmultiplexer device%s%s\n", + printf("Can not connect to EIShell device%s%s\n", config.serialSet ? " with serial " : "", config.serialSet ? serialStr : ""); return 1; } @@ -287,9 +351,9 @@ int main(int argc, char* argv[]) ++i; } - eismultiplexer_set_led(&multiplexer, true); - int cmdRet = process_commands(commands, i, &multiplexer, ""); - eismultiplexer_set_led(&multiplexer, false); + coincellhell_set_led(&hell, true); + int cmdRet = process_commands(commands, i, &hell, ""); + coincellhell_set_led(&hell, false); if(cmdRet == 0) puts("OK"); else @@ -298,11 +362,9 @@ int main(int argc, char* argv[]) } else { - eismultiplexer_set_led(&multiplexer, true); - ret = process_commands(config.commands, config.command_count, &multiplexer, argv[0]); - eismultiplexer_set_led(&multiplexer, false); + ret = process_commands(config.commands, config.command_count, &hell, argv[0]); } - eismultiplexer_disconnect(&multiplexer); + coincellhell_disconnect(&hell); return ret; } diff --git a/options.h b/options.h new file mode 100644 index 0000000000000000000000000000000000000000..ba047114e0690c85a5ee6bb8f9344163208b4c24 --- /dev/null +++ b/options.h @@ -0,0 +1,109 @@ +/* * Copyright (c) 2023 Carl Klemm <carl@uvos.xyz> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * * Neither the name of %ORGANIZATION% nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once +#include <argp.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> + +#define MAX_COMMANDS 8 + +const char *argp_program_version = "eismulitplexer_cli"; +const char *argp_program_bug_address = "<carl@uvos.xyz>"; +static char doc[] = "Applicaion to control eismultiplexer devices"; +static char args_doc[] = "COMMAND"; + +static struct argp_option options[] = +{ + {"interactive", 'i', 0, 0, "run in interactive mode" }, + {"pipe", 'p', 0, 0, "run in pipe mode" }, + {"serial", 's', "[NUMMBER]", 0, "serial number of device to connect to"}, + {"serial", 'l', 0, 0, "list commands"}, + {0} +}; + +struct command +{ + char* command; +}; + +struct config +{ + bool interactive; + bool pipe; + uint16_t serial; + bool serialSet; + char* commands[MAX_COMMANDS]; + size_t command_count; + bool list_commands; +}; + +static error_t parse_opt (int key, char *arg, struct argp_state *state) +{ + struct config *config = (struct config*)(state->input); + switch (key) + { + case 'i': + config->interactive = true; + break; + case 's': + { + int serial = atoi(arg); + if(serial < 0 || serial > UINT16_MAX ) + { + argp_usage(state); + break; + } + config->serial = serial; + config->serialSet = true; + break; + } + case 'p': + config->pipe = true; + break; + case 'l': + config->list_commands = true; + break; + case ARGP_KEY_ARG: + { + if(config->command_count+1 > MAX_COMMANDS) + { + argp_usage(state); + break; + } + config->commands[config->command_count] = arg; + ++config->command_count; + break; + } + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +static struct argp argp = {options, parse_opt, args_doc, doc}; diff --git a/pkgconfig/eismuliplexer.pc.in b/pkgconfig/eismuliplexer.pc.in index c181acff60ba40257e1f6a590f94e6f1e2e68248..176b49fe0a2ca7250db8eae3a4e89b4651ecead4 100644 --- a/pkgconfig/eismuliplexer.pc.in +++ b/pkgconfig/eismuliplexer.pc.in @@ -1,7 +1,7 @@ includedir=@CMAKE_INSTALL_PREFIX@/include Name: libeismuliplexer -Description: C lib to control EISmultiplexer devices +Description: C lib to control CoincellHell devices Version: 1.0 -Libs: -L${libdir} -leismultiplexer +Libs: -L${libdir} -lcoincellhell Cflags: -I${includedir} diff --git a/usbcommands.h b/usbcommands.h new file mode 100644 index 0000000000000000000000000000000000000000..0c8dff4c7ec86fb8d4b0bb5d9a33c585960bab81 --- /dev/null +++ b/usbcommands.h @@ -0,0 +1,24 @@ +#pragma once + +typedef enum { + COMMAND_LED_ON = 0, + COMMAND_LED_OFF, + COMMAND_SET_TEMPERATURE, + COMMAND_GET_TEMPERATURE, + COMMAND_GET_TEMPERATURE_SETPOINT, + COMMAND_READY, + COMMAND_RAMP, + COMMAND_RAMP_RUNNING, + COMMAND_RAMP_CANCLE, + COMMAND_GET_SECONDS = 200, + COMMAND_READ_EEPROM, + COMMAND_WRITE_EEPROM, + COMMAND_READ_OSCAL, +} usb_command_t; + +typedef enum { + TEMP_LOCATION_BOTH = 0, + TEMP_LOCATION_FRONT, + TEMP_LOCATION_SIDE, + TEMP_LOCATION_INVALID, +} temperature_sensor_location_t;