usbconsole.c (2804B)
1 /* usbconsole.c 2 * 3 * Copyright 2011 Brian Swetland <swetland@frotz.net> 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #include <fw/types.h> 19 #include <fw/lib.h> 20 21 #include <arch/cpu.h> 22 23 #define UC_OUT_SZ 256 24 #define UC_IN_SZ 32 25 26 struct usbconsole { 27 volatile u32 out_head; 28 volatile u32 out_tail; 29 volatile u32 out_busy; 30 volatile u32 in_count; 31 u8 *out_data; 32 // u8 *in_data; 33 }; 34 35 /* buffers separate from main structure to save on flash size */ 36 static u8 uc_out_buffer[UC_OUT_SZ]; 37 //static u8 uc_in_buffer[UC_IN_SZ]; 38 39 static struct usbconsole the_usb_console = { 40 .out_head = 0, 41 .out_tail = 0, 42 .out_busy = 1, 43 .in_count = 0, 44 .out_data = uc_out_buffer, 45 // .in_data = uc_in_buffer, 46 }; 47 48 static void uc_write(struct usbconsole *uc) { 49 u32 pos, len, rem; 50 51 pos = uc->out_tail & (UC_OUT_SZ - 1); 52 len = uc->out_head - uc->out_tail; 53 rem = UC_OUT_SZ - pos; 54 55 if (len > rem) 56 len = rem; 57 if (len > 64) 58 len = 64; 59 60 disable_interrupts(); 61 uc->out_busy = 1; 62 usb_ep1_write(uc->out_data + pos, len); 63 enable_interrupts(); 64 uc->out_tail += len; 65 } 66 67 static void uc_putc(unsigned c) { 68 struct usbconsole *uc = &the_usb_console; 69 while ((uc->out_head - uc->out_tail) == UC_OUT_SZ) { 70 if (!uc->out_busy) 71 uc_write(uc); 72 } 73 uc->out_data[uc->out_head & (UC_OUT_SZ - 1)] = c; 74 uc->out_head++; 75 } 76 77 void printu(const char *fmt, ...) { 78 struct usbconsole *uc = &the_usb_console; 79 va_list ap; 80 va_start(ap, fmt); 81 vprintx(uc_putc, fmt, ap); 82 va_end(ap); 83 if ((uc->out_head - uc->out_tail) && (!uc->out_busy)) { 84 uc_write(uc); 85 } 86 } 87 88 void handle_ep1_tx_empty(void) { 89 struct usbconsole *uc = &the_usb_console; 90 uc->out_busy = 0; 91 if (uc->out_head - uc->out_tail) 92 uc_write(uc); 93 } 94 95 void (*usb_console_rx_cb)(u8 *buf, int len); 96 97 void handle_ep1_rx_full(void) { 98 // struct usbconsole *uc = &the_usb_console; 99 u8 buf[65]; 100 int len = usb_ep1_read(buf, 64); 101 102 if (usb_console_rx_cb) 103 usb_console_rx_cb(buf, len); 104 } 105 106 void handle_usb_online(int yes) { 107 if (yes) { 108 handle_ep1_tx_empty(); 109 } else { 110 the_usb_console.out_busy = 1; 111 } 112 } 113 114 void usb_console_init(void) { 115 usb_ep1_tx_empty_cb = handle_ep1_tx_empty; 116 usb_ep1_rx_full_cb = handle_ep1_rx_full; 117 usb_online_cb = handle_usb_online; 118 // usb_init(0x18d1, 0xdb05, 0, 0); 119 usb_unmask_ep1_tx_empty(); 120 usb_unmask_ep1_rx_full(); 121 } 122