dnl Process this file with autoconf to create configure.
AC_PREREQ(2.57)
-AC_INIT([altos], 1.5.9.0)
+AC_INIT([altos], 1.5.9.1)
AC_CONFIG_SRCDIR([src/kernel/ao.h])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
AM_MAINTAINER_MODE
+++ /dev/null
-altusmetrum-micropeak.svg
\ No newline at end of file
uint16_t i;
int32_t accel_total;
uint8_t cal_data_ring;
+ int16_t min = 32767, max = -32768;
#if HAS_GYRO
int32_t accel_along_total = 0;
int32_t accel_across_total = 0;
while (i) {
ao_sleep(DATA_TO_XDATA(&ao_sample_data));
while (i && cal_data_ring != ao_sample_data) {
- accel_total += (int32_t) ao_data_accel(&ao_data_ring[cal_data_ring]);
+ int16_t v = ao_data_accel(&ao_data_ring[cal_data_ring]);
+ accel_total += (int32_t) v;
+ if (v < min) min = v;
+ if (v > max) max = v;
#if HAS_GYRO
accel_along_total += (int32_t) ao_data_along(&ao_data_ring[cal_data_ring]);
accel_across_total += (int32_t) ao_data_across(&ao_data_ring[cal_data_ring]);
accel_cal_across = accel_across_total >> ACCEL_CALIBRATE_SHIFT;
accel_cal_through = accel_through_total >> ACCEL_CALIBRATE_SHIFT;
#endif
+ printf ("total %d min %d max %d\n", accel_total, min, max);
return accel_total >> ACCEL_CALIBRATE_SHIFT;
}
#define AO_USB_OUT_EP 2
#define AO_USB_IN_EP 3
+extern uint8_t ao_usb_out_avail;
+
void
ao_serial_init(void);
asm("isb");
}
+void *
+ao_usb_alloc(uint16_t len);
+
+void
+ao_usb_write(void *block, int len);
+
#endif /* _AO_ARCH_FUNCS_H_ */
static uint8_t *ao_usb_ep0_rx_buffer;
/* Pointer to bulk data tx/rx buffers in USB memory */
-static uint8_t *ao_usb_in_tx_buffer;
-static uint8_t *ao_usb_out_rx_buffer;
-
-/* Our data buffers */
-static uint8_t ao_usb_tx_buffer[AO_USB_IN_SIZE];
+static uint8_t *ao_usb_in_tx_buffer[2];
+static uint8_t ao_usb_in_tx_cur;
static uint8_t ao_usb_tx_count;
-static uint8_t ao_usb_rx_buffer[AO_USB_OUT_SIZE];
+static uint8_t *ao_usb_out_rx_buffer[2];
+static uint8_t ao_usb_out_rx_cur;
static uint8_t ao_usb_rx_count, ao_usb_rx_pos;
extern struct lpc_usb_endpoint lpc_usb_endpoint;
/* Marks when an OUT packet has been received by the hardware
* but not pulled to the shadow buffer.
*/
-static uint8_t ao_usb_out_avail;
+uint8_t ao_usb_out_avail;
uint8_t ao_usb_running;
static uint8_t ao_usb_configuration;
/* Set up the INT end point */
ao_usb_enable_epn(AO_USB_INT_EP, 0, NULL, 0, NULL);
-
+
/* Set up the OUT end point */
- ao_usb_enable_epn(AO_USB_OUT_EP, AO_USB_OUT_SIZE, &ao_usb_out_rx_buffer, 0, NULL);
+ ao_usb_enable_epn(AO_USB_OUT_EP, AO_USB_OUT_SIZE * 2, &ao_usb_out_rx_buffer[0], 0, NULL);
+ ao_usb_out_rx_buffer[1] = ao_usb_out_rx_buffer[0] + AO_USB_OUT_SIZE;
+ ao_usb_out_rx_cur = 0;
/* Set up the IN end point */
- ao_usb_enable_epn(AO_USB_IN_EP, 0, NULL, AO_USB_IN_SIZE, &ao_usb_in_tx_buffer);
+ ao_usb_enable_epn(AO_USB_IN_EP, 0, NULL, AO_USB_IN_SIZE * 2, &ao_usb_in_tx_buffer[0]);
+ ao_usb_in_tx_buffer[1] = ao_usb_in_tx_buffer[0] + AO_USB_IN_SIZE;
+ ao_usb_in_tx_cur = 0;
ao_usb_running = 1;
}
ao_usb_in_pending = 1;
if (ao_usb_tx_count != AO_USB_IN_SIZE)
ao_usb_in_flushed = 1;
- memcpy(ao_usb_in_tx_buffer, ao_usb_tx_buffer, ao_usb_tx_count);
- ao_usb_set_ep(ao_usb_epn_in(AO_USB_IN_EP), ao_usb_in_tx_buffer, ao_usb_tx_count);
+ ao_usb_set_ep(ao_usb_epn_in(AO_USB_IN_EP), ao_usb_in_tx_buffer[ao_usb_in_tx_cur], ao_usb_tx_count);
+ ao_usb_in_tx_cur = 1 - ao_usb_in_tx_cur;
ao_usb_tx_count = 0;
_tx_dbg0("in_send end");
}
ao_arch_block_interrupts();
_ao_usb_in_wait();
+ ao_arch_release_interrupts();
ao_usb_in_flushed = 0;
- ao_usb_tx_buffer[ao_usb_tx_count++] = (uint8_t) c;
+ ao_usb_in_tx_buffer[ao_usb_in_tx_cur][ao_usb_tx_count++] = (uint8_t) c;
+ ao_arch_block_interrupts();
/* Send the packet when full */
if (ao_usb_tx_count == AO_USB_IN_SIZE) {
_tx_dbg0("putchar full");
ao_arch_release_interrupts();
}
+void *
+ao_usb_alloc(uint16_t len)
+{
+ return ao_usb_alloc_sram(len);
+}
+
+void
+ao_usb_write(void *block, int len)
+{
+ uint8_t *b = block;
+ int this_time;
+
+ if (!ao_usb_running)
+ return;
+
+ if (!ao_usb_in_flushed)
+ ao_usb_flush();
+
+ while (len) {
+ ao_usb_in_flushed = 0;
+ this_time = AO_USB_IN_SIZE;
+ if (this_time > len)
+ this_time = len;
+ b += this_time;
+ len -= this_time;
+
+ ao_arch_block_interrupts();
+ while (ao_usb_in_pending)
+ ao_sleep(&ao_usb_in_pending);
+ ao_usb_in_pending = 1;
+ if (this_time != AO_USB_IN_SIZE)
+ ao_usb_in_flushed = 1;
+ ao_usb_set_ep(ao_usb_epn_in(AO_USB_IN_EP), b, this_time);
+ ao_arch_release_interrupts();
+ }
+}
+
static void
_ao_usb_out_recv(void)
{
_rx_dbg1("out_recv count", ao_usb_rx_count);
debug ("recv %d\n", ao_usb_rx_count);
- debug_data("Fill OUT len %d:", ao_usb_rx_count);
- memcpy(ao_usb_rx_buffer, ao_usb_out_rx_buffer, ao_usb_rx_count);
- debug_data("\n");
+ debug_data("Fill OUT len %d\n", ao_usb_rx_count);
ao_usb_rx_pos = 0;
+ ao_usb_rx_out_cur = 1 - ao_usb_rx_out_cur;
/* ACK the packet */
- ao_usb_set_epn_out(AO_USB_OUT_EP, ao_usb_out_rx_buffer, AO_USB_OUT_SIZE);
+ ao_usb_set_epn_out(AO_USB_OUT_EP, ao_usb_out_rx_buffer[1-ao_usb_rx_out_cur], AO_USB_OUT_SIZE);
}
int
}
/* Pull a character out of the fifo */
- c = ao_usb_rx_buffer[ao_usb_rx_pos++];
+ c = ao_usb_rx_buffer[ao_usb_rx_out_cur][ao_usb_rx_pos++];
return c;
}
*/
#define HAS_SCK1 0
#define HAS_MOSI1 0
+
+#define AO_ADC_6 1
#include <ao.h>
#define AO_TRNG_SPI_BUS 1
-#define AO_TRNG_SPI_SPEED AO_SPI_SPEED_250kHz
+
+static uint32_t spi_speed = AO_SPI_SPEED_4MHz;
+
+#define AO_TRNG_SPI_BUF 1024
+
+#if 0
+
+static uint8_t *spi_buf;
+static uint8_t *spi_head, *spi_tail;
+static uint8_t spi_wakeup;
+
+static void
+ao_trng_run(void)
+{
+ int this_time;
+ uint8_t *end;
+
+ if (!spi_buf)
+ spi_buf = ao_usb_alloc(AO_TRNG_SPI_BUF);
+ flush();
+ ao_spi_get(AO_TRNG_SPI_BUS, spi_speed);
+ spi_tail = spi_buf;
+ spi_head = spi_buf;
+ ao_spi_recv_ring_start(spi_buf, AO_TRNG_SPI_BUF, &spi_head, &spi_tail, &spi_wakeup, AO_TRNG_SPI_BUS);
+ while (!ao_usb_out_avail) {
+ ao_arch_block_interrupts();
+ while (spi_head == spi_tail) {
+ spi_wakeup = 0;
+ ao_sleep(&spi_wakeup);
+ }
+ ao_arch_release_interrupts();
+ if (spi_tail > spi_head)
+ end = spi_buf + AO_TRNG_SPI_BUF;
+ else
+ end = spi_head;
+ this_time = end - spi_tail;
+ if (this_time > 64)
+ this_time = 64;
+ ao_usb_write(spi_tail, this_time);
+ spi_tail += this_time;
+ if (spi_tail == spi_buf + AO_TRNG_SPI_BUF)
+ spi_tail = spi_buf;
+ }
+ ao_spi_put(AO_TRNG_SPI_BUS);
+ getchar();
+}
+
static void
ao_trng_test(void)
static uint8_t random[32];
uint8_t i;
- ao_spi_get(AO_TRNG_SPI_BUS, AO_TRNG_SPI_SPEED);
+ ao_spi_get(AO_TRNG_SPI_BUS, spi_speed);
ao_spi_recv(random, sizeof (random), AO_TRNG_SPI_BUS);
ao_spi_put(AO_TRNG_SPI_BUS);
for (i = 0; i < sizeof (random); i++)
printf (" %02x", random[i]);
printf ("\n");
}
+#endif
+
+#define ADC_RING_SIZE 512
+
+static uint8_t *adc_ring;
+static uint16_t adc_head, adc_tail;
+static uint16_t adc_wake;
+
+void lpc_adc_isr(void)
+{
+ uint16_t avail;
+ uint16_t this, next;
+
+ this = adc_head;
+ next = (this + 1) & (ADC_RING_SIZE - 1);
+ if (next == adc_tail) {
+ lpc_adc.inten = 0;
+ return;
+ }
+ adc_ring[this] = lpc_adc.dr[6] >> 8;
+ adc_head = next;
+
+ /* If there are enough entries, wake up any waiters
+ */
+ avail = (next - adc_tail) & (ADC_RING_SIZE - 1);
+ if (avail >= adc_wake) {
+ adc_wake = 0;
+ ao_wakeup(&adc_wake);
+ }
+}
+
+#define AO_ADC_CLKDIV (AO_LPC_SYSCLK / 450000)
+
+static void
+ao_trng_adc_init(void)
+{
+ adc_ring = ao_usb_alloc(ADC_RING_SIZE);
+
+ lpc_scb.sysahbclkctrl |= (1 << LPC_SCB_SYSAHBCLKCTRL_ADC);
+ lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_ADC_PD);
+
+ /* Enable interrupt when AO_ADC_6 is complete */
+ lpc_adc.inten = 0;
+
+ lpc_nvic_set_enable(LPC_ISR_ADC_POS);
+ lpc_nvic_set_priority(LPC_ISR_ADC_POS, AO_LPC_NVIC_CLOCK_PRIORITY);
+
+#if AO_ADC_0
+ ao_enable_analog(0, 11, 0);
+#endif
+#if AO_ADC_1
+ ao_enable_analog(0, 12, 1);
+#endif
+#if AO_ADC_2
+ ao_enable_analog(0, 13, 2);
+#endif
+#if AO_ADC_3
+ ao_enable_analog(0, 14, 3);
+#endif
+#if AO_ADC_4
+ ao_enable_analog(0, 15, 4);
+#endif
+#if AO_ADC_5
+ ao_enable_analog(0, 16, 5);
+#endif
+#if AO_ADC_6
+ ao_enable_analog(0, 22, 6);
+#endif
+#if AO_ADC_7
+ ao_enable_analog(0, 23, 7);
+#endif
+
+ lpc_adc.cr = ((1 << (LPC_ADC_CR_SEL + 6)) |
+ (AO_ADC_CLKDIV << LPC_ADC_CR_CLKDIV) |
+ (1 << LPC_ADC_CR_BURST) |
+ (LPC_ADC_CR_CLKS_9 << LPC_ADC_CR_CLKS));
+}
+
+static void
+ao_trng_adc_dump(void)
+{
+ int i;
+
+ while (((adc_head - adc_tail) & (ADC_RING_SIZE - 1)) < 16) {
+ lpc_adc.inten = (1 << (LPC_ADC_INTEN_ADINTEN + 6));
+ adc_wake = 16;
+ ao_sleep(&adc_wake);
+ }
+ printf("adc_head %d tail %d\n", adc_head, adc_tail);
+
+ for (i = 0; i < 16; i++) {
+ printf(" %4d", adc_ring[adc_tail]);
+ adc_tail = (adc_tail + 1) & (ADC_RING_SIZE - 1);
+ }
+ printf("\n");
+ lpc_adc.inten = 0;
+}
+
+static void
+ao_trng_run(void)
+{
+ uint16_t this_time;
+ flush();
+
+ while (!ao_usb_out_avail) {
+ ao_arch_block_interrupts();
+ while (((adc_head - adc_tail) & (ADC_RING_SIZE - 1)) < 64) {
+ lpc_adc.inten = (1 << (LPC_ADC_INTEN_ADINTEN + 6));
+ adc_wake = 64;
+ ao_sleep(&adc_wake);
+ }
+ ao_arch_release_interrupts();
+
+ this_time = ADC_RING_SIZE - adc_tail;
+ if (this_time > 64)
+ this_time = 64;
+ ao_usb_write(&adc_ring[adc_tail], this_time);
+ adc_tail = (adc_tail + this_time) & (ADC_RING_SIZE - 1);
+ }
+ lpc_adc.inten = 0;
+}
+
+static void
+ao_trng_speed(void)
+{
+ ao_cmd_decimal();
+
+ if (ao_cmd_lex_u32 == 0 || ao_cmd_status != ao_cmd_success) {
+ ao_cmd_status = ao_cmd_success;
+ printf ("Current spi speed %d\n", spi_speed);
+ } else {
+ spi_speed = ao_cmd_lex_u32;
+ }
+}
static const struct ao_cmds ao_trng_cmds[] = {
- { ao_trng_test, "R\0Dump some random numbers" },
+// { ao_trng_test, "R\0Dump some random numbers" },
+ { ao_trng_run, "s\0Send random bits until char" },
+ { ao_trng_speed, "S <speed>\0Set SPI speed (48MHz/speed)" },
+ { ao_trng_adc_dump, "a\0Dump ADC data" },
{ 0, NULL }
};
ao_task_init();
ao_timer_init();
- ao_spi_init();
+// ao_spi_init();
ao_usb_init();
+ ao_trng_adc_init();
+
ao_serial_init();
ao_led_init(LEDS_AVAILABLE);
- ao_led_on(AO_LED_GREEN);
-
ao_cmd_init();
ao_cmd_register(ao_trng_cmds);