*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
#define debug(format, args...)
#endif
-struct ao_task __xdata ao_usb_task;
+struct ao_task ao_usb_task;
struct ao_usb_setup {
uint8_t dir_type_recip;
uint16_t value;
uint16_t index;
uint16_t length;
-} __xdata ao_usb_setup;
-
-static __xdata uint8_t ao_usb_ep0_state;
-static const uint8_t * __xdata ao_usb_ep0_in_data;
-static __xdata uint8_t ao_usb_ep0_in_len;
-static __xdata uint8_t ao_usb_ep0_in_pending;
-static __xdata uint8_t ao_usb_addr_pending;
-static __xdata uint8_t ao_usb_ep0_in_buf[2];
-static __xdata uint8_t ao_usb_ep0_out_len;
-static __xdata uint8_t *__xdata ao_usb_ep0_out_data;
-
-static __xdata uint8_t ao_usb_in_flushed;
-static __xdata uint8_t ao_usb_running;
-static __xdata uint8_t ao_usb_configuration;
-static __xdata uint8_t ueienx_0;
+} ao_usb_setup;
+
+static uint8_t ao_usb_ep0_state;
+static const uint8_t * ao_usb_ep0_in_data;
+static uint8_t ao_usb_ep0_in_len;
+static uint8_t ao_usb_ep0_in_pending;
+static uint8_t ao_usb_addr_pending;
+static uint8_t ao_usb_ep0_in_buf[2];
+static uint8_t ao_usb_ep0_out_len;
+static uint8_t *ao_usb_ep0_out_data;
+
+static uint8_t ao_usb_in_flushed;
+uint8_t ao_usb_running;
+static uint8_t ao_usb_configuration;
+static uint8_t ueienx_0;
void
ao_usb_set_address(uint8_t address)
}
-__xdata static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
+struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
/* Walk through the list of descriptors and find a match
*/
static void
ao_usb_get_descriptor(uint16_t value)
{
- const uint8_t *__xdata descriptor;
- __xdata uint8_t type = value >> 8;
- __xdata uint8_t index = value;
+ const uint8_t *descriptor;
+ uint8_t type = value >> 8;
+ uint8_t index = value;
descriptor = ao_usb_descriptors;
while (descriptor[0] != 0) {
static void
ao_usb_ep0_flush(void)
{
- __xdata uint8_t this_len;
+ uint8_t this_len;
cli();
UENUM = 0;
ao_usb_ep0_setup(void)
{
/* Pull the setup packet out of the fifo */
- ao_usb_ep0_out_data = (__xdata uint8_t *) &ao_usb_setup;
+ ao_usb_ep0_out_data = (uint8_t *) &ao_usb_setup;
ao_usb_ep0_out_len = 8;
ao_usb_ep0_fill(8, (1 << RXSTPI) | (1 << RXOUTI) | (1 << TXINI));
if (ao_usb_ep0_out_len != 0) {
case AO_USB_SET_LINE_CODING:
debug ("set line coding\n");
ao_usb_ep0_out_len = 7;
- ao_usb_ep0_out_data = (__xdata uint8_t *) &ao_usb_line_coding;
+ ao_usb_ep0_out_data = (uint8_t *) &ao_usb_line_coding;
break;
case AO_USB_GET_LINE_CODING:
debug ("get line coding\n");
/* Wait for a free IN buffer */
static void
-ao_usb_in_wait(void)
+_ao_usb_in_wait(void)
{
for (;;) {
/* Check if the current buffer is writable */
if (UEINTX & (1 << RWAL))
break;
- cli();
/* Wait for an IN buffer to be ready */
for (;;) {
UENUM = AO_USB_IN_EP;
}
/* Ack the interrupt */
UEINTX &= ~(1 << TXINI);
- sei();
}
}
/* Queue the current IN buffer for transmission */
static void
-ao_usb_in_send(void)
+_ao_usb_in_send(void)
{
UENUM = AO_USB_IN_EP;
UEINTX &= ~(1 << FIFOCON);
}
void
-ao_usb_flush(void) __critical
+ao_usb_flush(void)
{
if (!ao_usb_running)
return;
+ ao_arch_block_interrupts();
/* Anytime we've sent a character since
* the last time we flushed, we'll need
* to send a packet -- the only other time
*/
if (!ao_usb_in_flushed) {
ao_usb_in_flushed = 1;
- ao_usb_in_wait();
- ao_usb_in_send();
+ _ao_usb_in_wait();
+ _ao_usb_in_send();
}
+ ao_arch_release_interrupts();
}
void
-ao_usb_putchar(char c) __critical __reentrant
+ao_usb_putchar(char c)
{
if (!ao_usb_running)
return;
- ao_usb_in_wait();
+ ao_arch_block_interrupts();
+ _ao_usb_in_wait();
/* Queue a byte */
UENUM = AO_USB_IN_EP;
/* Send the packet when full */
if ((UEINTX & (1 << RWAL)) == 0)
- ao_usb_in_send();
+ _ao_usb_in_send();
ao_usb_in_flushed = 0;
+ ao_arch_release_interrupts();
}
-static char
+int
_ao_usb_pollchar(void)
{
- char c;
+ uint8_t c;
uint8_t intx;
if (!ao_usb_running)
}
char
-ao_usb_pollchar(void)
-{
- char c;
- cli();
- c = _ao_usb_pollchar();
- sei();
- return c;
-}
-
-char
-ao_usb_getchar(void) __critical
+ao_usb_getchar(void)
{
- char c;
+ int c;
- cli();
+ ao_arch_block_interrupts();
while ((c = _ao_usb_pollchar()) == AO_READ_AGAIN)
ao_sleep(&ao_stdin_ready);
- sei();
+ ao_arch_release_interrupts();
return c;
}
}
#if USB_DEBUG
-struct ao_task __xdata ao_usb_echo_task;
+struct ao_task ao_usb_echo_task;
static void
ao_usb_echo(void)
}
#endif
-static void
-ao_usb_irq(void)
-{
- printf ("control: %d out: %d in: %d\n",
- control_count, out_count, in_count);
-}
-
-__code struct ao_cmds ao_usb_cmds[] = {
- { ao_usb_irq, "i\0Show USB interrupt counts" },
- { 0, NULL }
-};
-
void
ao_usb_init(void)
{
#if USB_DEBUG
ao_add_task(&ao_usb_echo_task, ao_usb_echo, "usb echo");
#endif
- ao_cmd_register(&ao_usb_cmds[0]);
- ao_add_stdio(ao_usb_pollchar, ao_usb_putchar, ao_usb_flush);
+ ao_add_stdio(_ao_usb_pollchar, ao_usb_putchar, ao_usb_flush);
}