This commit is contained in:
Peter McGoron 2023-04-04 12:04:06 -04:00
parent 3416532378
commit 551f535513
7 changed files with 60 additions and 52 deletions

2
creole

@ -1 +1 @@
Subproject commit dc1abae13a7d8d50043dfbf22b8c8592692617f8 Subproject commit c7fc965fcfa72f26456f5221a6480de52f7d776a

View File

@ -13,7 +13,7 @@ class CSRGenerator:
regname = f"base_{name}" regname = f"base_{name}"
else: else:
regname = f"base_{name}_{num}" 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): def print(self, *args):
print(*args, end='', file=self.file) print(*args, end='', file=self.file)
@ -22,7 +22,7 @@ class CSRGenerator:
self.print(f'csr_t {name} = {self.get_reg(name, None)};\n') self.print(f'csr_t {name} = {self.get_reg(name, None)};\n')
else: else:
self.print(f'csr_t {name}[{num}] = {{', self.get_reg(name, 0)) 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(',', self.get_reg(name, i))
self.print('};\n\n') self.print('};\n\n')

View File

@ -3,7 +3,8 @@ cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr) find_package(Zephyr)
project(upsilon) project(upsilon)
include_directories("../firmware") include_directories("../firmware")
include_directories("src/")
include_directories("../creole") include_directories("../creole")
include_directories("../firmware/rtl/control_loop") 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)

View File

@ -1,5 +1,5 @@
build/zephyr/zephyr.bin: src/*.c ../firmware/overlay.dts ../firmware/pin_io.h build/zephyr/zephyr.bin: src/*.c ../firmware/overlay.dts ../firmware/pin_io.h
mkdir -p build 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: clean:
rm -rf build rm -rf build

View File

@ -11,8 +11,10 @@
#include <zephyr/kernel.h> #include <zephyr/kernel.h>
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
#include "upsilon.h"
#include "access.h" #include "access.h"
#include "pin_io.h" #include "pin_io.h"
#include "control_loop_cmds.h"
LOG_MODULE_REGISTER(access); LOG_MODULE_REGISTER(access);
@ -31,7 +33,7 @@ sign_extend(uint32_t in, unsigned len)
* DAC * 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]; static __thread int dac_locked[DAC_MAX];
int int
@ -74,7 +76,7 @@ dac_read_write(int dac, creole_word send, k_timeout_t timeout,
return e; return e;
*to_dac[dac] = send; *to_dac[dac] = send;
*dac_arm[adc] = 1; *dac_arm[dac] = 1;
/* Recursive locks should busy wait. */ /* Recursive locks should busy wait. */
/* 10ns * (2 * 10 cycles per half DAC cycle) /* 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 * 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]; static __thread int adc_locked[ADC_MAX];
int int
adc_take(int adc, int timeout) adc_take(int adc, k_timeout_t timeout)
{ {
if (adc < 0 || adc >= ADC_MAX) if (adc < 0 || adc >= ADC_MAX)
return -EFAULT; return -EFAULT;
@ -131,7 +133,7 @@ adc_release(int adc)
} }
int int
adc_read(int adc, int timeout, creole_word *wrd) adc_read(int adc, k_timeout_t timeout, creole_word *wrd)
{ {
int e; int e;
if ((e = adc_take(adc, timeout)) != 0) 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)); k_sleep(K_NSEC(550 + 24*2*10*10));
while (!*adc_finished[adc]); while (!*adc_finished[adc]);
*wrd = sign_extend(*from_adc[adc]); *wrd = sign_extend(*from_adc[adc], 20);
*adc_arm[adc] = 0; *adc_arm[adc] = 0;
adc_release(adc); adc_release(adc);
@ -155,8 +157,8 @@ adc_read(int adc, int timeout, creole_word *wrd)
* Control loop * Control loop
*******/ *******/
static struct k_mutex_t cloop_mutex; static struct k_mutex cloop_mutex;
static __thread cloop_locked; static __thread int cloop_locked;
int int
cloop_take(k_timeout_t timeout) cloop_take(k_timeout_t timeout)
@ -206,7 +208,7 @@ cloop_read(int code, uint32_t *high_reg, uint32_t *low_reg,
} }
int 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) k_timeout_t timeout)
{ {
if (cloop_take(timeout) != 0) if (cloop_take(timeout) != 0)
@ -228,7 +230,7 @@ cloop_write(int code, uint32_t high_reg, uint32_t low_reg,
* Waveforms * 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]; static __thread int waveform_locked[DAC_MAX];
int int
@ -249,7 +251,7 @@ waveform_disarm_wait(int wf)
{ {
*wf_arm[wf] = 0; *wf_arm[wf] = 0;
if (*wf_running[wf]) { 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]); while (*wf_running[wf]);
} }
} }
@ -264,10 +266,11 @@ waveform_release(int waveform)
waveform_disarm_wait(waveform); waveform_disarm_wait(waveform);
} }
int e k_mutex_unlock(waveform_mutex + waveform); int e = k_mutex_unlock(waveform_mutex + waveform);
if (e == 0) { if (e == 0) {
waveform_locked[e]--; waveform_locked[e]--;
} }
return e;
} }
size_t size_t
@ -275,7 +278,7 @@ creole_to_array(const struct creole_reader *start, creole_word *buf, size_t bufl
{ {
size_t i = 0; size_t i = 0;
struct creole_word w; struct creole_word w;
struct creole_reader r = start; struct creole_reader r = *start;
while (creole_decode(&r, &w) && i < buflen) { while (creole_decode(&r, &w) && i < buflen) {
buf[i++] = w.word; 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) if (waveform_take(slot, timeout) != 0)
return 0; return 0;
if (load_into_array(env->dats[db], buf, ARRAY_SIZE(buf)) *wf_start_addr[slot] = (uint32_t) buf;
!= MAX_WL_SIZE)
goto ret;
*wf_start_addr[slot] = &buf;
*wf_refresh_start[slot] = 1; *wf_refresh_start[slot] = 1;
while (!*wf_refresh_finished[slot]); while (!*wf_refresh_finished[slot]);
*wf_refresh_start[slot] = 0; *wf_refresh_start[slot] = 0;
@ -306,7 +305,9 @@ waveform_load(uint32_t buf[MAX_WL_SIZE], int slot, k_timeout_t timeout)
int int
waveform_halt_until_finished(int slot) waveform_halt_until_finished(int slot)
{ {
// stub *wf_halt_on_finish[slot] = 1;
while (!*wf_finished[slot]);
return 1;
} }
int int
@ -319,7 +320,7 @@ waveform_arm(int slot, bool halt_on_finish, uint32_t wait, k_timeout_t timeout)
return 0; 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_time_to_wait[slot] = wait;
*wf_arm[slot] = 1; *wf_arm[slot] = 1;
@ -350,7 +351,7 @@ access_release_thread(void)
} }
for (int i = 0; i < DAC_MAX; i++) { for (int i = 0; i < DAC_MAX; i++) {
while (dac_release(i) == 0); while (dac_release(i) == 0)
dac_locked[i]--; dac_locked[i]--;
if (dac_locked[i] != 0) { if (dac_locked[i] != 0) {
LOG_WRN("%s: dac mutex %d counter mismatch", get_thread_name(), i); 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) 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(dac_mutex + i);
k_mutex_init(waveform_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); k_mutex_init(adc_mutex + i);
} }
} }

View File

@ -1,16 +1,21 @@
#pragma once #pragma once
#include <zephyr/kernel.h> #include <zephyr/kernel.h>
#include "creole.h"
int dac_take(int dac, k_timeout_t timeout);
int dac_release(int dac); int dac_release(int dac);
int dac_read_write(int dac, creole_word send, k_timeout_t timeout, int dac_read_write(int dac, creole_word send, k_timeout_t timeout,
creole_word *recv); 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_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_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 cloop_release(void);
int waveform_take(int waveform, k_timeout_t timeout); int waveform_take(int waveform, k_timeout_t timeout);
@ -28,4 +33,4 @@ int waveform_disarm(int slot);
void access_release_thread(void); void access_release_thread(void);
/* Called once on initializion. */ /* Called once on initializion. */
int access_init(void); void access_init(void);

View File

@ -17,7 +17,7 @@ static K_KERNEL_STACK_ARRAY_DEFINE(stacks, THREADNUM, THREAD_STACK_SIZ);
#define READBUF_SIZ 0xFFFF #define READBUF_SIZ 0xFFFF
static unsigned char readbuf[THREADNUM][READBUF_SIZ]; 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 bool thread_ever_used[THREADNUM];
static int static int
@ -31,7 +31,7 @@ read_size(int s)
return (unsigned char)buf[0] | (unsigned char) buf[1] << 8; 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_COMPILE_OK] = "compile ok",
[CREOLE_OPCODE_READ_ERROR] = "opcode read error", [CREOLE_OPCODE_READ_ERROR] = "opcode read error",
[CREOLE_OPCODE_MALFORMED] = "opcode malformed", [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_DATA_OVERFLOW] = "data overflow",
[CREOLE_TYPE_ERROR] = "type error", [CREOLE_TYPE_ERROR] = "type error",
[CREOLE_PROGRAM_OVERFLOW] = "program overflow" [CREOLE_PROGRAM_OVERFLOW] = "program overflow"
} };
static const char *const run_ret_str[CREOLE_RUN_RET_LEN] = { static const char *const run_ret_str[CREOLE_RUN_RET_LEN] = {
[CREOLE_STEP_CONTINUE] = "continue", [CREOLE_STEP_CONTINUE] = "continue",
@ -67,12 +67,13 @@ hup(int sock)
.revents = 0 .revents = 0
}; };
return zsock_pollfd(&fd, 1, 0); return zsock_poll(&fd, 1, 0);
} }
static void static void
exec_creole(unsigned char *buf, int size, int sock) exec_creole(unsigned char *buf, int size, int sock)
{#define DATLEN 64 {
#define DATSLEN 64
struct creole_reader dats[DATSLEN]; struct creole_reader dats[DATSLEN];
#define REGLEN 32 #define REGLEN 32
creole_word reg[REGLEN]; creole_word reg[REGLEN];
@ -81,7 +82,7 @@ exec_creole(unsigned char *buf, int size, int sock)
struct creole_env env = { struct creole_env env = {
.dats = dats, .dats = dats,
.datlen = DATLEN, .datlen = DATSLEN,
.reg = reg, .reg = reg,
.reglen = REGLEN, .reglen = REGLEN,
.stk = stk, .stk = stk,
@ -89,7 +90,7 @@ exec_creole(unsigned char *buf, int size, int sock)
.r_current = {buf, size}, .r_current = {buf, size},
.r_start = {buf, size}, .r_start = {buf, size},
.sock = sock .fd = sock
}; };
int e = creole_compile(&env); int e = creole_compile(&env);
@ -113,7 +114,7 @@ exec_creole(unsigned char *buf, int size, int sock)
return; return;
default: default:
LOG_WRN("%s: run: %s", get_thread_name(), LOG_WRN("%s: run: %s", get_thread_name(),
creole_run_ret[e]); run_ret_str[e]);
return; return;
} }
@ -128,12 +129,12 @@ static void
exec_entry(void *client_p, void *threadnum_p, exec_entry(void *client_p, void *threadnum_p,
void *unused __attribute__((unused))) void *unused __attribute__((unused)))
{ {
intptr_t client = client_p; intptr_t client = (intptr_t)client_p;
intptr_t threadnum = threadnum_p; intptr_t threadnum = (intptr_t)threadnum_p;
int size = read_size(client); int size = read_size(client);
const char thread_name[64]; char thread_name[64];
vsnprintk(thread_name, sizeof(thread_name), "%d:%d", client, threadnum); snprintk(thread_name, sizeof(thread_name), "%"PRIdPTR":%"PRIdPTR, client, threadnum);
k_thread_name_set(k_current_get(), thread_name); k_thread_name_set(k_current_get(), thread_name);
LOG_INF("%s: Connection initiated", thread_name); LOG_INF("%s: Connection initiated", thread_name);
@ -152,7 +153,7 @@ exec_entry(void *client_p, void *threadnum_p,
return; return;
} }
exec_creole(size); exec_creole(readbuf[threadnum], size, (int)client);
zsock_close(client); zsock_close(client);
} }
@ -167,12 +168,12 @@ main_loop(int srvsock)
for (i = 0; i < THREADNUM; i++) { for (i = 0; i < THREADNUM; i++) {
if (!thread_ever_used[i] if (!thread_ever_used[i]
|| k_thread_join(threads[i], 0) == 0) { || k_thread_join(&threads[i], K_NO_WAIT) == 0) {
connection_counter++; connection_counter++;
k_thread_create(threads[i], stacks[i], k_thread_create(&threads[i], stacks[i],
THREAD_STACK_SIZ, exec_entry, THREAD_STACK_SIZ, exec_entry,
(uintptr_t) client, (uintptr_t) i, (void*) client, (void*) i,
(uintptr_t) connection_counter, (void*) connection_counter,
1, 0, K_NO_WAIT); 1, 0, K_NO_WAIT);
} }
} }
@ -189,7 +190,7 @@ void
main(void) main(void)
{ {
access_init(); access_init();
k_thread_name_get(k_current_get(), "main thread"); k_thread_name_set(k_current_get(), "main thread");
for (;;) { for (;;) {
int sock = server_init_sock(6626); int sock = server_init_sock(6626);
main_loop(sock); main_loop(sock);