aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Nordberg <linus@nordberg.se>2016-06-10 16:07:27 +0200
committerLinus Nordberg <linus@nordberg.se>2016-06-10 16:07:27 +0200
commit54cd4de78da2534b61c26a7f07abf45907e582d0 (patch)
treedc25868bdbf7cdfc7dcdf98b65f12667d381503d
parent4f229e0b1083154ee033ca9c2fd5c5367e1621ae (diff)
Do wipe MKM when tamper is detected, sleep when not.
Writing the MKM in "sequential mode" (a.k.a. "burst") but still busy-waiting for confirmation of SPI write operation being done. Would using an interrupt be faster? Sleeping is done in "power down mode". There are less sleepy modes which presumably consume more power but might wake up quicker. A good start would be to figure out how long time it takes to wake up from power down.
-rw-r--r--tamper.c142
1 files changed, 84 insertions, 58 deletions
diff --git a/tamper.c b/tamper.c
index 2893a6c..d1d5c04 100644
--- a/tamper.c
+++ b/tamper.c
@@ -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;