add submodules and switch
This commit is contained in:
parent
3a4224ff5b
commit
05f8878751
|
@ -0,0 +1,4 @@
|
||||||
|
[submodule "creole"]
|
||||||
|
path = creole
|
||||||
|
url = https://software.mcgoron.com/peter/creole
|
||||||
|
branch = upsilon
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 945bcd68a54ebf6794fa791545426e5f29644029
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
|
@ -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
|
|
|
@ -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);
|
||||||
|
|
|
@ -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, ...)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue