diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/kernel/ao_config.c | 7 | ||||
| -rw-r--r-- | src/lpc/ao_arch.h | 2 | ||||
| -rw-r--r-- | src/lpc/ao_arch_funcs.h | 6 | ||||
| -rw-r--r-- | src/lpc/ao_usb_lpc.c | 76 | ||||
| -rw-r--r-- | src/usbtrng/ao_pins.h | 2 | ||||
| -rw-r--r-- | src/usbtrng/ao_usbtrng.c | 195 | 
6 files changed, 263 insertions, 25 deletions
diff --git a/src/kernel/ao_config.c b/src/kernel/ao_config.c index 8dab7c42..83a8cd77 100644 --- a/src/kernel/ao_config.c +++ b/src/kernel/ao_config.c @@ -388,6 +388,7 @@ ao_config_accel_calibrate_auto(char *orientation) __reentrant  	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; @@ -405,7 +406,10 @@ ao_config_accel_calibrate_auto(char *orientation) __reentrant  	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]); @@ -420,6 +424,7 @@ ao_config_accel_calibrate_auto(char *orientation) __reentrant  	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;  } diff --git a/src/lpc/ao_arch.h b/src/lpc/ao_arch.h index 42faf06f..1b4c61f2 100644 --- a/src/lpc/ao_arch.h +++ b/src/lpc/ao_arch.h @@ -124,6 +124,8 @@ ao_adc_init(void);  #define AO_USB_OUT_EP	2  #define AO_USB_IN_EP	3 +extern uint8_t	ao_usb_out_avail; +  void  ao_serial_init(void); diff --git a/src/lpc/ao_arch_funcs.h b/src/lpc/ao_arch_funcs.h index fbe641d8..b963d3ab 100644 --- a/src/lpc/ao_arch_funcs.h +++ b/src/lpc/ao_arch_funcs.h @@ -249,4 +249,10 @@ static inline void ao_arch_start_scheduler(void) {  	asm("isb");  } +void * +ao_usb_alloc(uint16_t len); + +void +ao_usb_write(void *block, int len); +  #endif /* _AO_ARCH_FUNCS_H_ */ diff --git a/src/lpc/ao_usb_lpc.c b/src/lpc/ao_usb_lpc.c index 12f5d8e6..499de9e9 100644 --- a/src/lpc/ao_usb_lpc.c +++ b/src/lpc/ao_usb_lpc.c @@ -80,14 +80,12 @@ static uint8_t	*ao_usb_ep0_setup_buffer;  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; @@ -108,7 +106,7 @@ static uint8_t	ao_usb_in_pending;  /* 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; @@ -362,12 +360,16 @@ ao_usb_set_configuration(void)  	/* 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;  } @@ -716,8 +718,8 @@ _ao_usb_in_send(void)  	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");  } @@ -769,10 +771,12 @@ ao_usb_putchar(char c)  	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"); @@ -782,6 +786,43 @@ ao_usb_putchar(char c)  	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)  { @@ -792,13 +833,12 @@ _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 @@ -823,7 +863,7 @@ _ao_usb_pollchar(void)  	}  	/* 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;  } diff --git a/src/usbtrng/ao_pins.h b/src/usbtrng/ao_pins.h index b1fa6eb9..0f2b1ea6 100644 --- a/src/usbtrng/ao_pins.h +++ b/src/usbtrng/ao_pins.h @@ -71,3 +71,5 @@   */  #define HAS_SCK1		0  #define HAS_MOSI1		0 + +#define AO_ADC_6		1 diff --git a/src/usbtrng/ao_usbtrng.c b/src/usbtrng/ao_usbtrng.c index 6b4d20fe..66e12337 100644 --- a/src/usbtrng/ao_usbtrng.c +++ b/src/usbtrng/ao_usbtrng.c @@ -18,7 +18,53 @@  #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) @@ -26,16 +72,153 @@ 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 }  }; @@ -46,15 +229,15 @@ main(void)  	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);  | 
