diff options
| -rw-r--r-- | src/drivers/ao_trng_send.c | 96 | ||||
| -rw-r--r-- | src/stmf0/ao_adc_fast.c | 2 | ||||
| -rw-r--r-- | src/stmf0/ao_adc_fast.h | 2 | ||||
| -rw-r--r-- | src/stmf0/ao_arch_funcs.h | 15 | ||||
| -rw-r--r-- | src/stmf0/ao_usb_stm.c | 267 | ||||
| -rw-r--r-- | src/stmf0/registers.ld | 1 | ||||
| -rw-r--r-- | src/stmf0/stm32f0.h | 5 | 
7 files changed, 187 insertions, 201 deletions
| diff --git a/src/drivers/ao_trng_send.c b/src/drivers/ao_trng_send.c index 7cda053d..4e02c0ce 100644 --- a/src/drivers/ao_trng_send.c +++ b/src/drivers/ao_trng_send.c @@ -31,6 +31,29 @@ static AO_TICK_TYPE	trng_power_time;  static uint8_t		random_mutex; +static void +ao_trng_start(void) +{ +	if (!trng_running) { +		ao_mutex_get(&random_mutex); +		if (!trng_running) { +			AO_TICK_TYPE	delay; + +			delay = trng_power_time + TRNG_ENABLE_DELAY - ao_time(); +			if (delay > TRNG_ENABLE_DELAY) +				delay = TRNG_ENABLE_DELAY; + +			/* Delay long enough for the HV power supply +			 * to stabilize so that the first bits we read +			 * aren't of poor quality +			 */ +			ao_delay(delay); +			trng_running = TRUE; +		} +		ao_mutex_put(&random_mutex); +	} +} +  #if AO_USB_HAS_IN2  static struct ao_task	ao_trng_send_raw_task; @@ -54,34 +77,13 @@ ao_trng_get_raw(uint16_t *buf)  static void  ao_trng_send_raw(void)  { -	static uint16_t	*buffer[2]; +	uint16_t	*buffer[2];  	int		usb_buf_id; -	if (!buffer[0]) { -		buffer[0] = ao_usb_alloc(); -		buffer[1] = ao_usb_alloc(); -		if (!buffer[0]) -			ao_exit(); -	} - -	usb_buf_id = 0; +	usb_buf_id = ao_usb_alloc2(buffer);  	for (;;) { -		ao_mutex_get(&random_mutex); -		if (!trng_running) { -			AO_TICK_TYPE	delay; - -			delay = trng_power_time + TRNG_ENABLE_DELAY - ao_time(); -			if (delay > TRNG_ENABLE_DELAY) -				delay = TRNG_ENABLE_DELAY; - -			/* Delay long enough for the HV power supply -			 * to stabilize so that the first bits we read -			 * aren't of poor quality -			 */ -			ao_delay(delay); -			trng_running = TRUE; -		} +		ao_trng_start();  #ifdef AO_LED_TRNG_RAW  		ao_led_on(AO_LED_TRNG_RAW);  #endif @@ -89,9 +91,7 @@ ao_trng_send_raw(void)  #ifdef AO_LED_TRNG_RAW  		ao_led_off(AO_LED_TRNG_RAW);  #endif -		ao_mutex_put(&random_mutex); -		ao_usb_write2(buffer[usb_buf_id], AO_USB_IN_SIZE); -		usb_buf_id = 1-usb_buf_id; +		usb_buf_id = ao_usb_write2(AO_USB_IN_SIZE);  	}  } @@ -105,7 +105,7 @@ ao_trng_get_cooked(uint16_t *buf)  	uint16_t	i;  	uint16_t	t;  	uint32_t	*rnd = (uint32_t *) (void *) ao_adc_ring; -	uint8_t		mismatch = 0; +	uint8_t		mismatch = 1;  	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++) { @@ -131,20 +131,13 @@ ao_trng_get_cooked(uint16_t *buf)  static void  ao_trng_send(void)  { -	static uint16_t	*buffer[2]; -	int	usb_buf_id; -	int	good_bits; -	int	failed; -	int	s; - -	if (!buffer[0]) { -		buffer[0] = ao_usb_alloc(); -		buffer[1] = ao_usb_alloc(); -		if (!buffer[0]) -			ao_exit(); -	} +	uint16_t	*buffer[2]; +	int		usb_buf_id; +	int		good_bits; +	int		failed; +	int		s; -	usb_buf_id = 0; +	usb_buf_id = ao_usb_alloc(buffer);  #ifdef AO_TRNG_ENABLE_PORT  	ao_gpio_set(AO_TRNG_ENABLE_PORT, AO_TRNG_ENABLE_BIT, AO_TRNG_ENABLE_PIN, 1); @@ -191,21 +184,7 @@ ao_trng_send(void)  #endif  	for (;;) { -		ao_mutex_get(&random_mutex); -		if (!trng_running) { -			AO_TICK_TYPE	delay; - -			delay = trng_power_time + TRNG_ENABLE_DELAY - ao_time(); -			if (delay > TRNG_ENABLE_DELAY) -				delay = TRNG_ENABLE_DELAY; - -			/* Delay long enough for the HV power supply -			 * to stabilize so that the first bits we read -			 * aren't of poor quality -			 */ -			ao_delay(delay); -			trng_running = TRUE; -		} +		ao_trng_start();  #ifdef AO_LED_TRNG_COOKED  		ao_led_on(AO_LED_TRNG_COOKED);  #endif @@ -213,14 +192,11 @@ ao_trng_send(void)  #ifdef AO_LED_TRNG_COOKED  		ao_led_off(AO_LED_TRNG_COOKED);  #endif -		ao_mutex_put(&random_mutex);  		if (good_bits) { -			ao_usb_write(buffer[usb_buf_id], AO_USB_IN_SIZE); -			usb_buf_id = 1-usb_buf_id; +			usb_buf_id = ao_usb_write(AO_USB_IN_SIZE);  			failed = 0;  		} else {  			failed++; -			ao_delay(AO_MS_TO_TICKS(10));  			if (failed > 10) {  				ao_usb_disable();  				ao_panic(AO_PANIC_DMA); diff --git a/src/stmf0/ao_adc_fast.c b/src/stmf0/ao_adc_fast.c index 5ce3a396..fbf4ad2e 100644 --- a/src/stmf0/ao_adc_fast.c +++ b/src/stmf0/ao_adc_fast.c @@ -154,7 +154,7 @@ ao_adc_init(void)  #endif  	/* Set the clock */ -	stm_adc.cfgr2 = STM_ADC_CFGR2_CKMODE_ADCCLK << STM_ADC_CFGR2_CKMODE; +	stm_adc.cfgr2 = STM_ADC_CFGR2_CKMODE_PCLK_2 << STM_ADC_CFGR2_CKMODE;  	/* Shortest sample time */  	stm_adc.smpr = STM_ADC_SMPR_SMP_1_5 << STM_ADC_SMPR_SMP; diff --git a/src/stmf0/ao_adc_fast.h b/src/stmf0/ao_adc_fast.h index 3f0b0547..504651e5 100644 --- a/src/stmf0/ao_adc_fast.h +++ b/src/stmf0/ao_adc_fast.h @@ -26,7 +26,7 @@ void  ao_adc_init(void);  /* Total ring size in samples */ -#define AO_ADC_RING_SIZE	256 +#define AO_ADC_RING_SIZE	1024  extern uint16_t	ao_adc_ring[AO_ADC_RING_SIZE] __attribute__((aligned(4))); diff --git a/src/stmf0/ao_arch_funcs.h b/src/stmf0/ao_arch_funcs.h index 01d51f90..56a3bc75 100644 --- a/src/stmf0/ao_arch_funcs.h +++ b/src/stmf0/ao_arch_funcs.h @@ -488,14 +488,17 @@ static inline void ao_arch_start_scheduler(void) {  /* ao_usb_stm.c */  #if AO_USB_DIRECTIO -uint16_t * -ao_usb_alloc(void); +uint8_t +ao_usb_alloc(uint16_t *buffers[2]); -void -ao_usb_write(uint16_t *buffer, uint16_t len); +uint8_t +ao_usb_alloc2(uint16_t *buffers[2]); -void -ao_usb_write2(uint16_t *buffer, uint16_t len); +uint8_t +ao_usb_write(uint16_t len); + +uint8_t +ao_usb_write2(uint16_t len);  #endif /* AO_USB_DIRECTIO */  #endif /* _AO_ARCH_FUNCS_H_ */ diff --git a/src/stmf0/ao_usb_stm.c b/src/stmf0/ao_usb_stm.c index 5b9af00b..bf08abc1 100644 --- a/src/stmf0/ao_usb_stm.c +++ b/src/stmf0/ao_usb_stm.c @@ -82,15 +82,12 @@ static uint8_t 	ao_usb_ep0_out_len;   */  /* Buffer description tables */ -static union stm_usb_bdt	*ao_usb_bdt; -/* USB address of end of allocated storage */ -#if AO_USB_DIRECTIO -static uint16_t	ao_usb_sram_addr; -#endif + +#define ao_usb_bdt	((union stm_usb_bdt *) (intptr_t) (void *) stm_usb_sram)  /* Pointer to ep0 tx/rx buffers in USB memory */ -static uint16_t	*ao_usb_ep0_tx_buffer; -static uint16_t	*ao_usb_ep0_rx_buffer; +static uint16_t	ao_usb_ep0_tx_offset; +static uint16_t	ao_usb_ep0_rx_offset;  #if AO_USB_HAS_INT  /* Pointer to interrupt buffer in USB memory */ @@ -99,22 +96,19 @@ static uint16_t ao_usb_int_tx_offset;  /* Pointer to bulk data tx/rx buffers in USB memory */  #if AO_USB_HAS_IN -static uint16_t ao_usb_in_tx_offset[2]; -static uint16_t	*ao_usb_in_tx_buffer[2]; +static uint16_t ao_usb_in_tx_offset;  static uint8_t	ao_usb_in_tx_which;  static uint8_t	ao_usb_tx_count;  #endif  #if AO_USB_HAS_OUT -static uint16_t ao_usb_out_rx_offset[2]; -static uint16_t	*ao_usb_out_rx_buffer[2]; +static uint16_t ao_usb_out_rx_offset;  static uint8_t	ao_usb_out_rx_which;  static uint8_t	ao_usb_rx_count, ao_usb_rx_pos;  #endif  #if AO_USB_HAS_IN2 -static uint16_t ao_usb_in2_tx_offset[2]; -static uint16_t *ao_usb_in2_tx_buffer[2]; +static uint16_t ao_usb_in_tx2_offset;  static uint8_t	ao_usb_in_tx2_which;  static uint8_t	ao_usb_tx2_count;  #endif @@ -179,6 +173,16 @@ static inline uint16_t *ao_usb_packet_buffer_addr(uint16_t sram_addr)  	return (uint16_t *) (void *) (stm_usb_sram + sram_addr);  } +static inline uint16_t ao_usb_packet_get(uint16_t sram_addr) +{ +	return ao_usb_packet_buffer_addr(sram_addr)[0]; +} + +static inline void ao_usb_packet_put(uint16_t sram_addr, uint16_t val) +{ +	ao_usb_packet_buffer_addr(sram_addr)[0] = val; +} +  static inline uint16_t ao_usb_packet_buffer_offset(uint16_t *addr)  {  	return (uint16_t) ((uint8_t *) addr - stm_usb_sram); @@ -387,16 +391,15 @@ ao_usb_alloc_buffers(void)  {  	uint16_t sram_addr = 0; -	ao_usb_bdt = (void *) stm_usb_sram; +	/* allocate space for BDT, which is at the start of SRAM */  	sram_addr += 8 * STM_USB_BDT_SIZE; -	ao_usb_ep0_tx_buffer = ao_usb_packet_buffer_addr(sram_addr); +	ao_usb_ep0_tx_offset = sram_addr;  	sram_addr += AO_USB_CONTROL_SIZE; -	ao_usb_ep0_rx_buffer = ao_usb_packet_buffer_addr(sram_addr); +	ao_usb_ep0_rx_offset = sram_addr;  	sram_addr += AO_USB_CONTROL_SIZE; -  #if AO_USB_HAS_INT  	sram_addr += (sram_addr & 1);  	ao_usb_int_tx_offset = sram_addr; @@ -405,43 +408,20 @@ ao_usb_alloc_buffers(void)  #if AO_USB_HAS_OUT  	sram_addr += (sram_addr & 1); -	ao_usb_out_rx_buffer[0] = ao_usb_packet_buffer_addr(sram_addr); -	ao_usb_out_rx_offset[0] = sram_addr; -	sram_addr += AO_USB_OUT_SIZE; -	sram_addr += (sram_addr & 1); -	ao_usb_out_rx_buffer[1] = ao_usb_packet_buffer_addr(sram_addr); -	ao_usb_out_rx_offset[1] = sram_addr; -	sram_addr += AO_USB_OUT_SIZE; -	ao_usb_out_rx_which = 1; +	ao_usb_out_rx_offset = sram_addr; +	sram_addr += AO_USB_OUT_SIZE * 2;  #endif  #if AO_USB_HAS_IN  	sram_addr += (sram_addr & 1); -	ao_usb_in_tx_buffer[0] = ao_usb_packet_buffer_addr(sram_addr); -	ao_usb_in_tx_offset[0] = sram_addr; -	sram_addr += AO_USB_IN_SIZE; -	ao_usb_in_tx_buffer[1] = ao_usb_packet_buffer_addr(sram_addr); -	ao_usb_in_tx_offset[1] = sram_addr; -	sram_addr += AO_USB_IN_SIZE; -	ao_usb_in_tx_which = 0; +	ao_usb_in_tx_offset = sram_addr; +	sram_addr += AO_USB_IN_SIZE * 2;  #endif  #if AO_USB_HAS_IN2  	sram_addr += (sram_addr & 1); -	ao_usb_in2_tx_buffer[0] = ao_usb_packet_buffer_addr(sram_addr); -	ao_usb_in2_tx_offset[0] = sram_addr; -	sram_addr += AO_USB_IN_SIZE; - -	sram_addr += (sram_addr & 1); -	ao_usb_in2_tx_buffer[1] = ao_usb_packet_buffer_addr(sram_addr); -	ao_usb_in2_tx_offset[1] = sram_addr; -	sram_addr += AO_USB_IN_SIZE; -	ao_usb_in2_tx_which = 0; -#endif - -#if AO_USB_DIRECTIO -	sram_addr += (sram_addr & 1); -	ao_usb_sram_addr = sram_addr; +	ao_usb_in_tx2_offset = sram_addr; +	sram_addr += AO_USB_IN_SIZE * 2;  #endif  } @@ -450,11 +430,11 @@ ao_usb_init_btable(void)  {  	/* Set up EP 0 - a Control end point with 32 bytes of in and out buffers */ -	ao_usb_bdt[0].single.addr_tx = ao_usb_packet_buffer_offset(ao_usb_ep0_tx_buffer); -	ao_usb_bdt[0].single.count_tx = 0; +	stm_usb_bdt[0].single.addr_tx = ao_usb_ep0_tx_offset; +	stm_usb_bdt[0].single.count_tx = 0; -	ao_usb_bdt[0].single.addr_rx = ao_usb_packet_buffer_offset(ao_usb_ep0_rx_buffer); -	ao_usb_bdt[0].single.count_rx = ((1 << STM_USB_BDT_COUNT_RX_BL_SIZE) | +	stm_usb_bdt[0].single.addr_rx = ao_usb_ep0_rx_offset; +	stm_usb_bdt[0].single.count_rx = ((1 << STM_USB_BDT_COUNT_RX_BL_SIZE) |  				  (((AO_USB_CONTROL_SIZE / 32) - 1) << STM_USB_BDT_COUNT_RX_NUM_BLOCK));  } @@ -506,8 +486,8 @@ ao_usb_set_configuration(void)  #if AO_USB_HAS_INT  	/* Set up the INT end point */ -	ao_usb_bdt[AO_USB_INT_EPR].single.addr_tx = ao_usb_int_tx_offset; -	ao_usb_bdt[AO_USB_INT_EPR].single.count_tx = 0; +	stm_usb_bdt[AO_USB_INT_EPR].single.addr_tx = ao_usb_int_tx_offset; +	stm_usb_bdt[AO_USB_INT_EPR].single.count_tx = 0;  	ao_usb_init_ep(AO_USB_INT_EPR,  		       AO_USB_INT_EP, @@ -519,12 +499,12 @@ ao_usb_set_configuration(void)  #if AO_USB_HAS_OUT  	/* Set up the OUT end point */ -	ao_usb_bdt[AO_USB_OUT_EPR].double_rx[0].addr = ao_usb_out_rx_offset[0]; -	ao_usb_bdt[AO_USB_OUT_EPR].double_rx[0].count = ((1 << STM_USB_BDT_COUNT_RX_BL_SIZE) | +	stm_usb_bdt[AO_USB_OUT_EPR].double_rx[0].addr = ao_usb_out_rx_offset; +	stm_usb_bdt[AO_USB_OUT_EPR].double_rx[0].count = ((1 << STM_USB_BDT_COUNT_RX_BL_SIZE) |  							 (((AO_USB_OUT_SIZE / 32) - 1) << STM_USB_BDT_COUNT_RX_NUM_BLOCK)); -	ao_usb_bdt[AO_USB_OUT_EPR].double_rx[1].addr = ao_usb_out_rx_offset[1]; -	ao_usb_bdt[AO_USB_OUT_EPR].double_rx[1].count = ((1 << STM_USB_BDT_COUNT_RX_BL_SIZE) | +	stm_usb_bdt[AO_USB_OUT_EPR].double_rx[1].addr = ao_usb_out_rx_offset + AO_USB_OUT_SIZE; +	stm_usb_bdt[AO_USB_OUT_EPR].double_rx[1].count = ((1 << STM_USB_BDT_COUNT_RX_BL_SIZE) |  							 (((AO_USB_OUT_SIZE / 32) - 1) << STM_USB_BDT_COUNT_RX_NUM_BLOCK));  	/* set 'our' buffer to one, and the device buffer to 0 */ @@ -534,14 +514,17 @@ ao_usb_set_configuration(void)  		       STM_USB_EPR_STAT_RX_VALID,  		       STM_USB_EPR_STAT_TX_DISABLED,  		       STM_USB_EPR_EP_KIND_DBL_BUF, 0, 1); + +	/* At first receive, we'll flip this back to 0 */ +	ao_usb_out_rx_which = 1;  #endif  #if AO_USB_HAS_IN  	/* Set up the IN end point */ -	ao_usb_bdt[AO_USB_IN_EPR].double_tx[0].addr = ao_usb_in_tx_offset[0]; -	ao_usb_bdt[AO_USB_IN_EPR].double_tx[0].count = 0; -	ao_usb_bdt[AO_USB_IN_EPR].double_tx[1].addr = ao_usb_in_tx_offset[1]; -	ao_usb_bdt[AO_USB_IN_EPR].double_tx[1].count = 0; +	stm_usb_bdt[AO_USB_IN_EPR].double_tx[0].addr = ao_usb_in_tx_offset; +	stm_usb_bdt[AO_USB_IN_EPR].double_tx[0].count = 0; +	stm_usb_bdt[AO_USB_IN_EPR].double_tx[1].addr = ao_usb_in_tx_offset + AO_USB_IN_SIZE; +	stm_usb_bdt[AO_USB_IN_EPR].double_tx[1].count = 0;  	/* set 'our' buffer to 0, and the device buffer to 1 */  	ao_usb_init_ep(AO_USB_IN_EPR, @@ -551,12 +534,17 @@ ao_usb_set_configuration(void)  		       STM_USB_EPR_STAT_TX_NAK,  		       STM_USB_EPR_EP_KIND_DBL_BUF,  		       0, 1); + +	/* First transmit data goes to buffer 0 */ +	ao_usb_in_tx_which = 0;  #endif  #if AO_USB_HAS_IN2  	/* Set up the IN2 end point */ -	ao_usb_bdt[AO_USB_IN2_EPR].single.addr_tx = 0; -	ao_usb_bdt[AO_USB_IN2_EPR].single.count_tx = 0; +	stm_usb_bdt[AO_USB_IN2_EPR].double_tx[0].addr = ao_usb_in_tx2_offset; +	stm_usb_bdt[AO_USB_IN2_EPR].double_tx[0].count = 0; +	stm_usb_bdt[AO_USB_IN2_EPR].double_tx[1].addr = ao_usb_in_tx2_offset + AO_USB_IN_SIZE; +	stm_usb_bdt[AO_USB_IN2_EPR].double_tx[1].count = 0;  	ao_usb_init_ep(AO_USB_IN2_EPR,  		       AO_USB_IN2_EP, @@ -565,6 +553,9 @@ ao_usb_set_configuration(void)  		       STM_USB_EPR_STAT_TX_NAK,  		       STM_USB_EPR_EP_KIND_DBL_BUF,  		       0, 1); + +	/* First transmit data goes to buffer 0 */ +	ao_usb_in_tx2_which = 0;  #endif  	ao_usb_in_flushed = 0; @@ -599,47 +590,36 @@ static uint16_t	reset_count;   */  static void -ao_usb_copy_tx(const uint8_t *src, uint16_t *base, uint16_t bytes) +ao_usb_tx_byte(uint16_t offset, uint8_t byte)  { -	while (bytes >= 2) { -		*base++ = src[0] | (src[1] << 8); -		src += 2; -		bytes -= 2; -	} -	if (bytes) -		*base = *src; +	if (offset & 1) +		ao_usb_packet_put(offset - 1, +				  ao_usb_packet_get(offset - 1) | ((uint16_t) byte) << 8); +	else +		ao_usb_packet_put(offset, (uint16_t) byte);  } -static void -ao_usb_copy_rx(uint8_t *dst, uint16_t *base, uint16_t bytes) +static uint8_t +ao_usb_rx_byte(uint16_t offset)  { -	while (bytes >= 2) { -		uint16_t s = *base++; -		dst[0] = s; -		dst[1] = s >> 8; -		dst += 2; -		bytes -= 2; -	} -	if (bytes) -		*dst = *base; +	if (offset & 1) +		return (uint8_t) ((ao_usb_packet_get(offset - 1)) >> 8); +	else +		return (uint8_t) ao_usb_packet_get(offset);  } -static inline void -ao_usb_tx_byte(uint16_t *base, uint8_t tx_count, char byte) +static void +ao_usb_copy_tx(const uint8_t *src, uint16_t offset, uint16_t bytes)  { -	if (tx_count & 1) -		base[tx_count >> 1] |= ((uint16_t) byte) << 8; -	else -		base[tx_count >> 1] = (uint16_t) (uint8_t) byte; +	while (bytes--) +		ao_usb_tx_byte(offset++, *src++);  } -static inline char -ao_usb_rx_byte(uint16_t *base, uint8_t rx_count) +static void +ao_usb_copy_rx(uint8_t *dst, uint16_t offset, uint16_t bytes)  { -	if (rx_count & 1) -		return (char) (base[rx_count>>1] >> 8); -	else -		return (char) base[rx_count>>1]; +	while (bytes--) +		*dst++ = ao_usb_rx_byte(offset++);  }  /* Send an IN data packet */ @@ -664,12 +644,12 @@ ao_usb_ep0_flush(void)  	ao_usb_ep0_in_len -= this_len;  	debug_data ("Flush EP0 len %d:", this_len); -	ao_usb_copy_tx(ao_usb_ep0_in_data, ao_usb_ep0_tx_buffer, this_len); +	ao_usb_copy_tx(ao_usb_ep0_in_data, ao_usb_ep0_tx_offset, this_len);  	debug_data ("\n");  	ao_usb_ep0_in_data += this_len;  	/* Mark the endpoint as TX valid to send the packet */ -	ao_usb_bdt[AO_USB_CONTROL_EPR].single.count_tx = this_len; +	stm_usb_bdt[AO_USB_CONTROL_EPR].single.count_tx = this_len;  	ao_usb_set_stat_tx(AO_USB_CONTROL_EPR, STM_USB_EPR_STAT_TX_VALID);  	debug ("queue tx. epr 0 now %08x\n", stm_usb.epr[AO_USB_CONTROL_EPR]);  } @@ -678,7 +658,7 @@ ao_usb_ep0_flush(void)  static void  ao_usb_ep0_fill(void)  { -	uint16_t	len = ao_usb_bdt[0].single.count_rx & STM_USB_BDT_COUNT_RX_COUNT_RX_MASK; +	uint16_t	len = stm_usb_bdt[0].single.count_rx & STM_USB_BDT_COUNT_RX_COUNT_RX_MASK;  	if (len > ao_usb_ep0_out_len)  		len = ao_usb_ep0_out_len; @@ -686,7 +666,7 @@ ao_usb_ep0_fill(void)  	/* Pull all of the data out of the packet */  	debug_data ("Fill EP0 len %d:", len); -	ao_usb_copy_rx(ao_usb_ep0_out_data, ao_usb_ep0_rx_buffer, len); +	ao_usb_copy_rx(ao_usb_ep0_out_data, ao_usb_ep0_rx_offset, len);  	debug_data ("\n");  	ao_usb_ep0_out_data += len; @@ -1058,7 +1038,7 @@ _ao_usb_in_send(void)  	ao_usb_in_pending = 1;  	if (ao_usb_tx_count != AO_USB_IN_SIZE)  		ao_usb_in_flushed = 1; -	ao_usb_bdt[AO_USB_IN_EPR].double_tx[ao_usb_in_tx_which].count = ao_usb_tx_count; +	stm_usb_bdt[AO_USB_IN_EPR].double_tx[ao_usb_in_tx_which].count = ao_usb_tx_count;  	ao_usb_tx_count = 0;  	/* Toggle our usage */ @@ -1122,7 +1102,7 @@ ao_usb_putchar(char c)  	_ao_usb_in_wait();  	ao_usb_in_flushed = 0; -	ao_usb_tx_byte(ao_usb_in_tx_buffer[ao_usb_in_tx_which], ao_usb_tx_count++, c); +	ao_usb_tx_byte(ao_usb_in_tx_offset + AO_USB_IN_SIZE * ao_usb_in_tx_which + ao_usb_tx_count++, c);  	/* Send the packet when full */  	if (ao_usb_tx_count == AO_USB_IN_SIZE) { @@ -1146,11 +1126,15 @@ _ao_usb_in2_send(void)  	ao_usb_in2_pending = 1;  	if (ao_usb_tx2_count != AO_USB_IN_SIZE)  		ao_usb_in2_flushed = 1; -	ao_usb_bdt[AO_USB_IN2_EPR].single.addr_tx = ao_usb_in2_tx_offset[ao_usb_in2_tx_which]; -	ao_usb_bdt[AO_USB_IN2_EPR].single.count_tx = ao_usb_tx2_count; +	stm_usb_bdt[AO_USB_IN2_EPR].double_tx[ao_usb_in_tx2_which].count = ao_usb_tx2_count;  	ao_usb_tx2_count = 0; -	ao_usb_in2_tx_which = 1 - ao_usb_in2_tx_which; + +	/* Toggle our usage */ +	ao_usb_in_tx2_which = 1 - ao_usb_in_tx2_which; + +	/* Mark the outgoing buffer as valid */  	_ao_usb_set_stat_tx(AO_USB_IN2_EPR, STM_USB_EPR_STAT_TX_VALID); +  	_tx_dbg0("in2_send end");  } @@ -1203,8 +1187,7 @@ ao_usb_putchar2(char c)  	_ao_usb_in2_wait();  	ao_usb_in2_flushed = 0; -	ao_usb_tx_byte(ao_usb_in2_tx_buffer[ao_usb_in2_tx_which], ao_usb_tx2_count, c); -	ao_usb_tx2_count++; +	ao_usb_tx_byte(ao_usb_in_tx2_offset + AO_USB_IN_SIZE * ao_usb_in_tx2_which + ao_usb_tx2_count++, c);  	/* Send the packet when full */  	if (ao_usb_tx2_count == AO_USB_IN_SIZE) { @@ -1228,7 +1211,7 @@ _ao_usb_out_recv(void)  	/* Switch to new buffer */  	ao_usb_out_rx_which = 1 - ao_usb_out_rx_which; -	ao_usb_rx_count = ao_usb_bdt[AO_USB_OUT_EPR].double_rx[ao_usb_out_rx_which].count & STM_USB_BDT_COUNT_RX_COUNT_RX_MASK; +	ao_usb_rx_count = stm_usb_bdt[AO_USB_OUT_EPR].double_rx[ao_usb_out_rx_which].count & STM_USB_BDT_COUNT_RX_COUNT_RX_MASK;  	ao_usb_rx_pos = 0;  	/* Toggle the SW_BUF_RX bit */ @@ -1262,7 +1245,7 @@ _ao_usb_pollchar(void)  	}  	/* Pull a character out of the fifo */ -	c = ao_usb_rx_byte(ao_usb_out_rx_buffer[ao_usb_out_rx_which], ao_usb_rx_pos++); +	c = ao_usb_rx_byte(ao_usb_out_rx_offset + ao_usb_out_rx_which * AO_USB_OUT_SIZE + ao_usb_rx_pos++);  	_rx_dbg1("char", c);  	return c;  } @@ -1281,18 +1264,18 @@ ao_usb_getchar(void)  #endif  #if AO_USB_DIRECTIO -uint16_t * -ao_usb_alloc(void) -{ -	uint16_t	*buffer; -	buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr); -	ao_usb_sram_addr += AO_USB_IN_SIZE; -	return buffer; +#if AO_USB_HAS_IN +uint8_t +ao_usb_alloc(uint16_t *buffers[2]) +{ +	buffers[0] = ao_usb_packet_buffer_addr(ao_usb_in_tx_offset); +	buffers[1] = ao_usb_packet_buffer_addr(ao_usb_in_tx_offset + AO_USB_IN_SIZE); +	return ao_usb_in_tx_which;  } -void -ao_usb_write(uint16_t *buffer, uint16_t len) +uint8_t +ao_usb_write(uint16_t len)  {  	ao_arch_block_interrupts(); @@ -1304,12 +1287,6 @@ ao_usb_write(uint16_t *buffer, uint16_t len)  			continue;  		} -		/* Flush any pending regular I/O */ -		if (ao_usb_tx_count) { -			_ao_usb_in_send(); -			continue; -		} -  		/* Wait for an idle IN buffer */  		if (ao_usb_in_pending) {  			ao_sleep(&ao_usb_in_pending); @@ -1320,15 +1297,35 @@ ao_usb_write(uint16_t *buffer, uint16_t len)  	ao_usb_in_pending = 1;  	ao_usb_in_flushed = (len != AO_USB_IN_SIZE); -	ao_usb_bdt[AO_USB_IN_EPR].single.addr_tx = ao_usb_packet_buffer_offset(buffer); -	ao_usb_bdt[AO_USB_IN_EPR].single.count_tx = len; + +	stm_usb_bdt[AO_USB_IN_EPR].double_tx[ao_usb_in_tx_which].count = len; + +	/* Toggle our usage */ +	ao_usb_in_tx_which = 1 - ao_usb_in_tx_which; + +	/* Toggle the SW_BUF flag */ +	_ao_usb_toggle_dtog(AO_USB_IN_EPR, 1, 0); + +	/* Mark the outgoing buffer as valid */  	_ao_usb_set_stat_tx(AO_USB_IN_EPR, STM_USB_EPR_STAT_TX_VALID); +  	ao_arch_release_interrupts(); +	return ao_usb_in_tx_which;  } +#endif  #if AO_USB_HAS_IN2 -void -ao_usb_write2(uint16_t *buffer, uint16_t len) + +uint8_t +ao_usb_alloc2(uint16_t *buffers[2]) +{ +	buffers[0] = ao_usb_packet_buffer_addr(ao_usb_in_tx2_offset); +	buffers[1] = ao_usb_packet_buffer_addr(ao_usb_in_tx2_offset + AO_USB_IN_SIZE); +	return ao_usb_in_tx2_which; +} + +uint8_t +ao_usb_write2(uint16_t len)  {  	ao_arch_block_interrupts(); @@ -1340,12 +1337,6 @@ ao_usb_write2(uint16_t *buffer, uint16_t len)  			continue;  		} -		/* Flush any pending regular I/O */ -		if (ao_usb_tx2_count) { -			_ao_usb_in2_send(); -			continue; -		} -  		/* Wait for an idle IN buffer */  		if (ao_usb_in2_pending) {  			ao_sleep(&ao_usb_in2_pending); @@ -1356,10 +1347,20 @@ ao_usb_write2(uint16_t *buffer, uint16_t len)  	ao_usb_in2_pending = 1;  	ao_usb_in2_flushed = (len != AO_USB_IN_SIZE); -	ao_usb_bdt[AO_USB_IN2_EPR].single.addr_tx = ao_usb_packet_buffer_offset(buffer); -	ao_usb_bdt[AO_USB_IN2_EPR].single.count_tx = len; + +	stm_usb_bdt[AO_USB_IN2_EPR].double_tx[ao_usb_in_tx2_which].count = len; + +	/* Toggle our usage */ +	ao_usb_in_tx2_which = 1 - ao_usb_in_tx2_which; + +	/* Toggle the SW_BUF flag */ +	_ao_usb_toggle_dtog(AO_USB_IN2_EPR, 1, 0); + +	/* Mark the outgoing buffer as valid */  	_ao_usb_set_stat_tx(AO_USB_IN2_EPR, STM_USB_EPR_STAT_TX_VALID);  	ao_arch_release_interrupts(); + +	return ao_usb_in_tx2_which;  }  #endif  #endif diff --git a/src/stmf0/registers.ld b/src/stmf0/registers.ld index 1f9862b1..c301a7ce 100644 --- a/src/stmf0/registers.ld +++ b/src/stmf0/registers.ld @@ -26,6 +26,7 @@ stm_crs    = 0x40006c00;  stm_bxcan  = 0x40006400;  stm_usb_sram = 0x40006000; +stm_usb_bdt = 0x40006000;  stm_usb    = 0x40005c00;  stm_i2c1   = 0x40005400; diff --git a/src/stmf0/stm32f0.h b/src/stmf0/stm32f0.h index 277fa223..968c1295 100644 --- a/src/stmf0/stm32f0.h +++ b/src/stmf0/stm32f0.h @@ -2000,7 +2000,12 @@ union stm_usb_bdt {  #define STM_USB_BDT_SIZE	8 +/* We'll use the first block of usb SRAM for the BDT */  extern uint8_t stm_usb_sram[] __attribute__((aligned(4))); +extern union stm_usb_bdt stm_usb_bdt[STM_USB_BDT_SIZE] __attribute__((aligned(4))); + +#define stm_usb_sram	((uint8_t *) 0x40006000) +#define stm_usb_bdt	((union stm_usb_bdt *) 0x40006000)  struct stm_exti {  	vuint32_t	imr; | 
