Compare commits

..

No commits in common. "be83ec6ff75ede60f26a3137505202fb172c157f" and "93e1c3230e70b1b0f38585bf0c1c9619e0322692" have entirely different histories.

6 changed files with 2 additions and 484 deletions

View file

@ -16,10 +16,10 @@ SN_thhor = 1
# config.c includes .eeprom `port_config`, that should go second # config.c includes .eeprom `port_config`, that should go second
# .bss: rtc, adc, flash, uart, spi, pipe # .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 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)) MCU = $(MCU_$(PROJ))
OPT = -Os -fverbose-asm OPT = -Os
CC=avr-gcc -Wall -Wno-parentheses -MMD -std=c99 $(OPT) \ CC=avr-gcc -Wall -Wno-parentheses -MMD -std=c99 $(OPT) \
-mmcu=$(MCU) \ -mmcu=$(MCU) \

View file

@ -27,10 +27,6 @@ const struct config config = {
.pwm_min = 0x0000, .pwm_min = 0x0000,
.pwm_max = 0xffff, .pwm_max = 0xffff,
#endif #endif
#ifdef HAVE_FPGA
.fpga_config_page = 1,
.fpga_config_count = 511,
#endif
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View file

@ -23,10 +23,8 @@ struct config {
uint16_t pwm_min; uint16_t pwm_min;
uint16_t pwm_max; uint16_t pwm_max;
#endif #endif
#ifdef HAVE_FPGA
uint16_t fpga_config_page; uint16_t fpga_config_page;
uint16_t fpga_config_count; uint16_t fpga_config_count;
#endif
}; };
enum magic_flags { enum magic_flags {

239
src/spi.c
View file

@ -15,243 +15,6 @@ struct_ioconf(spi_config) = {
conf_io(SPI.CTRLA, SPI_MASTER_bm | SPI_ENABLE_bm | SPI_SPEED), 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 #if 0
ISR(SPI0_INT_vect) ISR(SPI0_INT_vect)
{ {
@ -464,8 +227,6 @@ ISR(SPI0_INT_vect, ISR_NAKED)
} }
#endif #endif
#endif // SPI_USE_IRQ
uint8_t spi_select(uint8_t mode) uint8_t spi_select(uint8_t mode)
{ {
uint8_t s = spi_busy_p(); uint8_t s = spi_busy_p();

View file

@ -33,37 +33,6 @@ enum spi_mode_bits {
SPI_CONT = 0x80, 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 static inline
uint8_t spi_abort() uint8_t spi_abort()
{ {
@ -86,8 +55,6 @@ void spi_start()
SPI.INTCTRL = SPI_DREIF_bm | SPI_TXCIF_bm| SPI_RXCIF_bm; SPI.INTCTRL = SPI_DREIF_bm | SPI_TXCIF_bm| SPI_RXCIF_bm;
} }
#endif // SPI_USE_IRQ
static inline void barrier() { __asm__("":::"memory"); } static inline void barrier() { __asm__("":::"memory"); }
void init_spi(uint8_t spi_div); void init_spi(uint8_t spi_div);
uint8_t spi_select(uint8_t mode); uint8_t spi_select(uint8_t mode);

View file

@ -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: