diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..c02f387 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "creole"] + path = creole + url = https://software.mcgoron.com/peter/creole + branch = upsilon diff --git a/creole b/creole new file mode 160000 index 0000000..945bcd6 --- /dev/null +++ b/creole @@ -0,0 +1 @@ +Subproject commit 945bcd68a54ebf6794fa791545426e5f29644029 diff --git a/firmware/rtl/control_loop/control_loop.v b/firmware/rtl/control_loop/control_loop.v index 7114a0e..a4e9f27 100644 --- a/firmware/rtl/control_loop/control_loop.v +++ b/firmware/rtl/control_loop/control_loop.v @@ -38,6 +38,7 @@ module control_loop parameter DAC_SS_WAIT_SIZ = 3 ) ( input clk, + output in_loop, output dac_mosi, input dac_miso, @@ -324,6 +325,8 @@ always @ (posedge clk) begin end end +assign in_loop = state != INIT_READ_FROM_DAC || running; + always @ (posedge clk) begin case (state) INIT_READ_FROM_DAC: begin diff --git a/firmware/rtl/spi/spi_switch.v b/firmware/rtl/spi/spi_switch.v new file mode 100644 index 0000000..60c2e61 --- /dev/null +++ b/firmware/rtl/spi/spi_switch.v @@ -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 diff --git a/software/src/io.c b/software/src/io.c deleted file mode 100644 index 944baec..0000000 --- a/software/src/io.c +++ /dev/null @@ -1,86 +0,0 @@ -#include -#include -#include - -LOG_MODULE_REGISTER(adc_dac_io); - -#include -#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; -} diff --git a/software/src/io.h b/software/src/io.h deleted file mode 100644 index b3dbc6e..0000000 --- a/software/src/io.h +++ /dev/null @@ -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); diff --git a/software/src/lsc.h b/software/src/lsc.h deleted file mode 100644 index 80090b6..0000000 --- a/software/src/lsc.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef LSC -#define LSC -#include - -#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 diff --git a/software/src/main.c b/software/src/main.c index f9f1478..be60604 100644 --- a/software/src/main.c +++ b/software/src/main.c @@ -7,115 +7,8 @@ #include "sock.h" #include "buf.h" -#define LSC_IMPLEMENTATION -#include "lsc.h" - 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 process_client(int cli) { @@ -140,7 +33,7 @@ process_client(int cli) void main(void) { - int srv = server_init_sock(PORT); + int srv = server_init_sock(6626); for (;;) { int cli = server_get_client(server_sock); diff --git a/software/src/sock.c b/software/src/sock.c index d2d86ba..bee911b 100644 --- a/software/src/sock.c +++ b/software/src/sock.c @@ -4,7 +4,6 @@ #include #include #include "sock.h" -#include "lsc.h" LOG_MODULE_REGISTER(sock); @@ -82,22 +81,6 @@ sock_vprintf(int sock, char *buf, int buflen, char *fmt, va_list va) 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 sock_printf(int sock, char *buf, int buflen, char *fmt, ...) { diff --git a/software/src/sock.h b/software/src/sock.h index 052e211..fe45efe 100644 --- a/software/src/sock.h +++ b/software/src/sock.h @@ -1,3 +1,7 @@ #pragma once + +/* Initialize server to listen on the port passed as an argument. */ int server_init_sock(int port); + +/* Accept a client and allocate a file descriptor for the client. */ int server_accept_client(int server);