Compare commits

...

3 commits

Author SHA1 Message Date
Stephan I. Böttcher
e979101398 spi_slave: fixes 2025-10-22 11:45:38 +02:00
Stephan I. Böttcher
58b56f20bf leia: c isrs, for initial tests 2025-10-22 11:45:16 +02:00
Stephan I. Böttcher
e890a58340 .gitignore docs 2025-10-22 11:44:23 +02:00
3 changed files with 48 additions and 61 deletions

1
.gitignore vendored
View file

@ -6,3 +6,4 @@
*.o
revision.h*
*~
docs

View file

@ -6,7 +6,7 @@
// PCINT2: disable interrupts when SSEL toggles. Allows the SPI to work undisturbed.
// TIMER1: Motor step period, 23µs resolution, 1.5s range
// OCR1A: interrupt: assert STEP
// OCR2B: interrupt: deassert STEP, RESET
// OCR1B: interrupt: deassert STEP, RESET
// ADC: Three NTCs ADC8,9,10, Iprim ADC3, internals.
// Interrupt stores conversionresults and advances channels.
// DAC: Motor current reference.
@ -99,12 +99,12 @@ const struct conf runcon = {
.period = STEP_NS(100000000),
.slen = STEP_NS(25000),
.lmask = LIMIT1 | LIMIT2 | FAULT1 | FAULT2,
.lval = LIMIT1 | LIMIT2 | FAULT1 | FAULT2,
.lval = FAULT1 | FAULT2,
.enable = SLEEP | RESET,
.reset = RESET,
.adc_ch = {3, 8, 9, 10, 11+0x80, 12+0x80, 17, 18,},
.adc_ch = {0, 3, 8, 9, 10, 11+0x80, 12+0x80, 17, 18,},
.adc_incr = 8, // two conversions per channel
.adc_period = TICK_NS(1000),
.adc_period = TICK_NS(1000000),
.dac_step = 0x20,
};
@ -149,7 +149,7 @@ char stepper_status()
return TIMSK1;
}
#if 0
#if 1
ISR(TIMER1_COMPA_vect)
{
if (!conf.n_steps || (LIMIT_PORT & conf.lmask) != conf.lval) {
@ -209,7 +209,7 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED)
}
#endif
#if 0
#if 1
ISR(TIMER1_COMPB_vect)
{
STEP_PORT = 0;
@ -229,7 +229,7 @@ ISR(TIMER1_COMPB_vect, ISR_NAKED)
"out %[IFR], r24" "\n\t"
"sts %[MSK], r24" "\n\t"
"pop r24" "\n\t"
"reti" "\n\t"
"reti" "\n\t"
:
:[MSK] "n" (_SFR_MEM_ADDR(TIMSK1)),
[IFR] "n" (_SFR_IO_ADDR(TIFR1)),
@ -241,7 +241,7 @@ ISR(TIMER1_COMPB_vect, ISR_NAKED)
}
#endif
#if 0
#if 1
ISR(TIMER0_COMPB_vect)
{
uint16_t d = conf.dac;
@ -382,7 +382,7 @@ void adc_stop()
uint16_t adc[16];
#if 0
#if 1
ISR(ADC_vect)
{
uint16_t a = ADCL | ADMUX & 0x1f | (ADMUX>>(REFS1-5)) & 0x20;
@ -490,7 +490,7 @@ static void conf_init()
uint8_t eewr_n; // number of bytes to write
uint16_t eewr_a; // EEPROM conf base address
#if 0
#if 1
ISR(EE_READY_vect)
{
uint8_t n = eewr_n;

View file

@ -3,6 +3,12 @@
#include <avr/interrupt.h>
#define SPSR_IF (1<<SPIF)
#ifndef PIN_SSEL
// ATmega32M1
# define PIN_SSEL (PIND & 8)
# define PCIF_SSEL 4
#endif
static inline void spi_slave_init()
{
SPCR = (1<<SPE)|(0<<CPOL)|(0<<CPHA);
@ -27,30 +33,14 @@ static inline char spi_slave_Rx_n(unsigned char d[], unsigned char n)
b = SPDR;
} while (b&0x80);
*d++ = b;
unsigned char s = 0;
while (--n) {
while (!(SPSR & SPSR_IF));
SPDR = 0xff;
*d++ = SPDR;
}
return 0;
}
static inline char spi_slave_Rx_cli(unsigned char d[], unsigned char n)
{
SPSR;
SPDR;
register unsigned char b;
do {
while (!(SPSR & SPSR_IF))
if (!(PIND & 8))
cli();
SPDR = 0xff;
b = SPDR;
} while (b&0x80);
cli();
*d++ = b;
while (--n) {
while (!(SPSR & SPSR_IF));
if (PIN_SSEL) {
if (s)
return n;
s = n;
}
SPDR = 0xff;
*d++ = SPDR;
}
@ -70,8 +60,14 @@ static inline char spi_slave_Rx_wdt(unsigned char d[], unsigned char n)
b = SPDR;
} while (b&0x80);
*d++ = b;
unsigned char s=0;
while (--n) {
while (!(SPSR & SPSR_IF));
while (!(SPSR & SPSR_IF))
if (PIN_SSEL) {
if (s)
return n;
s = n;
}
SPDR = 0xff;
*d++ = SPDR;
}
@ -79,24 +75,30 @@ static inline char spi_slave_Rx_wdt(unsigned char d[], unsigned char n)
}
#define spi_slave_Tx spi_slave_Tx_n
static inline void spi_slave_Tx_n(const unsigned char d[], unsigned char n)
static inline
unsigned char spi_slave_Tx_n(const unsigned char d[], unsigned char n)
{
SPSR;
SPDR;
while (n) {
register unsigned char b = *d++;
while (!(SPSR & SPSR_IF));
while (!(SPSR & SPSR_IF))
if (PIN_SSEL)
return n;
SPDR = b;
n--;
}
return n;
}
static inline void int2frame(unsigned int i, unsigned char *f)
static inline
void int2frame(unsigned int i, unsigned char *f)
{
f[0] = i;
f[1] = i>>8;
}
static inline unsigned int frame2int(const unsigned char *f)
static inline
unsigned int frame2int(const unsigned char *f)
{
return f[1]<<8 | f[0];
}
@ -108,8 +110,8 @@ static inline
void spi_busy_init()
{
PCMSK2 |= 8; // PIND3 PCINT19
while (!(PIND & 8));
PCIFR = 4;
while (!PIN_SSEL);
PCIFR |= PCIF_SSEL;
}
static inline
@ -132,12 +134,8 @@ void clear_spi_busy(const char *busy_msg)
#ifdef SPI_Rx_SEI
#ifndef PIN_SSEL
// ATmega32M1
# define PIN_SSEL (PIND & 8)
# define PCIF_SSEL 4
// TODO: avoid output in a header file?
ISR(PCINT2_vect, ISR_NAKED)
@ -153,7 +151,6 @@ void spi_slave_init_sei()
PCMSK2 |= 8;
PCICR |= PCIF_SSEL;
}
#endif
#undef spi_slave_Rx
#define spi_slave_Rx spi_slave_Rx_sei
@ -162,13 +159,11 @@ char spi_slave_Rx_sei(unsigned char d[], unsigned char n)
{
if (!PIN_SSEL)
return 1;
if (PCIFR & PCIF_SSEL)
return 1;
PCIFR = PCIF_SSEL;
PCIFR |= PCIF_SSEL;
sei();
spi_slave_Rx_n(d, n);
n = spi_slave_Rx_n(d, n);
cli();
return 0;
return n;
}
#undef spi_slave_Tx
@ -176,20 +171,11 @@ char spi_slave_Rx_sei(unsigned char d[], unsigned char n)
static inline
char spi_slave_Tx_sei(const unsigned char d[], unsigned char n)
{
SPSR;
SPDR;
while (n) {
register unsigned char b = *d++;
while (!(SPSR & SPSR_IF))
if (!PIN_SSEL)
return 1;
SPDR = b;
n--;
}
n = spi_slave_Tx_n(d, n);
while (!PIN_SSEL);
PCIFR = PCIF_SSEL;
PCIFR |= PCIF_SSEL;
sei();
return 0;
return n;
}
#endif