This commit is contained in:
Peter McGoron 2023-04-03 04:39:26 +00:00
parent 888ce66f52
commit eceb844e87
4 changed files with 63 additions and 18 deletions

View File

@ -1,5 +1,6 @@
/* Write a waveform to a DAC. */ /* Write a waveform to a DAC. */
/* TODO: Add reset pin. */ /* TODO: Add reset pin.
* Add "how many values to go" counter. */
module waveform #( module waveform #(
parameter DAC_WID = 24, parameter DAC_WID = 24,
parameter DAC_WID_SIZ = 5, parameter DAC_WID_SIZ = 5,
@ -20,6 +21,18 @@ module waveform #(
input clk, input clk,
input arm, input arm,
input halt_on_finish, input halt_on_finish,
/* NOTE:
* finished is used when a module wants to wait for a
* waveform with the halt_on_finish flag finishes
* one waveform.
*
* running is used when a module wants to know when
* the waveform module has finished running after
* deasserting arm.
*
* When in doubt, deassert arm and wait for running
* to be deasserted.
*/
output reg finished, output reg finished,
output running, output running,
input [TIMER_WID-1:0] time_to_wait, input [TIMER_WID-1:0] time_to_wait,

View File

@ -11,7 +11,7 @@
#include <zephyr/kernel.h> #include <zephyr/kernel.h>
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
#include "converters.h" #include "access.h"
#include "pin_io.h" #include "pin_io.h"
LOG_MODULE_REGISTER(access); LOG_MODULE_REGISTER(access);
@ -244,6 +244,16 @@ waveform_take(int waveform, k_timeout_t timeout)
return e; return e;
} }
static void
waveform_disarm_wait(int wf)
{
*wf_arm[wf] = 0;
if (*wf_running[wf]) {
k_sleep(K_NSEC(10* *wf_time_to_wait[wf]);
while (*wf_running[wf]);
}
}
int int
waveform_release(int waveform) waveform_release(int waveform)
{ {
@ -251,8 +261,7 @@ waveform_release(int waveform)
return -EFAULT; return -EFAULT;
if (waveform_locked[waveform] == 1) { if (waveform_locked[waveform] == 1) {
*wf_arm[waveform] = 0; waveform_disarm_wait(waveform);
while (*wf_running[waveform]);
} }
int e k_mutex_unlock(waveform_mutex + waveform); int e k_mutex_unlock(waveform_mutex + waveform);
@ -294,6 +303,12 @@ waveform_load(uint32_t buf[MAX_WL_SIZE], int slot, k_timeout_t timeout)
return 1; return 1;
} }
int
waveform_halt_until_finished(int slot)
{
// stub
}
int int
waveform_arm(int slot, bool halt_on_finish, uint32_t wait, k_timeout_t timeout) waveform_arm(int slot, bool halt_on_finish, uint32_t wait, k_timeout_t timeout)
{ {
@ -314,8 +329,7 @@ waveform_arm(int slot, bool halt_on_finish, uint32_t wait, k_timeout_t timeout)
int int
waveform_disarm(int slot) waveform_disarm(int slot)
{ {
*wf_arm[slot] = 0; waveform_disarm_wait(slot);
while (*wf_running[slot]);
waveform_release(slot); waveform_release(slot);
dac_release(slot); dac_release(slot);
return 1; return 1;
@ -331,7 +345,7 @@ access_release_thread(void)
while (cloop_release() == 0) while (cloop_release() == 0)
cloop_locked--; cloop_locked--;
if (cloop_locked != 0) { if (cloop_locked != 0) {
LOG_WRN("cloop mutex counter mismatch"); LOG_WRN("%s: cloop mutex counter mismatch", get_thread_name());
cloop_locked = 0; cloop_locked = 0;
} }
@ -339,14 +353,14 @@ access_release_thread(void)
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("dac mutex %d counter mismatch", i); LOG_WRN("%s: dac mutex %d counter mismatch", get_thread_name(), i);
dac_locked[i] = 0; dac_locked[i] = 0;
} }
while (waveform_release(i) == 0) while (waveform_release(i) == 0)
waveform_locked[i]--; waveform_locked[i]--;
if (waveform_locked[i] != 0) { if (waveform_locked[i] != 0) {
LOG_WRN("waveform mutex %d counter mismatch", i); LOG_WRN("%s: waveform mutex %d counter mismatch", get_thread_name(), i);
waveform_locked[i] = 0; waveform_locked[i] = 0;
} }
} }
@ -358,7 +372,7 @@ access_release_thread(void)
while (adc_release(i) == 0) while (adc_release(i) == 0)
adc_locked[i]--; adc_locked[i]--;
if (adc_locked[i] != 0) { if (adc_locked[i] != 0) {
LOG_WRN("adc mutex %d counter mismatch", i); LOG_WRN("%s: adc mutex %d counter mismatch", get_thread_name(), i);
adc_locked[i] = 0; adc_locked[i] = 0;
} }
} }

