Compare commits
2 commits
60d830fdae
...
0514546b7d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0514546b7d | ||
|
|
c972a723c1 |
6 changed files with 70 additions and 67 deletions
2
Makefile
2
Makefile
|
|
@ -129,7 +129,7 @@ OBJS = crt.o $(patsubst %,%.o,$(sources))
|
||||||
objs: $(OBJS)
|
objs: $(OBJS)
|
||||||
|
|
||||||
%.s: %.c
|
%.s: %.c
|
||||||
$(CC) -S $(CFLAGS) $<
|
$(CC) -fverbose-asm -S $(CFLAGS) $<
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) -MMD $(DEBUGFORMAT) -c $(CFLAGS) $<
|
$(CC) -MMD $(DEBUGFORMAT) -c $(CFLAGS) $<
|
||||||
|
|
|
||||||
|
|
@ -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, 0);
|
ssp_submit(frame, 1, n+1, 0);
|
||||||
int r = ssp_wait(timeout);
|
int r = ssp_wait(timeout);
|
||||||
if (!r)
|
if (!r)
|
||||||
ssp_deassert_ssel();
|
ssp_deassert_ssel();
|
||||||
|
|
|
||||||
|
|
@ -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, 0, 0);
|
ssp_submit(cmd, 2, 2, 0);
|
||||||
int r = ssp_wait(timeout);
|
int r = ssp_wait(timeout);
|
||||||
if (!r)
|
if (!r)
|
||||||
ssp_deassert_ssel();
|
ssp_deassert_ssel();
|
||||||
|
|
|
||||||
12
pressure.c
12
pressure.c
|
|
@ -113,9 +113,10 @@ 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 = 1,
|
.buf_count = 11,
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -126,6 +127,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) {
|
||||||
.command = bate_cmds+11,
|
.command = bate_cmds+11,
|
||||||
|
.count = 2,
|
||||||
.cmd_count = 2,
|
.cmd_count = 2,
|
||||||
.read_count = 2,
|
.read_count = 2,
|
||||||
}},
|
}},
|
||||||
|
|
@ -137,7 +139,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) {
|
||||||
.idle_count = 1,
|
.count = 1,
|
||||||
.read_count = 1,
|
.read_count = 1,
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
|
|
@ -167,7 +169,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, 0, 0);
|
r = ssp_submit(bate_cmds, 11, 11, 0);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
case 6:
|
case 6:
|
||||||
|
|
@ -190,9 +192,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, 0, 1);
|
r = ssp_submit(bate_cmds+11, 2, 2, 1);
|
||||||
break;
|
break;
|
||||||
case 8: r = ssp_submit(bate_cmds+11, 1, 0, 1);
|
case 8: r = ssp_submit(0, 0, 1, 1);
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
ssp_deassert_ssel();
|
ssp_deassert_ssel();
|
||||||
|
|
|
||||||
72
ssp.c
72
ssp.c
|
|
@ -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 unsigned int ssp_frame_count;
|
volatile int ssp_frames_sent;
|
||||||
|
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->idle_count || j->read_count || j->cmd_count || SSPSR & (SSPSR_RNE|SSPSR_BSY))
|
if (j->count || SSPSR & (SSPSR_RNE|SSPSR_BSY))
|
||||||
SSPIMSC = SSP_INT_RX | SSP_INT_TX;
|
SSPIMSC = SSP_INT_RX | SSP_INT_TX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,18 +58,22 @@ static void ssp_isr(void)
|
||||||
|
|
||||||
unsigned int sr = SSPSR;
|
unsigned int sr = SSPSR;
|
||||||
|
|
||||||
unsigned int nread = 0;
|
int nread = 0;
|
||||||
unsigned int rc = j->read_count;
|
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_frame_count++ >= ssp_match.count
|
if (ssp_frames_read++ >= ssp_match.frame_count
|
||||||
&& !rc
|
&& !rc
|
||||||
&& (dr & ssp_match.mask) == ssp_match.value) {
|
&& (dr & ssp_match.mask) == ssp_match.value) {
|
||||||
rc = ssp_match.size;
|
rc = ssp_match.read_count;
|
||||||
j->idle_count = 0;
|
if (ssp_match.count) {
|
||||||
|
j->count = ssp_match.count
|
||||||
|
+ ssp_match.frame_count
|
||||||
|
- ssp_frames_sent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (rc) {
|
if (rc) {
|
||||||
rc--;
|
rc--;
|
||||||
|
|
@ -81,18 +85,19 @@ 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 (!j->cmd_count && !j->idle_count) {
|
if (!ic)
|
||||||
if (!rc && !(sr & (SSPSR_BSY|SSPSR_RNE))) {
|
if ((sr & (SSPSR_BSY|SSPSR_RNE)))
|
||||||
|
goto outic;
|
||||||
|
else {
|
||||||
SSPIMSC = 0;
|
SSPIMSC = 0;
|
||||||
if (ssp_callback)
|
if (ssp_callback)
|
||||||
ssp_callback();
|
ssp_callback();
|
||||||
}
|
goto out;
|
||||||
else
|
|
||||||
SSPIMSC = SSP_INT_RX;
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (!(sr & (SSPSR_BSY|SSPSR_RNE)))
|
else if (!(sr & (SSPSR_BSY|SSPSR_RNE)))
|
||||||
nread = 8;
|
nread = 8;
|
||||||
|
|
||||||
|
|
@ -100,25 +105,24 @@ 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.
|
||||||
|
|
||||||
unsigned int ic = j->idle_count;
|
while (ic && nread && (sr&SSPSR_TNF)) {
|
||||||
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 if (ic) {
|
else
|
||||||
ic--;
|
SSPDR = j->idle_frame;
|
||||||
SSPDR = ssp_match.idle;
|
ssp_frames_sent ++;
|
||||||
}
|
|
||||||
else {
|
|
||||||
SSPIMSC = SSP_INT_RX;
|
|
||||||
goto outic;
|
|
||||||
}
|
|
||||||
nread--;
|
nread--;
|
||||||
|
ic--;
|
||||||
sr = SSPSR;
|
sr = SSPSR;
|
||||||
}
|
}
|
||||||
outic:
|
|
||||||
j->idle_count = ic;
|
if (!ic)
|
||||||
|
outic:
|
||||||
|
SSPIMSC = SSP_INT_RX;
|
||||||
|
|
||||||
|
j->count = ic;
|
||||||
out:
|
out:
|
||||||
VICVectAddr = 0;
|
VICVectAddr = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -134,15 +138,16 @@ 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, int cmd_size, unsigned int ic, unsigned int rc)
|
int ssp_submit(const unsigned short *cmd, short cmd_size, unsigned short ic, unsigned short 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->idle_count = ic;
|
j->count = ic;
|
||||||
j->read_count = rc;
|
j->read_count = rc;
|
||||||
ssp_frame_count = 0;
|
ssp_frames_sent = 0;
|
||||||
|
ssp_frames_read = 0;
|
||||||
enable_irq(iflg);
|
enable_irq(iflg);
|
||||||
ssp_poll();
|
ssp_poll();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -158,6 +163,8 @@ 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;
|
||||||
|
|
@ -168,8 +175,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);
|
||||||
}
|
}
|
||||||
|
|
@ -218,7 +225,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->cmd_count + j->idle_count + j->read_count;
|
unsigned int c = j->count;
|
||||||
if (c)
|
if (c)
|
||||||
return c;
|
return c;
|
||||||
// Hardware is busy
|
// Hardware is busy
|
||||||
|
|
@ -386,7 +393,8 @@ 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_frame_count", (void *)&ssp_frame_count),
|
VARIABLE("ssp_frames_sent", (void *)&ssp_frames_sent),
|
||||||
|
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
47
ssp.h
|
|
@ -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, int cmd_size, unsigned int ic, unsigned int rc);
|
int ssp_submit(const unsigned short *cmd, short cmd_size, unsigned short ic, unsigned short rc);
|
||||||
int ssp_busy(void);
|
int ssp_busy(void);
|
||||||
int ssp_wait(int timeout);
|
int ssp_wait(int timeout);
|
||||||
|
|
||||||
|
|
@ -23,7 +23,8 @@ 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 unsigned int ssp_frame_count;
|
extern volatile int ssp_frames_sent;
|
||||||
|
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)();
|
||||||
|
|
||||||
|
|
@ -61,23 +62,26 @@ 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, inaccessible globally
|
// volatile part of the job
|
||||||
|
// inaccessible globally
|
||||||
struct ssp_job {
|
struct ssp_job {
|
||||||
unsigned int cmd_count;
|
unsigned short cmd_count;
|
||||||
unsigned int read_count;
|
unsigned short read_count;
|
||||||
unsigned int idle_count;
|
unsigned short count;
|
||||||
|
unsigned short idle_frame;
|
||||||
const unsigned short *command;
|
const unsigned short *command;
|
||||||
unsigned int buf_count;
|
unsigned short buf_count;
|
||||||
unsigned short *buf_ptr;
|
unsigned short *buf_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// global variables part of the job
|
// global static variables for the job
|
||||||
|
// not changed by the isr
|
||||||
extern struct ssp_match {
|
extern struct ssp_match {
|
||||||
unsigned int mask;
|
unsigned char frame_count;
|
||||||
unsigned int value;
|
unsigned char read_count;
|
||||||
unsigned int count;
|
unsigned short count;
|
||||||
unsigned int idle;
|
unsigned short mask;
|
||||||
unsigned int size;
|
unsigned short value;
|
||||||
} ssp_match;
|
} ssp_match;
|
||||||
|
|
||||||
struct ssp_batch;
|
struct ssp_batch;
|
||||||
|
|
@ -116,23 +120,12 @@ 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 int count, unsigned int size)
|
void ssp_set_read(unsigned short count, unsigned short size)
|
||||||
{
|
{
|
||||||
ssp_match.count = count;
|
ssp_match.frame_count = count;
|
||||||
ssp_match.size = size;
|
ssp_match.read_count = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssp_submit_job(const struct ssp_job *jj);
|
int ssp_submit_job(const struct ssp_job *jj);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue