diff options
-rw-r--r-- | tamper.c | 142 |
1 files changed, 84 insertions, 58 deletions
@@ -5,12 +5,6 @@ #include <avr/io.h> /* -D__AVR_ATtiny828__ will include <avr/iotn828.h> */ /* Mapping of pins to names. */ -#define AVR_LED1 PORTA0 -#define AVR_LED2 PORTA3 -#define AVR_LED3 PORTA2 -#define AVR_LED4 PORTA1 -#define AVR_PANIC PORTA4 - #define MKM_AVR_CS_N PORTA5 #define MKM_CONTROL_AVR_ENA PORTA6 #define MKM_CONTROL_FPGA_DIS PORTA7 @@ -19,7 +13,6 @@ #define MKM_AVR_MISO PORTD1 #define MKM_AVR_SCK PORTD3 - /* Input pins. */ #define AVR_PANIC_PIN PINA /* Panic button. */ #define AVR_PANIC_BIT PINA4 /* 0 = panic. */ @@ -32,13 +25,13 @@ #define AVR_LED_GREEN_BIT PORTA1 #define MKM_CS_PORT PORTA /* MKM chip select. */ -#define MKM_CS_BIT MKM_AVR_CS_N /* 0 -> selected. */ +#define MKM_CS_BIT MKM_AVR_CS_N /* 0 => selected. */ #define MKM_CONTROL_AVR_PORT PORTA /* AVR in control. */ -#define MKM_CONTROL_AVR_BIT MKM_CONTROL_AVR_ENA /* 0 -> in control. */ +#define MKM_CONTROL_AVR_BIT MKM_CONTROL_AVR_ENA /* 0 => in control. */ #define MKM_CONTROL_FPGA_PORT PORTA /* FPGA in control. */ -#define MKM_CONTROL_FPGA_BIT MKM_CONTROL_FPGA_DIS /* 0 -> in control. */ +#define MKM_CONTROL_FPGA_BIT MKM_CONTROL_FPGA_DIS /* 0 => in control. */ /* SPI. */ #define MKM_AVR_MOSI_PORT PORTD @@ -85,11 +78,11 @@ spi_setup(int on_flag) /* Disable SPI power reduction. */ PRR &= ~_BV(PRSPI); - /* Set MOSI and SCK to output. */ + /* Configure MOSI and SCK pins as output. */ DDRD = _BV(MKM_AVR_MOSI_BIT) | _BV(MKM_AVR_SCK_BIT); - /* Make sure SPI slave select (SS) is configured as output before - enabling SPI master mode!. */ + /* Make sure SPI slave select (SS) is configured as output + before enabling SPI master mode! */ DDRC |= _BV(SPI_SS); /* Enable SPI in master mode, clock rate f/16. */ @@ -97,8 +90,8 @@ spi_setup(int on_flag) } else { - SPCR &= ~_BV(SPE); - PRR |= _BV(PRSPI); + SPCR &= ~_BV(SPE); /* Disable SPI. */ + PRR |= _BV(PRSPI); /* Enable SPI power reduction. */ } } @@ -138,27 +131,18 @@ spi_read_status() return SPDR; } -static inline void -spi_set_operation_byte() -{ - spi_write(SPI_WRSR); - spi_write(0x00); -} +#define SPI_OPERATION_BYTE 0x00 +#define SPI_OPERATION_SEQUENCE 0x40 +#define SPI_OPERATION_PAGE 0x80 static inline void -spi_set_operation_page() +spi_set_operation(uint8_t mode) { spi_write(SPI_WRSR); - spi_write(0x80); -} - -static inline void -spi_set_operation_seq() -{ - spi_write(SPI_WRSR); - spi_write(0x40); + spi_write(mode); } +#if 0 static void spi_write_byte(uint16_t addr, uint8_t data) { @@ -181,6 +165,17 @@ spi_read_byte(uint16_t addr) mkm_chip_select(0); return data; } +#endif + +/**********************/ +/* Tamper protection. */ +#if 0 +/* Interrupt handler for tamper pin. */ +void +tamper_int(void) __attribute__ ((interrupt)) +{ +} +#endif static inline int panic_p() @@ -188,49 +183,80 @@ panic_p() return !bit_is_set(AVR_PANIC_PIN, AVR_PANIC_BIT); } - static inline void init_ports() { - /* Configure all PORTA pins except the tamper detection pin to + /* Configure all PORTA pins except the tamper detection pin as outputs. */ DDRA = 0xff & ~_BV(AVR_PANIC_BIT); } +static void +init_interrupts() +{ + PCMSK0 |= _BV(PCINT4); /* Set mask bit for PCINT4 */ + PCICR |= _BV(PCIE0); /* Enable pin change interrupt 0. */ +} + +static void +init_power_reduction() +{ + /* TBD: Disable everything that we don't need? Note that the effect + of this should marginal since it's only saving energy when we're + awaken and actualy wiping memory. */ +} + +static inline void +mkm_wipe() +{ + AVR_LED_PORT |= _BV(AVR_LED_RED_BIT); + + spi_setup(1); + mkm_grab(); + mkm_chip_select(1); + spi_set_operation(SPI_OPERATION_SEQUENCE); + spi_write(SPI_WRITE); + spi_write(0); /* Address, high byte. */ + spi_write(0); /* Address, low byte. */ + for (int i = 0; i < 0x1fff; i++) /* 8192 bytes (64Kbit). */ + spi_write(0); + mkm_chip_select(0); + mkm_release(); + spi_setup(0); + + AVR_LED_PORT &= ~_BV(AVR_LED_RED_BIT); +} + +static inline void +sleep() +{ + SMCR &= ~0x2; /* Set sleep mode to "power down"... */ + SMCR |= 0x5; /* ... and enable sleep. */ + asm("sei"); /* Enable interrupts. */ + asm("sleep"); /* Go to sleep. */ + + SMCR &= ~0x1; /* Disable sleep. */ +} + int main() { init_ports(); + init_power_reduction(); + init_interrupts(); + + /* Flash LED's at startup. */ + AVR_LED_PORT |= 0x0f; + for (int i = 0; i < 16000; i++); + AVR_LED_PORT &= ~0x0f; - int i, j = 0, wait; - uint8_t mkm_val = 0; while (1) { if (panic_p()) - { - spi_setup(1); - mkm_grab(); - - spi_write_byte(0, spi_read_byte(0) + 1); - mkm_val = spi_read_byte(0); - AVR_LED_PORT = (AVR_LED_PORT & 0xf0) | (mkm_val & 0x0f); - - wait = 32000; - } - else - { - mkm_release(); - spi_setup(0); - - if ((j++ & 1) == 0) - AVR_LED_PORT = (AVR_LED_PORT & 0xf0) | 0xa; - else - AVR_LED_PORT = (AVR_LED_PORT & 0xf0) | 0x5; - - wait = 16000; - } - - for (i = 0; i < wait; i++); + mkm_wipe(); + + if (!panic_p()) + sleep(); } return 0; |