View File

@ -4,6 +4,8 @@
#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 "sock.h" #include "sock.h"
#include "buf.h" #include "buf.h"
@ -23,9 +25,9 @@ read_size(int s)
{ {
char buf[2]; char buf[2];
struct bufptr bp = {buf, sizeof(buf)}; struct bufptr bp = {buf, sizeof(buf)};
int e = sock_read_buf(s, &bp, true);
if (!sock_read_buf(s, &bp, true)) if (e != 0)
return -1; return e;
return (unsigned char)buf[0] | (unsigned char) buf[1] << 8; return (unsigned char)buf[0] | (unsigned char) buf[1] << 8;
} }
@ -54,8 +56,6 @@ exec_creole(unsigned char *buf, int size, int sock)
} }
/* TODO: error messages */
static void 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)))
@ -64,13 +64,22 @@ exec_entry(void *client_p, void *threadnum_p,
intptr_t threadnum = threadnum_p; intptr_t threadnum = threadnum_p;
int size = read_size(client); int size = read_size(client);
const char thread_name[32];
vsnprintk(thread_name, sizeof(thread_name), "%d", client);
k_thread_name_set(k_current_get(), thread_name);
LOG_INF("%s: Connection initiated", thread_name);
if (size < 0) { if (size < 0) {
LOG_WRN("%s: error in read size: %d", get_thread_name(), size);
zsock_close(client); zsock_close(client);
return; return;
} }
struct bufptr bp = {readbuf[threadnum], size}; struct bufptr bp = {readbuf[threadnum], size};
if (!sock_read_buf(client, &bp, true)) { 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); zsock_close(client);
return; return;
} }
@ -83,6 +92,7 @@ exec_entry(void *client_p, void *threadnum_p,
static void static void
main_loop(int srvsock) main_loop(int srvsock)
{ {
static unsigned int connection_counter = 0;
for (;;) { for (;;) {
int client = server_accept_client(srvsock); int client = server_accept_client(srvsock);
int i; int i;
@ -90,9 +100,11 @@ 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], 0) == 0) {
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, NULL, (uintptr_t) client, (uintptr_t) i,
(uintptr_t) connection_counter,
1, 0, K_NO_WAIT); 1, 0, K_NO_WAIT);
} }
} }
@ -100,6 +112,7 @@ main_loop(int srvsock)
if (i == THREADNUM) { if (i == THREADNUM) {
LOG_INF("Too many connections (max %d)", LOG_INF("Too many connections (max %d)",
THREADNUM); THREADNUM);
zsock_close(client);
} }
} }
} }
@ -107,9 +120,11 @@ main_loop(int srvsock)
void void
main(void) main(void)
{ {
access_init();
k_thread_name_get(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);
close(sock); zsock_close(sock);
} }
} }

3
software/src/upsilon.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
#define get_thread_name() k_thread_name_get(k_current_get())