From 7ebd56579f5e90861c39fdf46fa7d53446cfeccf Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Wed, 18 May 2016 12:07:50 +0200 Subject: Read from and write to MKM when panic button is pressed. --- tamper.c | 227 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 tamper.c (limited to 'tamper.c') diff --git a/tamper.c b/tamper.c new file mode 100644 index 0000000..ca3cb2d --- /dev/null +++ b/tamper.c @@ -0,0 +1,227 @@ +/* FIXME: copyright */ + +#include +#include /* -D__AVR_ATtiny828__ will include */ + +/* 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 + +#define MKM_AVR_MOSI PORTD0 +#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. */ + +/* Output ports. */ +#define AVR_LED_PORT PORTA +#define AVR_LED_BLUE_BIT PORTA0 +#define AVR_LED_RED_BIT PORTA3 +#define AVR_LED_YELLOW_BIT PORTA2 +#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_CONTROL_AVR_PORT PORTA /* AVR 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. */ + +/* SPI. */ +#define MKM_AVR_MOSI_PORT PORTD +#define MKM_AVR_MOSI_BIT MKM_AVR_MOSI /* PD0, Master Out Slave In. */ +#define MKM_AVR_MISO_PORT PORTD +#define MKM_AVR_MISO_BIT PORTD1 /* PD1, Master In Slave Out. */ +#define MKM_AVR_SCK_PORT PORTD +#define MKM_AVR_SCK_BIT PORTD3 /* PD3, SPI clock. */ + +/*******/ +/* MKM */ +static inline void +mkm_chip_select(int select_flag) +{ + if (select_flag) + MKM_CS_PORT &= ~_BV(MKM_CS_BIT); /* CS low. */ + else + MKM_CS_PORT |= _BV(MKM_CS_BIT); /* CS high. */ +} + +static inline void +mkm_grab() +{ + MKM_CONTROL_FPGA_PORT |= _BV(MKM_CONTROL_FPGA_BIT); + MKM_CONTROL_AVR_PORT &= ~_BV(MKM_CONTROL_AVR_BIT); +} + +static inline void +mkm_release() +{ + MKM_CONTROL_AVR_PORT |= _BV(MKM_CONTROL_AVR_BIT); + MKM_CONTROL_FPGA_PORT &= ~_BV(MKM_CONTROL_FPGA_BIT); +} + +/*******/ +/* SPI */ +#define SPI_SS DDRC0 /* SPI slave select. */ + +static inline void +spi_setup(int on_flag) +{ + if (on_flag) + { + /* Disable SPI power reduction. */ + PRR &= ~_BV(PRSPI); + + /* Set MOSI and SCK to 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!. */ + DDRC |= _BV(SPI_SS); + + /* Enable SPI in master mode, clock rate f/16. */ + SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR0); + } + else + { + SPCR &= ~_BV(SPE); + PRR |= _BV(PRSPI); + } +} + +/* SPI commands for MKM (23K640). */ +#define SPI_READ 0x03 +#define SPI_WRITE 0x02 +#define SPI_RDSR 0x05 /* Read status register. */ +#define SPI_WRSR 0x01 /* Write status register. */ + +static inline void +spi_write(uint8_t val) +{ + SPDR = val; + loop_until_bit_is_set(SPSR, SPIF); +} + +static inline uint8_t +spi_read() +{ + spi_write(0); + return SPDR; +} + +static inline uint8_t +spi_read_status() +{ + spi_write(SPI_RDSR); + return SPDR; +} + +static inline void +spi_set_operation_byte() +{ + spi_write(SPI_WRSR); + spi_write(0x00); +} + +static inline void +spi_set_operation_page() +{ + spi_write(SPI_WRSR); + spi_write(0x80); +} + +static inline void +spi_set_operation_seq() +{ + spi_write(SPI_WRSR); + spi_write(0x40); +} + +static void +spi_write_byte(uint16_t addr, uint8_t data) +{ + mkm_chip_select(1); + spi_write(SPI_WRITE); + spi_write(addr & 0xff00); + spi_write(addr & 0x00ff); + spi_write(data); + mkm_chip_select(0); +} + +static uint8_t +spi_read_byte(uint16_t addr) +{ + mkm_chip_select(1); + spi_write(SPI_READ); + spi_write(addr & 0xff00); + spi_write(addr & 0x00ff); + uint8_t data = spi_read(); + mkm_chip_select(0); + return data; +} + +static inline int +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 + outputs. */ + DDRA = 0xff & ~_BV(AVR_PANIC_BIT); +} + +int +main() +{ + init_ports(); + + 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++); + } + + return 0; +} -- cgit v1.2.3