diff --git a/creole b/creole index dc1abae..c7fc965 160000 --- a/creole +++ b/creole @@ -1 +1 @@ -Subproject commit dc1abae13a7d8d50043dfbf22b8c8592692617f8 +Subproject commit c7fc965fcfa72f26456f5221a6480de52f7d776a diff --git a/firmware/generate_csr_locations.py b/firmware/generate_csr_locations.py index e278fdc..c575575 100644 --- a/firmware/generate_csr_locations.py +++ b/firmware/generate_csr_locations.py @@ -13,7 +13,7 @@ class CSRGenerator: regname = f"base_{name}" else: regname = f"base_{name}_{num}" - return self.j["csr_registers"][regname]["addr"] + return f'(csr_t) {self.j["csr_registers"][regname]["addr"]}' def print(self, *args): print(*args, end='', file=self.file) @@ -22,7 +22,7 @@ class CSRGenerator: self.print(f'csr_t {name} = {self.get_reg(name, None)};\n') else: self.print(f'csr_t {name}[{num}] = {{', self.get_reg(name, 0)) - for i in range(0,num): + for i in range(1,num): self.print(',', self.get_reg(name, i)) self.print('};\n\n') diff --git a/software/CMakeLists.txt b/software/CMakeLists.txt index 4e6f783..ae3e92f 100644 --- a/software/CMakeLists.txt +++ b/software/CMakeLists.txt @@ -3,7 +3,8 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr) project(upsilon) include_directories("../firmware") +include_directories("src/") include_directories("../creole") include_directories("../firmware/rtl/control_loop") -target_sources(app PRIVATE src/access.c src/buf.c src/main.c src/sock.c) +target_sources(app PRIVATE src/access.c src/buf.c src/main.c src/sock.c ../creole/creole.c) diff --git a/software/Makefile b/software/Makefile index 6318517..98e1870 100644 --- a/software/Makefile +++ b/software/Makefile @@ -1,5 +1,5 @@ build/zephyr/zephyr.bin: src/*.c ../firmware/overlay.dts ../firmware/pin_io.h mkdir -p build - cd build && cmake $$(cat ../../firmware/overlay.config) -DDTC_OVERLAY_FILE=../firmware/overlay.dts -DBOARD=litex_vexriscv .. && make -j7 + cd build && CMAKE_BINARY_DIR=$$(pwd) cmake $$(cat ../../firmware/overlay.config) -DDTC_OVERLAY_FILE=../firmware/overlay.dts -DBOARD=litex_vexriscv -DEXTRA_CFLAGS=-Wfatal-errors .. && make clean: rm -rf build diff --git a/software/src/access.c b/software/src/access.c index 8d8c21d..c93c538 100644 --- a/software/src/access.c +++ b/software/src/access.c @@ -11,8 +11,10 @@ #include #include +#include "upsilon.h" #include "access.h" #include "pin_io.h" +#include "control_loop_cmds.h" LOG_MODULE_REGISTER(access); @@ -31,7 +33,7 @@ sign_extend(uint32_t in, unsigned len) * DAC *********************/ -static struct k_mutex_t dac_mutex[DAC_MAX]; +static struct k_mutex dac_mutex[DAC_MAX]; static __thread int dac_locked[DAC_MAX]; int @@ -74,7 +76,7 @@ dac_read_write(int dac, creole_word send, k_timeout_t timeout, return e; *to_dac[dac] = send; - *dac_arm[adc] = 1; + *dac_arm[dac] = 1; /* Recursive locks should busy wait. */ /* 10ns * (2 * 10 cycles per half DAC cycle) @@ -96,11 +98,11 @@ dac_read_write(int dac, creole_word send, k_timeout_t timeout, * adc read *********************/ -static struct k_mutex_t adc_mutex[ADC_MAX]; +static struct k_mutex adc_mutex[ADC_MAX]; static __thread int adc_locked[ADC_MAX]; int -adc_take(int adc, int timeout) +adc_take(int adc, k_timeout_t timeout) { if (adc < 0 || adc >= ADC_MAX) return -EFAULT; @@ -131,7 +133,7 @@ adc_release(int adc) } int -adc_read(int adc, int timeout, creole_word *wrd) +adc_read(int adc, k_timeout_t timeout, creole_word *wrd) { int e; if ((e = adc_take(adc, timeout)) != 0) @@ -144,7 +146,7 @@ adc_read(int adc, int timeout, creole_word *wrd) k_sleep(K_NSEC(550 + 24*2*10*10)); while (!*adc_finished[adc]); - *wrd = sign_extend(*from_adc[adc]); + *wrd = sign_extend(*from_adc[adc], 20); *adc_arm[adc] = 0; adc_release(adc); @@ -155,8 +157,8 @@ adc_read(int adc, int timeout, creole_word *wrd) * Control loop *******/ -static struct k_mutex_t cloop_mutex; -static __thread cloop_locked; +static struct k_mutex cloop_mutex; +static __thread int cloop_locked; int cloop_take(k_timeout_t timeout) @@ -206,7 +208,7 @@ cloop_read(int code, uint32_t *high_reg, uint32_t *low_reg, } int -cloop_write(int code, uint32_t high_reg, uint32_t low_reg, +cloop_write(int code, uint32_t high_val, uint32_t low_val, k_timeout_t timeout) { if (cloop_take(timeout) != 0) @@ -228,7 +230,7 @@ cloop_write(int code, uint32_t high_reg, uint32_t low_reg, * Waveforms ***********/ -static struct k_mutex_t waveform_mutex[DAC_MAX]; +static struct k_mutex waveform_mutex[DAC_MAX]; static __thread int waveform_locked[DAC_MAX]; int @@ -249,7 +251,7 @@ waveform_disarm_wait(int wf) { *wf_arm[wf] = 0; if (*wf_running[wf]) { - k_sleep(K_NSEC(10* *wf_time_to_wait[wf]); + k_sleep(K_NSEC(10* *wf_time_to_wait[wf])); while (*wf_running[wf]); } } @@ -264,10 +266,11 @@ waveform_release(int waveform) waveform_disarm_wait(waveform); } - int e k_mutex_unlock(waveform_mutex + waveform); + int e = k_mutex_unlock(waveform_mutex + waveform); if (e == 0) { waveform_locked[e]--; } + return e; } size_t @@ -275,7 +278,7 @@ creole_to_array(const struct creole_reader *start, creole_word *buf, size_t bufl { size_t i = 0; struct creole_word w; - struct creole_reader r = start; + struct creole_reader r = *start; while (creole_decode(&r, &w) && i < buflen) { buf[i++] = w.word; @@ -290,11 +293,7 @@ waveform_load(uint32_t buf[MAX_WL_SIZE], int slot, k_timeout_t timeout) if (waveform_take(slot, timeout) != 0) return 0; - if (load_into_array(env->dats[db], buf, ARRAY_SIZE(buf)) - != MAX_WL_SIZE) - goto ret; - - *wf_start_addr[slot] = &buf; + *wf_start_addr[slot] = (uint32_t) buf; *wf_refresh_start[slot] = 1; while (!*wf_refresh_finished[slot]); *wf_refresh_start[slot] = 0; @@ -306,7 +305,9 @@ waveform_load(uint32_t buf[MAX_WL_SIZE], int slot, k_timeout_t timeout) int waveform_halt_until_finished(int slot) { - // stub + *wf_halt_on_finish[slot] = 1; + while (!*wf_finished[slot]); + return 1; } int @@ -319,7 +320,7 @@ waveform_arm(int slot, bool halt_on_finish, uint32_t wait, k_timeout_t timeout) return 0; } - *wf_halt_on_finished[slot] = halt_on_finish; + *wf_halt_on_finish[slot] = halt_on_finish; *wf_time_to_wait[slot] = wait; *wf_arm[slot] = 1; @@ -350,7 +351,7 @@ access_release_thread(void) } for (int i = 0; i < DAC_MAX; i++) { - while (dac_release(i) == 0); + 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); @@ -378,17 +379,17 @@ access_release_thread(void) } } -int +void access_init(void) { - k_mutex_init(cloop_mutex); + k_mutex_init(&cloop_mutex); - for (int i = 0; i < DAC_NUM; i++) { + for (int i = 0; i < DAC_MAX; i++) { k_mutex_init(dac_mutex + i); k_mutex_init(waveform_mutex + i); } - for (int i = 0; i < ADC_NUM; i++) { + for (int i = 0; i < ADC_MAX; i++) { k_mutex_init(adc_mutex + i); } } diff --git a/software/src/access.h b/software/src/access.h index 2ac1ab3..3a42ba8 100644 --- a/software/src/access.h +++ b/software/src/access.h @@ -1,16 +1,21 @@ #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); -int adc_take(int adc, int timeout); +int adc_take(int adc, k_timeout_t timeout); int adc_release(int adc); -int adc_read(int adc, int timeout, creole_word *wrd); +int adc_read(int adc, k_timeout_t timeout, creole_word *wrd); 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); @@ -28,4 +33,4 @@ int waveform_disarm(int slot); void access_release_thread(void); /* Called once on initializion. */ -int access_init(void); +void access_init(void); diff --git a/software/src/main.c b/software/src/main.c index 5e157c1..9d2874d 100644 --- a/software/src/main.c +++ b/software/src/main.c @@ -17,7 +17,7 @@ static K_KERNEL_STACK_ARRAY_DEFINE(stacks, THREADNUM, THREAD_STACK_SIZ); #define READBUF_SIZ 0xFFFF static unsigned char readbuf[THREADNUM][READBUF_SIZ]; -static struct kthread_t threads[THREADNUM]; +static struct k_thread threads[THREADNUM]; static bool thread_ever_used[THREADNUM]; static int @@ -31,7 +31,7 @@ read_size(int s) return (unsigned char)buf[0] | (unsigned char) buf[1] << 8; } -static const char *const compiler_ret_str[CREOLE_COMPILER_RET_LEN] = { +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", @@ -42,7 +42,7 @@ static const char *const compiler_ret_str[CREOLE_COMPILER_RET_LEN] = { [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", @@ -67,12 +67,13 @@ hup(int sock) .revents = 0 }; - return zsock_pollfd(&fd, 1, 0); + return zsock_poll(&fd, 1, 0); } static void exec_creole(unsigned char *buf, int size, int sock) -{#define DATLEN 64 +{ +#define DATSLEN 64 struct creole_reader dats[DATSLEN]; #define REGLEN 32 creole_word reg[REGLEN]; @@ -81,7 +82,7 @@ exec_creole(unsigned char *buf, int size, int sock) struct creole_env env = { .dats = dats, - .datlen = DATLEN, + .datlen = DATSLEN, .reg = reg, .reglen = REGLEN, .stk = stk, @@ -89,7 +90,7 @@ exec_creole(unsigned char *buf, int size, int sock) .r_current = {buf, size}, .r_start = {buf, size}, - .sock = sock + .fd = sock }; int e = creole_compile(&env); @@ -113,7 +114,7 @@ exec_creole(unsigned char *buf, int size, int sock) return; default: LOG_WRN("%s: run: %s", get_thread_name(), - creole_run_ret[e]); + run_ret_str[e]); return; } @@ -128,12 +129,12 @@ static void exec_entry(void *client_p, void *threadnum_p, void *unused __attribute__((unused))) { - intptr_t client = client_p; - intptr_t threadnum = threadnum_p; + intptr_t client = (intptr_t)client_p; + intptr_t threadnum = (intptr_t)threadnum_p; int size = read_size(client); - const char thread_name[64]; - vsnprintk(thread_name, sizeof(thread_name), "%d:%d", client, threadnum); + char thread_name[64]; + snprintk(thread_name, sizeof(thread_name), "%"PRIdPTR":%"PRIdPTR, client, threadnum); k_thread_name_set(k_current_get(), thread_name); LOG_INF("%s: Connection initiated", thread_name); @@ -152,7 +153,7 @@ exec_entry(void *client_p, void *threadnum_p, return; } - exec_creole(size); + exec_creole(readbuf[threadnum], size, (int)client); zsock_close(client); } @@ -167,12 +168,12 @@ main_loop(int srvsock) for (i = 0; i < THREADNUM; i++) { if (!thread_ever_used[i] - || k_thread_join(threads[i], 0) == 0) { + || k_thread_join(&threads[i], K_NO_WAIT) == 0) { connection_counter++; - k_thread_create(threads[i], stacks[i], + k_thread_create(&threads[i], stacks[i], THREAD_STACK_SIZ, exec_entry, - (uintptr_t) client, (uintptr_t) i, - (uintptr_t) connection_counter, + (void*) client, (void*) i, + (void*) connection_counter, 1, 0, K_NO_WAIT); } } @@ -189,7 +190,7 @@ void main(void) { access_init(); - k_thread_name_get(k_current_get(), "main thread"); + k_thread_name_set(k_current_get(), "main thread"); for (;;) { int sock = server_init_sock(6626); main_loop(sock);