Compare commits
No commits in common. "be83ec6ff75ede60f26a3137505202fb172c157f" and "93e1c3230e70b1b0f38585bf0c1c9619e0322692" have entirely different histories.
be83ec6ff7
...
93e1c3230e
6 changed files with 2 additions and 484 deletions
|
|
@ -16,10 +16,10 @@ SN_thhor = 1
|
|||
# config.c includes .eeprom `port_config`, that should go second
|
||||
# .bss: rtc, adc, flash, uart, spi, pipe
|
||||
C_FILES_thhor = config.c rtc.c adc.c flash.c uart.c cmd.c base85.c pwm.c spi.c bch4369.c pipe.c fpga.c
|
||||
S_FILES_thhor = uart_tx.S base85a.S spi_poll.S
|
||||
S_FILES_thhor = uart_tx.S base85a.S
|
||||
|
||||
MCU = $(MCU_$(PROJ))
|
||||
OPT = -Os -fverbose-asm
|
||||
OPT = -Os
|
||||
|
||||
CC=avr-gcc -Wall -Wno-parentheses -MMD -std=c99 $(OPT) \
|
||||
-mmcu=$(MCU) \
|
||||
|
|
|
|||
|
|
@ -27,10 +27,6 @@ const struct config config = {
|
|||
.pwm_min = 0x0000,
|
||||
.pwm_max = 0xffff,
|
||||
#endif
|
||||
#ifdef HAVE_FPGA
|
||||
.fpga_config_page = 1,
|
||||
.fpga_config_count = 511,
|
||||
#endif
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -23,10 +23,8 @@ struct config {
|
|||
uint16_t pwm_min;
|
||||
uint16_t pwm_max;
|
||||
#endif
|
||||
#ifdef HAVE_FPGA
|
||||
uint16_t fpga_config_page;
|
||||
uint16_t fpga_config_count;
|
||||
#endif
|
||||
};
|
||||
|
||||
enum magic_flags {
|
||||
|
|
|
|||
239
src/spi.c
239
src/spi.c
|
|
@ -15,243 +15,6 @@ struct_ioconf(spi_config) = {
|
|||
conf_io(SPI.CTRLA, SPI_MASTER_bm | SPI_ENABLE_bm | SPI_SPEED),
|
||||
};
|
||||
|
||||
#ifndef SPI_USE_IRQ
|
||||
|
||||
#ifdef SPI_POLL_C
|
||||
|
||||
static
|
||||
uint8_t spi_poll_delay()
|
||||
{
|
||||
uint8_t t = 0xff;
|
||||
uint8_t ifg;
|
||||
do {
|
||||
ifg = SPI.INTFLAGS & SPI_RXCIF_bm;
|
||||
} while (~ifg && t--);
|
||||
return ifg;
|
||||
}
|
||||
|
||||
static
|
||||
void spi_poll_drop_tail()
|
||||
{
|
||||
uint8_t ifg;
|
||||
do {
|
||||
ifg = SPI.INTFLAGS;
|
||||
SPI.DATA;
|
||||
} while (~ifg & SPI_TXCIF_bm);
|
||||
spi_poll_delay();
|
||||
SPI.DATA;
|
||||
}
|
||||
|
||||
static
|
||||
void spi_poll_write_drop(uint8_t n, const uint8_t *c)
|
||||
{
|
||||
do {
|
||||
uint8_t ifg = SPI.INTFLAGS;
|
||||
if (ifg & SPI_DREIF_bm) {
|
||||
SPI.DATA = *c++;
|
||||
SPI.INTFLAGS = SPI_TXCIF_bm;
|
||||
n--;
|
||||
}
|
||||
SPI.DATA;
|
||||
} while (n);
|
||||
spi_poll_drop_tail();
|
||||
}
|
||||
|
||||
static
|
||||
void spi_poll_zero_drop(uint8_t n)
|
||||
{
|
||||
uint8_t z = spi.zero;
|
||||
do {
|
||||
uint8_t ifg = SPI.INTFLAGS;
|
||||
if (ifg & SPI_DREIF_bm) {
|
||||
SPI.DATA = z;
|
||||
SPI.INTFLAGS = SPI_TXCIF_bm;
|
||||
n--;
|
||||
}
|
||||
SPI.DATA;
|
||||
} while (n);
|
||||
spi_poll_drop_tail();
|
||||
}
|
||||
|
||||
static
|
||||
uint8_t spi_poll_drop(uint8_t n, const uint8_t *c)
|
||||
{
|
||||
if (c)
|
||||
spi_poll_write_drop(n, c);
|
||||
else
|
||||
spi_poll_zero_drop(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
static
|
||||
void spi_poll_read_tail(uint8_t r, uint8_t *d)
|
||||
{
|
||||
uint8_t ifg;
|
||||
do {
|
||||
ifg = SPI.INTFLAGS;
|
||||
if (ifg & SPI_RXCIF_bm) {
|
||||
*d++ = SPI.DATA;
|
||||
if (!--r)
|
||||
goto done;
|
||||
}
|
||||
} while (~ifg & SPI_TXCIF_bm);
|
||||
|
||||
if (spi_poll_delay()) {
|
||||
*d = SPI.DATA;
|
||||
r--;
|
||||
}
|
||||
done:
|
||||
spi.rdata = d;
|
||||
spi.rsize = r;
|
||||
}
|
||||
|
||||
static
|
||||
uint8_t spi_poll_write_read(uint8_t n, const uint8_t *c)
|
||||
{
|
||||
uint8_t r = spi.rsize;
|
||||
uint8_t *d = spi.rdata;
|
||||
uint8_t w = n;
|
||||
do {
|
||||
uint8_t ifg = SPI.INTFLAGS;
|
||||
if (ifg & SPI_DREIF_bm) {
|
||||
SPI.DATA = *c++;
|
||||
SPI.INTFLAGS = SPI_TXCIF_bm;
|
||||
if (!--n) {
|
||||
spi_poll_read_tail(r, d);
|
||||
return w;
|
||||
}
|
||||
}
|
||||
if (ifg & SPI_RXCIF_bm) {
|
||||
*d++ = SPI.DATA;
|
||||
r--;
|
||||
}
|
||||
} while(r);
|
||||
spi.rdata = d;
|
||||
spi.rsize = r;
|
||||
return w-n;
|
||||
}
|
||||
|
||||
static
|
||||
uint8_t spi_poll_read(uint8_t n, uint8_t r, uint8_t *d)
|
||||
{
|
||||
uint8_t z = spi.zero;
|
||||
uint8_t w = n;
|
||||
do {
|
||||
uint8_t ifg = SPI.INTFLAGS;
|
||||
if (ifg & SPI_DREIF_bm) {
|
||||
SPI.DATA = z;
|
||||
SPI.INTFLAGS = SPI_TXCIF_bm;
|
||||
if (!--n) {
|
||||
spi_poll_read_tail(r, d);
|
||||
return w;
|
||||
}
|
||||
}
|
||||
if (ifg & SPI_RXCIF_bm) {
|
||||
*d++ = SPI.DATA;
|
||||
r--;
|
||||
}
|
||||
} while(r);
|
||||
spi.rdata = d;
|
||||
spi.rsize = r;
|
||||
return w-n;
|
||||
}
|
||||
|
||||
static
|
||||
uint8_t spi_poll_wait(uint8_t n)
|
||||
{
|
||||
uint8_t r = spi.rsize;
|
||||
uint8_t *d = spi.rdata;
|
||||
uint8_t z = spi.zero;
|
||||
uint8_t w = n;
|
||||
do {
|
||||
uint8_t ifg = SPI.INTFLAGS;
|
||||
if (ifg & SPI_DREIF_bm) {
|
||||
SPI.DATA = z;
|
||||
SPI.INTFLAGS = SPI_TXCIF_bm;
|
||||
if (!--n) {
|
||||
spi_poll_read_tail(r, d);
|
||||
return w;
|
||||
}
|
||||
}
|
||||
if (ifg & SPI_RXCIF_bm) {
|
||||
uint8_t b = SPI.DATA;
|
||||
if ((b & spi.mask) == spi.wait) {
|
||||
*d++ = SPI.DATA;
|
||||
r--;
|
||||
spi.mask = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
n++;
|
||||
}
|
||||
} while (1);
|
||||
if (r)
|
||||
return w - n + spi_poll_read(n, r, d);
|
||||
spi.rdata = d;
|
||||
spi.rsize = r;
|
||||
return w-n;
|
||||
}
|
||||
|
||||
static
|
||||
uint8_t spi_poll_write(uint8_t n, const uint8_t *c)
|
||||
{
|
||||
uint8_t i = spi.isize;
|
||||
uint8_t r = spi.rsize;
|
||||
uint8_t w =0;
|
||||
while (n) {
|
||||
if (!r)
|
||||
i = n;
|
||||
if (i) {
|
||||
if (i < n) {
|
||||
uint8_t ww = spi_poll_drop(i, c);
|
||||
w += ww;
|
||||
c += ww;
|
||||
n -= ww;
|
||||
spi.isize = i = 0;
|
||||
continue;
|
||||
}
|
||||
spi.isize = i -= n;
|
||||
uint8_t ww = spi_poll_drop(n, c);
|
||||
w += ww;
|
||||
return w;
|
||||
}
|
||||
if (c)
|
||||
w += spi_poll_write_read(n, c);
|
||||
else if (spi.mask)
|
||||
w += spi_poll_wait(n);
|
||||
else
|
||||
w += spi_poll_read(n, r, spi.rdata);
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
uint8_t spi_poll()
|
||||
{
|
||||
uint8_t n;
|
||||
n = spi_poll_write(spi.csize, spi.cmd);
|
||||
spi.cmd += n;
|
||||
spi.csize -= n;
|
||||
n = spi_poll_write(spi.zsize, 0);
|
||||
spi.zsize -= n;
|
||||
n = spi_poll_write(spi.wsize, spi.wdata);
|
||||
spi.wdata += n;
|
||||
spi.wsize -= n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // SPI_POLL_C
|
||||
|
||||
#else // SPI_USE_IRQ
|
||||
|
||||
/****************************************************
|
||||
|
||||
The SPI is way to fast for this CPU, the job is done
|
||||
in a single IRQ invocation.
|
||||
|
||||
Running the SPI synchronously allows other Interrupts
|
||||
to happen.
|
||||
****************************************************/
|
||||
|
||||
#if 0
|
||||
ISR(SPI0_INT_vect)
|
||||
{
|
||||
|
|
@ -464,8 +227,6 @@ ISR(SPI0_INT_vect, ISR_NAKED)
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif // SPI_USE_IRQ
|
||||
|
||||
uint8_t spi_select(uint8_t mode)
|
||||
{
|
||||
uint8_t s = spi_busy_p();
|
||||
|
|
|
|||
33
src/spi.h
33
src/spi.h
|
|
@ -33,37 +33,6 @@ enum spi_mode_bits {
|
|||
SPI_CONT = 0x80,
|
||||
};
|
||||
|
||||
#define SPI_USE_IRQ
|
||||
|
||||
#ifndef SPI_USE_IRQ
|
||||
|
||||
#ifdef SPI_POLL_C
|
||||
uint8_t spi_poll();
|
||||
#else
|
||||
uint8_t _spi_poll();
|
||||
#define spi_poll _spi_poll
|
||||
#endif
|
||||
|
||||
static inline
|
||||
uint8_t spi_abort()
|
||||
{
|
||||
return spi_poll();
|
||||
}
|
||||
|
||||
static inline
|
||||
uint8_t spi_busy_p()
|
||||
{
|
||||
return spi_poll();
|
||||
}
|
||||
|
||||
static inline
|
||||
void spi_start()
|
||||
{
|
||||
spi_poll();
|
||||
}
|
||||
|
||||
#else // SPI_USE_IRQ
|
||||
|
||||
static inline
|
||||
uint8_t spi_abort()
|
||||
{
|
||||
|
|
@ -86,8 +55,6 @@ void spi_start()
|
|||
SPI.INTCTRL = SPI_DREIF_bm | SPI_TXCIF_bm| SPI_RXCIF_bm;
|
||||
}
|
||||
|
||||
#endif // SPI_USE_IRQ
|
||||
|
||||
static inline void barrier() { __asm__("":::"memory"); }
|
||||
void init_spi(uint8_t spi_div);
|
||||
uint8_t spi_select(uint8_t mode);
|
||||
|
|
|
|||
204
src/spi_poll.S
204
src/spi_poll.S
|
|
@ -1,204 +0,0 @@
|
|||
#include <avr/io.h>
|
||||
#define INTFLAGS SPI0_INTFLAGS
|
||||
#define DATA SPI0_DATA
|
||||
#define RXC SPI_RXCIF_bp
|
||||
#define TXC SPI_TXCIF_bp
|
||||
#define DRE SPI_DREIF_bp
|
||||
#define csize Y+1
|
||||
#define zsize Y+2
|
||||
#define isize Y+3
|
||||
#define zero Y+4
|
||||
#define wait Y+5
|
||||
#define mask Y+6
|
||||
#define rsize Y+7
|
||||
#define wsize Y+8
|
||||
#define cmd Y+9
|
||||
#define rdata Y+11
|
||||
#define wdata Y+13
|
||||
|
||||
.global _spi_poll
|
||||
|
||||
_spi_poll:
|
||||
push r28
|
||||
push r29
|
||||
ldi r28, lo8(spi)
|
||||
ldi r29, hi8(spi)
|
||||
ldd r18, mask
|
||||
; r19, wait, …
|
||||
ldd r20, isize
|
||||
ldd r21, zero
|
||||
ldd r22, rsize
|
||||
ldi r23, 1<<TXC
|
||||
; r24, [czw]size
|
||||
; r25, INTFLAG
|
||||
; X, [cw]data
|
||||
ldd r30, rdata
|
||||
ldd r31, rdata+1
|
||||
|
||||
ldd r24, csize
|
||||
tst r24
|
||||
breq 1f
|
||||
ldd r26, cmd
|
||||
ldd r27, cmd+1
|
||||
rcall _write
|
||||
std csize, r24
|
||||
std cmd, r26
|
||||
std cmd+1, r27
|
||||
1: ldd r24, zsize
|
||||
tst r24
|
||||
breq 1f
|
||||
mov r26, r1
|
||||
mov r27, r1
|
||||
rcall _write
|
||||
std zsize, r24
|
||||
1: ldd r24, wsize
|
||||
tst r24
|
||||
breq 1f
|
||||
ldd r26, wdata
|
||||
ldd r27, wdata+1
|
||||
rcall _write
|
||||
std wsize, r24
|
||||
std wdata, r26
|
||||
std wdata+1, r27
|
||||
1: std isize, r21
|
||||
std rsize, r22
|
||||
std rdata, r30
|
||||
std rdata+1, r31
|
||||
mov r24, 0
|
||||
pop r29
|
||||
pop r28
|
||||
ret
|
||||
|
||||
_write_read:
|
||||
lds r25, INTFLAGS
|
||||
sbrs r25, DRE
|
||||
rjmp 1f
|
||||
ld r0, X+
|
||||
sts DATA, r0
|
||||
sts INTFLAGS, r23
|
||||
subi r24, 1
|
||||
breq _read_tail
|
||||
sbrs r25, RXC
|
||||
rjmp _write_read
|
||||
lds r0, DATA
|
||||
st Z+, r0
|
||||
subi r22, 1
|
||||
brne _write_read
|
||||
rjmp _write_drop
|
||||
|
||||
_read_tail:
|
||||
lds r25, INTFLAGS
|
||||
sbrs r25, RXC
|
||||
rjmp 1f
|
||||
lds r0, DATA
|
||||
st Z+, r0
|
||||
subi r22, 1
|
||||
breq 9f
|
||||
1: sbrs r25, TXC
|
||||
rjmp _read_tail
|
||||
rcall _delay
|
||||
sbrs r25, RXC
|
||||
rjmp 9f
|
||||
lds r0, DATA
|
||||
st Z+, r0
|
||||
subi r22, 1
|
||||
9: ret
|
||||
|
||||
_w1: mov r20, r24 ; no rsize, i=n
|
||||
_w2: sub r20, r24 ; isize = i-n
|
||||
brcc _drop
|
||||
add r24, r20 ; n = n + (i-n) = i
|
||||
neg r20 ; next n = n-i
|
||||
push r20
|
||||
mov r20, r1 ; i = 0
|
||||
rcall _drop
|
||||
pop r24
|
||||
_write:
|
||||
tst r22
|
||||
breq _w1
|
||||
tst r20
|
||||
brne _w2
|
||||
mov r0, r26
|
||||
or r0, r27
|
||||
brne _write_read
|
||||
_zero_read:
|
||||
lds r25, INTFLAGS
|
||||
sbrs r25, DRE
|
||||
rjmp 1f
|
||||
sts DATA, r21
|
||||
sts INTFLAGS, r23
|
||||
subi r24, 1
|
||||
breq _read_tail
|
||||
1: sbrs r25, RXC
|
||||
rjmp _zero_read
|
||||
lds r0, DATA
|
||||
_zr: st Z+, r0
|
||||
subi r22, 1
|
||||
brne _zero_read
|
||||
9: ret
|
||||
|
||||
_zero_wait:
|
||||
lds r25, INTFLAGS
|
||||
sbrs r25, DRE
|
||||
rjmp 1f
|
||||
sts DATA, r21
|
||||
sts INTFLAGS, r23
|
||||
subi r24, 1
|
||||
breq _read_tail
|
||||
1: sbrs r25, RXC
|
||||
rjmp _zero_wait
|
||||
subi r24, -1
|
||||
lds r0, DATA
|
||||
ldd r19, wait
|
||||
eor r19, r0
|
||||
and r19, r18
|
||||
brne _zero_wait
|
||||
subi r24, 1
|
||||
rjmp _zr
|
||||
|
||||
_drop:
|
||||
mov r0, r26
|
||||
or r0, r27
|
||||
brne _write_drop
|
||||
tst r18
|
||||
brne _zero_wait
|
||||
_zero_drop:
|
||||
lds r25, INTFLAGS
|
||||
lds r0, DATA
|
||||
sbrs r25, DRE
|
||||
rjmp _zero_drop
|
||||
sts DATA, r21
|
||||
sts INTFLAGS, r23
|
||||
subi r24, 1
|
||||
brne _zero_drop
|
||||
rjmp _drop_tail
|
||||
|
||||
_write_drop:
|
||||
lds r25, INTFLAGS
|
||||
lds r0, DATA
|
||||
sbrs r25, DRE
|
||||
rjmp _write_drop
|
||||
ld r0, X+
|
||||
sts DATA, r0
|
||||
sts INTFLAGS, r23
|
||||
subi r24, 1
|
||||
brne _write_drop
|
||||
_drop_tail:
|
||||
lds r25, INTFLAGS
|
||||
lds r0, DATA
|
||||
sbrs r25, TXC
|
||||
rjmp _drop_tail
|
||||
rcall _delay
|
||||
lds r0, DATA
|
||||
9: ret
|
||||
|
||||
_delay:
|
||||
ldi r19, 0xff
|
||||
1: lds r25, INTFLAGS
|
||||
sbrc r25, RXC
|
||||
ret
|
||||
subi r19, 1
|
||||
brcc 1b
|
||||
9: ret
|
||||
|
||||
_spi_poll_end:
|
||||
Loading…
Add table
Add a link
Reference in a new issue