From de970b5dd6e8d868f5f231816064a5d8c928bccc Mon Sep 17 00:00:00 2001 From: Peter McGoron Date: Wed, 14 Jun 2023 15:17:23 -0400 Subject: [PATCH] remove zephyr --- .gitmodules | 4 - creole | 1 - software/CMakeLists.txt | 21 -- software/Kconfig | 3 - software/Makefile | 13 - software/manual_dhcp.c | 42 --- software/prj.conf | 29 -- software/src/access.c | 447 ------------------------- software/src/access.h | 46 --- software/src/buf.c | 44 --- software/src/buf.h | 35 -- software/src/main.c | 213 ------------ software/src/sock.c | 135 -------- software/src/sock.h | 29 -- software/src/tests/test_dac_adc_main.c | 211 ------------ software/src/tests/test_ethernet.c | 120 ------- software/src/upsilon.h | 3 - 17 files changed, 1396 deletions(-) delete mode 100644 .gitmodules delete mode 160000 creole delete mode 100644 software/CMakeLists.txt delete mode 100644 software/Kconfig delete mode 100644 software/Makefile delete mode 100644 software/manual_dhcp.c delete mode 100644 software/prj.conf delete mode 100644 software/src/access.c delete mode 100644 software/src/access.h delete mode 100644 software/src/buf.c delete mode 100644 software/src/buf.h delete mode 100644 software/src/main.c delete mode 100644 software/src/sock.c delete mode 100644 software/src/sock.h delete mode 100644 software/src/tests/test_dac_adc_main.c delete mode 100644 software/src/tests/test_ethernet.c delete mode 100644 software/src/upsilon.h diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index c02f387..0000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "creole"] - path = creole - url = https://software.mcgoron.com/peter/creole - branch = upsilon diff --git a/creole b/creole deleted file mode 160000 index 52279a9..0000000 --- a/creole +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 52279a9afc6afb3c589216e3f930e3d8d96dd119 diff --git a/software/CMakeLists.txt b/software/CMakeLists.txt deleted file mode 100644 index 6008679..0000000 --- a/software/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -cmake_minimum_required(VERSION 3.20.0) - -# These must come BEFORE the zephyr package declaration. -set(DTC_OVERLAY_FILE "../firmware/overlay.dts") -set(BOARD "litex_vexriscv") -set(EXTRA_CFLAGS "-Wfatal-errors -Werror -Wno-error=unused-const-variable -Wno-error=unused-variable -Wno-error=unused-function") -include("../firmware/overlay.cmake") - -find_package(Zephyr) -project(upsilon) -include_directories("../firmware") -include_directories("src/") -include_directories("../creole") -include_directories("../firmware/rtl/control_loop") - -set_source_files_properties(src/main.c PROPERTIES COMPILE_FLAGS -DMAIN_LOG_LEVEL=4) -set_source_files_properties(../creole/creole.c PROPERTIES COMPILE_FLAGS -DCREOLE_LOG_LEVEL=4) - -# Add all source files here. -target_sources(app PRIVATE src/access.c src/buf.c src/main.c src/sock.c ../creole/creole.c) -# target_sources(app PRIVATE src/tests/test_ethernet.c) diff --git a/software/Kconfig b/software/Kconfig deleted file mode 100644 index 1f47670..0000000 --- a/software/Kconfig +++ /dev/null @@ -1,3 +0,0 @@ -mainmenu "CryoSNOM 1" - -source "Kconfig.zephyr" diff --git a/software/Makefile b/software/Makefile deleted file mode 100644 index 5b878e7..0000000 --- a/software/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -unexport CXXFLAGS -unexport CFLAGS -unexport CPPFLAGS -unexport LDFLAGS - -# TODO: Number of processors -build/zephyr/zephyr.bin: build/Makefile - cd build && make -j7 -build/Makefile: ../creole/creole.c src/*.c ../firmware/overlay.dts ../firmware/pin_io.c prj.conf CMakeLists.txt - mkdir -p build - cd build && cmake .. -clean: - rm -rf build diff --git a/software/manual_dhcp.c b/software/manual_dhcp.c deleted file mode 100644 index 8e1dd17..0000000 --- a/software/manual_dhcp.c +++ /dev/null @@ -1,42 +0,0 @@ -K_SEM_DEFINE(dhcp_ready, 0, 1); - -static bool -check_dhcp(struct net_if *iface) -{ - // Scan IP addresses allocated for Unicast - for (int i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - if (iface->config.ip.ipv4->unicast[i].addr_type != NET_ADDR_DHCP) - continue; - return true; - } - - return false; -} - -static void -dhcp_handler(struct net_mgmt_event_callback *cb, - uint32_t ev, - struct net_if *iface) -{ - if (ev != NET_EVENT_IPV4_ADDR_ADD) - return; - if (check_dhcp(iface)) - k_sem_give(&dhcp_ready); -} - -static void -setup_dhcp(void) -{ - - static struct net_mgmt_event_callback cb; - net_mgmt_init_event_callback(&cb, dhcp_handler, NET_EVENT_IPV4_ADDR_ADD); - net_mgmt_add_event_callback(&cb); - - struct net_if *iface = net_if_get_default(); - - if (!check_dhcp(iface)) { - net_dhcpv4_start(iface); - k_sem_take(&dhcp_ready, K_FOREVER); - } -} - diff --git a/software/prj.conf b/software/prj.conf deleted file mode 100644 index c67f525..0000000 --- a/software/prj.conf +++ /dev/null @@ -1,29 +0,0 @@ -CONFIG_LOG=y -CONFIG_NET_LOG=y -CONFIG_LOG_BUFFER_SIZE=1024 -CONFIG_LOG_PRINTK=y -CONFIG_LOG_DEFAULT_LEVEL=3 - -CONFIG_NETWORKING=y -CONFIG_NET_IPV4=y -CONFIG_NET_IPV6=n -CONFIG_NET_TCP=y -CONFIG_NET_SOCKETS=y -CONFIG_NET_ARP=y -CONFIG_NET_UDP=y - -CONFIG_NET_TCP_ISN_RFC6528=n - -CONFIG_INIT_STACKS=y -CONFIG_THREAD_LOCAL_STORAGE=y -CONFIG_SCHED_SCALABLE=y - -CONFIG_NET_CONFIG_SETTINGS=y -CONFIG_NET_CONFIG_NEED_IPV4=y -CONFIG_NET_MGMT=y -CONFIG_NET_MGMT_EVENT=y -# Ethernet config. Change me for your setup! -CONFIG_NET_DHCPV4=n -CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.168.1.50" -CONFIG_NET_CONFIG_MY_IPV4_GW="192.168.1.1" -CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0" diff --git a/software/src/access.c b/software/src/access.c deleted file mode 100644 index ae61a1f..0000000 --- a/software/src/access.c +++ /dev/null @@ -1,447 +0,0 @@ -/* Verilog access control. - * - * Mutex management for hardware resources. - * Each mutex has a thread-local lock counter associated with it, since in - * Zephyr the recursive lock counter is not publically accessable. - * - * On the final unlock for a thread, the code will always take steps to - * reset the state of the Verilog module so that another thread will - * see a consistent start state. - */ - -#include -#include -#include -#include "upsilon.h" -#include "access.h" -#include "control_loop_cmds.h" - -LOG_MODULE_REGISTER(access, 4); -#include "pin_io.c" - -/* The values from converters are not aligned to 32 bits. - * These values are still in twos compliment and have to be - * manually sign-extended. - */ -static inline uint32_t -sign_extend(uint32_t in, unsigned len) -{ - if (in >> (len - 1) & 1) { - uint32_t mask = (1 << len) - 1; - return ~mask | (in & mask); - } else { - return in; - } -} - -/********************* - * DAC - *********************/ - -static struct k_mutex dac_mutex[DAC_MAX]; -static __thread int dac_locked[DAC_MAX]; - -int -dac_take(int dac, k_timeout_t timeout) -{ - if (dac < 0 || dac >= DAC_MAX) - return -EFAULT; - - int e = k_mutex_lock(dac_mutex + dac, timeout); - if (e == 0) { - dac_locked[dac] += 1; - } - return e; -} - -int -dac_release(int dac) -{ - if (dac < 0 || dac >= DAC_MAX) - return -EFAULT; - - if (dac_locked[dac] == 1) { - write_dac_arm(0, dac); - // TODO: Flush DAC? - // while (!read_dac_finished(dac)); - } - - int e = k_mutex_unlock(dac_mutex + dac); - if (e == 0) { - dac_locked[dac] -= 1; - } - return e; -} - -int -dac_read_write(int dac, creole_word send, k_timeout_t timeout, - creole_word *recv) -{ - int e = dac_take(dac, timeout); - if (e != 0) - return e; - dac_switch(dac, DAC_SPI_PORT, K_NO_WAIT); - - write_to_dac(send, dac); - write_dac_arm(1, dac); - - /* Non-recursive locks should busy wait. */ - /* 10ns * (2 * 10 cycles per half DAC cycle) - * 24 bits - */ - if (dac_locked[dac] > 1) - k_sleep(K_NSEC(10*2*10*24)); - while (!read_dac_finished(dac)); - - if (recv) - *recv = sign_extend(read_from_dac(dac), 20); - write_dac_arm(0, dac); - - dac_release(dac); - return 0; -} - -int -dac_switch(int dac, int setting, k_timeout_t timeout) -{ - int e = dac_take(dac, timeout); - if (e != 0) - return e; - - write_dac_sel(setting, dac); - - dac_release(dac); - return 0; -} - -/********************** - * adc read - *********************/ - -static struct k_mutex adc_mutex[ADC_MAX]; -static __thread int adc_locked[ADC_MAX]; - -int -adc_take(int adc, k_timeout_t timeout) -{ - if (adc < 0 || adc >= ADC_MAX) - return -EFAULT; - - LOG_DBG("%s: taking adc %d", get_thread_name(), adc); - int e = k_mutex_lock(adc_mutex + adc, timeout); - LOG_DBG("%s: adc %d taken", get_thread_name(), adc); - if (e == 0) { - adc_locked[adc] += 1; - } - LOG_DBG("%s: adc %d lockeg", get_thread_name(), adc); - return e; -} - -int -adc_release(int adc) -{ - if (adc < 0 || adc >= ADC_MAX) - return -EFAULT; - - LOG_DBG("%s: in adc_release", get_thread_name()); - if (adc_locked[adc] == 1) { - write_adc_arm(0, adc); - // TODO: flush ADC? - } - - int e = k_mutex_unlock(adc_mutex + adc); - if (e == 0) { - adc_locked[adc] -= 1; - } - return e; -} - -int -adc_switch(int adc, int setting, k_timeout_t timeout) -{ - /* As of now, only one ADC (the CLOOP adc) is used - * by two modules at the same time. - */ - if (adc != 0) - return -ENOENT; - - int e = adc_take(adc, timeout); - if (e != 0) - return e; - - write_adc_sel_0(setting); - - adc_release(adc); - return 0; -} - -int -adc_read(int adc, k_timeout_t timeout, creole_word *wrd) -{ - int e; - if ((e = adc_take(adc, timeout)) != 0) - return e; - - adc_switch(adc, ADC_SPI_PORT, K_NO_WAIT); - write_adc_arm(1, adc); - - /* Recursive locks should busy wait. */ - if (adc_locked[adc] > 1) - k_sleep(K_NSEC(550 + 24*2*10*10)); - while (!read_adc_finished(adc)); - - *wrd = sign_extend(read_from_adc(adc), 20); - write_adc_arm(0, adc); - - adc_release(adc); - return 0; -} - -/******** - * Control loop - *******/ - -static struct k_mutex cloop_mutex; -static __thread int cloop_locked; - -int -cloop_take(k_timeout_t timeout) -{ - int e = k_mutex_lock(&cloop_mutex, timeout); - if (e == 0) { - cloop_locked++; - } - return e; -} - -int -cloop_release(void) -{ - /* Do not attempt to reset the CLOOP interface. - * Other scripts will fight to modify the CLOOP constants - * while the loop is still running. - */ - int e = k_mutex_unlock(&cloop_mutex); - if (e == 0) { - cloop_locked--; - } - return e; -} - -int -cloop_read(int code, uint32_t *high_reg, uint32_t *low_reg, - k_timeout_t timeout) -{ - uint64_t v = 0; - if (cloop_take(timeout) != 0) - return 0; - - write_cl_cmd(code); - write_cl_start_cmd(1); - while (!read_cl_finish_cmd()); - v = read_cl_word_out(); - write_cl_start_cmd(0); - - *high_reg = v >> 32; - *low_reg = v & 0xFFFFFFFF; - - cloop_release(); - return 1; -} - -int -cloop_write(int code, uint32_t high_val, uint32_t low_val, - k_timeout_t timeout) -{ - if (cloop_take(timeout) != 0) - return 0; - - write_cl_cmd(code); - write_cl_word_in((uint64_t) high_val << 32 | low_val); - write_cl_start_cmd(1); - while (!read_cl_finish_cmd()); - write_cl_start_cmd(0); - - cloop_release(); - return 1; -} - -/************ - * Waveforms - ***********/ - -static struct k_mutex waveform_mutex[DAC_MAX]; -static __thread int waveform_locked[DAC_MAX]; - -int -waveform_take(int waveform, k_timeout_t timeout) -{ - if (waveform < 0 || waveform >= DAC_MAX) - return -EFAULT; - - int e = k_mutex_lock(waveform_mutex + waveform, timeout); - if (e == 0) { - waveform_locked[e]++; - } - return e; -} - -static void -waveform_disarm_wait(int wf) -{ - write_wf_arm(0, wf); - /* TODO: add wait */ - while (read_wf_running(wf)); -} - -int -waveform_release(int waveform) -{ - if (waveform < 0 || waveform >= DAC_MAX) - return -EFAULT; - - if (waveform_locked[waveform] == 1) { - waveform_disarm_wait(waveform); - } - - int e = k_mutex_unlock(waveform_mutex + waveform); - if (e == 0) { - waveform_locked[e]--; - } - return e; -} - -size_t -creole_to_array(const struct creole_reader *start, creole_word *buf, size_t buflen) -{ - size_t i = 0; - struct creole_word w; - struct creole_reader r = *start; - - while (creole_decode(&r, &w) && i < buflen) { - buf[i++] = w.word; - } - - return i; -} - -int -waveform_load(uint32_t buf[MAX_WL_SIZE], int slot, k_timeout_t timeout) -{ - if (waveform_take(slot, timeout) != 0) - return 0; - - write_wf_start_addr((uint32_t) buf, slot); - write_wf_refresh_start(1, slot); - while (!read_wf_refresh_finished(slot)); - write_wf_refresh_start(0, slot); - - waveform_release(slot); - return 1; -} - -int -waveform_halt_until_finished(int slot) -{ - write_wf_halt_on_finish(1, slot); - while (!read_wf_finished(slot)); - return 1; -} - -int -waveform_arm(int slot, bool halt_on_finish, uint32_t wait, k_timeout_t timeout) -{ - if (waveform_take(slot, timeout) != 0) - return 0; - if (dac_take(slot, timeout) != 0) { - waveform_release(slot); - return 0; - } - - dac_switch(slot, DAC_WF_PORT, K_NO_WAIT); - - write_wf_halt_on_finish(halt_on_finish, slot); - write_wf_time_to_wait(wait, slot); - write_wf_arm(1, slot); - - return 1; -} - -int -waveform_disarm(int slot) -{ - waveform_disarm_wait(slot); - waveform_release(slot); - dac_release(slot); - return 1; -} - -/********** - * Init and deinit - *********/ - -void -access_release_thread(void) -{ - while (cloop_release() == 0) - cloop_locked--; - if (cloop_locked != 0) { - LOG_WRN("%s: cloop mutex counter mismatch", get_thread_name()); - cloop_locked = 0; - } - - for (int i = 0; i < DAC_MAX; i++) { - while (dac_release(i) == 0) - dac_locked[i]--; - if (dac_locked[i] != 0) { - LOG_WRN("%s: dac mutex %d counter mismatch", get_thread_name(), i); - dac_locked[i] = 0; - } - - while (waveform_release(i) == 0) - waveform_locked[i]--; - if (waveform_locked[i] != 0) { - LOG_WRN("%s: waveform mutex %d counter mismatch", get_thread_name(), i); - waveform_locked[i] = 0; - } - } - - for (int i = 0; i < ADC_MAX; i++) { - while (adc_release(i) == 0) - adc_locked[i]--; - if (adc_locked[i] != 0) { - LOG_WRN("%s: adc mutex %d counter mismatch", get_thread_name(), i); - adc_locked[i] = 0; - } - } -} - -void -access_init(void) -{ - LOG_INF("access_init"); - if (k_mutex_init(&cloop_mutex) != 0) { - LOG_ERR("err: cloop mutex"); - k_fatal_halt(K_ERR_KERNEL_PANIC); - } - - for (int i = 0; i < DAC_MAX; i++) { - if (k_mutex_init(dac_mutex + i) != 0) { - LOG_ERR("err: dac mutex %d", i); - k_fatal_halt(K_ERR_KERNEL_PANIC); - } - - if (k_mutex_init(waveform_mutex + i) != 0) { - LOG_ERR("err: waveform mutex %d", i); - k_fatal_halt(K_ERR_KERNEL_PANIC); - } - } - - for (int i = 0; i < ADC_MAX; i++) { - if (k_mutex_init(adc_mutex + i) != 0) { - LOG_ERR("err: adc mutex %d", i); - k_fatal_halt(K_ERR_KERNEL_PANIC); - } - } - LOG_INF("access_init done"); -} diff --git a/software/src/access.h b/software/src/access.h deleted file mode 100644 index 24bfc5c..0000000 --- a/software/src/access.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once -#include -#include "creole.h" - -int dac_take(int dac, k_timeout_t timeout); -int dac_release(int dac); -int dac_read_write(int dac, creole_word send, k_timeout_t timeout, - creole_word *recv); - -/* These ports are defined in firmware/rtl/base/base.v.m4 */ -#define DAC_SPI_PORT 0 -#define DAC_WF_PORT 1 -#define DAC_CLOOP_PORT 2 -int dac_switch(int dac, int setting, k_timeout_t timeout); - -int adc_take(int adc, k_timeout_t timeout); -int adc_release(int adc); -int adc_read(int adc, k_timeout_t timeout, creole_word *wrd); - -#define ADC_SPI_PORT 0 -#define ADC_CLOOP_PORT 1 -int adc_switch(int adc, int setting, k_timeout_t timeout); - -int cloop_take(k_timeout_t timeout); -int cloop_read(int code, uint32_t *high_reg, uint32_t *low_reg, - k_timeout_t timeout); -int cloop_write(int code, uint32_t high_val, uint32_t low_val, - k_timeout_t timeout); -int cloop_release(void); - -int waveform_take(int waveform, k_timeout_t timeout); -int waveform_release(int waveform); - -#define MAX_WL_SIZE 4096 -int waveform_load(uint32_t buf[MAX_WL_SIZE], int slot, k_timeout_t timeout); -int waveform_arm(int slot, bool halt_on_finish, uint32_t wait, k_timeout_t timeout); -int waveform_disarm(int slot); - - -/* Zephyr OS does not automatically clean up mutex resources. - * This will release all held locks. - */ -void access_release_thread(void); - -/* Called once on initializion. */ -void access_init(void); diff --git a/software/src/buf.c b/software/src/buf.c deleted file mode 100644 index 6d042e2..0000000 --- a/software/src/buf.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include "buf.h" - -int -buf_writevf(struct bufptr *bp, const char *fmt, va_list va) -{ - /* vsnprintk() returns the amount of bytes that would - * be stored in the buffer if the buffer was big enough, - * excluding the NUL terminator. - * The function will _always_ write a NUL terminator - * unless bp->left == 0. - */ - int w = vsnprintk(bp->p, bp->left, fmt, va); - - if (w < 0) - return BUF_WRITE_ERR; - - /* Return the number of bytes that are required to be - * written. - * Do not increment the buffer pointer, the truncated - * data may not be safe. - * Since w is the amount of required bytes minus the NUL - * terminator, w == bp->left is still an out-of-memory - * situation. - */ - if (w >= bp->left) { - return w - bp->left + 1; - } else { - bp->p += w; - bp->left -= w; - return BUF_OK; - } -} - -int -buf_writef(struct bufptr *bp, const char *fmt, ...) -{ - va_list va; - va_start(va, fmt); - int r = buf_writevf(bp, fmt, va); - va_end(va); - return r; -} diff --git a/software/src/buf.h b/software/src/buf.h deleted file mode 100644 index ab0ed4a..0000000 --- a/software/src/buf.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -/* This is a pointer _into_ a buffer. It is incremented (and the variable - * "left" decremented) after each operation. - * - * Space is always left for a NUL terminator. - */ -struct bufptr { - char *p; - size_t left; -}; - -enum { - BUF_OK = 0, - BUF_WRITE_ERR = -1, - BUF_SOCK_ERR = -2 -}; - -/* Write a formatted string to bp. - * This function uses printf(), which means that it deals with - * writing _C-strings_, not unterminated buffers. - * When using this function, the buffer must be _one more_ than - * the maximum message length. For instance, a 1024-byte message - * should be in a 1025-byte buffer. HOWEVER, bp->left must still - * be set to the total length of the buffer (in the example, 1025). - * - * The final bufptr points to the NUL terminator, so that it - * is overwritten on each call to the function. - * - * This function returns 0 for a successful write, -1 for an - * encoding error (should never happen), and a positive value - * for the amount of bytes that could not fit. - */ -int buf_writevf(struct bufptr *bp, const char *fmt, va_list va); -int buf_writef(struct bufptr *bp, const char *fmt, ...); diff --git a/software/src/main.c b/software/src/main.c deleted file mode 100644 index 77ad14c..0000000 --- a/software/src/main.c +++ /dev/null @@ -1,213 +0,0 @@ -#include -#include -#include -#include -#include - -#include "upsilon.h" -#include "access.h" -#include "sock.h" -#include "buf.h" - -LOG_MODULE_REGISTER(main, 4); - -#define THREAD_STACK_SIZ 1024*32 -#define THREADNUM 32 -static K_KERNEL_STACK_ARRAY_DEFINE(stacks, THREADNUM, THREAD_STACK_SIZ); - -#define READBUF_SIZ 0xFFFF -static unsigned char readbuf[THREADNUM][READBUF_SIZ]; -static struct k_thread threads[THREADNUM]; -static bool thread_ever_used[THREADNUM]; - -static const char *const compiler_ret_str[CREOLE_COMPILE_RET_LEN] = { - [CREOLE_COMPILE_OK] = "compile ok", - [CREOLE_OPCODE_READ_ERROR] = "opcode read error", - [CREOLE_OPCODE_MALFORMED] = "opcode malformed", - [CREOLE_ARG_READ_ERROR] = "arg read error", - [CREOLE_ARG_MALFORMED] = "arg malformed", - [CREOLE_LAST_READ_ERROR] = "last read error", - [CREOLE_LAST_MALFORMED] = "last malformed", - [CREOLE_DATA_OVERFLOW] = "data overflow", - [CREOLE_TYPE_ERROR] = "type error", - [CREOLE_PROGRAM_OVERFLOW] = "program overflow" -}; - -static const char *const run_ret_str[CREOLE_RUN_RET_LEN] = { - [CREOLE_STEP_CONTINUE] = "continue", - [CREOLE_STEP_SYSCALL] = "syscall", - [CREOLE_STEP_STOP] = "stop", - [CREOLE_STACK_OVERFLOW] = "overflow", - [CREOLE_STACK_UNDERFLOW] = "underflow", - [CREOLE_RUN_DECODE_ERROR] = "decode error", - [CREOLE_REGISTER_OVERFLOW] = "register overflow", - [CREOLE_STEP_UNKNOWN_OPCODE] = "unknown opcode", - [CREOLE_DIV_BY_ZERO] = "div by zero", - [CREOLE_STEP_HIGH_BIT_MALFORMED] = "high bit malformed", - [CREOLE_JUMP_OVERFLOW] = "jump overflow" -}; - -/* Returns 0 if the sock is still connected. */ -static int -hup(int sock) -{ - struct zsock_pollfd fd = { - .fd = sock, - .events = POLLHUP, - .revents = 0 - }; - - return zsock_poll(&fd, 1, 0); -} - -static void -exec_creole(unsigned char *buf, int size, int sock) -{ -#define DATSLEN 64 - struct creole_reader dats[DATSLEN]; -#define REGLEN 32 - creole_word reg[REGLEN]; -#define STKLEN 1024 - creole_word stk[STKLEN]; - - struct creole_env env = { - .dats = dats, - .datlen = DATSLEN, - .reg = reg, - .reglen = REGLEN, - .stk = stk, - .stklen = STKLEN, - - .r_current = {buf, size}, - .r_start = {buf, size}, - .fd = sock - }; - - int e = creole_compile(&env); - if (e != CREOLE_COMPILE_OK) { - LOG_WRN("%s: compile: %s at %zu", get_thread_name(), - compiler_ret_str[e], - (env.r_start.left - env.r_current.left)); - return; - } - - for (;;) { - creole_word sc; - e = creole_step(&env, &sc); - LOG_DBG("%s: %s", get_thread_name(), run_ret_str[e]); - switch (e) { - case CREOLE_STEP_CONTINUE: - continue; - case CREOLE_STEP_SYSCALL: - LOG_WRN("%s: syscall unsupported", get_thread_name()); - continue; - case CREOLE_STEP_STOP: - return; - default: - LOG_WRN("%s: run: %s", get_thread_name(), - run_ret_str[e]); - return; - } - - if (hup(sock) != 0) { - LOG_WRN("%s: hangup", get_thread_name()); - return; - } - } -} - -/* Read the size of the message from the socket. */ -static int -read_size(int s) -{ - char buf[2]; - struct bufptr bp = {buf, sizeof(buf)}; - int e = sock_read_buf(s, &bp, true); - if (e != 0) - return e; - return (unsigned char)buf[0] | (unsigned char) buf[1] << 8; -} - -/* Thread entry. Reads the program send by the connection and executes it. */ -static void -exec_entry(void *client_p, void *connection_num_p, - void *threadnum_p) -{ - intptr_t client = (intptr_t)client_p; - intptr_t connection_num = (intptr_t)connection_num_p; - intptr_t threadnum = (intptr_t)threadnum_p; - char thread_name[64]; - snprintk(thread_name, sizeof(thread_name), "%"PRIdPTR":%"PRIdPTR, threadnum, connection_num); - k_thread_name_set(k_current_get(), thread_name); - - LOG_DBG("%s: entered thread", get_thread_name()); - - int size = read_size(client); - if (size < 0) { - LOG_WRN("%s: error in read size: %d", get_thread_name(), size); - zsock_close(client); - return; - } - LOG_INF("%s: program length: %d", get_thread_name(), size); - - struct bufptr bp = {readbuf[threadnum], size}; - int e = sock_read_buf(client, &bp, true); - if (e != 0) { - LOG_WRN("%s: error in read body: %d", get_thread_name(), e); - zsock_close(client); - return; - } - LOG_DBG("%s: read program", get_thread_name()); - - exec_creole(readbuf[threadnum], size, (int)client); - zsock_close(client); - LOG_INF("Exiting thread %s", get_thread_name()); -} - -static void -main_loop(int srvsock) -{ - static unsigned int connection_counter = 0; - for (;;) { - int client = server_accept_client(srvsock); - int i; - - for (i = 0; i < THREADNUM; i++) { - if (!thread_ever_used[i] || k_thread_join(&threads[i], K_NO_WAIT) == 0) { - LOG_DBG("launching thread %d", i); - connection_counter++; - thread_ever_used[i] = true; - k_thread_create(&threads[i], stacks[i], - THREAD_STACK_SIZ, exec_entry, - (void*) client, (void*) connection_counter, - NULL, 1, 0, K_NO_WAIT); - break; - } - } - - if (i == THREADNUM) { - LOG_INF("Too many connections (max %d)", - THREADNUM); - zsock_close(client); - } - } -} - -/* For reproducible builds if needed */ -#ifdef SOURCE_DATE_EPOCH -# define BUILD_TIME SOURCE_DATE_EPOCH -#else -# define BUILD_TIME __DATE__ " " __TIME__ -#endif -void -main(void) -{ - LOG_PRINTK("Upsilon on ZephyrOS, built on %s\n", BUILD_TIME); - access_init(); - k_thread_name_set(k_current_get(), "main thread"); - for (;;) { - int sock = server_init_sock(6626); - main_loop(sock); - zsock_close(sock); - } -} diff --git a/software/src/sock.c b/software/src/sock.c deleted file mode 100644 index 4a15434..0000000 --- a/software/src/sock.c +++ /dev/null @@ -1,135 +0,0 @@ -#include -#include -#include -#include -#include -#include "sock.h" -#include "buf.h" - -LOG_MODULE_REGISTER(sock); - -int -server_init_sock(int port) -{ - int sock; - - sock = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - - if (sock < 0) { - LOG_ERR("error: socket: %d", sock); - k_fatal_halt(K_ERR_KERNEL_PANIC); - } - - struct sockaddr_in addr = { - .sin_family = AF_INET, - .sin_addr = {.s_addr = htonl(INADDR_ANY)}, - .sin_port = htons(port) - }; - - if (zsock_bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - LOG_ERR("error: bind: %d", errno); - k_fatal_halt(K_ERR_KERNEL_PANIC); - } - - if (zsock_listen(sock, 5) < 0) { - LOG_ERR("error: listen: %d", errno); - k_fatal_halt(K_ERR_KERNEL_PANIC); - } - LOG_INF("Upsilon waiting on %d", port); - - return sock; -} - -int -server_accept_client(int server) -{ - int client; - struct sockaddr_in addr; - socklen_t len = sizeof(addr); - - /* Accept clients in a loop. This should block when there are no clients - * so other threads can run. - */ - do { - LOG_DBG("Accept"); - /* - struct zsock_pollfd server_fd = { .fd = server, .events = ZSOCK_POLLIN }; - zsock_poll(&server_fd, 1, -1); - */ - client = zsock_accept(server, (struct sockaddr *)&addr, &len); - if (client < 0) - LOG_WRN("error in accept: %d", errno); - } while (client < 0); - - char ipaddr[32]; - zsock_inet_ntop(addr.sin_family, &addr.sin_addr, ipaddr, sizeof(ipaddr)); - LOG_INF("Connection received from %s", ipaddr); - return client; -} - -int -sock_read_buf(int sock, struct bufptr *bp, bool entire) -{ - do { - ssize_t l = zsock_recv(sock, bp->p, bp->left, 0); - if (l == 0) - return -ECONNRESET; - if (l < 0) - return -errno; - - bp->left -= l; - bp->p += l; - } while (entire && bp->left > 0); - - return 0; -} - -int -sock_write_buf(int sock, struct bufptr *bp) -{ - /* Since send may not send all data in the buffer at once, - * loop until it sends all data (or fails). - */ - while (bp->left) { - ssize_t l = zsock_send(sock, bp->p, bp->left, 0); - if (l == 0) - return -ECONNRESET; - if (l < 0) - return -errno; - bp->p += l; - bp->left -= l; - } - - return 0; -} - -int -sock_vprintf(int sock, struct bufptr *bp, const char *fmt, va_list va) -{ - struct bufptr store_bp = *bp; - int r = buf_writevf(bp, fmt, va); - if (r != BUF_OK) - return r; - - /* The difference between the initial and final values of - * `left` is the amount of bytes written to the buffer. - * Set left to this difference so that the only thing sent - * is the bytes written by buf_writevf. - */ - store_bp.left -= bp->left; - if (!sock_write_buf(sock, &store_bp)) { - return BUF_SOCK_ERR; - } else { - return BUF_OK; - } -} - -int -sock_printf(int sock, struct bufptr *bp, const char *fmt, ...) -{ - va_list va; - va_start(va, fmt); - bool b = sock_vprintf(sock, bp, fmt, va); - va_end(va); - return b; -} diff --git a/software/src/sock.h b/software/src/sock.h deleted file mode 100644 index 709ee66..0000000 --- a/software/src/sock.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -#include -#include "buf.h" - -/* Initialize server to listen on the port passed as an argument. - */ -int server_init_sock(int port); - -/* Accept a client and allocate a file descriptor for the client. - */ -int server_accept_client(int server); - -/* Read data into buffer. Returns 0 if buffer is filled. This is - * raw binary (no NUL termination). - */ -int sock_read_buf(int sock, struct bufptr *bp, bool entire); - -/* Write raw buffer data into socket. This data is raw binary and - * does not have to be NUL terminated. Returns 0 when all data has - * been written. - */ -int sock_write_buf(int sock, struct bufptr *bp); - -/* Write formatted string into socket. The user must provide a - * buffer into which the formatted string is written. These return - * with a buf.h error, or BUF_OK when successful. - */ -int sock_vprintf(int sock, struct bufptr *bp, const char *fmt, va_list va); -int sock_printf(int sock, struct bufptr *bp, const char *fmt, ...); diff --git a/software/src/tests/test_dac_adc_main.c b/software/src/tests/test_dac_adc_main.c deleted file mode 100644 index 3cfa466..0000000 --- a/software/src/tests/test_dac_adc_main.c +++ /dev/null @@ -1,211 +0,0 @@ -#include -#include -#include -#include -#include "pin_io.h" -#include "io.h" - -LOG_MODULE_REGISTER(dac_adc_test_main); - -#define ATTEMPTS 5 - -static bool dac_ready[DAC_MAX] = {0}; - -static void -init_dacs(void) -{ - for (size_t i = 0; i < DAC_MAX; i++) { - for (int j = 0; j < ATTEMPTS; j++) { - if (dac_init(i)) { - LOG_INF("DAC #%zu initialized, attempt %d\n", i, j); - dac_ready[i] = 1; - break; - } - } - - if (!dac_ready[i]) - LOG_WRN("DAC #%zu disconnected!\n", i); - } -} - -K_MUTEX_DEFINE(print_mutex); - -static void -print_mutex_unlock_impl(const char *func) -{ - if (k_mutex_unlock(&print_mutex) != 0) { - LOG_ERR("Fatal error in mutex_unlock in %s\n", func); - k_fatal_halt(K_ERR_KERNEL_PANIC); - } -} - -#define print_mutex_unlock() print_mutex_unlock_impl(__func__) - -struct dac_info { - float lo; - float hi; - unsigned num; -}; - -#ifdef PRINT_DAC -#define MAX_DAC (1 << 20) - 1 - -static void -print_dac(const struct dac_info *info, uint32_t val) -{ - k_mutex_lock(&print_mutex, K_FOREVER); - - float volt = (info->hi - info->lo) * val / MAX_DAC - + info->lo; - LOG_PRINTK("DAC\t%u\t%f\n", info->num, volt); - - print_mutex_unlock(); -} -#endif - -static void -dac_thread(void *p1, void *p2, void *p3) -{ - ARG_UNUSED(p2); - ARG_UNUSED(p3); - - const struct dac_info *info = p1; - uint32_t val = (1 << 19); - int incr = 1; -#ifdef PRINT_DAC - int print_cntr = 0; -#endif - - for (;;) { - dac_write_v(info->num, val); - if (val == 0xFFFFF) { - incr = -1; - } else if (val == 0) { - incr = 1; - } - val += incr; -#ifdef PRINT_DAC - if (print_cntr == 8000) { - print_cntr = 0; - print_dac(info); - } -#endif - k_sleep(K_NSEC(125)); - } -} - -struct adc_info { - float hi; - unsigned num; - unsigned wid; -}; - -static void -print_adc(const struct adc_info *info, int32_t val) -{ - k_mutex_lock(&print_mutex, K_FOREVER); - - const uint32_t bitnum = (1 << info->wid) - 1; - float volt = info->hi / bitnum * val; - LOG_PRINTK("ADC\t%u\t%f\n", info->num, volt); - - print_mutex_unlock(); -} - -static void -adc_thread(void *p1, void *p2, void *p3) -{ - ARG_UNUSED(p2); - ARG_UNUSED(p3); - const struct adc_info *info = p1; - int32_t v; - - for (;;) { - v = adc_read(info->num, info->wid); - print_adc(info, v); - k_sleep(K_MSEC(1000)); - } -} - -#define MK_DAC_INFO(n, lo, hi) [n] = {lo, hi, n} -const struct dac_info dac_info[DAC_MAX] = { - MK_DAC_INFO(0, -10, 10), - MK_DAC_INFO(1, -10, 10), - MK_DAC_INFO(2, -10, 10), - MK_DAC_INFO(3, -10, 10), - MK_DAC_INFO(4, -10, 10), - MK_DAC_INFO(5, -10, 10), - MK_DAC_INFO(6, -10, 10), - MK_DAC_INFO(7, -10, 10) -}; - -#undef MK_DAC_INFO - -#define STACKSIZ 2048 -#define MKSTACK(name, num) \ - K_THREAD_STACK_DEFINE(name##_stk_##num, STACKSIZ) - -#define DAC_STACK(n) MKSTACK(dac, n) -DAC_STACK(0); -DAC_STACK(1); -DAC_STACK(2); -DAC_STACK(3); -DAC_STACK(4); -DAC_STACK(5); -DAC_STACK(6); -DAC_STACK(7); -#undef DAC_STACK - -const struct adc_info adc_info[ADC_MAX] = { - // TODO -}; - -#define ADC_STACK(n) MKSTACK(adc, n) -ADC_STACK(0); -ADC_STACK(1); -ADC_STACK(2); -ADC_STACK(3); -ADC_STACK(4); -ADC_STACK(5); -ADC_STACK(6); -ADC_STACK(7); -#undef ADC_STACK - -#undef MKSTACK - -void -main(void) -{ - struct k_thread dac_tids[8]; - struct k_thread adc_tids[8]; - - LOG_PRINTK("DAC ADC test program.\n"); - init_dacs(); - -#define CREATE_THREAD(name, num) \ - k_thread_create(&name##_tids[num], \ - (k_thread_stack_t *) name##_stk_##num, \ - K_THREAD_STACK_SIZEOF(&name##_stk_##num), \ - name##_thread, &name##_info[num], NULL, NULL, \ - -1, K_FP_REGS, K_MSEC(10)) - - CREATE_THREAD(dac, 0); - CREATE_THREAD(dac, 1); - CREATE_THREAD(dac, 2); - CREATE_THREAD(dac, 3); - CREATE_THREAD(dac, 4); - CREATE_THREAD(dac, 5); - CREATE_THREAD(dac, 6); - CREATE_THREAD(dac, 7); - - CREATE_THREAD(adc, 0); - CREATE_THREAD(adc, 1); - CREATE_THREAD(adc, 2); - CREATE_THREAD(adc, 3); - CREATE_THREAD(adc, 4); - CREATE_THREAD(adc, 5); - CREATE_THREAD(adc, 6); - CREATE_THREAD(adc, 7); - -#undef CREATE_THREAD -} diff --git a/software/src/tests/test_ethernet.c b/software/src/tests/test_ethernet.c deleted file mode 100644 index c66a296..0000000 --- a/software/src/tests/test_ethernet.c +++ /dev/null @@ -1,120 +0,0 @@ -#include -#include -#include -#include - -LOG_MODULE_REGISTER(test_ethernet); - -#define PORT 6626 - -static int -ip_init(void) -{ - int sock; - - sock = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - - if (sock < 0) { - LOG_ERR("error: socket: %d", sock); - k_fatal_halt(K_ERR_KERNEL_PANIC); - } - - struct sockaddr_in addr = { - .sin_family = AF_INET, - .sin_addr = {.s_addr = htonl(INADDR_ANY)}, - .sin_port = htons(PORT) - }; - - if (zsock_bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - LOG_ERR("error: bind: %d", errno); - k_fatal_halt(K_ERR_KERNEL_PANIC); - } - - if (zsock_listen(sock, 2) < 0) { - LOG_ERR("error: listen: %d", errno); - k_fatal_halt(K_ERR_KERNEL_PANIC); - } - - return sock; -} - -static int -get_client(int server) -{ - int client; - struct sockaddr_in addr; - socklen_t len = sizeof(addr); - - do { - client = zsock_accept(server, (struct sockaddr *)&addr, &len); - if (client < 0) - LOG_WRN("error in accept: %d", errno); - } while (client < 0); - - char ipaddr[32]; - zsock_inet_ntop(addr.sin_family, &addr.sin_addr, ipaddr, sizeof(ipaddr)); - LOG_PRINTK("Connection: %s\n", ipaddr); - return client; -} - -static int -send_all(int sock, char *buf, int len) -{ - do { - int sent = zsock_send(sock, buf, len, 0); - if (sent < 0) { - LOG_WRN("error in send: %d", errno); - return 0; - } - buf += sent; - len -= sent; - } while (len > 0); - return 1; -} - -static void -print_buf_escaped(const char *buf, size_t len) -{ - for (size_t i = 0; i < len; i++) { - if (*buf < 0x20 || *buf >= 0x7F) - LOG_PRINTK("[%02x]", *buf++); - else - LOG_PRINTK("%c", *buf++); - } -} - -static void -client_comm(int sock) -{ - for (;;) { - char buf[256]; - ssize_t len = zsock_recv(sock, buf, sizeof(buf), 0); - - if (len < 0) { - LOG_WRN("Error in client socket: %d", errno); - return; - } else if (len == 0) { - LOG_INF("Client disconnected"); - return; - } - print_buf_escaped(buf, len); - if (!send_all(sock, buf, len)) - return; - } -} - -/* DHCP is done before main(), so no manual DHCP setup required. */ - -void -main(void) -{ - LOG_PRINTK("Init test server...\n"); - int server_sock = ip_init(); - LOG_PRINTK("Test server waiting on %d\n", PORT); - - for (;;) { - int client_sock = get_client(server_sock); - client_comm(client_sock); - zsock_close(client_sock); - } -} diff --git a/software/src/upsilon.h b/software/src/upsilon.h deleted file mode 100644 index ab6b521..0000000 --- a/software/src/upsilon.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -#define get_thread_name() k_thread_name_get(k_current_get())