add submodules and switch

This commit is contained in:
Peter McGoron 2023-03-03 08:06:50 +00:00
parent 3a4224ff5b
commit 05f8878751
10 changed files with 54 additions and 330 deletions

4
.gitmodules vendored Normal file
View File

@ -0,0 +1,4 @@
[submodule "creole"]
path = creole
url = https://software.mcgoron.com/peter/creole
branch = upsilon

1
creole Submodule

@ -0,0 +1 @@
Subproject commit 945bcd68a54ebf6794fa791545426e5f29644029

View File

@ -38,6 +38,7 @@ module control_loop
parameter DAC_SS_WAIT_SIZ = 3 parameter DAC_SS_WAIT_SIZ = 3
) ( ) (
input clk, input clk,
output in_loop,
output dac_mosi, output dac_mosi,
input dac_miso, input dac_miso,
@ -324,6 +325,8 @@ always @ (posedge clk) begin
end end
end end
assign in_loop = state != INIT_READ_FROM_DAC || running;
always @ (posedge clk) begin always @ (posedge clk) begin
case (state) case (state)
INIT_READ_FROM_DAC: begin INIT_READ_FROM_DAC: begin

View File

@ -0,0 +1,41 @@
/* This module is a co-operative crossbar for the wires only. Each end
* implements its own SPI master.
*
* This crossbar is entirely controlled by the kernel.
*/
module spi_crossbar #(
parameter PORTS = 2,
(
input select[PORTS-1:0],
output mosi,
input miso,
output sck,
output ss,
input mosi_ports[PORTS-1:0],
output miso_ports[PORTS-1:0],
input sck_ports[PORTS-1:0],
input ss_ports[PORTS-1:0]
);
/* Avoid using for loops, they might not synthesize correctly.
Do things the old, dumb way instead.
*/
always @(*) begin
if (select[1]) begin
mosi = mosi_ports[1];
miso = miso_ports[1];
sck = sck_ports[1];
ss = ss_ports[1];
end else begin
/* Select zeroth slot by default. No latches. */
mosi = mosi_ports[0];
miso = miso_ports[0];
sck = sck_ports[0];
ss = ss_ports[0];
end
end
endmodule

View File

@ -1,86 +0,0 @@
#include <zephyr/zephyr.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(adc_dac_io);
#include <string.h>
#define CSR_LOCATIONS
#include "pin_io.h"
static int32_t
sign_extend(uint32_t n, unsigned wid)
{
if (n >> (wid - 1))
return (int32_t) (~((uint32_t) 0) & n);
else
return (int32_t) n;
}
int32_t
adc_read(size_t num, unsigned wid)
{
if (num >= ADC_MAX) {
LOG_ERR("adc_read got bad ADC %zd\n", num);
k_fatal_halt(K_ERR_KERNEL_OOPS);
}
if (wid > 32) {
LOG_ERR("adc_read got bad width %u\n", wid);
k_fatal_halt(K_ERR_KERNEL_OOPS);
}
*adc_conv[num] = 1;
k_sleep(K_NSEC(550));
*adc_arm[num] = 1;
*adc_conv[num] = 0;
// XXX: Guess
k_sleep(K_MSEC(40));
while (!*adc_finished[num]);
uint32_t buf = *adc_from_slave[num];
*adc_arm[num] = 0;
return sign_extend(buf);
}
uint32_t
dac_write_raw(size_t n, uint32_t data)
{
if (n >= DAC_MAX) {
LOG_ERR("dac_write_raw got bad ADC %d\n", n);
k_fatal_halt(K_ERR_KERNEL_OOPS);
}
*dac_to_slave[n] = data;
*dac_ss[n] = 1;
k_sleep(K_NSEC(20));
*dac_arm[n] = 1;
// XXX: Guess
k_sleep(K_MSEC(50));
while (!*dac_finished[num]);
*dac_ss[n] = 0;
uint32_t r = *dac_from_slave[n];
*dac_arm[n] = 0;
return r;
}
void
dac_write_v(size_t n, uint32_t v)
{
dac_write_raw(n, (1 << 20) | (v & 0xFFFFF));
}
int
dac_init(size_t n)
{
/* Write to control register. */
const uint32_t msg =
(1 << 1) // RBUF
| (1 << 4) // Binary Offset
;
dac_write_raw(n, (1 << 21) | msg);
// Read from the control register
dac_write_raw(n, (1 << 21) | (1 << 23));
// Send NOP to read the returned data.
return dac_write_raw(n, 0) == msg;
}

View File

@ -1,7 +0,0 @@
#pragma once
int32_t adc_read(size_t num, unsigned wid);
uint32_t dac_write_raw(size_t n, uint32_t data);
void dac_write_v(size_t n, uint32_t v);
int dac_init(size_t n);

View File

@ -1,112 +0,0 @@
#ifndef LSC
#define LSC
#include <stddef.h>
#ifndef LSC_MAXARG
# define LSC_MAXARG 32
#endif
#ifndef LSC_MAXBUF
# define LSC_MAXBUF 1024
#endif
struct lsc_line {
size_t name;
char *buf[LSC_MAXARG];
size_t len;
};
struct lsc_parser {
int state;
char intbuf[LSC_MAXBUF];
size_t len;
char *rptr;
};
enum lsc_r {
LSC_MORE,
LSC_OVERFLOW,
LSC_ARG_OVERFLOW,
LSC_INVALID_ARGUMENT,
LSC_COMPLETE
};
void lsc_reset(struct lsc_parser *, char *);
enum lsc_r lsc_read(struct lsc_parser *,
struct lsc_line *);
static void lsc_load_ptr(struct lsc_parser *in, char *p) {
in->rptr = p;
}
#endif
#ifdef LSC_IMPLEMENTATION
enum { LSC_READ, LSC_DISCARD };
static void reset_parse_state(struct lsc_parser *in) {
in->state = LSC_READ;
in->len = 0;
}
void lsc_reset(struct lsc_parser *in, char *p) {
reset_parse_state(in);
in->rptr = p;
}
static enum lsc_r lsc_parse(struct lsc_parser *in,
struct lsc_line *line) {
char *s = in->intbuf;
enum lsc_r r = LSC_ARG_OVERFLOW;
line->name = (*s == ':');
line->len = 0;
while (line->len < LSC_MAXARG) {
line->buf[line->len++] = s;
for (; *s && *s != '\t'; s++);
if (!*s) {
r = LSC_COMPLETE;
break;
} else {
*s = 0;
s++;
}
}
reset_parse_state(in);
return r;
}
enum lsc_r lsc_read(struct lsc_parser *psr,
struct lsc_line *line) {
char c;
if (!psr || !psr->rptr || !line)
return LSC_INVALID_ARGUMENT;
while ((c = *psr->rptr)) {
psr->rptr++;
if (psr->state == LSC_DISCARD) {
if (c == '\n') {
reset_parse_state(psr);
return LSC_OVERFLOW;
}
} else {
switch (c) {
case '\n':
psr->intbuf[psr->len] = 0;
return lsc_parse(psr, line);
default:
if (psr->len == LSC_MAXBUF)
psr->state = LSC_DISCARD;
psr->intbuf[psr->len++] = c;
}
}
}
return LSC_MORE;
}
#endif

View File

@ -7,115 +7,8 @@
#include "sock.h" #include "sock.h"
#include "buf.h" #include "buf.h"
#define LSC_IMPLEMENTATION
#include "lsc.h"
LOG_MODULE_REGISTER(main); LOG_MODULE_REGISTER(main);
#define PORT 6626
enum {
IDENT,
ADC,
DAC,
CL_SETPT,
CL_P,
CL_I,
CL_ARM,
CL_ERR,
CL_Z,
CL_CYCLES,
CL_DELAY,
RASTER_MAX_SAMPLES,
RASTER_MAX_LINES,
RASTER_SETTLE_TIME,
RASTER_DX,
RASTER_DY,
RASTER_USED_ADCS,
RASTER_ARM,
ARGS_NUM
};
static int _strcmp(const void *p1, const void *p2) {return strcmp(p1,p2);}
static int
client_exec(int sock, struct lsc_line *l)
{
static char buf[4096];
# define stringify(s) #s
# define mkid(s) [s] = stringify(s)
static const char *argnames[ARGS_NUM] = {
mkid(IDENT),
mkid(ADC),
mkid(DAC),
mkid(CL_SETPT),
mkid(CL_P),
mkid(CL_I),
mkid(CL_ARM),
mkid(CL_ERR),
mkid(CL_Z),
mkid(CL_CYCLES),
mkid(CL_DELAY),
mkid(RASTER_MAX_SAMPLES),
mkid(RASTER_MAX_LINES),
mkid(RASTER_SETTLE_TIME),
mkid(RASTER_DX),
mkid(RASTER_DY),
mkid(RASTER_USED_ADCS),
mkid(RASTER_ARM)
};
# undef mkid
# undef stringify
char **p = bsearch(l->buf[l->name], argnames, ARGS_NUM,
sizeof(argnames[0]), _strcmp);
if (!p) {
sock_name_printf(sock, l, buf, sizeof(buf),
"ERROR\tunknown command\n");
return 0;
}
switch (p - argnames) {
}
}
static void
client_parse(int cli)
{
static char buf[LSC_MAXBUF];
static struct bufptr bp = {buf, sizeof(buf)};
static struct lsc_parser psr = {0};
static bool first = true;
struct lsc_line l;
if (first) {
lsc_reset(&psr, buf);
first = false;
}
switch (lsc_read(&psr, &l)) {
case LSC_OVERFLOW:
LOG_ERR("client command overflow\n");
break;
case LSC_OVERFLOW:
LOG_ERR("client command argument overflow\n");
break;
case LSC_INVALID_ARGUMENT:
LOG_ERR("programmer misuse");
break;
case LSC_COMPLETE:
// process
lsc_reset(&psr, buf);
break:
}
}
static void static void
process_client(int cli) process_client(int cli)
{ {
@ -140,7 +33,7 @@ process_client(int cli)
void void
main(void) main(void)
{ {
int srv = server_init_sock(PORT); int srv = server_init_sock(6626);
for (;;) { for (;;) {
int cli = server_get_client(server_sock); int cli = server_get_client(server_sock);

View File

@ -4,7 +4,6 @@
#include <zephyr/kernel.h> #include <zephyr/kernel.h>
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
#include "sock.h" #include "sock.h"
#include "lsc.h"
LOG_MODULE_REGISTER(sock); LOG_MODULE_REGISTER(sock);
@ -82,22 +81,6 @@ sock_vprintf(int sock, char *buf, int buflen, char *fmt, va_list va)
return w; return w;
} }
int
sock_name_printf(int sock, struct lsc_line *l, char *buf, int buflen, char *fmt, ...)
{
if (l->name) {
int r = sock_printf(sock, buf, buflen, "%s\t", l->buf[0]);
if (r < 0)
return r;
}
va_list va;
va_start(va, fmt);
int r = sock_vprintf(sock, buf, buflen, fmt, va);
va_end(va);
return r;
}
int int
sock_printf(int sock, char *buf, int buflen, char *fmt, ...) sock_printf(int sock, char *buf, int buflen, char *fmt, ...)
{ {

View File

@ -1,3 +1,7 @@
#pragma once #pragma once
/* Initialize server to listen on the port passed as an argument. */
int server_init_sock(int port); int server_init_sock(int port);
/* Accept a client and allocate a file descriptor for the client. */
int server_accept_client(int server); int server_accept_client(int server);