Compare commits

..

No commits in common. "0514546b7d87c84b58218f043fd7300848d01ee1" and "60d830fdaebb7a9848f48be9d1c75fe4d7e7536d" have entirely different histories.

6 changed files with 67 additions and 70 deletions

View file

@ -129,7 +129,7 @@ OBJS = crt.o $(patsubst %,%.o,$(sources))
objs: $(OBJS) objs: $(OBJS)
%.s: %.c %.s: %.c
$(CC) -fverbose-asm -S $(CFLAGS) $< $(CC) -S $(CFLAGS) $<
%.o: %.c %.o: %.c
$(CC) -MMD $(DEBUGFORMAT) -c $(CFLAGS) $< $(CC) -MMD $(DEBUGFORMAT) -c $(CFLAGS) $<

View file

@ -42,7 +42,7 @@ int ads8688(unsigned short *frame, int n, int flags, int timeout)
ssp_assert_ssel(); ssp_assert_ssel();
ssp_set_buffer(data.data, N); ssp_set_buffer(data.data, N);
ssp_set_read(1, n); ssp_set_read(1, n);
ssp_submit(frame, 1, n+1, 0); ssp_submit(frame, 1, n, 0);
int r = ssp_wait(timeout); int r = ssp_wait(timeout);
if (!r) if (!r)
ssp_deassert_ssel(); ssp_deassert_ssel();

View file

@ -12,7 +12,7 @@ int ltc2656(unsigned int frame, int flags, int timeout)
ssp_assert_ssel(); ssp_assert_ssel();
ssp_set_buffer(0,0); ssp_set_buffer(0,0);
unsigned short cmd[2] = { frame >> 16, frame & 0xffff }; unsigned short cmd[2] = { frame >> 16, frame & 0xffff };
ssp_submit(cmd, 2, 2, 0); ssp_submit(cmd, 2, 0, 0);
int r = ssp_wait(timeout); int r = ssp_wait(timeout);
if (!r) if (!r)
ssp_deassert_ssel(); ssp_deassert_ssel();

View file

