static uint16_t *ao_usb_ep0_rx_buffer;
/* Pointer to bulk data tx/rx buffers in USB memory */
+static uint16_t ao_usb_in_tx_offset;
static uint16_t *ao_usb_in_tx_buffer;
static uint16_t *ao_usb_out_rx_buffer;
return (uint16_t *) (stm_usb_sram + sram_addr);
}
+#if AO_USB_DIRECTIO
+static inline uint16_t ao_usb_packet_buffer_offset(uint16_t *addr)
+{
+ return (uint16_t) ((uint8_t *) addr - stm_usb_sram);
+}
+#endif
+
static inline uint32_t ao_usb_epr_stat_rx(uint32_t epr) {
return (epr >> STM_USB_EPR_STAT_RX) & STM_USB_EPR_STAT_RX_MASK;
}
/* Set up the INT end point */
ao_usb_bdt[AO_USB_INT_EPR].single.addr_tx = ao_usb_sram_addr;
ao_usb_bdt[AO_USB_INT_EPR].single.count_tx = 0;
- ao_usb_in_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
ao_usb_sram_addr += AO_USB_INT_SIZE;
ao_usb_init_ep(AO_USB_INT_EPR,
/* Set up the IN end point */
ao_usb_bdt[AO_USB_IN_EPR].single.addr_tx = ao_usb_sram_addr;
ao_usb_bdt[AO_USB_IN_EPR].single.count_tx = 0;
- ao_usb_in_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
+ ao_usb_in_tx_offset = ao_usb_sram_addr;
+ ao_usb_in_tx_buffer = ao_usb_packet_buffer_addr(ao_usb_in_tx_offset);
ao_usb_sram_addr += AO_USB_IN_SIZE;
ao_usb_init_ep(AO_USB_IN_EPR,
*/
static void
-ao_usb_write(const uint8_t *src, uint16_t *base, uint16_t bytes)
+ao_usb_copy_tx(const uint8_t *src, uint16_t *base, uint16_t bytes)
{
while (bytes >= 2) {
*base++ = src[0] | (src[1] << 8);
}
static void
-ao_usb_read(uint8_t *dst, uint16_t *base, uint16_t bytes)
+ao_usb_copy_rx(uint8_t *dst, uint16_t *base, uint16_t bytes)
{
while (bytes >= 2) {
uint16_t s = *base++;
ao_usb_ep0_in_len -= this_len;
debug_data ("Flush EP0 len %d:", this_len);
- ao_usb_write(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_buffer, this_len);
debug_data ("\n");
ao_usb_ep0_in_data += this_len;
/* Pull all of the data out of the packet */
debug_data ("Fill EP0 len %d:", len);
- ao_usb_read(ao_usb_ep0_out_data, ao_usb_ep0_rx_buffer, len);
+ ao_usb_copy_rx(ao_usb_ep0_out_data, ao_usb_ep0_rx_buffer, len);
debug_data ("\n");
ao_usb_ep0_out_data += len;
ao_usb_in_pending = 1;
if (ao_usb_tx_count != AO_USB_IN_SIZE)
ao_usb_in_flushed = 1;
- ao_usb_write(ao_usb_tx_buffer, ao_usb_in_tx_buffer, ao_usb_tx_count);
+ ao_usb_copy_tx(ao_usb_tx_buffer, ao_usb_in_tx_buffer, ao_usb_tx_count);
+ ao_usb_bdt[AO_USB_IN_EPR].single.addr_tx = ao_usb_in_tx_offset;
ao_usb_bdt[AO_USB_IN_EPR].single.count_tx = ao_usb_tx_count;
ao_usb_tx_count = 0;
_ao_usb_set_stat_tx(AO_USB_IN_EPR, STM_USB_EPR_STAT_TX_VALID);
_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);
- ao_usb_read(ao_usb_rx_buffer, ao_usb_out_rx_buffer, ao_usb_rx_count);
+ ao_usb_copy_rx(ao_usb_rx_buffer, ao_usb_out_rx_buffer, ao_usb_rx_count);
debug_data("\n");
ao_usb_rx_pos = 0;
return c;
}
+#if AO_USB_DIRECTIO
+uint16_t *
+ao_usb_alloc(void)
+{
+ uint16_t *buffer;
+
+ if (!ao_usb_running)
+ return NULL;
+ buffer = ao_usb_packet_buffer_addr(ao_usb_sram_addr);
+ ao_usb_sram_addr += AO_USB_IN_SIZE;
+ return buffer;
+}
+
+void
+ao_usb_free(uint16_t *addr)
+{
+ uint16_t offset = ao_usb_packet_buffer_offset(addr);
+ if (offset < ao_usb_sram_addr)
+ ao_usb_sram_addr = offset;
+}
+
+void
+ao_usb_write(uint16_t *buffer, uint16_t len)
+{
+ ao_arch_block_interrupts();
+
+ /* Flush any pending regular */
+ if (ao_usb_tx_count)
+ _ao_usb_in_send();
+
+ while (ao_usb_in_pending)
+ ao_sleep(&ao_usb_in_pending);
+ 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;
+ _ao_usb_set_stat_tx(AO_USB_IN_EPR, STM_USB_EPR_STAT_TX_VALID);
+ ao_arch_release_interrupts();
+}
+#endif
+
void
ao_usb_disable(void)
{