aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;