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)
%.s: %.c
$(CC) -fverbose-asm -S $(CFLAGS) $<
$(CC) -S $(CFLAGS) $<
%.o: %.c
$(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_set_buffer(data.data, N);
ssp_set_read(1, n);
ssp_submit(frame, 1, n+1, 0);
ssp_submit(frame, 1, n, 0);
int r = ssp_wait(timeout);
if (!r)
ssp_deassert_ssel();

View file

@ -12,7 +12,7 @@ int ltc2656(unsigned int frame, int flags, int timeout)
ssp_assert_ssel();
ssp_set_buffer(0,0);
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);
if (!r)
ssp_deassert_ssel();

View file

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

68
ssp.c
View file

@ -16,10 +16,10 @@ unsigned int ssp_bits;
int (*ssp_callback)();
volatile unsigned int ssp_lastword;
unsigned int ssp_ssel_mask = SSP_SSEL_MASK0 | SSP_SSEL_MASK1;
static const struct timer_wait *ssp_batch_wait;
unsigned short *ssp_buffer;
volatile int ssp_frames_sent;
volatile int ssp_frames_read;
volatile unsigned int ssp_frame_count;
unsigned short ssp_scratch[256];
@ -44,7 +44,7 @@ void ssp_set_buffer(short *buf, int size)
void ssp_poll(void)
{
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;
}
@ -58,22 +58,18 @@ static void ssp_isr(void)
unsigned int sr = SSPSR;
int nread = 0;
int rc = j->read_count;
unsigned int nread = 0;
unsigned int rc = j->read_count;
while (sr&SSPSR_RNE) {
unsigned int dr = SSPDR;
sr=SSPSR;
nread++;
ssp_lastword = ssp_lastword << ssp_bits | dr;
if (ssp_frames_read++ >= ssp_match.frame_count
if (ssp_frame_count++ >= ssp_match.count
&& !rc
&& (dr & ssp_match.mask) == ssp_match.value) {
rc = ssp_match.read_count;
if (ssp_match.count) {
j->count = ssp_match.count
+ ssp_match.frame_count
- ssp_frames_sent;
}
rc = ssp_match.size;
j->idle_count = 0;
}
if (rc) {
rc--;
@ -85,19 +81,18 @@ static void ssp_isr(void)
}
}
j->read_count = rc;
int ic = j->count;
sr |= SSPSR; // race between SSPSR_BSY, SSPSR_RNE?
if (!ic)
if ((sr & (SSPSR_BSY|SSPSR_RNE)))
goto outic;
else {
if (!j->cmd_count && !j->idle_count) {
if (!rc && !(sr & (SSPSR_BSY|SSPSR_RNE))) {
SSPIMSC = 0;
if (ssp_callback)
ssp_callback();
}
else
SSPIMSC = SSP_INT_RX;
goto out;
}
else if (!(sr & (SSPSR_BSY|SSPSR_RNE)))
nread = 8;
@ -105,24 +100,25 @@ static void ssp_isr(void)
// This prevents Rx FIFO overflow.
// 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) {
j->cmd_count--;
SSPDR = *j->command++;
}
else
SSPDR = j->idle_frame;
ssp_frames_sent ++;
nread--;
else if (ic) {
ic--;
SSPDR = ssp_match.idle;
}
else {
SSPIMSC = SSP_INT_RX;
goto outic;
}
nread--;
sr = SSPSR;
}
if (!ic)
outic:
SSPIMSC = SSP_INT_RX;
j->count = ic;
j->idle_count = ic;
out:
VICVectAddr = 0;
}
@ -138,16 +134,15 @@ out:
// idle=0x8000 RFIFO, send what the acquisition fifos provide.
// 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;
unsigned int iflg = disable_irq(INT_DISABLE);
j->command = cmd;
j->cmd_count = cmd_size;
j->count = ic;
j->idle_count = ic;
j->read_count = rc;
ssp_frames_sent = 0;
ssp_frames_read = 0;
ssp_frame_count = 0;
enable_irq(iflg);
ssp_poll();
return 0;
@ -163,8 +158,6 @@ int ssp_submit_job(const struct ssp_job *jj)
ssp_set_buffer(0, 0);
}
memcpy((void*)&job, jj, n);
ssp_frames_sent = 0;
ssp_frames_read = 0;
enable_irq(iflg);
ssp_poll();
return 0;
@ -175,8 +168,8 @@ void ssp_reset(void)
SSPIMSC = 0;
volatile struct ssp_job *j=&job;
unsigned int iflg = disable_irq(INT_DISABLE);
j->count = 0;
j->cmd_count = 0;
j->idle_count = 0;
j->read_count = 0;
enable_irq(iflg);
}
@ -225,7 +218,7 @@ int ssp_busy(void)
volatile struct ssp_job *j=&job;
ssp_poll(); // run the isr to drain the backlog
// 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)
return c;
// Hardware is busy
@ -393,8 +386,7 @@ const struct keywords ssp_variable_names[] = {
VARIABLE("ssp_response", (void *)&ssp_lastword),
VARIABLE("ssp_match", &ssp_match),
VARIABLE("ssp_ssel_mask", &ssp_ssel_mask),
VARIABLE("ssp_frames_sent", (void *)&ssp_frames_sent),
VARIABLE("ssp_frames_read", (void *)&ssp_frames_read),
VARIABLE("ssp_frame_count", (void *)&ssp_frame_count),
VARIABLE("ssp_bits", &ssp_bits),
VARIABLE("ssp_config", &ssp_conf_default),
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_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_wait(int timeout);
@ -23,8 +23,7 @@ extern unsigned int ssp_idle;
extern unsigned int ssp_match_mask;
extern unsigned int ssp_match_value;
extern unsigned int ssp_match_count;
extern volatile int ssp_frames_sent;
extern volatile int ssp_frames_read;
extern volatile unsigned int ssp_frame_count;
extern unsigned short ssp_scratch[256];
extern int (*ssp_callback)();
@ -62,26 +61,23 @@ extern struct ssp_config ssp_confs[];
#define ssp_conf_dac ssp_confs[2]
#define ssp_conf_bate ssp_confs[3]
// volatile part of the job
// inaccessible globally
// volatile part of the job, inaccessible globally
struct ssp_job {
unsigned short cmd_count;
unsigned short read_count;
unsigned short count;
unsigned short idle_frame;
unsigned int cmd_count;
unsigned int read_count;
unsigned int idle_count;
const unsigned short *command;
unsigned short buf_count;
unsigned int buf_count;
unsigned short *buf_ptr;
};
// global static variables for the job
// not changed by the isr
// global variables part of the job
extern struct ssp_match {
unsigned char frame_count;
unsigned char read_count;
unsigned short count;
unsigned short mask;
unsigned short value;
unsigned int mask;
unsigned int value;
unsigned int count;
unsigned int idle;
unsigned int size;
} ssp_match;
struct ssp_batch;
@ -120,12 +116,23 @@ enum ssp_batch_flags {
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.
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.read_count = size;
ssp_match.count = count;
ssp_match.size = size;
}
int ssp_submit_job(const struct ssp_job *jj);