diff options
author | Keith Packard <keithp@keithp.com> | 2016-01-28 00:14:36 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2016-01-28 00:15:31 -0800 |
commit | f2d3202de9a5847923f72afe2969eb7ccd7342c7 (patch) | |
tree | fcc2978cf91666fe078e7d2405b0ceedfc796eb7 /src/drivers/ao_trng_send.c | |
parent | 02fd767ab60a9957faa2bff29c62ed954abc34e7 (diff) |
altos/chaoskey: Add support for flipping between raw and cooked bits
Plug the 'force bootloader' thing onto the board while it's running
and it will generate raw bits instead of running them through the CRC
to whiten. Useful for validating the raw hardware.
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/drivers/ao_trng_send.c')
-rw-r--r-- | src/drivers/ao_trng_send.c | 55 |
1 files changed, 44 insertions, 11 deletions
diff --git a/src/drivers/ao_trng_send.c b/src/drivers/ao_trng_send.c index bac6035c..64c016b2 100644 --- a/src/drivers/ao_trng_send.c +++ b/src/drivers/ao_trng_send.c @@ -19,17 +19,48 @@ #include <ao_adc_fast.h> #include <ao_crc.h> #include <ao_trng_send.h> +#include <ao_exti.h> static void -ao_trng_send(void) +ao_trng_send_raw(uint16_t *buf) +{ + uint16_t i; + uint16_t t; + uint16_t *rnd = (uint16_t *) ao_adc_ring; + + t = ao_adc_get(AO_USB_IN_SIZE>>1); /* one 16-bit value per two output bytes */ + for (i = 0; i < AO_USB_IN_SIZE / sizeof (uint16_t); i++) { + *buf++ = rnd[t]; + t = (t + 1) & (AO_ADC_RING_SIZE - 1); + } +} + +static void +ao_trng_send_cooked(uint16_t *buf) { - static uint16_t *buffer[2]; - int usb_buf_id; uint16_t i; - uint16_t *buf; uint16_t t; uint32_t *rnd = (uint32_t *) ao_adc_ring; + t = ao_adc_get(AO_USB_IN_SIZE) >> 1; /* one 16-bit value per output byte */ + for (i = 0; i < AO_USB_IN_SIZE / sizeof (uint16_t); i++) { + *buf++ = ao_crc_in_32_out_16(rnd[t]); + t = (t + 1) & ((AO_ADC_RING_SIZE>>1) - 1); + } +} + +static inline int +ao_send_raw(void) +{ + return !ao_gpio_get(AO_RAW_PORT, AO_RAW_BIT, AO_RAW_PIN); +} + +static void +ao_trng_send(void) +{ + static uint16_t *buffer[2]; + int usb_buf_id; + if (!buffer[0]) { buffer[0] = ao_usb_alloc(); buffer[1] = ao_usb_alloc(); @@ -42,15 +73,16 @@ ao_trng_send(void) ao_crc_reset(); for (;;) { - ao_led_on(AO_LED_TRNG_ACTIVE); - t = ao_adc_get(AO_USB_IN_SIZE) >> 1; /* one 16-bit value per output byte */ - buf = buffer[usb_buf_id]; - for (i = 0; i < AO_USB_IN_SIZE / sizeof (uint16_t); i++) { - *buf++ = ao_crc_in_32_out_16(rnd[t]); - t = (t + 1) & ((AO_ADC_RING_SIZE>>1) - 1); + if (ao_send_raw()) { + ao_led_on(AO_LED_TRNG_RAW); + ao_trng_send_raw(buffer[usb_buf_id]); + ao_led_off(AO_LED_TRNG_RAW); + } else { + ao_led_on(AO_LED_TRNG_COOKED); + ao_trng_send_cooked(buffer[usb_buf_id]); + ao_led_off(AO_LED_TRNG_COOKED); } ao_adc_ack(AO_USB_IN_SIZE); - ao_led_off(AO_LED_TRNG_ACTIVE); ao_usb_write(buffer[usb_buf_id], AO_USB_IN_SIZE); usb_buf_id = 1-usb_buf_id; } @@ -61,5 +93,6 @@ static struct ao_task ao_trng_send_task; void ao_trng_send_init(void) { + ao_enable_input(AO_RAW_PORT, AO_RAW_BIT, AO_EXTI_MODE_PULL_UP); ao_add_task(&ao_trng_send_task, ao_trng_send, "trng_send"); } |