@ -113,10 +113,9 @@ static const struct ssp_batch bate_batch[] = {
.flags = ssp_b_job, .flags = ssp_b_job,
{ .job = &(const struct ssp_job) { { .job = &(const struct ssp_job) {
.command = bate_cmds, .command = bate_cmds,
.count = 11,
.cmd_count = 11, .cmd_count = 11,
.read_count = 11, .read_count = 11,
.buf_count = 11, .buf_count = 1,
}}, }},
}, },
{ {
@ -127,7 +126,6 @@ static const struct ssp_batch bate_batch[] = {
.flags = ssp_b_job, .flags = ssp_b_job,
{ .job = &(const struct ssp_job) { { .job = &(const struct ssp_job) {
.command = bate_cmds+11, .command = bate_cmds+11,
.count = 2,
.cmd_count = 2, .cmd_count = 2,
.read_count = 2, .read_count = 2,
}}, }},
@ -139,7 +137,7 @@ static const struct ssp_batch bate_batch[] = {
{ {
.flags = ssp_b_job, .flags = ssp_b_job,
{ .job = &(const struct ssp_job) { { .job = &(const struct ssp_job) {
.count = 1, .idle_count = 1,
.read_count = 1, .read_count = 1,
}}, }},
}, },
@ -169,7 +167,7 @@ int read_pressure(int from_phase, int to_phase, int value)
ssp_assert_ssel(); ssp_assert_ssel();
ssp_set_buffer(pressure_reading, 8); ssp_set_buffer(pressure_reading, 8);
ssp_set_read(3, 8); ssp_set_read(3, 8);
r = ssp_submit(bate_cmds, 11, 11, 0); r = ssp_submit(bate_cmds, 11, 0, 0);
break; break;
case 2: case 2:
case 6: case 6:
@ -192,9 +190,9 @@ int read_pressure(int from_phase, int to_phase, int value)
break; break;
case 5: ssp_set_buffer(pressure_reading+6, 2); case 5: ssp_set_buffer(pressure_reading+6, 2);
ssp_set_read(0, 0); ssp_set_read(0, 0);
r = ssp_submit(bate_cmds+11, 2, 2, 1); r = ssp_submit(bate_cmds+11, 2, 0, 1);
break; break;
case 8: r = ssp_submit(0, 0, 1, 1); case 8: r = ssp_submit(bate_cmds+11, 1, 0, 1);
break; break;
case 10: case 10:
ssp_deassert_ssel(); ssp_deassert_ssel();

68
ssp.c
View file

@ -16,10 +16,10 @@ unsigned int ssp_bits;
int (*ssp_callback)(); int (*ssp_callback)();
volatile unsigned int ssp_lastword; volatile unsigned int ssp_lastword;
unsigned int ssp_ssel_mask = SSP_SSEL_MASK0 | SSP_SSEL_MASK1; unsigned int ssp_ssel_mask = SSP_SSEL_MASK0 | SSP_SSEL_MASK1;
static const struct timer_wait *ssp_batch_wait;
unsigned short *ssp_buffer; unsigned short *ssp_buffer;
volatile int ssp_frames_sent; volatile unsigned int ssp_frame_count;
volatile int ssp_frames_read;
unsigned short ssp_scratch[256]; unsigned short ssp_scratch[256];
@ -44,7 +44,7 @@ void ssp_set_buffer(short *buf, int size)
void ssp_poll(void) void ssp_poll(void)
{ {
volatile struct ssp_job *j=&job; volatile struct ssp_job *j=&job;
if (j->count || SSPSR & (SSPSR_RNE|SSPSR_BSY)) if (j->idle_count || j->read_count || j->cmd_count || SSPSR & (SSPSR_RNE|SSPSR_BSY))
SSPIMSC = SSP_INT_RX | SSP_INT_TX; SSPIMSC = SSP_INT_RX | SSP_INT_TX;
} }
@ -58,22 +58,18 @@ static void ssp_isr(void)
unsigned int sr = SSPSR; unsigned int sr = SSPSR;
int nread = 0; unsigned int nread = 0;
int rc = j->read_count; unsigned int rc = j->read_count;
while (sr&SSPSR_RNE) { while (sr&SSPSR_RNE) {
unsigned int dr = SSPDR; unsigned int dr = SSPDR;
sr=SSPSR; sr=SSPSR;
nread++; nread++;
ssp_lastword = ssp_lastword << ssp_bits | dr; ssp_lastword = ssp_lastword << ssp_bits | dr;
if (ssp_frames_read++ >= ssp_match.frame_count if (ssp_frame_count++ >= ssp_match.count
&& !rc && !rc
&& (dr & ssp_match.mask) == ssp_match.value) { && (dr & ssp_match.mask) == ssp_match.value) {
rc = ssp_match.read_count; rc = ssp_match.size;
if (ssp_match.count) { j->idle_count = 0;
j->count = ssp_match.count
+ ssp_match.frame_count
- ssp_frames_sent;
}
} }
if (rc) { if (rc) {
rc--; rc--;
@ -85,19 +81,18 @@ static void ssp_isr(void)
} }
} }
j->read_count = rc; j->read_count = rc;
int ic = j->count;
sr |= SSPSR; // race between SSPSR_BSY, SSPSR_RNE? sr |= SSPSR; // race between SSPSR_BSY, SSPSR_RNE?
if (!ic) if (!j->cmd_count && !j->idle_count) {
if ((sr & (SSPSR_BSY|SSPSR_RNE))) if (!rc && !(sr & (SSPSR_BSY|SSPSR_RNE))) {
goto outic;
else {
SSPIMSC = 0; SSPIMSC = 0;
if (ssp_callback) if (ssp_callback)
ssp_callback(); ssp_callback();
}
else
SSPIMSC = SSP_INT_RX;
goto out; goto out;
} }
else if (!(sr & (SSPSR_BSY|SSPSR_RNE))) else if (!(sr & (SSPSR_BSY|SSPSR_RNE)))
nread = 8; nread = 8;
@ -105,24 +100,25 @@ static void ssp_isr(void)
// This prevents Rx FIFO overflow. // This prevents Rx FIFO overflow.
// Except, when the Tx is not busy at all, then we can fill it up. // Except, when the Tx is not busy at all, then we can fill it up.
while (ic && nread && (sr&SSPSR_TNF)) { unsigned int ic = j->idle_count;
while (nread && (sr&SSPSR_TNF)) {
if (j->cmd_count) { if (j->cmd_count) {
j->cmd_count--; j->cmd_count--;
SSPDR = *j->command++; SSPDR = *j->command++;
} }
else else if (ic) {
SSPDR = j->idle_frame;
ssp_frames_sent ++;
nread--;
ic--; ic--;
SSPDR = ssp_match.idle;
}
else {
SSPIMSC = SSP_INT_RX;
goto outic;
}
nread--;
sr = SSPSR; sr = SSPSR;
} }
if (!ic)
outic: outic:
SSPIMSC = SSP_INT_RX; j->idle_count = ic;
j->count = ic;
out: out:
VICVectAddr = 0; VICVectAddr = 0;
} }
@ -138,16 +134,15 @@ out:
// idle=0x8000 RFIFO, send what the acquisition fifos provide. // idle=0x8000 RFIFO, send what the acquisition fifos provide.
// idle=0x8001 NOOPP, just drain the FPGA buffer. // idle=0x8001 NOOPP, just drain the FPGA buffer.
int ssp_submit(const unsigned short *cmd, short cmd_size, unsigned short ic, unsigned short rc) int ssp_submit(const unsigned short *cmd, int cmd_size, unsigned int ic, unsigned int rc)
{ {
volatile struct ssp_job *j=&job; volatile struct ssp_job *j=&job;
unsigned int iflg = disable_irq(INT_DISABLE); unsigned int iflg = disable_irq(INT_DISABLE);
j->command = cmd; j->command = cmd;
j->cmd_count = cmd_size; j->cmd_count = cmd_size;
j->count = ic; j->idle_count = ic;
j->read_count = rc; j->read_count = rc;
ssp_frames_sent = 0; ssp_frame_count = 0;
ssp_frames_read = 0;
enable_irq(iflg); enable_irq(iflg);
ssp_poll(); ssp_poll();
return 0; return 0;
@ -163,8 +158,6 @@ int ssp_submit_job(const struct ssp_job *jj)
ssp_set_buffer(0, 0); ssp_set_buffer(0, 0);
} }
memcpy((void*)&job, jj, n); memcpy((void*)&job, jj, n);
ssp_frames_sent = 0;
ssp_frames_read = 0;
enable_irq(iflg); enable_irq(iflg);
ssp_poll(); ssp_poll();
return 0; return 0;
@ -175,8 +168,8 @@ void ssp_reset(void)
SSPIMSC = 0; SSPIMSC = 0;
volatile struct ssp_job *j=&job; volatile struct ssp_job *j=&job;
unsigned int iflg = disable_irq(INT_DISABLE); unsigned int iflg = disable_irq(INT_DISABLE);
j->count = 0;
j->cmd_count = 0; j->cmd_count = 0;
j->idle_count = 0;
j->read_count = 0; j->read_count = 0;
enable_irq(iflg); enable_irq(iflg);
} }
@ -225,7 +218,7 @@ int ssp_busy(void)
volatile struct ssp_job *j=&job; volatile struct ssp_job *j=&job;
ssp_poll(); // run the isr to drain the backlog ssp_poll(); // run the isr to drain the backlog
// j->* is volatile and we don't want races // j->* is volatile and we don't want races
unsigned int c = j->count; unsigned int c = j->cmd_count + j->idle_count + j->read_count;
if (c) if (c)
return c; return c;
// Hardware is busy // Hardware is busy
@ -393,8 +386,7 @@ const struct keywords ssp_variable_names[] = {
VARIABLE("ssp_response", (void *)&ssp_lastword), VARIABLE("ssp_response", (void *)&ssp_lastword),
VARIABLE("ssp_match", &ssp_match), VARIABLE("ssp_match", &ssp_match),
VARIABLE("ssp_ssel_mask", &ssp_ssel_mask), VARIABLE("ssp_ssel_mask", &ssp_ssel_mask),
VARIABLE("ssp_frames_sent", (void *)&ssp_frames_sent), VARIABLE("ssp_frame_count", (void *)&ssp_frame_count),
VARIABLE("ssp_frames_read", (void *)&ssp_frames_read),
VARIABLE("ssp_bits", &ssp_bits), VARIABLE("ssp_bits", &ssp_bits),
VARIABLE("ssp_config", &ssp_conf_default), VARIABLE("ssp_config", &ssp_conf_default),
VARIABLE("ssp_adc", &ssp_conf_adc), VARIABLE("ssp_adc", &ssp_conf_adc),

47
ssp.h
View file

@ -10,7 +10,7 @@ void ssp_reset(void);
void ssp_set_buffer(short *buf, int size); void ssp_set_buffer(short *buf, int size);
void ssp_poll(void); void ssp_poll(void);
int ssp_submit(const unsigned short *cmd, short cmd_size, unsigned short ic, unsigned short rc); int ssp_submit(const unsigned short *cmd, int cmd_size, unsigned int ic, unsigned int rc);
int ssp_busy(void); int ssp_busy(void);
int ssp_wait(int timeout); int ssp_wait(int timeout);
@ -23,8 +23,7 @@ extern unsigned int ssp_idle;
extern unsigned int ssp_match_mask; extern unsigned int ssp_match_mask;
extern unsigned int ssp_match_value; extern unsigned int ssp_match_value;
extern unsigned int ssp_match_count; extern unsigned int ssp_match_count;
extern volatile int ssp_frames_sent; extern volatile unsigned int ssp_frame_count;
extern volatile int ssp_frames_read;
extern unsigned short ssp_scratch[256]; extern unsigned short ssp_scratch[256];
extern int (*ssp_callback)(); extern int (*ssp_callback)();
@ -62,26 +61,23 @@ extern struct ssp_config ssp_confs[];
#define ssp_conf_dac ssp_confs[2] #define ssp_conf_dac ssp_confs[2]
#define ssp_conf_bate ssp_confs[3] #define ssp_conf_bate ssp_confs[3]
// volatile part of the job // volatile part of the job, inaccessible globally
// inaccessible globally
struct ssp_job { struct ssp_job {
unsigned short cmd_count; unsigned int cmd_count;
unsigned short read_count; unsigned int read_count;
unsigned short count; unsigned int idle_count;
unsigned short idle_frame;
const unsigned short *command; const unsigned short *command;
unsigned short buf_count; unsigned int buf_count;
unsigned short *buf_ptr; unsigned short *buf_ptr;
}; };
// global static variables for the job // global variables part of the job
// not changed by the isr
extern struct ssp_match { extern struct ssp_match {
unsigned char frame_count; unsigned int mask;
unsigned char read_count; unsigned int value;
unsigned short count; unsigned int count;
unsigned short mask; unsigned int idle;
unsigned short value; unsigned int size;
} ssp_match; } ssp_match;
struct ssp_batch; struct ssp_batch;
@ -120,12 +116,23 @@ enum ssp_batch_flags {
ssp_b_return = 0x80000000, ssp_b_return = 0x80000000,
}; };
// search for a pattern before recording frames
static inline
void ssp_set_match(unsigned int mask, unsigned int value,
unsigned int count, unsigned int size)
{
ssp_match.mask = mask;
ssp_match.value = value;
ssp_match.count = count;
ssp_match.size = size;
}
// skip `count` frames before recording `size` frames. // skip `count` frames before recording `size` frames.
static inline static inline
void ssp_set_read(unsigned short count, unsigned short size) void ssp_set_read(unsigned int count, unsigned int size)
{ {
ssp_match.frame_count = count; ssp_match.count = count;
ssp_match.read_count = size; ssp_match.size = size;
} }
int ssp_submit_job(const struct ssp_job *jj); int ssp_submit_job(const struct ssp_job *jj);