Compare commits

..

No commits in common. "3760ef787071e7cb1eddeb08cbb4a27d8c618d4e" and "3e85e0257c8506ba54e57e54414952b39213b3d0" have entirely different histories.

2 changed files with 29 additions and 138 deletions

View file

@ -5,8 +5,8 @@ The upboard talks to the irena µC (LPC2148) via UART, implemented in `irena.c`
Two gpios are used for reset and flash of the µC.
TODO
- ✔️ Complete the `numbers[]` array support.
- ✔️ Use `arm_reset()` from `print_status()` in case of error when available.
- Complete the `numbers[]` array support.
- Use `arm_reset()` from `print_status()` in case of error when available.
- implement `altera_from_file()`:
- ARM firmware: base64 upload of data into `flash_buffer`
- convert a `.rbf` to a series if `irena` commands.

169
irena.c
View file

@ -52,7 +52,7 @@ int send_irena_command(const char *c);
#define CR_RESET 2
#define CR_ONCE 4
#define CR_EVER 8
#define CR_AT 0xffff00
#define CR_AT 0xff00
#define CR_AT_CNT 0x0100
#define CR_AT_HK 0x0200
#define CR_AT_BATE 0x0400
@ -60,7 +60,6 @@ int send_irena_command(const char *c);
#define CR_AT_DROT 0x1000
#define CR_AT_CROT 0x2000
#define CR_AT_SROT 0x4000
#define CR_BUFFER 0x10000
void do_cron(time_t t, int flags, int force);
int config_cron(int na, char **av);
@ -778,7 +777,6 @@ struct status {
static int status_reset_cadence = 3600;
static time_t last_status_reset;
int arm_reset();
void print_status(FILE *f, time_t t)
{
@ -858,8 +856,7 @@ void print_status(FILE *f, time_t t)
if (do_avg && st->reset_delay >= 0 && st->flags & ST_DO_RESET
&& last_status_reset + status_reset_cadence < t
&& error > st->reset_delay) {
if (!tried_reset && !did_reset
&& (!arm_reset() || !send_irena_command("arm/reset")))
if (!tried_reset && !did_reset && !send_irena_command("arm/reset"))
did_reset = 1;
tried_reset = 1;
if (did_reset) {
@ -1028,7 +1025,6 @@ int gpio_write_value(const char *gpio, int value)
char reset_gpio[MAX_FN];
char eint1_gpio[MAX_FN];
int reset_flags = 0;
void arm_reset_gpio(int polarity)
{
@ -1076,16 +1072,12 @@ void arm_reset_uart(int fd, int polarity)
return;
}
int arm_reset()
void arm_reset(int fd, int flags)
{
if (reset_flags >= 4 && reset_flags < 6)
arm_reset_gpio(reset_flags & 1);
else if (i_buf.fd >=0 && reset_flags >= 1 && reset_flags < 4)
arm_reset_uart(i_buf.fd, reset_flags);
else
return -1;
fprintf(mout, "Sent hardware RESET, mode %d\n", reset_flags);
return 0;
if (flags < 4)
arm_reset_uart(fd, flags);
else if (flags < 6)
arm_reset_gpio(flags & 1);
}
int init_serial_port(const char *name, speed_t baud, int do_reset)
@ -1114,8 +1106,7 @@ int init_serial_port(const char *name, speed_t baud, int do_reset)
return -2;
}
if (do_reset) {
reset_flags = do_reset;
arm_reset();
arm_reset(i_buf.fd, do_reset);
if (baud != B38400) {
sleep(1);
if (cfsetspeed(&tios, baud))
@ -2026,58 +2017,6 @@ void poll_uart(unsigned int ev)
}
}
char *poll_response(time_t timeout)
{
if (!last_irena_command_sent)
return 0;
timeout += time(0);
char *l;
do {
l = get_line(&i_buf, 1);
if (l)
process_line(l);
} while (last_irena_command_sent && time(0) < timeout);
return l;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Send the contents of a file to the flash_buffer and exectute CR_BUFFER in each
int send_file(const char *fn)
{
FILE *f = fopen(fn, "r");
if (!f) {
merror(fn);
return -2;
}
unsigned int buf[128];
int n;
while ((n = fread(buf, 1, sizeof(buf), f))) {
for (int i=0; 4*i < n; i++) {
char cmd[64];
int retry = 0;
snprintf(cmd, 64, "v f[%d]=%u", i, buf[i]);
while (retry<3) {
while (-2==send_irena_command(cmd))
poll_uart(1);
char *res = poll_response(2);
if (!res)
fprintf(mout, "timeout for cmd «%s»\n", cmd);
else if (strncmp(res+1, "303", 3))
fprintf(mout, "invalid response to «%s» → «%s»\n", cmd, res);
else
break;
poll_uart(0);
retry ++;
}
if (retry >= 3)
break;
do_cron(0, CR_BUFFER, 1);
}
}
return -1;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Sync irena rtc with host clock
// Optionally sleep for the rest of the current second
@ -2331,19 +2270,6 @@ int number(char *s, int *i)
return 0;
}
int index_number(char *s, int *i)
{
if (*s != '[') return -1;
char *e;
int ii = strtol(s+1, &e, 0);
if (*e != ']') {
fprintf(mout, "invalid index: %s\n", s);
return -1;
}
*i = ii;
return 0;
}
int float_number(char *s, double *d)
{
char *e;
@ -2421,32 +2347,20 @@ struct paths {
{.name=0}
};
void print_number(FILE *f, struct numbers *nu)
{
int n = nu->size;
if (!n)
n=1;
fprintf(f, "\t%s «%s» ", nu->name, nu->doc);
for (int i=0; i<n; i++) {
if (nu->flags & NU_INT)
fprintf(f, " %d", nu->i[i]);
else if (nu->flags & NU_DOUBLE)
fprintf(f, " %g", nu->d[i]);
else if (nu->flags & NU_TIME) {
struct tm gm;
gmtime_r(nu->t+i, &gm);
char tt[] = "1970-01-01T00:00:00Z\0";
strftime(tt, sizeof(tt), "%Y-%m-%dT%H:%M:%SZ", &gm);
fprintf(f, " %ld %s", nu->t[i], tt);
}
}
fprintf(f, "\n");
}
void print_numbers(FILE *f)
{
for (struct numbers *nu=numbers; nu->name; nu++)
print_number(f, nu);
if (nu->flags & NU_INT)
fprintf(mout, "\t%s «%s» %d\n", nu->name, nu->doc, *nu->i);
else if (nu->flags & NU_DOUBLE)
fprintf(mout, "\t%s «%s» %g\n", nu->name, nu->doc, *nu->d);
else if (nu->flags & NU_TIME) {
struct tm gm;
gmtime_r(nu->t, &gm);
char tt[] = "1970-01-01T00:00:00Z\0";
strftime(tt, sizeof(tt), "%Y-%m-%dT%H:%M:%SZ", &gm);
fprintf(mout, "\t%s «%s» %ld %s\n", nu->name, nu->doc, *nu->t, tt);
}
}
int process_cmd(char *l);
@ -2519,7 +2433,6 @@ int process_cmd(char *l)
"\tcron [«index» [«flags»… [«delay» «cmd»]]]\n"
"\tcron force «flags»… [«times»]\n"
"\tcron «index» delete\n"
"\t«number» [[«index»]] [«value» …]\n"
"\n"
);
print_numbers(mout);
@ -2533,44 +2446,32 @@ int process_cmd(char *l)
for (struct numbers *n=numbers; n->name; n++) {
if (strcmp(av[0], n->name))
continue;
int ii = 0;
char **aa = av+1;
na--;
int nn = n->size;
if (!nn)
nn=1;
if (nn>1 && na>=2 && !index_number(*aa, &ii)) {
aa++;
na--;
}
if (ii<0 || na+ii > nn) {
if (nn>1)
fprintf(mout, "usage: %s [[«i»]] «%s» [… %d items]\n", n->name, n->doc, nn);
else
if (na>2) {
fprintf(mout, "usage: %s «%s»\n", n->name, n->doc);
return -1;
}
for (; na && ii<nn; ii++, aa++, na--) {
if (na==2) {
int r=-1;
if (n->flags & NU_INT) r = number(*aa, n->i+ii);
if (n->flags & NU_DOUBLE) r = float_number(*aa, n->d+ii);
if (n->flags & NU_INT) r = number(av[1], n->i);
if (n->flags & NU_DOUBLE) r = float_number(av[1], n->d);
if (n->flags & NU_TIME) {
if (!strcmp(*aa, "now")) {
n->t[ii] = time(0);
if (!strcmp(av[1], "now")) {
*n->t = time(0);
r = 0;
}
else {
int t=0;
r = number(*aa, &t);
r = number(av[1], &t);
if (!r)
n->t[ii] = t;
*n->t = t;
}
}
if (r)
return -1;
}
print_number(mout, n);
if (n->flags & NU_INT) fprintf(mout, "%s %d\n", n->name, *n->i);
if (n->flags & NU_DOUBLE) fprintf(mout, "%s %g\n", n->name, *n->d);
if (n->flags & NU_TIME) fprintf(mout, "%s %ld\n", n->name, *n->t);
return 0;
}
@ -2603,14 +2504,6 @@ int process_cmd(char *l)
return process_script(av[1]);
}
if (!strcmp(av[0], "sendfile")) {
if (na!=2) {
fprintf(mout, "usage: sendfile «filename»\n");
return -1;
}
return send_file(av[1]);
}
if (!strcmp(av[0], "uart")) {
speed_t baud = B921600;
int do_reset = 0;
@ -2809,8 +2702,6 @@ int config_cron(int na, char **av)
flags |= CR_ONCE;
else if (!strcmp(av[ai], "ever"))
flags |= CR_EVER;
else if (!strcmp(av[ai], "buffer"))
flags |= CR_BUFFER;
else if (!strcmp(av[ai], "got_hk"))
flags |= CR_AT_HK;
else if (!strcmp(av[ai], "got_cntr"))