summaryrefslogtreecommitdiff
path: root/src/drivers/ao_trng_send.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2016-01-28 00:14:36 -0800
committerKeith Packard <keithp@keithp.com>2016-01-28 00:15:31 -0800
commitf2d3202de9a5847923f72afe2969eb7ccd7342c7 (patch)
treefcc2978cf91666fe078e7d2405b0ceedfc796eb7 /src/drivers/ao_trng_send.c
parent02fd767ab60a9957faa2bff29c62ed954abc34e7 (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.c55
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");
}