Compare commits
2 commits
b23ad870c8
...
560f7b806b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
560f7b806b | ||
|
|
88f7f36fb4 |
11 changed files with 297 additions and 629 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -8,3 +8,4 @@ revision.h
|
|||
__pycache__
|
||||
revision.h+
|
||||
*~
|
||||
*.s
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -147,7 +147,7 @@ sources = irena mainloop parser message isr crc \
|
|||
usb controlpipe usbconfig dma stream \
|
||||
enc28j60 net udp \
|
||||
expression variables display \
|
||||
pressure \
|
||||
pressure gpio \
|
||||
adc rtc \
|
||||
plugin \
|
||||
nomalloc strtol uart uart1 base85
|
||||
|
|
|
|||
22
altera.c
22
altera.c
|
|
@ -13,16 +13,6 @@
|
|||
#include "script.h"
|
||||
#include <string.h>
|
||||
|
||||
error_msg_t ssp_error(const char *m, int c)
|
||||
{
|
||||
if (!c)
|
||||
return 0;
|
||||
return error_printf(800+c, "SSP error: %s: %d\n", m, c);
|
||||
}
|
||||
|
||||
static unsigned int ssp_response;
|
||||
static unsigned int ssp_sync_response;
|
||||
|
||||
unsigned int stream_flags;
|
||||
|
||||
static const struct keywords stream_enable_kw[] = {
|
||||
|
|
@ -117,15 +107,3 @@ error_msg_t parse_stream_flags(struct command *cmd, unsigned int defaults)
|
|||
return 0;
|
||||
}
|
||||
|
||||
const struct keywords altera_variable_names[] = {
|
||||
{"ssp_response", {.par=&ssp_response}},
|
||||
{"ssp_sync_response", {.par=&ssp_sync_response}},
|
||||
{"ssp_lastword", {.par=&ssp_lastword}},
|
||||
{"ssp_buffer", {.par=&ssp_injection_buffer}},
|
||||
{"ssp_block_idle", {.par=&ssp_block_idle}},
|
||||
{"ssp_block_size", {.par=&ssp_block_size}},
|
||||
{"ssp_write_ptr", {.par=&ssp_injection_write_ptr}},
|
||||
{"ssp_read_ptr", {.par=&ssp_injection_read_ptr}},
|
||||
{"stream_flags", {.par=&stream_flags}},
|
||||
{"", {0}}};
|
||||
|
||||
|
|
|
|||
60
altera.h
60
altera.h
|
|
@ -1,64 +1,6 @@
|
|||
#ifndef _altera_h
|
||||
#define _altera_h
|
||||
#include "parser.h"
|
||||
void altera_init(void);
|
||||
error_msg_t altera_reset(void);
|
||||
error_msg_t altera_config(unsigned char *buf, unsigned int bsize);
|
||||
error_msg_t altera_config_file(int fd, const char *fn, int secondary);
|
||||
error_msg_t altera_send_command(unsigned int c, unsigned int l, unsigned short *r);
|
||||
error_msg_t altera_sync(unsigned short c, unsigned short *r);
|
||||
error_msg_t inject(unsigned int c);
|
||||
error_msg_t inject_delay(unsigned int c, unsigned int flags, unsigned int delay);
|
||||
error_msg_t altera_stream_enable(unsigned int where, unsigned int what, unsigned int size);
|
||||
extern const struct command_par altera_command;
|
||||
extern const struct command_par altera2_command;
|
||||
extern const struct keywords altera_variable_names[];
|
||||
error_msg_t altera_read_packet(unsigned int fifo, unsigned int packetsize, unsigned short *buf);
|
||||
error_msg_t altera_read_timer(unsigned int addr, unsigned int *r);
|
||||
error_msg_t altera_set_timer(unsigned int addr, unsigned int *r);
|
||||
error_msg_t altera_wait_status(unsigned int c, unsigned short mask, unsigned short val, unsigned int timeout);
|
||||
extern unsigned int wait_status;
|
||||
|
||||
#define Altera_CRC_Error 0x00010000
|
||||
#define Altera_nSTATUS 0x00020000
|
||||
#define Altera_DCLK 0x00040000
|
||||
#define Altera_DATA0 0x00080000
|
||||
#define Altera_nCONFIG 0x00100000
|
||||
#define Altera_CONF_DONE 0x00200000
|
||||
#define GPIO1_Altera_Mask (~0x003f0000)
|
||||
#define GPIO1_Altera_Dir 0x001c0000
|
||||
|
||||
error_msg_t ssp_error(const char *m, int c);
|
||||
|
||||
int altera_inject_command(struct command *cmd, const struct command_par *par);
|
||||
int altera_set_register(struct command *cmd, const struct command_par *par,
|
||||
const struct keywords *regs,
|
||||
unsigned int how, unsigned int cc,
|
||||
const char *name);
|
||||
int altera_cmd(struct command *cmd, const struct command_par *par);
|
||||
|
||||
enum {
|
||||
alt_cmd_inj = 0x010000,
|
||||
alt_cmd_sync = 0x020000,
|
||||
alt_cmd_send = 0x040000,
|
||||
alt_cmd_scan = 0x080000,
|
||||
alt_cmd_trans = 0x0f0000,
|
||||
alt_cmd_double= 0x0800000,
|
||||
alt_cmd_clock = 0x1000000,
|
||||
alt_cmd_read = 0x2000000,
|
||||
alt_cmd_delay = 0x4000000,
|
||||
alt_cmd_save = 0x8000000,
|
||||
alt_cmd_force = 0x10000000,
|
||||
alt_cmd_aflag = 0x20000000,
|
||||
alt_cmd_nkeyw = 0x80000000,
|
||||
alt_cmd_write = 0x4000,
|
||||
alt_cmd_addr = 0x8000,
|
||||
};
|
||||
|
||||
#define ALT_CMD_KW(p) (&(p)->name)
|
||||
#define ALT_CMD_AD(a) ((const void*)((a)|alt_cmd_nkeyw|alt_cmd_addr))
|
||||
#define ALT_CMD_AF(a) ((const void*)((a)|alt_cmd_nkeyw|alt_cmd_aflag))
|
||||
#define ALT_CMD_FG(f) ((const void*)((f)|alt_cmd_nkeyw))
|
||||
|
||||
enum {
|
||||
stk_dma_ch = 3,
|
||||
|
|
@ -103,4 +45,6 @@ extern unsigned int stream_flags;
|
|||
error_msg_t stream_destination(unsigned int where);
|
||||
extern const struct command_par err_invalid_source;
|
||||
|
||||
static inline void disable_ssp_dma() {}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
24
gpio.c
Normal file
24
gpio.c
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
#include "gpio.h"
|
||||
#include <lpc2148/gpio.h>
|
||||
|
||||
unsigned int gpio1_mask = 0x00ff0000;
|
||||
|
||||
void gpio_set(unsigned int pins)
|
||||
{
|
||||
pins &= gpio1_mask;
|
||||
GPIO_FIO1SET = pins;
|
||||
GPIO_FIO1DIR |= pins;
|
||||
}
|
||||
void gpio_clr(unsigned int pins)
|
||||
{
|
||||
pins &= gpio1_mask;
|
||||
GPIO_FIO1CLR = pins;
|
||||
GPIO_FIO1DIR |= pins;
|
||||
}
|
||||
unsigned int gpio_read(unsigned int pins)
|
||||
{
|
||||
pins &= gpio1_mask;
|
||||
GPIO_FIO1DIR &=~ pins;
|
||||
return GPIO_FIO1PIN & pins;
|
||||
}
|
||||
105
gpio.h
Normal file
105
gpio.h
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
|
||||
#ifndef _gpio_h
|
||||
#define _gpio_h
|
||||
|
||||
/*
|
||||
* port: (pin) function (options) (remarks)
|
||||
*
|
||||
* 0.0: (19) TxD0
|
||||
* 0.1: (21) RxD0
|
||||
* 0.2: (22) SPI SSEL flash (open drain)
|
||||
* 0.3: (26) SPI SSEL sdcard (open drain)
|
||||
* 0.4: (27) SPI SCK
|
||||
* 0.5: (29) SPI MISO
|
||||
* 0.6: (30) SPI MOSI
|
||||
* 0.7: (31) SPI SSEL (PWM, EINT) (power board)
|
||||
* 0.8: (33) TxD1 (AD1.1, PWM)
|
||||
* 0.9: (34) RxD1 (PWM, EINT)
|
||||
* 0.10: (35) AD1.2 (power board)
|
||||
* 0.11: (37) SSP SSEL DAC (open drain)
|
||||
* 0.12: (38) AD1.3 (MAT) (power board)
|
||||
* 0.13: (39) AD1.4 Ipos (MAT)
|
||||
* 0.14: (41) EINT1 ISP
|
||||
* 0.15: (45) AD1.5 Ineg (EINT)
|
||||
* 0.16: (46) SSP SSEL/MCLK MAT0.2
|
||||
* 0.17: (47) SSP SCK
|
||||
* 0.18: (53) SSP MISO
|
||||
* 0.19: (54) SSP MOSI
|
||||
* 0.20: (55) SSL SSEL ADC
|
||||
* 0.21: (1) AD1.6 Vpos (PWM)
|
||||
* 0.22: (2) AD1.7 Vneg (MAT)
|
||||
* 0.23: (58) USB VBUS
|
||||
* 0.24:
|
||||
* 0.25: (9) AOUT (AD0.4)
|
||||
* 0.26:
|
||||
* 0.27:
|
||||
* 0.28: (13) AD0.1 (MAT)
|
||||
* 0.29: (14) AD0.2 (MAT)
|
||||
* 0.30: (15) AD0.3 (MAT, EINT)
|
||||
* 0.31: (17) USB UP_LED
|
||||
*
|
||||
* 1.16: (16) GPIO OUT (internal pull-up)
|
||||
* 1.17: (12) GPIO OUT (internal pull-up)
|
||||
* 1.18: (8) GPIO OUT (internal pull-up)
|
||||
* 1.19: (4) GPIO IN (internal pull-up)
|
||||
* 1.20: (48) GPIO (internal pull-up)
|
||||
* 1.21: (44) GPIO (internal pull-up)
|
||||
* 1.22: (40) GPIO RS232 Tx (internal pull-up)
|
||||
* 1.23: (36) GPIO RS232 Rx (internal pull-up)
|
||||
* 1.24: (32) SSP SSEL_P2 (internal pull-up)
|
||||
* 1.25: (28) SSP SSEL_P1 MS5534C (internal pull-up)
|
||||
* 1.26: (24) JTAG
|
||||
* 1.27: (64) JTAG
|
||||
* 1.28: (60) JTAG
|
||||
* 1.29: (56) JTAG
|
||||
* 1.30: (52) JTAG
|
||||
* 1.31: (20) JTAG
|
||||
*
|
||||
* UART1:
|
||||
* 3.3V CMOS/RS232
|
||||
* TxD, RxD, IN, OUT
|
||||
* RxD can be used as EINT interrupt input
|
||||
* RxD and TxD can be used as 2 phase PWM outputs
|
||||
* IN OUT are part of the 8-bit GPIO1 port
|
||||
*
|
||||
* GPIO1:
|
||||
* eight bits [32:16], 3.3V CMOS with pull-up
|
||||
* one RS232 output [22]
|
||||
* one RS232 input [23]
|
||||
* three 5V driver outputs [18:16]
|
||||
* one 5V driver input [17]
|
||||
*
|
||||
* AD0, DAC:
|
||||
* four AD inputs, AD0.1 … AD0.4.
|
||||
* AD0.4 is the DAC output
|
||||
* Use as GPIO
|
||||
* AD0.1…3 three MATch outputs for clock generation
|
||||
* AD0.3 can be used as EINT interrupt.
|
||||
*
|
||||
* SSP:
|
||||
* five SSEL pins
|
||||
* P0.11: DAC LTC2656
|
||||
* P0.16: External SPI/pressure sensor MCLK
|
||||
* P0.20: ADC ADS8688
|
||||
* P1.24: External SPI driver enable
|
||||
* P1.25: internal pressure sensor MS5534C driver enable
|
||||
*
|
||||
* To readout the pressure sensor(s), P0.16 must be driven by counter 0
|
||||
* to provide a 32768kHz MCLK (MAT0.2).
|
||||
* The external MISO input can be jumpered to the ADS8688 DAISY chain,
|
||||
* to readout external ADS8688 in a chain with the internal one.
|
||||
*/
|
||||
|
||||
static inline void init_gpio(void) {}
|
||||
|
||||
#define SSP_SSEL_MASK0 0x00110800 // gpio0 pins to set high on deassert ssel
|
||||
#define SSP_SSEL_MASK1 0x03000000 // gpio1 pins to set high on deassert ssel
|
||||
#define SSP_SSEL_CONF0 0x00113f00 // ssel bits associated with gpio0 pins
|
||||
#define SSP_SSEL_CONF1 0x03ee0000 // ssel bits associated with gpio1 pins
|
||||
|
||||
extern unsigned int gpio1_mask;
|
||||
void gpio_set(unsigned int pins);
|
||||
void gpio_clr(unsigned int pins);
|
||||
unsigned int gpio_read(unsigned int pins);
|
||||
|
||||
#endif
|
||||
19
mainloop.c
19
mainloop.c
|
|
@ -647,24 +647,8 @@ void sleep(int count)
|
|||
// qtime() is the time of day in units of 1/2¹⁵ seconds.
|
||||
if (qtime_limit_test(&spi_qtime_limit))
|
||||
buf = dma_get_spi_block();
|
||||
if (buf) {
|
||||
if (buf)
|
||||
qtime_limit_set(&spi_qtime_limit);
|
||||
// test if the data is all the same words
|
||||
unsigned short *b = buf;
|
||||
int i=255;
|
||||
while (i && b[0]==b[i])
|
||||
i--;
|
||||
if (!i) {
|
||||
spy_return = 0xb0ff0000 | b[0];
|
||||
// if its 0xffff, the FPGA tripped.
|
||||
if (b[0]==0xffff) {
|
||||
ssp_dma_size = 0;
|
||||
message(MSG_PRIO_ERROR, "got block of 0xffff, ssp_dma stopped\n");
|
||||
}
|
||||
else
|
||||
message(MSG_PRIO_WARN, "got block of 0x%04x\n", b[0]);
|
||||
}
|
||||
}
|
||||
if (buf && uart_size)
|
||||
if (uart_send_dma_block_base64(buf))
|
||||
uart_size--, uart_count++;
|
||||
|
|
@ -894,7 +878,6 @@ const struct keywords *variable_names[] = {
|
|||
script_variable_names,
|
||||
eth_variable_names,
|
||||
pressure_variable_names,
|
||||
altera_variable_names,
|
||||
0
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -147,6 +147,6 @@ int printf(const char *fmt, ...)
|
|||
return -1;
|
||||
submit:
|
||||
poll_dma_buffer_size += n;
|
||||
poll_dma_submit(0,0);
|
||||
return n;
|
||||
poll_dma_submit(0,0);
|
||||
return n;
|
||||
}
|
||||
|
|
|
|||
6
spi.c
6
spi.c
|
|
@ -68,9 +68,9 @@ void spi_init()
|
|||
if (ssel)
|
||||
ssel |= SPI_Ssel_Ext;
|
||||
unsigned int mask = SPI_Ssel_Flash|SPI_Ssel_SD|ssel;
|
||||
GPIO_FIO0MASK = ~mask;
|
||||
GPIO_FIO0PIN = mask;
|
||||
GPIO_FIO0DIR = mask;
|
||||
GPIO_FIO0MASK &= ~mask;
|
||||
GPIO_FIO0PIN |= mask;
|
||||
GPIO_FIO0DIR |= mask;
|
||||
ssel &= ~SPI_Ssel_Ext;
|
||||
// make any selected extra SSEL a GPIO
|
||||
// This reaches up to pin 15.
|
||||
|
|
|
|||
584
ssp.c
584
ssp.c
|
|
@ -1,119 +1,54 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <lpc2148/ssp.h>
|
||||
#include <lpc2148/gpio.h>
|
||||
#include <lpc2148/pcb.h>
|
||||
#include <lpc2148/vic.h>
|
||||
|
||||
#include "ssp.h"
|
||||
#include "dma.h"
|
||||
#include "gpio.h"
|
||||
#include "isr.h"
|
||||
|
||||
// The SSP keeps its state in these private static variables.
|
||||
// The interface is through public functions.
|
||||
|
||||
static volatile struct ssp_job {
|
||||
unsigned int idle;
|
||||
int count;
|
||||
unsigned int cmd_count;
|
||||
unsigned int read_count;
|
||||
unsigned int idle_count;
|
||||
unsigned int buf_count;
|
||||
unsigned short *command;
|
||||
unsigned int flags;
|
||||
int compress_count;
|
||||
unsigned short *buf_start;
|
||||
unsigned short *buf_ptr;
|
||||
int buf_count;
|
||||
unsigned int word_in;
|
||||
unsigned int maxidlecount;
|
||||
} job;
|
||||
|
||||
unsigned int ssp_idleword;
|
||||
unsigned int ssp_lastword;
|
||||
unsigned int ssp_dma_size;
|
||||
unsigned int ssp_min_size = 1;
|
||||
unsigned int ssp_block_idle = 256;
|
||||
unsigned int ssp_block_size = 3;
|
||||
unsigned int ssp_bits;
|
||||
volatile unsigned int ssp_lastword;
|
||||
unsigned int ssp_ssel_mask = SSP_SSEL_MASK0 | SSP_SSEL_MASK1;
|
||||
|
||||
unsigned int ssp_get_status(void)
|
||||
{
|
||||
unsigned int f = job.flags;
|
||||
if (job.count)
|
||||
f |= ssp_do_cmd;
|
||||
if (job.idle)
|
||||
f |= ssp_do_idle;
|
||||
if (job.buf_count)
|
||||
f |= ssp_have_buffer;
|
||||
return f;
|
||||
}
|
||||
unsigned int ssp_read_size;
|
||||
unsigned int ssp_idle;
|
||||
unsigned int ssp_match_mask;
|
||||
unsigned int ssp_match_value;
|
||||
unsigned int ssp_match_count;
|
||||
unsigned short *ssp_buffer;
|
||||
volatile unsigned int ssp_frame_count;
|
||||
|
||||
// This is called when the SSP Rx buffer is full. It shall return
|
||||
// zero when a new buffer was made available
|
||||
// When the buffer could not be taken care of, return non-zero, we
|
||||
// will call again soon.
|
||||
// The SSP is stopped when no buffer is made available, i.e., we do
|
||||
// not send any further frames.
|
||||
unsigned short ssp_scratch[256];
|
||||
|
||||
///// extern void *dma_poll(void *start);
|
||||
|
||||
|
||||
// Provide a new buffer with size bytes, size must be a multiple of 2.
|
||||
// Normally, this should be 512 bytes. This should be called by
|
||||
// by the DMA enable with the first buffer..
|
||||
|
||||
static unsigned short scratch[16];
|
||||
|
||||
static inline void ssp_set_buffer(void *start, int size)
|
||||
void ssp_set_buffer(void *start, int size)
|
||||
{
|
||||
unsigned int iflg = disable_irq(INT_DISABLE);
|
||||
volatile struct ssp_job *j=&job;
|
||||
if (!(size && start)) {
|
||||
j->flags &=~ ssp_do_dma;
|
||||
start = scratch;
|
||||
size = sizeof(scratch);
|
||||
start = ssp_scratch;
|
||||
size = sizeof(ssp_scratch);
|
||||
}
|
||||
j->buf_start = (unsigned short *)start;
|
||||
ssp_buffer = (unsigned short *)start;
|
||||
j->buf_ptr = (unsigned short *)start;
|
||||
j->buf_count = size/2;
|
||||
enable_irq(iflg);
|
||||
}
|
||||
|
||||
static inline int get_new_buffer(void *oldbuf)
|
||||
{
|
||||
// We disable IRQs for the main loop to ge a chance to run
|
||||
SSPIMSC = 0;
|
||||
volatile struct ssp_job *j=&job;
|
||||
if (j->flags & ssp_do_dma) {
|
||||
// When we run out of ssp_dma_size, just wait for somebody
|
||||
// to increase it again ...
|
||||
if (!ssp_dma_size)
|
||||
return 1;
|
||||
void *newbuf = dma_poll(oldbuf);
|
||||
if (newbuf) {
|
||||
j->buf_start = newbuf;
|
||||
j->buf_ptr = newbuf;
|
||||
j->buf_count = 512/2;
|
||||
ssp_dma_size--;
|
||||
return 0;
|
||||
}
|
||||
return 91;
|
||||
}
|
||||
j->buf_ptr = scratch;
|
||||
j->buf_count = sizeof(scratch)/2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
THE FOLLOWING COMMENT IS OBSOLETE, we now use 16-bit frames
|
||||
|
||||
All incomming data goes into 512 byte buffers. Well, we require
|
||||
the size of the buffer to be a multiple of 2 16-bit words.
|
||||
j->buf_ptr points to the next free 16-bit word, j->buf_count is the
|
||||
number of free 16-bit words. j->buf_start is the start of the buffer,
|
||||
for the dma_poll to check if we are in sync.
|
||||
|
||||
The FPGA shall send ssp_idleword when no data is available. When requested
|
||||
(e.g., for FIFO streaming), sequences of those will be run length
|
||||
compressed. every word with value ssp_idleword will be followed by the
|
||||
number of occurances, or 0xffff there were more.
|
||||
*/
|
||||
|
||||
|
||||
// ssp_poll shall be called by the main loop once, to reenable the IRQ.
|
||||
// Other places may call this when they think there should be free traffic,
|
||||
// or when they wait for traffic.
|
||||
|
|
@ -121,12 +56,10 @@ static inline int get_new_buffer(void *oldbuf)
|
|||
void ssp_poll(void)
|
||||
{
|
||||
volatile struct ssp_job *j=&job;
|
||||
if (j->idle || 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;
|
||||
}
|
||||
|
||||
unsigned int ssp_stalled_count;
|
||||
|
||||
// we may want to put this on a rather low priority IRQ line
|
||||
// because this one will saturate the CPU.
|
||||
|
||||
|
|
@ -135,96 +68,33 @@ static void ssp_isr(void)
|
|||
{
|
||||
volatile struct ssp_job *j=&job;
|
||||
|
||||
// Somehow we could not get rid of the data last time.
|
||||
// Try again.
|
||||
if (!j->buf_count) {
|
||||
if (get_new_buffer(j->buf_start)) {
|
||||
VICVectAddr = 0;
|
||||
return;
|
||||
}
|
||||
if (j->word_in) {
|
||||
// We have a word in the cache
|
||||
// to go into the buffer
|
||||
*j->buf_ptr++ = j->word_in;
|
||||
--j->buf_count;
|
||||
j->word_in = 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int cc = ssp_compressing(j);
|
||||
unsigned int flags = j->flags;
|
||||
unsigned int sr = SSPSR;
|
||||
|
||||
int nread = 0;
|
||||
unsigned int nread = 0;
|
||||
unsigned int rc = j->read_count;
|
||||
while (sr&SSPSR_RNE) {
|
||||
unsigned int dr = SSPDR;
|
||||
sr=SSPSR;
|
||||
nread++;
|
||||
if (cc) {
|
||||
// we were counting idlewords ...
|
||||
if (dr==ssp_idleword) {
|
||||
// we continue counting idle words
|
||||
if (++cc >= 0x10000)
|
||||
cc = 0xffff;
|
||||
unsigned int mic = j->maxidlecount;
|
||||
if (mic && cc>=mic)
|
||||
j->idle = 0;
|
||||
if (flags & ssp_nonblock && cc >= ssp_block_idle) {
|
||||
// To send a partial buffer in
|
||||
// nonblock mode, the buffer
|
||||
// must have two words
|
||||
// content, i.e., more than an
|
||||
// idleword.
|
||||
unsigned int c = j->buf_count;
|
||||
if (c + ssp_block_size < 256) {
|
||||
unsigned short *p = j->buf_ptr;
|
||||
*p++ = cc;
|
||||
while (--c)
|
||||
*p++ = 0;
|
||||
if (get_new_buffer(j->buf_start))
|
||||
SSPIMSC = 0;
|
||||
else
|
||||
cc = 0;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
*j->buf_ptr++ = cc;
|
||||
cc = 0;
|
||||
if (!--j->buf_count && get_new_buffer(j->buf_start)) {
|
||||
j->word_in = dr|0x10000;
|
||||
goto stall;
|
||||
}
|
||||
// Fall thru, put the word into the buffer
|
||||
ssp_lastword = ssp_lastword << ssp_bits | dr;
|
||||
if (!rc
|
||||
&& ssp_frame_count++ >= ssp_match_count
|
||||
&& (dr & ssp_match_mask) == ssp_match_value) {
|
||||
rc = ssp_read_size;
|
||||
j->idle_count = 0;
|
||||
}
|
||||
else if (dr==ssp_idleword) {
|
||||
if (flags & ssp_skipidle) {
|
||||
// give the mainloop a chance to run
|
||||
SSPIMSC = 0;
|
||||
continue;
|
||||
if (rc) {
|
||||
rc--;
|
||||
unsigned int bc = j->buf_count;
|
||||
if (bc) {
|
||||
*j->buf_ptr++ = dr;
|
||||
j->buf_count = bc-1;
|
||||
}
|
||||
if (flags & ssp_compress)
|
||||
// This is the start of an idle sequence,
|
||||
cc = 1;
|
||||
// Fall thru, put the word into the buffer
|
||||
}
|
||||
*j->buf_ptr++ = dr;
|
||||
ssp_lastword = dr;
|
||||
if (!--j->buf_count && get_new_buffer(j->buf_start)) {
|
||||
// 512 bytes received, do something with it.
|
||||
// If we cannot get rid of the data just now,
|
||||
// do not clock the ssp further.
|
||||
stall:
|
||||
j->compress_count = cc;
|
||||
ssp_stalled_count++;
|
||||
VICVectAddr = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
j->read_count = rc;
|
||||
|
||||
j->compress_count = cc;
|
||||
|
||||
if (!nread && !(sr&SSPSR_BSY) && !ssp_idling(j) && !j->count) {
|
||||
if (!nread && !rc && !(sr&SSPSR_BSY) && !j->cmd_count && !j->idle_count) {
|
||||
// there is nothing left to do
|
||||
SSPIMSC = 0;
|
||||
VICVectAddr = 0;
|
||||
|
|
@ -244,27 +114,29 @@ static void ssp_isr(void)
|
|||
if (!(sr & (SSPSR_BSY|SSPSR_RNE)))
|
||||
nread = 8;
|
||||
}
|
||||
if (rc && nread > rc)
|
||||
nread = rc;
|
||||
unsigned int ic = j->idle_count;
|
||||
while (nread && (sr&SSPSR_TNF)) {
|
||||
if (j->count) {
|
||||
j->count--;
|
||||
if (j->cmd_count) {
|
||||
j->cmd_count--;
|
||||
SSPDR = *j->command++;
|
||||
}
|
||||
else {
|
||||
if (!ssp_idling(j)) {
|
||||
if (!(rc || ic)) {
|
||||
// nothing to send, disable TX irq
|
||||
SSPIMSC = SSP_INT_RX;
|
||||
break;
|
||||
}
|
||||
SSPDR = j->idle;
|
||||
if (ic)
|
||||
ic--;
|
||||
SSPDR = ssp_idle;
|
||||
}
|
||||
nread--;
|
||||
sr = SSPSR;
|
||||
}
|
||||
j->idle_count = ic;
|
||||
|
||||
// we disable IRQs when there is no data, for the main loop to ge a chance
|
||||
if (cc>0x100 && !j->count)
|
||||
SSPIMSC = 0;
|
||||
|
||||
VICVectAddr = 0;
|
||||
}
|
||||
|
||||
|
|
@ -279,17 +151,15 @@ static void ssp_isr(void)
|
|||
// idle=0x8000 RFIFO, send what the acquisition fifos provide.
|
||||
// idle=0x8001 NOOPP, just drain the FPGA buffer.
|
||||
|
||||
int ssp_submit(unsigned short *cmd, int cmd_size, unsigned int idle, unsigned int flags)
|
||||
int ssp_submit(unsigned short *cmd, int cmd_size, unsigned int ic, unsigned int rc)
|
||||
{
|
||||
volatile struct ssp_job *j=&job;
|
||||
unsigned int c = j->count;
|
||||
if (c)
|
||||
return c;
|
||||
unsigned int iflg = disable_irq(INT_DISABLE);
|
||||
j->command = cmd;
|
||||
j->count = cmd_size;
|
||||
j->idle = idle;
|
||||
j->flags = flags;
|
||||
j->cmd_count = cmd_size;
|
||||
j->idle_count = ic;
|
||||
j->read_count = rc;
|
||||
ssp_frame_count = 0;
|
||||
enable_irq(iflg);
|
||||
ssp_poll();
|
||||
return 0;
|
||||
|
|
@ -300,24 +170,31 @@ void ssp_reset(void)
|
|||
SSPIMSC = 0;
|
||||
volatile struct ssp_job *j=&job;
|
||||
unsigned int iflg = disable_irq(INT_DISABLE);
|
||||
j->idle = 0;
|
||||
j->count = 0;
|
||||
j->flags = 0;
|
||||
j->word_in = 0;
|
||||
j->compress_count = 0;
|
||||
j->cmd_count = 0;
|
||||
j->idle_count = 0;
|
||||
j->read_count = 0;
|
||||
ssp_set_buffer(0,0);
|
||||
ssp_injection_write_ptr = 0;
|
||||
ssp_injection_read_ptr = 0;
|
||||
ssp_dma_size = 0;
|
||||
enable_irq(iflg);
|
||||
}
|
||||
|
||||
void ssp_init(int pclk)
|
||||
struct ssp_config ssp_config;
|
||||
|
||||
void ssp_deassert_ssel()
|
||||
{
|
||||
GPIO_FIO1SET = ssp_ssel_mask & SSP_SSEL_CONF1;
|
||||
GPIO_FIO0SET = ssp_ssel_mask & SSP_SSEL_CONF0;
|
||||
}
|
||||
|
||||
void ssp_init(struct ssp_config *c)
|
||||
{
|
||||
ssp_reset();
|
||||
// pclk is ignored, we run as fast as we can (pclk/2).
|
||||
SSPCPSR= SSPCPSR_MIN; // Prescaler div by 2, 60 --> 30 MHz
|
||||
SSPCR0 = SSPCR0_16bits | SSPCR0_SPI | SSPCR0_CPHA | SSPCR0_SCR(1);
|
||||
ssp_ssel_mask |= c->ssel;
|
||||
ssp_deassert_ssel();
|
||||
ssp_config = *c;
|
||||
ssp_bits = (c->mode & 15) + 1;
|
||||
SSPCR1 = 0;
|
||||
SSPCPSR = SSPCPSR_MIN; // 30 MHz
|
||||
SSPCR0 = c->mode;
|
||||
// 16 bit frames, SPI mode, CPOL=0, CPHA=1, clock div by 1 (30 MHz).
|
||||
SSPICR = SSP_INT_ROR|SSP_INT_RT; // clear any pending irqs.
|
||||
// Route the SSP IRQ through the VIC
|
||||
|
|
@ -327,298 +204,69 @@ void ssp_init(int pclk)
|
|||
SSPCR1 = SSPCR1_SSE; // enable
|
||||
}
|
||||
|
||||
void ssp_assert_ssel(unsigned int ssel)
|
||||
{
|
||||
if (ssel & ssp_flag_mclk)
|
||||
PCB_PINSEL1 |= PCB_PINSEL1_P016_Match0_2;
|
||||
else
|
||||
PCB_PINSEL1 &=~ PCB_PINSEL1_P016_Match0_2;
|
||||
GPIO_FIO1SET = ssp_ssel_mask & SSP_SSEL_CONF1 & ~ssel;
|
||||
GPIO_FIO0SET = ssp_ssel_mask & SSP_SSEL_CONF0 & ~ssel;
|
||||
GPIO_FIO1DIR |= SSP_SSEL_CONF1 & ssel;
|
||||
GPIO_FIO0DIR |= SSP_SSEL_CONF0 & ssel;
|
||||
}
|
||||
|
||||
// When this command returns zero, the SSP is idle and reset
|
||||
|
||||
int ssp_flush(void)
|
||||
int ssp_busy(void)
|
||||
{
|
||||
volatile struct ssp_job *j=&job;
|
||||
j->idle = 0; // stop streaming whatever
|
||||
ssp_poll(); // run the isr to drain the backlog
|
||||
while (!j->buf_count) {
|
||||
// dma is busy, abort whatever we do
|
||||
unsigned int iflg = disable_irq(INT_DISABLE);
|
||||
if (!j->buf_count) {
|
||||
ssp_reset();
|
||||
// drain the ssp hardware
|
||||
while (SSPSR&(SSPSR_RNE|SSPSR_BSY))
|
||||
if (SSPSR&SSPSR_RNE) {
|
||||
unsigned int x = SSPDR;
|
||||
}
|
||||
enable_irq(iflg);
|
||||
return 0;
|
||||
}
|
||||
enable_irq(iflg);
|
||||
}
|
||||
// j->count is volatile and we don't want races
|
||||
unsigned int c = j->count;
|
||||
// j->* is volatile and we don't want races
|
||||
unsigned int c = j->cmd_count + j->idle_count + j->read_count;
|
||||
if (c)
|
||||
return c;
|
||||
// Hardware is busy
|
||||
if (SSPSR&(SSPSR_RNE|SSPSR_BSY))
|
||||
return 90;
|
||||
// Submit the last dma buffer
|
||||
if (j->flags & ssp_do_dma) {
|
||||
unsigned int iflg = disable_irq(INT_DISABLE);
|
||||
if (j->flags & ssp_do_dma) {
|
||||
unsigned short *b=j->buf_ptr;
|
||||
unsigned short *s=j->buf_start;
|
||||
unsigned int n = j->buf_count;
|
||||
ssp_reset();
|
||||
enable_irq(iflg);
|
||||
if (n && b>s) {
|
||||
memset(b, 0, 2*n);
|
||||
dma_poll(s);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
enable_irq(iflg);
|
||||
}
|
||||
return 1;
|
||||
done:
|
||||
ssp_reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Send a 16 or 32 bit command to the FPGA.
|
||||
// 'read' tells how many NOOPPs need to be send, 0..3.
|
||||
|
||||
int ssp_send_command(unsigned int cmd, int read)
|
||||
{
|
||||
int r = ssp_flush();
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ssp_injection_write(cmd|0x8000, cmd&0x4000 ? 2 : 1);
|
||||
while (read>=4) {
|
||||
ssp_injection_write(0,2);
|
||||
read -= 2;
|
||||
}
|
||||
switch (read) {
|
||||
case 3: ssp_injection_write(0,1);
|
||||
case 2: ssp_injection_write(0x8001,2);
|
||||
break;
|
||||
case 1: ssp_injection_write(0,1);
|
||||
}
|
||||
return ssp_injection_submit(1);
|
||||
}
|
||||
|
||||
// Read the command response, i.e., the last 16 bits received.
|
||||
// Return 0 when done, non-zero when the SSP is still busy.
|
||||
int ssp_read_response(unsigned short *res)
|
||||
{
|
||||
int r = ssp_flush();
|
||||
if (!r)
|
||||
*res = ssp_lastword;
|
||||
return r;
|
||||
}
|
||||
|
||||
// Return extended response from scratch
|
||||
|
||||
int ssp_wait(int timeout)
|
||||
{
|
||||
volatile struct ssp_job *j=&job;
|
||||
if (j->idle)
|
||||
return 92;
|
||||
while ((j->count || SSPSR&(SSPSR_RNE|SSPSR_BSY)) && timeout-->0)
|
||||
ssp_poll();
|
||||
if (j->count)
|
||||
return 93;
|
||||
return 0;
|
||||
while (ssp_busy() && timeout-->0);
|
||||
return !timeout;
|
||||
}
|
||||
|
||||
int ssp_extended_response(unsigned short *res, int size)
|
||||
const struct ssp_config ssp_conf_adc =
|
||||
{
|
||||
int r = ssp_wait(1000);
|
||||
if (r)
|
||||
return -r;
|
||||
volatile struct ssp_job *j=&job;
|
||||
if (j->buf_start != scratch)
|
||||
return -94;
|
||||
int n=0;
|
||||
unsigned short *p = j->buf_start;
|
||||
if (j->buf_ptr - j->buf_start > size)
|
||||
p = j->buf_ptr - size;
|
||||
while (p < j->buf_ptr && n++<size)
|
||||
*res++ = *p++;
|
||||
ssp_flush();
|
||||
return n;
|
||||
}
|
||||
|
||||
#ifndef DLRENA_SSP
|
||||
|
||||
// Turn on DMA streaming.
|
||||
// Turn off with ssp_flush().
|
||||
|
||||
int ssp_enable_dma(unsigned int idle, unsigned int flags, int usbspi, unsigned int size)
|
||||
.mode = SSPCR0_16bits | SSPCR0_CPHA | SSP_kHz(10000),
|
||||
.ssel = SSP_ADS8688,
|
||||
};
|
||||
const struct ssp_config ssp_conf_adc_daisy =
|
||||
{
|
||||
int r = ssp_flush();
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
void *buf = dma_reset(usbspi&1, usbspi&2);
|
||||
if (!buf)
|
||||
return 95;
|
||||
ssp_set_buffer(buf, 512);
|
||||
ssp_dma_size = size;
|
||||
|
||||
volatile struct ssp_job *j=&job;
|
||||
j->maxidlecount = 0;
|
||||
j->flags = flags;
|
||||
j->idle = idle;
|
||||
ssp_poll();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ssp_sync(unsigned short *r)
|
||||
.mode = SSPCR0_16bits | SSPCR0_CPHA | SSP_kHz(1000),
|
||||
.ssel = SSP_ADS8688 | SSP_SSEL,
|
||||
};
|
||||
const struct ssp_config ssp_conf_dac =
|
||||
{
|
||||
int e = ssp_flush();
|
||||
if (e)
|
||||
return e;
|
||||
ssp_set_buffer(0,0);
|
||||
ssp_submit(r, 1, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ssp_idle(unsigned int idle, unsigned int mic)
|
||||
.mode = SSPCR0_16bits | SSP_kHz(30000),
|
||||
.ssel = SSP_LTC2656,
|
||||
};
|
||||
const struct ssp_config ssp_conf_dac_daisy =
|
||||
{
|
||||
volatile struct ssp_job *j=&job;
|
||||
j->idle = idle;
|
||||
j->maxidlecount = mic;
|
||||
ssp_poll();
|
||||
}
|
||||
|
||||
int ssp_idle_wait(unsigned int idle, unsigned int mic)
|
||||
.mode = SSPCR0_16bits | SSP_kHz(1000),
|
||||
.ssel = SSP_LTC2656 | SSP_SSEL,
|
||||
};
|
||||
const struct ssp_config ssp_conf_bate =
|
||||
{
|
||||
volatile struct ssp_job *j=&job;
|
||||
ssp_idle(idle, mic);
|
||||
while (mic & j->idle) {
|
||||
mic--;
|
||||
ssp_poll();
|
||||
}
|
||||
if (!j->buf_count)
|
||||
return ssp_flush();
|
||||
return j->idle;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// API for injecting a stream of commands while we block during DMA
|
||||
|
||||
unsigned short ssp_injection_buffer[SSP_INJ_SIZE];
|
||||
unsigned int ssp_injection_write_ptr = 0;
|
||||
unsigned int ssp_injection_read_ptr = 0;
|
||||
|
||||
int ssp_injection_reset(unsigned int timeout)
|
||||
.mode = SSPCR0_16bits | SSP_kHz(250),
|
||||
.ssel = SSP_MS5534C,
|
||||
};
|
||||
const struct ssp_config ssp_conf_bate_ext =
|
||||
{
|
||||
volatile struct ssp_job *j=&job;
|
||||
if (ssp_injection_read_ptr)
|
||||
while (j->count) {
|
||||
if (!--timeout) {
|
||||
ssp_injection_write_ptr = ssp_injection_read_ptr;
|
||||
return 80;
|
||||
}
|
||||
ssp_poll();
|
||||
}
|
||||
ssp_injection_write_ptr = 0;
|
||||
ssp_injection_read_ptr = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ssp_injection_abort(unsigned int timeout)
|
||||
{
|
||||
volatile struct ssp_job *j=&job;
|
||||
if (ssp_injection_reset(timeout)) {
|
||||
unsigned int iflg = disable_irq(INT_DISABLE);
|
||||
j->count = 0;
|
||||
enable_irq(iflg);
|
||||
ssp_injection_write_ptr = 0;
|
||||
ssp_injection_read_ptr = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ssp_injection_write_buf(unsigned short *cmd, unsigned int csize)
|
||||
{
|
||||
if (ssp_injection_read_ptr && ssp_injection_write_ptr==ssp_injection_read_ptr)
|
||||
ssp_injection_reset(2);
|
||||
if (ssp_injection_write_ptr+csize>SSP_INJ_SIZE)
|
||||
return 81;
|
||||
while (csize--)
|
||||
ssp_injection_buffer[ssp_injection_write_ptr++] = *cmd++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ssp_injection_write(unsigned int cmd, unsigned int csize)
|
||||
{
|
||||
// return ssp_injection_write_buf((unsigned short *)&cmd, csize);
|
||||
if (ssp_injection_read_ptr && ssp_injection_write_ptr==ssp_injection_read_ptr)
|
||||
ssp_injection_reset(2);
|
||||
if (ssp_injection_write_ptr+csize>SSP_INJ_SIZE)
|
||||
return 82;
|
||||
if (csize>=1)
|
||||
ssp_injection_buffer[ssp_injection_write_ptr++] = cmd&0xffff;
|
||||
if (csize>=2)
|
||||
ssp_injection_buffer[ssp_injection_write_ptr++] = cmd>>16;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ssp_injection_write_submit(unsigned int cmd, unsigned int csize)
|
||||
{
|
||||
int e = ssp_injection_write(cmd, csize);
|
||||
if (e==82) {
|
||||
e = ssp_injection_submit(100);
|
||||
if (!e)
|
||||
e = ssp_injection_write(cmd, csize);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
int ssp_injection_submit(unsigned int timeout)
|
||||
{
|
||||
if (ssp_injection_write_ptr <= ssp_injection_read_ptr)
|
||||
return 83;
|
||||
|
||||
unsigned int csize = ssp_injection_write_ptr - ssp_injection_read_ptr;
|
||||
unsigned short *command = ssp_injection_buffer + ssp_injection_read_ptr;
|
||||
|
||||
volatile struct ssp_job *j=&job;
|
||||
|
||||
unsigned int iflg = disable_irq(INT_DISABLE);
|
||||
if (j->count && j->command + j->count == command) {
|
||||
j->count += csize;
|
||||
ssp_injection_read_ptr = ssp_injection_write_ptr;
|
||||
enable_irq(iflg);
|
||||
return 0;
|
||||
}
|
||||
enable_irq(iflg);
|
||||
|
||||
while (j->count) {
|
||||
if (!--timeout)
|
||||
return 84;
|
||||
ssp_poll();
|
||||
}
|
||||
|
||||
if (ssp_injection_read_ptr) {
|
||||
for (unsigned int i=0; i<csize; i++)
|
||||
ssp_injection_buffer[i] = ssp_injection_buffer[ssp_injection_read_ptr+i];
|
||||
ssp_injection_read_ptr = 0;
|
||||
ssp_injection_write_ptr = csize;
|
||||
command = ssp_injection_buffer;
|
||||
}
|
||||
|
||||
iflg = disable_irq(INT_DISABLE);
|
||||
j->command = command;
|
||||
j->count = csize;
|
||||
ssp_injection_read_ptr = ssp_injection_write_ptr;
|
||||
enable_irq(iflg);
|
||||
ssp_poll();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ssp_inject_command(unsigned int cmd, unsigned int csize, unsigned int timeout)
|
||||
{
|
||||
ssp_injection_reset(timeout);
|
||||
int r = ssp_injection_write(cmd, csize);
|
||||
if (!r)
|
||||
r = ssp_injection_submit(timeout);
|
||||
return r;
|
||||
}
|
||||
.mode = SSPCR0_16bits | SSP_kHz(120),
|
||||
.ssel = SSP_EXT | SSP_MCLK,
|
||||
};
|
||||
|
|
|
|||
87
ssp.h
87
ssp.h
|
|
@ -1,64 +1,49 @@
|
|||
|
||||
void ssp_init(int pclk);
|
||||
void ssp_reset(void);
|
||||
|
||||
void ssp_set_buffer(void *start, int size);
|
||||
void ssp_poll(void);
|
||||
int ssp_submit(unsigned short *cmd, int cmd_size, unsigned int idle, unsigned int compress);
|
||||
int ssp_flush(void);
|
||||
int ssp_send_command(unsigned int cmd, int read);
|
||||
int ssp_inject_command(unsigned int cmd, unsigned int csize, unsigned int timeout);
|
||||
int ssp_busy(void);
|
||||
int ssp_wait(int timeout);
|
||||
|
||||
int ssp_read_response(unsigned short *res);
|
||||
int ssp_extended_response(unsigned short *res, int size);
|
||||
int ssp_enable_dma(unsigned int idle, unsigned int flags, int usbspi, unsigned int size);
|
||||
int ssp_sync(unsigned short *r);
|
||||
void ssp_idle(unsigned int idle, unsigned int mic);
|
||||
int ssp_idle_wait(unsigned int idle, unsigned int mic);
|
||||
unsigned int ssp_get_status(void);
|
||||
extern unsigned int ssp_bits;
|
||||
extern volatile unsigned int ssp_lastword;
|
||||
extern unsigned int ssp_ssel_mask;
|
||||
extern unsigned int ssp_ssel;
|
||||
extern unsigned int ssp_read_size;
|
||||
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 unsigned int ssp_frame_count;
|
||||
extern unsigned short ssp_scratch[256];
|
||||
|
||||
extern unsigned int ssp_idleword;
|
||||
extern unsigned int ssp_lastword;
|
||||
extern unsigned int ssp_dma_size;
|
||||
extern unsigned int ssp_block_idle;
|
||||
extern unsigned int ssp_block_size;
|
||||
extern struct ssp_config {
|
||||
unsigned int ssel;
|
||||
unsigned int mode;
|
||||
} ssp_config;
|
||||
|
||||
enum ssp_flags {
|
||||
ssp_compress = 1,
|
||||
ssp_do_dma = 2,
|
||||
ssp_skipidle = 4,
|
||||
ssp_nonblock = 8,
|
||||
ssp_have_buffer = 0x100,
|
||||
ssp_do_idle = 0x200,
|
||||
ssp_do_cmd = 0x400,
|
||||
enum ssp_config_flags {
|
||||
ssp_flag_mclk = 0x01,
|
||||
};
|
||||
|
||||
#define SSP_INJ_SIZE 2048
|
||||
extern unsigned short ssp_injection_buffer[SSP_INJ_SIZE];
|
||||
extern unsigned int ssp_injection_write_ptr;
|
||||
extern unsigned int ssp_injection_read_ptr;
|
||||
int ssp_injection_reset(unsigned int timeout);
|
||||
int ssp_injection_abort(unsigned int timeout);
|
||||
int ssp_injection_write_buf(unsigned short *cmd, unsigned int csize);
|
||||
int ssp_injection_write(unsigned int cmd, unsigned int csize);
|
||||
int ssp_injection_write_submit(unsigned int cmd, unsigned int csize);
|
||||
int ssp_injection_submit(unsigned int timeout);
|
||||
void ssp_init(struct ssp_config *c);
|
||||
void ssp_deassert_ssel();
|
||||
void ssp_assert_ssel(unsigned int ssel);
|
||||
|
||||
static inline void disable_ssp_dma() { ssp_dma_size = 0; }
|
||||
#define SSP_kHz(kHz) SSPCR0_SCR(30000/(kHz))
|
||||
|
||||
// DLRENA does not do ssp dma
|
||||
#ifndef DLRENA_SSP
|
||||
#define SSP_MCLK ssp_flag_mclk
|
||||
#define SSP_LTC2656 (1<<11)
|
||||
#define SSP_ADS8688 (1<<20)
|
||||
#define SSP_EXT (1<<24)
|
||||
#define SSP_SSEL ((1<<16)|SSP_EXT)
|
||||
#define SSP_MS5534C ((1<<25)|SSP_MCLK)
|
||||
|
||||
#define ssp_idle(j) j->idle
|
||||
#define ssp_compress(j) j->compress_count
|
||||
|
||||
#else
|
||||
|
||||
#define ssp_do_dma 0
|
||||
#define ssp_do_idle 0
|
||||
#define ssp_compress 0
|
||||
#define ssp_skipidle 0
|
||||
|
||||
#define ssp_idling(j) 0
|
||||
#define ssp_compressing(j) 0
|
||||
|
||||
#endif
|
||||
extern const struct ssp_config ssp_conf_adc;
|
||||
extern const struct ssp_config ssp_conf_adc_daisy;
|
||||
extern const struct ssp_config ssp_conf_dac;
|
||||
extern const struct ssp_config ssp_conf_dac_daisy;
|
||||
extern const struct ssp_config ssp_conf_bate;
|
||||
extern const struct ssp_config ssp_conf_bate_ext;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue