Compare commits

...

4 commits

Author SHA1 Message Date
Stephan I. Böttcher
b57552a3e7 leia: 'V' 2025-10-22 20:39:22 +02:00
Stephan I. Böttcher
7de7b3a732 spi_slave: sleep 2025-10-22 20:38:29 +02:00
Stephan I. Böttcher
27bbff81b3 leia: "zW" for eeprom write 2025-10-22 19:10:07 +02:00
Stephan I. Böttcher
6e8a9325e7 leia: add EEPROM write counter 2025-10-22 18:56:23 +02:00
2 changed files with 91 additions and 24 deletions

View file

@ -27,7 +27,7 @@ const char revision[] = Id;
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <avr/sleep.h> #include <avr/sleep.h>
#define SPI_Rx_SEI #define SPI_Rx_SLEEP
#include "spi_slave.h" #include "spi_slave.h"
#define upcase(c) (!((c)&0x20)) #define upcase(c) (!((c)&0x20))
@ -80,7 +80,6 @@ struct conf {
uint8_t adc_period; // 24 uint8_t adc_period; // 24
uint8_t pad[7]; // 25 uint8_t pad[7]; // 25
uint8_t adc_ch[16]; // 32 uint8_t adc_ch[16]; // 32
uint8_t tail[16]; // 48
} conf; // 64 } conf; // 64
enum { enum {
@ -570,6 +569,7 @@ ISR(EE_READY_vect)
EEDR = d; EEDR = d;
EECR |= 1<<EEMWE; EECR |= 1<<EEMWE;
EECR |= 1<<EEWE; EECR |= 1<<EEWE;
GPIOR2++;
return; return;
} }
EECR &=~ (1<<EERIE); // clear EERIE EECR &=~ (1<<EERIE); // clear EERIE
@ -611,7 +611,10 @@ ISR(EE_READY_vect, ISR_NAKED)
"sbi %[C], %[IE]" "\n\t" "sbi %[C], %[IE]" "\n\t"
"out %[D], r30" "\n\t" "out %[D], r30" "\n\t"
"sbi %[C], %[MWE]" "\n\t" "sbi %[C], %[MWE]" "\n\t"
"sbi %[C], %[WE]" "\n" "sbi %[C], %[WE]" "\n\t"
"in r30, %[CC]" "\n\t"
"subi r30, -1" "\n\t"
"out %[CC], r30" "\n\t"
"2:" "\n\t" "2:" "\n\t"
"sts eewr_n, r24" "\n\t" "sts eewr_n, r24" "\n\t"
"pop r31" "\n\t" "pop r31" "\n\t"
@ -625,12 +628,12 @@ ISR(EE_READY_vect, ISR_NAKED)
[AL] "n" (_SFR_IO_ADDR(EEARL)), [AL] "n" (_SFR_IO_ADDR(EEARL)),
[AH] "n" (_SFR_IO_ADDR(EEARH)), [AH] "n" (_SFR_IO_ADDR(EEARH)),
[D] "n" (_SFR_IO_ADDR(EEDR)), [D] "n" (_SFR_IO_ADDR(EEDR)),
[CC] "n" (_SFR_IO_ADDR(GPIOR2)),
[IE] "n" (EERIE), [IE] "n" (EERIE),
[RE] "n" (EERE), [RE] "n" (EERE),
[WE] "n" (EEWE), [WE] "n" (EEWE),
[MWE] "n" (EEMWE) [MWE] "n" (EEMWE)
); );
} }
#endif #endif
@ -643,6 +646,7 @@ uint8_t eeprom_save(uint16_t a)
return 1; return 1;
eewr_a = a; eewr_a = a;
eewr_n = sizeof(conf); eewr_n = sizeof(conf);
GPIOR2 = 0;
EECR = 1<<EERIE; EECR = 1<<EERIE;
return 0; return 0;
} }
@ -807,18 +811,15 @@ void reg88(uint8_t *v1, uint8_t *v2, unsigned char *r, const unsigned char *c)
int main() int main()
{ {
MCUSR = 0; MCUSR = 0;
// turn of unused IO modules
PRR = (1<<PRPSC)|(1<<PRCAN)|(1<<PRLIN); PRR = (1<<PRPSC)|(1<<PRCAN)|(1<<PRLIN);
spi_slave_init_sei(); spi_slave_init_sleep();
DDRB = MISO; DDRB = MISO;
eeprom_load(0); eeprom_load(0);
adc_init(); adc_init();
if (conf.magic == MAGIC && conf.version == VERSION)
if (conf.magic == MAGIC && conf.version == VERSION) {
conf_init(); conf_init();
}
while (1) { while (1) {
unsigned char cmd[3]; unsigned char cmd[3];
unsigned char resp[3]; unsigned char resp[3];
@ -893,11 +894,20 @@ int main()
else else
adc_stop(); adc_stop();
break; break;
case 'V':
resp[1] = 0;
resp[2] = cmd[1];
while (revision[resp[1]] && resp[2]) {
resp[1]++;
resp[2]--;
}
resp[1] = revision[resp[1]];
break;
case 'z': // Load/Save conf case 'z': // Load/Save conf
resp[1] = cmd[1]; resp[1] = cmd[1];
resp[2] = sizeof(conf); resp[2] = sizeof(conf);
if (!up) { if (!up) {
if (eeprom_save(cmd[2]*4)) { if (cmd[1]!='W' || eeprom_save(cmd[2]*4)) {
resp[0] = 'E'; resp[0] = 'E';
resp[1] = 'W'; resp[1] = 'W';
resp[2] = 'Y'; resp[2] = 'Y';

View file

@ -9,23 +9,30 @@
# define PCIF_SSEL 4 # define PCIF_SSEL 4
#endif #endif
static inline void spi_slave_init() static inline
void spi_slave_init()
{ {
SPCR = (1<<SPE)|(0<<CPOL)|(0<<CPHA); SPCR = (1<<SPE)|(0<<CPOL)|(0<<CPHA);
SPSR; SPSR;
SPDR; SPDR;
} }
static inline unsigned char spi_slave_Rx_status() static inline
unsigned char spi_slave_Rx_status()
{ {
return SPSR & SPSR_IF && !(SPDR & 0x80); return SPSR & SPSR_IF && !(SPDR & 0x80);
} }
#define spi_slave_Rx spi_slave_Rx_n #define spi_slave_Rx spi_slave_Rx_n
static inline char spi_slave_Rx_n(unsigned char d[], unsigned char n) static inline
unsigned char spi_slave_Rx_n(unsigned char d[], unsigned char n)
{ {
SPSR; d[0] = 0xff;
SPDR; if (SPSR & SPSR_IF) {
SPSR;
SPDR;
return n;
}
register unsigned char b; register unsigned char b;
do { do {
while (!(SPSR & SPSR_IF)); while (!(SPSR & SPSR_IF));
@ -48,7 +55,8 @@ static inline char spi_slave_Rx_n(unsigned char d[], unsigned char n)
} }
extern volatile unsigned char wdt_tick; extern volatile unsigned char wdt_tick;
static inline char spi_slave_Rx_wdt(unsigned char d[], unsigned char n) static inline
unsigned char spi_slave_Rx_wdt(unsigned char d[], unsigned char n)
{ {
SPSR; SPSR;
SPDR; SPDR;
@ -132,6 +140,10 @@ void clear_spi_busy(const char *busy_msg)
spi_was_busy = 0; spi_was_busy = 0;
} }
#ifdef SPI_Rx_SLEEP
# define SPI_Rx_SEI
#endif
#ifdef SPI_Rx_SEI #ifdef SPI_Rx_SEI
// ATmega32M1 // ATmega32M1
@ -147,15 +159,19 @@ ISR(PCINT2_vect, ISR_NAKED)
static inline static inline
void spi_slave_init_sei() void spi_slave_init_sei()
{ {
spi_slave_init();
PCMSK2 |= 8; PCMSK2 |= 8;
PCICR |= PCIF_SSEL; PCICR |= PCIF_SSEL;
spi_slave_init();
} }
#undef spi_slave_Rx # undef spi_slave_Rx
#define spi_slave_Rx spi_slave_Rx_sei # define spi_slave_Rx spi_slave_Rx_sei
# undef spi_slave_Tx
# define spi_slave_Tx spi_slave_Tx_sei
static inline static inline
char spi_slave_Rx_sei(unsigned char d[], unsigned char n) unsigned char spi_slave_Rx_sei(unsigned char d[], unsigned char n)
{ {
if (!PIN_SSEL) if (!PIN_SSEL)
return 1; return 1;
@ -166,10 +182,8 @@ char spi_slave_Rx_sei(unsigned char d[], unsigned char n)
return n; return n;
} }
#undef spi_slave_Tx
#define spi_slave_Tx spi_slave_Tx_sei
static inline static inline
char spi_slave_Tx_sei(const unsigned char d[], unsigned char n) unsigned char spi_slave_Tx_sei(const unsigned char d[], unsigned char n)
{ {
n = spi_slave_Tx_n(d, n); n = spi_slave_Tx_n(d, n);
while (!PIN_SSEL); while (!PIN_SSEL);
@ -179,3 +193,46 @@ char spi_slave_Tx_sei(const unsigned char d[], unsigned char n)
} }
#endif #endif
#ifdef SPI_Rx_SLEEP
#include <avr/sleep.h>
static inline
void spi_slave_init_sleep()
{
SMCR = 1<<SE | 0<<SM0;
spi_slave_init_sei();
}
# undef spi_slave_Rx
# define spi_slave_Rx spi_slave_Rx_sleep
static inline
unsigned char spi_slave_Rx_sleep(unsigned char d[], unsigned char n)
{
cli();
if (!PIN_SSEL) {
while (!PIN_SSEL) {
if (SPSR & SPSR_IF) {
SPSR;
SPDR;
}
sei();
sleep_cpu();
cli();
}
d[0] = 0xff;
return n;
}
SPSR;
SPDR;
while (PIN_SSEL) {
sei();
sleep_cpu();
cli();
}
return spi_slave_Rx_n(d, n);
}
#endif