Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <usb/usb.h>
00022 #include <usb/usb_device.h>
00023 #include "usb_function_cdc.h"
00024 #include "usb-buffer.h"
00025 #include "usb_uart.h"
00026
00027 struct fifo {
00028 unsigned char * buffer;
00029 size_t size;
00030 size_t insert;
00031 size_t consume;
00032 };
00033
00034 static struct {
00035 struct fifo rx;
00036 struct fifo tx;
00037 } AsebaUsb;
00038
00039
00040
00041
00042
00043 static inline size_t get_used(struct fifo * f) {
00044 size_t ipos, cpos;
00045 ipos = f->insert;
00046 cpos = f->consume;
00047 if (ipos >= cpos)
00048 return ipos - cpos;
00049 else
00050 return f->size - cpos + ipos;
00051 }
00052
00053 static inline size_t get_free(struct fifo * f) {
00054 return f->size - get_used(f);
00055 }
00056
00057
00058
00059
00060 static inline void memcpy_out_fifo(unsigned char * dest, struct fifo * f, size_t size) {
00061 while(size--) {
00062 *dest++ = f->buffer[f->consume++];
00063 if(f->consume == f->size)
00064 f->consume = 0;
00065 }
00066 }
00067
00068 static inline void memcpy_to_fifo(struct fifo * f, const unsigned char * src, size_t size) {
00069 while(size--) {
00070 f->buffer[f->insert++] = *src++;
00071 if(f->insert == f->size)
00072 f->insert = 0;
00073 }
00074 }
00075
00076 static inline void fifo_peek(unsigned char * d, struct fifo * f,size_t size) {
00077 int ct = f->consume;
00078 while(size--) {
00079 *d++ = f->buffer[ct++];
00080 if(ct == f->size)
00081 ct = 0;
00082 }
00083 }
00084
00085 static inline void fifo_reset(struct fifo * f) {
00086 f->insert = f->consume = 0;
00087 }
00088
00089
00090
00091 static int tx_busy;
00092 static int debug;
00093
00094 unsigned char AsebaTxReady(unsigned char *data) {
00095 size_t size = get_used(&AsebaUsb.tx);
00096
00097 if(size == 0) {
00098 tx_busy = 0;
00099 debug = 0;
00100 return 0;
00101 }
00102
00103 if(size > ASEBA_USB_MTU)
00104 size = ASEBA_USB_MTU;
00105
00106 memcpy_out_fifo(data, &AsebaUsb.tx, size);
00107 debug ++;
00108 return size;
00109 }
00110
00111 int AsebaUsbBulkRecv(unsigned char *data, unsigned char size) {
00112 size_t free = get_free(&AsebaUsb.rx);
00113
00114 if(size >= free)
00115 return 1;
00116
00117 memcpy_to_fifo(&AsebaUsb.rx, data, size);
00118
00119 return 0;
00120 }
00121
00122
00123
00124 void AsebaSendBuffer(AsebaVMState *vm, const uint8 *data, uint16 length) {
00125 int flags;
00126
00127
00128 if(!usb_uart_serial_port_open())
00129 return;
00130
00131
00132 if (length < 2)
00133 return;
00134
00135 do {
00136 USBMaskInterrupts(flags);
00137 if(get_free(&AsebaUsb.tx) > length + 4) {
00138 length -= 2;
00139 memcpy_to_fifo(&AsebaUsb.tx, (unsigned char *) &length, 2);
00140 memcpy_to_fifo(&AsebaUsb.tx, (unsigned char *) &vm->nodeId, 2);
00141 memcpy_to_fifo(&AsebaUsb.tx, (unsigned char *) data, length + 2);
00142
00143
00144 if (!tx_busy) {
00145 tx_busy = 1;
00146 USBCDCKickTx();
00147 }
00148
00149 length = 0;
00150 }
00151
00152
00153
00154
00155 if(!usb_uart_serial_port_open()) {
00156 fifo_reset(&AsebaUsb.tx);
00157 USBUnmaskInterrupts(flags);
00158 break;
00159 }
00160
00161 USBUnmaskInterrupts(flags);
00162 } while(length);
00163 }
00164
00165 uint16 AsebaGetBuffer(AsebaVMState *vm, uint8 * data, uint16 maxLength, uint16* source) {
00166 int flags;
00167 uint16 ret = 0;
00168 size_t u;
00169
00170 USBMaskInterrupts(flags);
00171
00172 u = get_used(&AsebaUsb.rx);
00173
00174
00175 if(u >= 6) {
00176 int len;
00177 fifo_peek((unsigned char *) &len, &AsebaUsb.rx, 2);
00178 if (u >= len + 6) {
00179 memcpy_out_fifo((unsigned char *) &len, &AsebaUsb.rx, 2);
00180 memcpy_out_fifo((unsigned char *) source, &AsebaUsb.rx, 2);
00181
00182 len = len + 2;
00183
00184 if(len > maxLength)
00185 len = maxLength;
00186 memcpy_out_fifo(data, &AsebaUsb.rx, len);
00187 ret = len;
00188 }
00189 }
00190 if(usb_uart_serial_port_open())
00191 USBCDCKickRx();
00192 else
00193 fifo_reset(&AsebaUsb.rx);
00194
00195 USBUnmaskInterrupts(flags);
00196 return ret;
00197 }
00198
00199 void AsebaUsbInit(unsigned char * sendQueue, size_t sendQueueSize, unsigned char * recvQueue, size_t recvQueueSize) {
00200 AsebaUsb.tx.buffer = sendQueue;
00201 AsebaUsb.tx.size = sendQueueSize;
00202
00203 AsebaUsb.rx.buffer = recvQueue;
00204 AsebaUsb.rx.size = recvQueueSize;
00205 }
00206
00207 int AsebaUsbRecvBufferEmpty(void) {
00208
00209
00210 int u;
00211
00212 u = get_used(&AsebaUsb.rx);
00213 if(u > 6) {
00214 int len;
00215 fifo_peek((unsigned char *) &len, &AsebaUsb.rx, 2);
00216 if (u >= len + 6)
00217 return 0;
00218 }
00219 return 1;
00220 }
00221
00222 int AsebaUsbTxBusy(void) {
00223 return tx_busy;
00224 }