diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/kernel/ao.h | 1 | ||||
| -rw-r--r-- | src/stmf0/ao_adc_fast.c | 42 | ||||
| -rw-r--r-- | src/stmf0/ao_adc_fast.h | 62 | ||||
| -rw-r--r-- | src/usbtrng-v2.0/ao_usbtrng.c | 10 | 
4 files changed, 91 insertions, 24 deletions
| diff --git a/src/kernel/ao.h b/src/kernel/ao.h index 16d600aa..59a469ae 100644 --- a/src/kernel/ao.h +++ b/src/kernel/ao.h @@ -72,6 +72,7 @@ typedef AO_PORT_TYPE ao_port_t;  #define AO_PANIC_BUFIO		15	/* Mis-using bufio API */  #define AO_PANIC_EXTI		16	/* Mis-using exti API */  #define AO_PANIC_FAST_TIMER	17	/* Mis-using fast timer API */ +#define AO_PANIC_ADC		18	/* Mis-using ADC interface */  #define AO_PANIC_SELF_TEST_CC1120	0x40 | 1	/* Self test failure */  #define AO_PANIC_SELF_TEST_HMC5883	0x40 | 2	/* Self test failure */  #define AO_PANIC_SELF_TEST_MPU6000	0x40 | 3	/* Self test failure */ diff --git a/src/stmf0/ao_adc_fast.c b/src/stmf0/ao_adc_fast.c index 5885ae4f..be9b5986 100644 --- a/src/stmf0/ao_adc_fast.c +++ b/src/stmf0/ao_adc_fast.c @@ -18,7 +18,10 @@  #include <ao.h>  #include <ao_adc_fast.h> -static uint8_t			ao_adc_done; +uint16_t ao_adc_ring[AO_ADC_RING_SIZE]; + +uint16_t ao_adc_ring_head, ao_adc_ring_tail; +uint8_t ao_adc_running;  /*   * Callback from DMA ISR @@ -28,22 +31,30 @@ static uint8_t			ao_adc_done;  static void ao_adc_dma_done(int index)  {  	(void) index; -	ao_adc_done = 1; -	ao_wakeup(&ao_adc_done); +	ao_adc_ring_head += AO_ADC_RING_CHUNK; +	if (ao_adc_ring_head == AO_ADC_RING_SIZE) +		ao_adc_ring_head = 0; +	ao_adc_running = 0; +	ao_wakeup(&ao_adc_ring_head); +	ao_dma_done_transfer(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1));  } -/* - * Start the ADC sequence using the DMA engine - */  void -ao_adc_read(uint16_t *dest, int len) +_ao_adc_start(void)  { -	ao_adc_done = 0; +	uint16_t	*buf; + +	if (ao_adc_running) +		return; +	if (_ao_adc_space() < AO_ADC_RING_CHUNK) +		return; +	ao_adc_running = 1; +	buf = ao_adc_ring + ao_adc_ring_head;  	stm_adc.isr = 0;  	ao_dma_set_transfer(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1),  			    &stm_adc.dr, -			    dest, -			    len, +			    buf, +			    AO_ADC_RING_CHUNK,  			    (0 << STM_DMA_CCR_MEM2MEM) |  			    (STM_DMA_CCR_PL_HIGH << STM_DMA_CCR_PL) |  			    (STM_DMA_CCR_MSIZE_16 << STM_DMA_CCR_MSIZE) | @@ -56,16 +67,6 @@ ao_adc_read(uint16_t *dest, int len)  	ao_dma_start(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1));  	stm_adc.cr |= (1 << STM_ADC_CR_ADSTART); -	ao_arch_block_interrupts(); -	while (!ao_adc_done) -		ao_sleep(&ao_adc_done); -	ao_arch_release_interrupts(); - -	ao_dma_done_transfer(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1)); - -	stm_adc.cr |= (1 << STM_ADC_CR_ADSTP); -	while ((stm_adc.cr & (1 << STM_ADC_CR_ADSTP)) != 0) -		;  }  void @@ -185,4 +186,5 @@ ao_adc_init(void)  	stm_syscfg.cfgr1 &= ~(1 << STM_SYSCFG_CFGR1_ADC_DMA_RMP);  	ao_dma_alloc(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1)); +	ao_dma_set_isr(STM_DMA_INDEX(STM_DMA_CHANNEL_ADC_1), ao_adc_dma_done);  } diff --git a/src/stmf0/ao_adc_fast.h b/src/stmf0/ao_adc_fast.h index a2408d14..eec45505 100644 --- a/src/stmf0/ao_adc_fast.h +++ b/src/stmf0/ao_adc_fast.h @@ -24,4 +24,66 @@ ao_adc_read(uint16_t *dest, int len);  void  ao_adc_init(void); +/* Total ring size in samples */ +#define AO_ADC_RING_SIZE	256 +/* Number of samples fetched per ao_adc_start call */ +#define AO_ADC_RING_CHUNK	(AO_ADC_RING_SIZE >> 1) + +extern uint16_t	ao_adc_ring[AO_ADC_RING_SIZE]; + +#define ao_adc_ring_step(pos,inc)	(((pos) + (inc)) & (AO_ADC_RING_SIZE - 1)) + +extern uint16_t	ao_adc_ring_head, ao_adc_ring_tail; +extern uint8_t	ao_adc_running; + +void +_ao_adc_start(void); + +static inline uint16_t +_ao_adc_remain(void) +{ +	if (ao_adc_ring_tail > ao_adc_ring_head) +		return AO_ADC_RING_SIZE - ao_adc_ring_tail; +	return ao_adc_ring_head - ao_adc_ring_tail; +} + +static inline uint16_t +_ao_adc_space(void) +{ +	if (ao_adc_ring_head == ao_adc_ring_tail) +		return AO_ADC_RING_SIZE; +	if (ao_adc_ring_head > ao_adc_ring_tail) +		return AO_ADC_RING_SIZE - ao_adc_ring_head; +	return ao_adc_ring_tail - ao_adc_ring_head; +} + +static inline uint16_t * +ao_adc_get(uint16_t n) +{ +	if (ao_adc_ring_tail + n > AO_ADC_RING_SIZE) +		ao_panic(AO_PANIC_ADC); +	ao_arch_block_interrupts(); +	while (_ao_adc_remain() < n) { +		if (!ao_adc_running) +			_ao_adc_start(); +		ao_sleep(&ao_adc_ring_head); +	} +	ao_arch_release_interrupts(); +	return &ao_adc_ring[ao_adc_ring_tail]; +} + +static inline void +ao_adc_ack(uint16_t n) +{ +	if (ao_adc_ring_tail + n > AO_ADC_RING_SIZE) +		ao_panic(AO_PANIC_ADC); +	ao_arch_block_interrupts(); +	ao_adc_ring_tail += n; +	if (ao_adc_ring_tail == AO_ADC_RING_SIZE) +		ao_adc_ring_tail = 0; +	if (!ao_adc_running && _ao_adc_space() >= AO_ADC_RING_CHUNK) +		_ao_adc_start(); +	ao_arch_release_interrupts(); +} +  #endif /* _AO_ADC_FAST_H_ */ diff --git a/src/usbtrng-v2.0/ao_usbtrng.c b/src/usbtrng-v2.0/ao_usbtrng.c index 26cfbac9..e1f43cdd 100644 --- a/src/usbtrng-v2.0/ao_usbtrng.c +++ b/src/usbtrng-v2.0/ao_usbtrng.c @@ -23,7 +23,6 @@ static void  ao_trng_fetch(void)  {  	static uint16_t	*buffer[2]; -	static uint32_t	adc_in[AO_USB_IN_SIZE/2];	/* twice as many as we need */  	uint32_t	kbytes = 1;  	uint32_t	count;  	int		usb_buf_id; @@ -50,18 +49,21 @@ ao_trng_fetch(void)  	ao_led_on(AO_LED_GREEN);  	while (count--) { -		ao_adc_read((uint16_t *) adc_in, AO_USB_IN_SIZE); -		rnd = adc_in;  		buf = buffer[usb_buf_id]; +//		printf ("before get: head %3d tail %3d running %d\n", ao_adc_ring_head, ao_adc_ring_tail, ao_adc_running); flush(); +		rnd = (uint32_t *) ao_adc_get(AO_USB_IN_SIZE);	/* one 16-bit value per output byte */ +//		printf ("after get: head %3d tail %3d running %d\n", ao_adc_ring_head, ao_adc_ring_tail, ao_adc_running); flush();  		for (i = 0; i < 32; i++)  			*buf++ = ao_crc_in_32_out_16(*rnd++); +		ao_adc_ack(AO_USB_IN_SIZE); +//		printf ("after ack: head %3d tail %3d running %d\n", ao_adc_ring_head, ao_adc_ring_tail, ao_adc_running); flush();  		ao_led_toggle(AO_LED_GREEN|AO_LED_RED);  		ao_usb_write(buffer[usb_buf_id], AO_USB_IN_SIZE);  		ao_led_toggle(AO_LED_GREEN|AO_LED_RED);  		usb_buf_id = 1-usb_buf_id;  	}  	ao_led_off(AO_LED_GREEN|AO_LED_RED); -	ao_usb_flush(); +	flush();  }  static const struct ao_cmds usbtrng_cmds[] = { | 
