usb-arch.c

00001 #include <usb-arch.h>
00002 #include <gpio.h>
00003 #include <nvic.h>
00004 #include <stdio.h>
00005 #include <debug-uart.h>
00006 #include <usb-stm32f103.h>
00007 
00008 /* #define DEBUG     */
00009 #ifdef DEBUG
00010 #define PRINTF(...) printf(__VA_ARGS__)
00011 #else
00012 #define PRINTF(...)
00013 #endif
00014 typedef struct
00015 {
00016   vu32 EPR[8];
00017   u32  RESERVED[8];
00018   vu32 CNTR;
00019   vu32 ISTR;
00020   vu32 FNR;
00021   vu32 DADDR;
00022   vu32 BTABLE;
00023 } USB_TypeDef;
00024 
00025 #define USB_BASE             (APB1PERIPH_BASE + 0x5c00)
00026 #define USB_MEM_BASE         (APB1PERIPH_BASE + 0x6000)
00027 #define USB_MEM_SIZE         (512)
00028 #define USB ((volatile USB_TypeDef *) USB_BASE)
00029 
00030 typedef struct {
00031   vu32 ADDR_TX;
00032   vu32 COUNT_TX;
00033   vu32 ADDR_RX;
00034   vu32 COUNT_RX;
00035 } USB_HW_Buffer;
00036 
00037 #define USB_EP0_BUF_SIZE (2*CTRL_EP_SIZE)
00038 
00039 #define USB_EP1_BUF_SIZE (2*USB_EP1_SIZE)
00040 
00041 #define USB_EP2_BUF_SIZE (2*USB_EP2_SIZE)
00042 
00043 #define USB_EP3_BUF_SIZE (2*USB_EP3_SIZE)
00044 
00045 #define USB_EP4_BUF_SIZE (2*USB_EP4_SIZE)
00046 
00047 #define USB_EP5_BUF_SIZE (2*USB_EP5_SIZE)
00048 
00049 #define USB_EP6_BUF_SIZE (2*USB_EP6_SIZE)
00050 
00051 #define USB_EP7_BUF_SIZE (2*USB_EP7_SIZE)
00052 
00053 
00054 
00055 #ifndef MAX_CTRL_DATA
00056 #define MAX_CTRL_DATA 128
00057 #endif
00058 /* Double buffered IN endpoint */
00059 #define ADDR_TX_0 ADDR_TX
00060 #define ADDR_TX_1 ADDR_RX
00061 #define COUNT_TX_0 COUNT_TX
00062 #define COUNT_TX_1 COUNT_RX
00063 
00064 /* Double buffered OUT endpoint */
00065 #define ADDR_RX_0 ADDR_TX
00066 #define ADDR_RX_1 ADDR_RX
00067 #define COUNT_RX_0 COUNT_TX
00068 #define COUNT_RX_1 COUNT_RX
00069 
00070 #define USB_EPxR_EP_TYPE_BULK 0
00071 #define USB_EPxR_EP_TYPE_CONTROL USB_EP0R_EP_TYPE_0
00072 #define USB_EPxR_EP_TYPE_ISO USB_EP0R_EP_TYPE_1
00073 #define USB_EPxR_EP_TYPE_INTERRUPT (USB_EP0R_EP_TYPE_1|USB_EP0R_EP_TYPE_0)
00074 
00075 #define USB_EPxR_EP_DBL_BUF USB_EP0R_EP_KIND
00076 #define USB_EPxR_EP_STATUS_OUT USB_EP0R_EP_KIND
00077 
00078 #define USB_EPxR_STAT_RX_DISABLED 0
00079 #define USB_EPxR_STAT_RX_STALL USB_EP0R_STAT_RX_0
00080 #define USB_EPxR_STAT_RX_NAK USB_EP0R_STAT_RX_1
00081 #define USB_EPxR_STAT_RX_VALID (USB_EP0R_STAT_RX_1|USB_EP0R_STAT_RX_0)
00082 
00083 #define USB_EPxR_STAT_TX_DISABLED 0
00084 #define USB_EPxR_STAT_TX_STALL USB_EP0R_STAT_TX_0
00085 #define USB_EPxR_STAT_TX_NAK USB_EP0R_STAT_TX_1
00086 #define USB_EPxR_STAT_TX_VALID (USB_EP0R_STAT_TX_1|USB_EP0R_STAT_TX_0)
00087 
00088 #define USB_EPxR_SW_BUF_TX USB_EP0R_DTOG_RX
00089 #define USB_EPxR_SW_BUF_RX USB_EP0R_DTOG_TX
00090 
00091 static const uint16_t ep_buffer_size[8] =
00092   {
00093     USB_EP0_BUF_SIZE,
00094     USB_EP1_BUF_SIZE,
00095     USB_EP2_BUF_SIZE,
00096     USB_EP3_BUF_SIZE,
00097     USB_EP4_BUF_SIZE,
00098     USB_EP5_BUF_SIZE,
00099     USB_EP6_BUF_SIZE,
00100     USB_EP7_BUF_SIZE
00101   };
00102 
00103 #define USB_EP_BUF_SIZE(ep) ep_buffer_size[ep]
00104 #define USB_EP_BUF_OFFSET(ep) ep_buffer_offset[ep]
00105 #define USB_EP_BUF_ADDR(ep) (u32*)(USB_MEM_BASE + ep_buffer_offset[ep]*2);
00106 #define USB_EP_BUF_DESC(ep) ((USB_HW_Buffer*)(USB_MEM_BASE + 16 * (ep)))
00107 
00108 #define USB_EP0_OFFSET (8*USB_MAX_ENDPOINTS)
00109 #define USB_EP1_OFFSET (USB_EP0_OFFSET + USB_EP0_BUF_SIZE)
00110 #define USB_EP2_OFFSET (USB_EP1_OFFSET + USB_EP1_BUF_SIZE)
00111 #define USB_EP3_OFFSET (USB_EP2_OFFSET + USB_EP2_BUF_SIZE)
00112 #define USB_EP4_OFFSET (USB_EP3_OFFSET + USB_EP3_BUF_SIZE)
00113 #define USB_EP5_OFFSET (USB_EP4_OFFSET + USB_EP4_BUF_SIZE)
00114 #define USB_EP6_OFFSET (USB_EP5_OFFSET + USB_EP5_BUF_SIZE)
00115 #define USB_EP7_OFFSET (USB_EP6_OFFSET + USB_EP6_BUF_SIZE)
00116 
00117 #if (USB_EP7_OFFSET+USB_EP7_BUF_SIZE) > USB_MEM_SIZE
00118 #error USB endpoints buffers does not fit in USB memory
00119 #endif
00120 static const uint16_t ep_buffer_offset[8] =
00121   {
00122     USB_EP0_OFFSET,
00123     USB_EP1_OFFSET,
00124     USB_EP2_OFFSET,
00125     USB_EP3_OFFSET,
00126     USB_EP4_OFFSET,
00127     USB_EP5_OFFSET,
00128     USB_EP6_OFFSET,
00129     USB_EP7_OFFSET
00130   };
00131 
00132 #define USB_EP_BUF_CAPACITY(s) ((((s) <64)?((s)/2):(0x20 | ((s)/64)))<<10)
00133 
00134 typedef struct _USBEndpoint USBEndpoint;
00135 struct _USBEndpoint
00136 {
00137   uint16_t status;
00138   uint8_t addr;
00139   uint8_t flags;
00140   USBBuffer *buffer;    /* NULL if no current buffer */
00141   struct process *event_process;
00142   uint16_t events;
00143   uint16_t xfer_size;
00144 };
00145 
00146 #define USB_EP_FLAGS_TYPE_MASK 0x03
00147 #define USB_EP_FLAGS_TYPE_BULK 0x00
00148 #define USB_EP_FLAGS_TYPE_CONTROL 0x01
00149 #define USB_EP_FLAGS_TYPE_ISO 0x02
00150 #define USB_EP_FLAGS_TYPE_INTERRUPT 0x03
00151 
00152 #define IS_EP_TYPE(ep, type) (((ep)->flags & USB_EP_FLAGS_TYPE_MASK) == (type))
00153 #define IS_CONTROL_EP(ep) IS_EP_TYPE(ep, USB_EP_FLAGS_TYPE_CONTROL)
00154 #define IS_BULK_EP(ep) IS_EP_TYPE(ep, USB_EP_FLAGS_TYPE_BULK)
00155 #define IS_INTERRUPT_EP(ep) IS_EP_TYPE(ep, USB_EP_FLAGS_TYPE_INTERRUPT)
00156 
00157 #define USB_EP_FLAGS_ENABLED 0x04
00158 
00159 /* A packet has been received but the data is still in hardware buffer */
00160 #define USB_EP_FLAGS_RECV_PENDING 0x08
00161 /* The pending packet is a SETUP packet */
00162 #define USB_EP_FLAGS_SETUP_PENDING 0x10
00163 
00164 /* The data in the hardware buffer is being transmitted */
00165 #define USB_EP_FLAGS_TRANSMITTING 0x20
00166 
00167 /* The  receiver is waiting for a packet */
00168 #define USB_EP_FLAGS_RECEIVING 0x40
00169 
00170 /* For bulk endpoints. Both buffers are busy are in use, either by
00171    hardware or software. */
00172 #define USB_EP_FLAGS_DOUBLE 0x80
00173 
00174 /* States for double buffered reception:
00175 
00176 Packets being received  0       1       2       1       0       0
00177 Packets pending         0       0       0       1       2       1
00178 
00179 RECVING                 0       1       1       1       0       0
00180 RECV_PENDING            0       0       0       1       1       1
00181 DOUBLE                  0       0       1       0       1       0
00182 */
00183 
00184 /* States for double buffered transmission:
00185    
00186 Packets being transmitted       0       1       2
00187 
00188 TRANSMITTING                    0       1       1
00189 DOUBLE                          0       0       1
00190 */
00191 
00192 /* Index in endpoint array */
00193 #define EP_INDEX(addr) ((addr) & 0x7f)
00194 
00195 /* Get address of endpoint struct */
00196 #define EP_STRUCT(addr) (&usb_endpoints[EP_INDEX(addr)])
00197 
00198 /* Number of hardware endpoint */
00199 #define EP_HW_NUM(addr) ((addr) & 0x7f)
00200 
00201 #define USB_DISABLE_INT \
00202   NVIC_DISABLE_INT(USB_LP_CAN_RX0_IRQChannel);\
00203   NVIC_DISABLE_INT(USB_HP_CAN_TX_IRQChannel)
00204 
00205 #define USB_ENABLE_INT \
00206   NVIC_ENABLE_INT(USB_LP_CAN_RX0_IRQChannel);\
00207   NVIC_ENABLE_INT(USB_HP_CAN_TX_IRQChannel)
00208 
00209 static inline uint32_t
00210 usb_save_disable_int()
00211 {
00212   uint32_t v = NVIC->ISER[0];
00213   NVIC->ICER[0] = (1<<USB_HP_CAN_TX_IRQChannel | 1<<USB_LP_CAN_RX0_IRQChannel);
00214   return v;
00215 }
00216 
00217 static inline void
00218 usb_restore_int(uint32_t v)
00219 {
00220   NVIC->ISER[0] =
00221     v & (1<<USB_HP_CAN_TX_IRQChannel | 1<<USB_LP_CAN_RX0_IRQChannel);
00222 }
00223 
00224 static USBEndpoint usb_endpoints[USB_MAX_ENDPOINTS];
00225 struct process *event_process = 0;
00226 volatile unsigned int events = 0;
00227 
00228 static void
00229 notify_process(unsigned int e)
00230 {
00231   events |= e;
00232   if (event_process) {
00233     process_poll(event_process);
00234   }
00235 }
00236 
00237 static void
00238 notify_ep_process(USBEndpoint *ep, unsigned int e)
00239 {
00240   ep->events |= e;
00241   if (ep->event_process) {
00242     process_poll(ep->event_process);
00243   }
00244 }
00245 
00246 
00247 static void
00248 usb_arch_reset(void)
00249 {
00250   unsigned int e;
00251   for (e = 0; e < USB_MAX_ENDPOINTS; e++) {
00252     if (usb_endpoints[e].flags &USB_EP_FLAGS_ENABLED) {
00253       USBBuffer *buffer = usb_endpoints[e].buffer;
00254       usb_endpoints[e].flags = 0;
00255       while(buffer) {
00256         buffer->flags &= ~USB_BUFFER_SUBMITTED;
00257         buffer = buffer->next;
00258       }
00259     }
00260   }
00261   usb_arch_setup_control_endpoint(0);  
00262   USB->DADDR = 0x80;
00263 }
00264 
00265 void
00266 usb_arch_setup(void)
00267 {
00268   unsigned int i;
00269   RCC->APB1RSTR |= RCC_APB1RSTR_USBRST;
00270   RCC->APB2ENR |=  (RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN);
00271   RCC->APB1ENR |= (RCC_APB1ENR_USBEN);
00272   RCC->APB1RSTR &= ~RCC_APB1RSTR_USBRST;
00273 
00274   GPIO_CONF_OUTPUT_PORT(A,11,ALT_PUSH_PULL,50);
00275   GPIO_CONF_OUTPUT_PORT(A,12,ALT_PUSH_PULL,50);
00276   GPIO_CONF_OUTPUT_PORT(A,10, PUSH_PULL, 2);
00277   GPIOA->BSRR = GPIO_BSRR_BR10;
00278 
00279   /* Turn on analog part */
00280   USB->CNTR &= ~USB_CNTR_PDWN;
00281   
00282   for (i = 0; i < 24; i++) asm("nop"::); /* Wait at least 1us */
00283   /* Release reset */
00284   USB->CNTR &= ~USB_CNTR_FRES;
00285   /* Clear any interrupts */
00286   USB->ISTR = ~(USB_ISTR_PMAOVR |USB_ISTR_ERR | USB_ISTR_WKUP | USB_ISTR_SUSP
00287                 | USB_ISTR_RESET);
00288 
00289   for(i = 0; i < USB_MAX_ENDPOINTS; i++) {
00290     usb_endpoints[i].flags = 0;
00291     usb_endpoints[i].event_process = 0;
00292   }
00293   /* Put buffer table at beginning of buffer memory */
00294   USB->BTABLE = 0;
00295   usb_arch_reset();
00296   GPIOA->BSRR = GPIO_BSRR_BS10;
00297   USB->CNTR |= (USB_CNTR_CTRM | USB_CNTR_PMAOVRM | USB_CNTR_ERRM
00298                 | USB_CNTR_WKUPM| USB_CNTR_SUSPM | USB_CNTR_RESETM);
00299   NVIC_SET_PRIORITY(USB_LP_CAN_RX0_IRQChannel, 4);
00300   NVIC_ENABLE_INT(USB_LP_CAN_RX0_IRQChannel);
00301 }
00302 
00303 #define EPR_RW (USB_EP0R_EP_TYPE|USB_EP0R_EP_KIND|USB_EP0R_EA)
00304 #define EPR_W0 (USB_EP0R_CTR_RX|USB_EP0R_CTR_TX)
00305 #define EPR_TOGGLE (USB_EP0R_DTOG_RX | USB_EP0R_STAT_RX \
00306                     | USB_EP0R_DTOG_TX | USB_EP0R_STAT_TX)
00307 
00308 #define EPR_INVARIANT(epr) ((epr & (EPR_RW)) | EPR_W0)
00309 
00310 #define EPR_TOGGLE_SET(epr, mask, set) \
00311 ((((epr) & (EPR_RW | (mask))) | EPR_W0) ^ (set))
00312 
00313 static void
00314 usb_arch_setup_endpoint(unsigned char addr)
00315 {
00316   USBEndpoint *ep = EP_STRUCT(addr);
00317   ep->status = 0;
00318   ep->flags = USB_EP_FLAGS_ENABLED;
00319   ep->buffer = 0;
00320   ep->addr = addr;
00321   ep->events = 0;
00322   ep->xfer_size = 0;
00323 };
00324 
00325 void
00326 usb_arch_setup_control_endpoint(unsigned char addr)
00327 {
00328   USB_HW_Buffer *buf_desc;
00329   unsigned int ei = EP_HW_NUM(addr);
00330   unsigned int epr;
00331   USBEndpoint *ep = EP_STRUCT(addr);
00332   usb_arch_setup_endpoint(addr);
00333   ep->flags |= USB_EP_FLAGS_TYPE_CONTROL;
00334 
00335   buf_desc = USB_EP_BUF_DESC(ei);
00336   buf_desc->ADDR_TX = USB_EP_BUF_OFFSET(ei);
00337   buf_desc->COUNT_TX = USB_EP_BUF_SIZE(ei)/2;
00338   buf_desc->ADDR_RX = USB_EP_BUF_OFFSET(ei) + USB_EP_BUF_SIZE(ei)/2;
00339   buf_desc->COUNT_RX = USB_EP_BUF_CAPACITY(USB_EP_BUF_SIZE(ei)/2);
00340   ep->xfer_size = USB_EP_BUF_SIZE(ei)/2;
00341   epr = USB->EPR[EP_HW_NUM(addr)];
00342   /* Clear interrupt flags */
00343   epr &= ~(USB_EP0R_CTR_RX | USB_EP0R_CTR_TX);
00344   /* NACK both directions */
00345   epr ^= USB_EPxR_STAT_RX_NAK | USB_EPxR_STAT_TX_NAK;
00346   /* Set control type */
00347   epr = ((epr & ~(USB_EP0R_EP_TYPE | USB_EP0R_EP_KIND))
00348          | USB_EPxR_EP_TYPE_CONTROL);
00349   /* Set address */
00350   epr = ((epr & ~USB_EP0R_EA) | addr);
00351   USB->EPR[EP_HW_NUM(addr)] = epr; 
00352 }
00353 
00354 void
00355 usb_arch_setup_bulk_endpoint(unsigned char addr)
00356 {
00357   USB_HW_Buffer *buf_desc;
00358   unsigned int ei = EP_HW_NUM(addr);
00359   unsigned int epr;
00360   USBEndpoint *ep = EP_STRUCT(addr);
00361   usb_arch_setup_endpoint(addr);
00362   ep->flags |= USB_EP_FLAGS_TYPE_BULK;
00363 
00364   buf_desc = USB_EP_BUF_DESC(ei);
00365   buf_desc->ADDR_TX = USB_EP_BUF_OFFSET(ei);
00366   buf_desc->ADDR_RX = USB_EP_BUF_OFFSET(ei) + USB_EP_BUF_SIZE(ei)/2;
00367   epr = USB->EPR[ei];
00368   if (addr & 0x80) {
00369     /* IN */
00370     buf_desc->COUNT_TX_0 = 0;
00371     buf_desc->COUNT_TX_1 = 0;
00372     /* VALID transmission */
00373     epr ^= USB_EPxR_STAT_TX_VALID;
00374   } else {
00375     /* OUT */
00376     buf_desc->COUNT_RX_0 = USB_EP_BUF_CAPACITY(USB_EP_BUF_SIZE(ei)/2);
00377     buf_desc->COUNT_RX_1 = USB_EP_BUF_CAPACITY(USB_EP_BUF_SIZE(ei)/2);
00378     
00379     /* VALID reception  */
00380     epr ^= USB_EPxR_STAT_RX_VALID;
00381    }
00382   ep->xfer_size = USB_EP_BUF_SIZE(ei)/2;
00383   /* Clear interrupt flags */
00384   epr &= ~(USB_EP0R_CTR_RX | USB_EP0R_CTR_TX);
00385   /* Set bulk type */
00386   epr = ((epr & ~(USB_EP0R_EP_TYPE | USB_EP0R_EP_KIND))
00387          | USB_EPxR_EP_TYPE_BULK | USB_EPxR_EP_DBL_BUF);
00388   /* Set address */
00389   epr = ((epr & ~USB_EP0R_EA) | addr);
00390   USB->EPR[ei] = epr;
00391 
00392 }
00393 
00394 void
00395 usb_arch_setup_interrupt_endpoint(unsigned char addr)
00396 {
00397   USB_HW_Buffer *buf_desc;
00398   unsigned int ei = EP_HW_NUM(addr);
00399   unsigned int epr;
00400   USBEndpoint *ep = EP_STRUCT(addr);
00401   usb_arch_setup_endpoint(addr);
00402   ep->flags |= USB_EP_FLAGS_TYPE_INTERRUPT;
00403   
00404   epr = USB->EPR[EP_HW_NUM(addr)];
00405 
00406   buf_desc = USB_EP_BUF_DESC(ei);
00407   if (addr & 0x80) {
00408     /* IN */
00409     buf_desc->ADDR_TX = USB_EP_BUF_OFFSET(ei);
00410     buf_desc->COUNT_TX = USB_EP_BUF_SIZE(ei);
00411     epr ^= USB_EPxR_STAT_TX_NAK;
00412   } else {
00413     /* OUT */
00414     buf_desc->ADDR_RX = USB_EP_BUF_OFFSET(ei);
00415     buf_desc->COUNT_RX = USB_EP_BUF_CAPACITY(USB_EP_BUF_SIZE(ei));
00416     epr ^= USB_EPxR_STAT_RX_NAK;
00417   }
00418   ep->xfer_size = USB_EP_BUF_SIZE(ei);
00419   /* Clear interrupt flags */
00420   epr &= ~(USB_EP0R_CTR_RX | USB_EP0R_CTR_TX);
00421   /* Set control type */
00422   epr = ((epr & ~(USB_EP0R_EP_TYPE | USB_EP0R_EP_KIND))
00423          | USB_EPxR_EP_TYPE_INTERRUPT);
00424   /* Set address */
00425   epr = ((epr & ~USB_EP0R_EA) | addr);
00426   USB->EPR[EP_HW_NUM(addr)] = epr; 
00427 }
00428 
00429 void
00430 usb_arch_disable_endpoint(uint8_t addr)
00431 {
00432   unsigned int epr;
00433   USBEndpoint *ep = EP_STRUCT(addr);
00434   ep->flags &= ~USB_EP_FLAGS_ENABLED;
00435   
00436   epr = USB->EPR[EP_HW_NUM(addr)];
00437 
00438   epr ^= USB_EPxR_STAT_TX_DISABLED | USB_EPxR_STAT_RX_DISABLED;
00439   /* Clear interrupt flags */
00440   epr &= ~(USB_EP0R_CTR_RX | USB_EP0R_CTR_TX);
00441   USB->EPR[EP_HW_NUM(addr)] = epr; 
00442 }
00443 
00444 inline void
00445 stall_bulk_in(unsigned int hw_ep)
00446 {
00447   volatile uint32_t *eprp = &USB->EPR[hw_ep];
00448   *eprp = (*eprp & (EPR_RW | USB_EP0R_STAT_TX_1)) | EPR_W0;
00449   PRINTF("HALT IN\n");
00450 }
00451 
00452 inline void
00453 stall_bulk_out(unsigned int hw_ep)
00454 {
00455   volatile uint32_t *eprp = &USB->EPR[hw_ep];
00456   *eprp = (*eprp & ((EPR_RW | USB_EP0R_STAT_RX_1) & ~USB_EP0R_CTR_RX)) |EPR_W0;
00457   PRINTF("HALT OUT\n");
00458 }
00459 
00460 
00461 #define USB_READ_BLOCK 0x01     /* The currently submitted buffers
00462                                    can't hold the received data, wait
00463                                    for more buffers. No data was read
00464                                    from the hardware buffer */
00465 #define USB_READ_NOTIFY 0x02    /* Some buffers that had the
00466                                    USB_BUFFER_NOTIFY flags set were
00467                                    released */
00468 #define USB_READ_FAIL 0x04      /* The received data doesn't match the
00469                                    submitted buffers. The hardware
00470                                    buffer is discarded. */
00471 
00472 inline unsigned int
00473 ep_capacity(unsigned int count)
00474 {
00475   return (((count & USB_COUNT0_RX_NUM_BLOCK)>>10)
00476           * ((count & USB_COUNT0_RX_BLSIZE) ? 32 : 2));
00477 }
00478 
00479 /* Skip buffers until mask and flags matches*/
00480 static USBBuffer *
00481 skip_buffers_until(USBBuffer *buffer, unsigned int mask, unsigned int flags,
00482                    unsigned int *resp)
00483 {
00484   while(buffer && !((buffer->flags & mask) == flags)) {
00485     USBBuffer *next = buffer->next;
00486     buffer->flags &= ~USB_BUFFER_SUBMITTED ;
00487     buffer->flags |= USB_BUFFER_FAILED;
00488     if (buffer->flags & USB_BUFFER_NOTIFY) *resp |= USB_READ_NOTIFY;
00489     buffer = next;
00490   }
00491   return buffer;
00492 }
00493 
00494 static void
00495 read_hw_buffer(USBBuffer *buffer, unsigned int offset, unsigned int len)
00496 {
00497 #ifdef USB_STM32F103_ENABLE_ALT_COPY
00498   if (buffer->flags & USB_BUFFER_ARCH_ALT_COPY) {
00499     copy_from_hw_buffer(buffer, offset, len);
00500   } else
00501 #endif
00502     {
00503       uint8_t *data = buffer->data;
00504       const uint32_t *hw_data = ((u32*)USB_MEM_BASE) + offset/2;
00505       buffer->data += len;
00506       if (offset & 1) {
00507         *data++ = *hw_data++ >> 8;
00508         len--;
00509       }
00510       while(len >= 2) {
00511         *((uint16_t*)data) = *hw_data++;
00512         data += 2;
00513         len -= 2;
00514       }
00515       if (len == 1) {
00516         *data++ = *hw_data;
00517       }
00518     }
00519 }
00520 
00521 
00522 #define USB_WRITE_BLOCK 0x01
00523 #define USB_WRITE_NOTIFY 0x02
00524 
00525 void
00526 write_hw_buffer(USBBuffer *buffer,unsigned int offset, unsigned int len)
00527 {
00528 #ifdef USB_STM32F103_ENABLE_ALT_COPY
00529   if (buffer->flags & USB_BUFFER_ARCH_ALT_COPY) {
00530     copy_to_hw_buffer(buffer, offset, len);
00531   } else
00532 #endif    
00533     {
00534       const uint8_t *data;
00535       uint32_t *hw_data;
00536       if (len == 0) return;
00537       data = buffer->data;
00538       hw_data = ((u32*)USB_MEM_BASE) + offset/2;
00539       buffer->data += len;
00540       if (offset & 1) {
00541         *hw_data = (*hw_data & 0xff) | (*data++ << 8);
00542         hw_data++;
00543         len--;
00544       }
00545       while(len >= 2) {
00546         *hw_data++ = *((uint16_t*)data) ;
00547         data += 2;
00548         len -= 2;
00549       }
00550       if (len == 1) {
00551         *hw_data = *data++;
00552       }
00553     }
00554 }
00555 
00556 static unsigned int
00557 get_receive_capacity(USBBuffer *buffer)
00558 {
00559   unsigned int capacity = 0;
00560   while(buffer && !(buffer->flags & (USB_BUFFER_IN| USB_BUFFER_SETUP|USB_BUFFER_HALT))) {
00561     capacity += buffer->left;
00562     buffer = buffer->next;
00563   }
00564   return capacity;
00565 }
00566 
00567 static int
00568 handle_pending_receive(USBEndpoint *ep)
00569 {
00570   int short_packet;
00571   unsigned int len;
00572   unsigned int copy;
00573   unsigned int res = 0;
00574   unsigned int hw_offset;
00575   unsigned int hw_ep = EP_HW_NUM(ep->addr);
00576   USBBuffer *buffer = ep->buffer;
00577   unsigned int flags = ep->flags;
00578   USB_HW_Buffer *buf_desc = USB_EP_BUF_DESC(hw_ep);
00579   PRINTF("handle_pending_receive:\n"); 
00580   if (!(flags & USB_EP_FLAGS_ENABLED) || !buffer) return USB_READ_BLOCK;
00581   switch(flags & USB_EP_FLAGS_TYPE_MASK) {
00582   case USB_EP_FLAGS_TYPE_CONTROL:
00583     len = buf_desc->COUNT_RX & USB_COUNT0_RX_COUNT0_RX;
00584     if (flags & USB_EP_FLAGS_SETUP_PENDING) {
00585       /* Discard buffers until we find a SETUP buffer */
00586       buffer =
00587         skip_buffers_until(buffer, USB_BUFFER_SETUP, USB_BUFFER_SETUP, &res);
00588       ep->buffer = buffer;
00589       if (!buffer || buffer->left < len) {
00590         res |= USB_READ_BLOCK;
00591         return res;
00592       }
00593       /* SETUP buffer must fit in a single buffer */
00594       if (buffer->left < len) {
00595         buffer->flags |= USB_BUFFER_FAILED;
00596         buffer->flags &= ~USB_BUFFER_SUBMITTED ;
00597         if (buffer->flags & USB_BUFFER_NOTIFY) res |= USB_READ_NOTIFY;
00598         ep->buffer = buffer->next;
00599         res |= USB_READ_FAIL;
00600         return res;
00601       }
00602     } else {
00603       if (buffer->flags & (USB_BUFFER_SETUP|USB_BUFFER_IN)) {
00604         buffer->flags |= USB_BUFFER_FAILED;
00605         
00606         buffer->flags &= ~USB_BUFFER_SUBMITTED ;
00607         if (buffer->flags & USB_BUFFER_NOTIFY) res |= USB_READ_NOTIFY;
00608         ep->buffer = buffer->next;
00609         res |= USB_READ_FAIL;
00610         return res;
00611       }
00612 
00613       if (len == 0) {
00614         /* Status OUT */
00615         if (buffer->left > 0) {
00616           buffer->flags |= USB_BUFFER_FAILED;
00617           res |= USB_READ_FAIL;
00618         }
00619         buffer->flags &= ~USB_BUFFER_SUBMITTED ;
00620         if (buffer->flags & USB_BUFFER_NOTIFY) res |= USB_READ_NOTIFY;
00621         ep->buffer = buffer->next;
00622         return res;
00623       }
00624       if (get_receive_capacity(buffer) <  len) return USB_READ_BLOCK;
00625     }
00626     hw_offset =  buf_desc->ADDR_RX;
00627     break;
00628   case USB_EP_FLAGS_TYPE_INTERRUPT:
00629     len = buf_desc->COUNT_RX & USB_COUNT0_RX_COUNT0_RX;
00630     if (get_receive_capacity(buffer) <  len) return USB_READ_BLOCK;
00631     hw_offset =  buf_desc->ADDR_RX;
00632     break;
00633   case USB_EP_FLAGS_TYPE_BULK:
00634      if (USB->EPR[hw_ep] & USB_EPxR_SW_BUF_RX) {
00635       len = buf_desc->COUNT_RX_1 & USB_COUNT0_RX_COUNT0_RX;
00636       hw_offset =  buf_desc->ADDR_RX_1;
00637     } else {
00638       len = buf_desc->COUNT_RX_0 & USB_COUNT0_RX_COUNT0_RX;
00639       hw_offset =  buf_desc->ADDR_RX_0;
00640     }
00641     if (get_receive_capacity(buffer) <  len) return USB_READ_BLOCK;
00642     break;
00643   case USB_EP_FLAGS_TYPE_ISO:
00644     len = buf_desc->COUNT_RX & USB_COUNT0_RX_COUNT0_RX;
00645     if (get_receive_capacity(buffer) <  len) return USB_READ_BLOCK;
00646     hw_offset =  buf_desc->ADDR_RX;
00647   }
00648   /* printf("handle_pending_receive: %d %04x\n", len, ep->flags);   */
00649   short_packet = len < ep->xfer_size;
00650 
00651   do {
00652     if (buffer->left < len) {
00653       copy = buffer->left;
00654     } else {
00655       copy = len;
00656     }
00657     len -= copy;
00658     buffer->left -= copy;
00659     read_hw_buffer(buffer, hw_offset, copy);
00660     hw_offset += copy;
00661 
00662     if (len == 0) break;
00663 
00664     /* Release buffer */
00665     buffer->flags &= ~(USB_BUFFER_SUBMITTED | USB_BUFFER_SHORT_PACKET);
00666     if (buffer->flags & USB_BUFFER_NOTIFY) res |= USB_READ_NOTIFY;
00667     /* Use next buffer. */
00668     buffer = buffer->next;
00669   } while(1);
00670   
00671   if (short_packet) {
00672     buffer->flags |= USB_BUFFER_SHORT_PACKET;
00673   }
00674   
00675   if ((buffer->left == 0)
00676       || (buffer->flags & USB_BUFFER_PACKET_END)
00677       || (short_packet && (buffer->flags & USB_BUFFER_SHORT_END))) {
00678     /* Release buffer */
00679     buffer->flags &= ~USB_BUFFER_SUBMITTED;
00680     if (buffer->flags & USB_BUFFER_NOTIFY) res |= USB_READ_NOTIFY;
00681     /* Use next buffer. */
00682     buffer = buffer->next;
00683   }
00684   
00685   ep->buffer = buffer;
00686   if (IS_BULK_EP(ep)) {
00687     USB->EPR[hw_ep] = EPR_INVARIANT(USB->EPR[hw_ep]) | USB_EPxR_SW_BUF_RX;
00688   }
00689 
00690   /* PRINTF("read_endpoint %d %d\n", (int)hw_offset-buf_desc->ADDR_RX, (int)buf_desc->ADDR_RX); */
00691   return res;
00692 }
00693 
00694 
00695 static void
00696 start_receive(USBEndpoint *ep)
00697 {
00698   unsigned int hw_ep = EP_HW_NUM(ep->addr);
00699   uint32_t epr =  (USB->EPR[hw_ep] | EPR_W0);
00700   uint32_t epr_mask = EPR_RW | EPR_W0;
00701   switch(ep->flags & USB_EP_FLAGS_TYPE_MASK) {
00702   case USB_EP_FLAGS_TYPE_CONTROL:
00703   case USB_EP_FLAGS_TYPE_INTERRUPT:
00704     {
00705       unsigned int capacity = get_receive_capacity(ep->buffer);
00706       if (capacity <= ep->xfer_size) {
00707         /* This is the last OUT packet of the data stage */
00708         epr ^= USB_EPxR_STAT_TX_NAK;
00709       } else {
00710         epr ^= USB_EPxR_STAT_TX_STALL;
00711       }
00712       epr ^= USB_EPxR_STAT_RX_VALID;
00713       epr_mask |= USB_EP0R_STAT_TX | USB_EP0R_STAT_RX;
00714     }
00715     break;
00716   case USB_EP_FLAGS_TYPE_BULK:
00717   case USB_EP_FLAGS_TYPE_ISO: 
00718    break;
00719   }
00720   ep->flags |= USB_EP_FLAGS_RECEIVING;
00721   USB->EPR[hw_ep] = epr & epr_mask;
00722 }
00723 
00724 static unsigned int
00725 get_transmit_length(USBBuffer *buffer)
00726 {
00727   unsigned int length = 0;
00728   while(buffer && (buffer->flags & USB_BUFFER_IN)) {
00729     length += buffer->left;
00730     buffer = buffer->next;
00731   }
00732   return length;
00733 }
00734 
00735 static int
00736 start_transmit(USBEndpoint *ep)
00737 {
00738   unsigned int hw_start;
00739   unsigned int res = 0;
00740   USBBuffer *buffer = ep->buffer;
00741   unsigned int len;
00742   unsigned int hw_offset;
00743   volatile uint32_t *hw_countp;
00744   unsigned int hw_ep = EP_HW_NUM(ep->addr);
00745   uint32_t epr =  USB->EPR[hw_ep];
00746   unsigned int ep_flags = ep->flags;
00747   USB_HW_Buffer *buf_desc = USB_EP_BUF_DESC(hw_ep);
00748   len = ep->xfer_size;
00749   if (!(ep_flags & USB_EP_FLAGS_ENABLED) || !buffer) return USB_WRITE_BLOCK;
00750   /* PRINTF("start_transmit: %02x\n", ep->addr); */
00751   switch(ep_flags & USB_EP_FLAGS_TYPE_MASK) {
00752   case USB_EP_FLAGS_TYPE_CONTROL:
00753     
00754     if (get_transmit_length(ep->buffer) <= len) {
00755       /* This is the last IN packet of the data stage */
00756       USB->EPR[hw_ep] = USB_EPxR_EP_STATUS_OUT 
00757         | EPR_TOGGLE_SET(epr, USB_EP0R_STAT_RX, USB_EPxR_STAT_RX_NAK);
00758     } else {
00759       USB->EPR[hw_ep] = USB_EPxR_EP_STATUS_OUT
00760         | EPR_TOGGLE_SET(epr, USB_EP0R_STAT_RX, USB_EPxR_STAT_RX_STALL);
00761     }
00762     hw_offset =  buf_desc->ADDR_TX;
00763     hw_countp = &buf_desc->COUNT_TX;
00764     break;
00765   case USB_EP_FLAGS_TYPE_BULK:
00766     if (buffer->flags & USB_BUFFER_HALT) {
00767       if (ep->status & 0x01) return USB_WRITE_BLOCK;
00768       ep->status |= 0x01;
00769       stall_bulk_in(hw_ep);
00770       return USB_WRITE_BLOCK;
00771     }
00772     if (USB->EPR[hw_ep] & USB_EPxR_SW_BUF_TX) {
00773       hw_offset =  buf_desc->ADDR_TX_1;
00774       hw_countp = &buf_desc->COUNT_TX_1;
00775     } else {
00776       hw_offset =  buf_desc->ADDR_TX_0;
00777       hw_countp = &buf_desc->COUNT_TX_0;
00778     }
00779     break;
00780   }
00781   hw_start = hw_offset;
00782   while (buffer) {
00783     unsigned int copy;
00784     if (buffer->left < len) {
00785       copy = buffer->left;
00786     } else {
00787       copy = len;
00788     }
00789     len -= copy;
00790     buffer->left -= copy;
00791     write_hw_buffer(buffer, hw_offset, copy);
00792     hw_offset += copy;
00793     if (buffer->left == 0) {
00794       if (buffer->flags & USB_BUFFER_SHORT_END) {
00795         if (len == 0) {
00796           /* Send zero length packet. */
00797           break; /* Leave without moving to next buffer */
00798         } else {
00799           len = 0;
00800         }
00801       }
00802       /* Release buffer */
00803       buffer->flags &= ~USB_BUFFER_SUBMITTED;
00804       if (buffer->flags & USB_BUFFER_NOTIFY) res = USB_WRITE_NOTIFY;
00805            /* Use next buffer. */
00806       buffer = buffer->next;
00807     }
00808     if (len == 0) break;
00809   }
00810   ep->buffer = buffer;
00811   if (ep->flags & USB_EP_FLAGS_TRANSMITTING) {
00812     ep->flags |= USB_EP_FLAGS_DOUBLE;
00813   } else {
00814     ep->flags |= USB_EP_FLAGS_TRANSMITTING;
00815   }
00816   *hw_countp = hw_offset - hw_start;
00817   /* printf("start_transmit: %02x %d %04lx\n", ep->addr, hw_offset - hw_start, USB->EPR[hw_ep]); */
00818   switch(ep->flags & USB_EP_FLAGS_TYPE_MASK) {
00819   case USB_EP_FLAGS_TYPE_CONTROL:
00820   case USB_EP_FLAGS_TYPE_INTERRUPT:
00821     USB->EPR[hw_ep] =
00822       EPR_TOGGLE_SET(epr, USB_EP0R_STAT_TX, USB_EPxR_STAT_TX_VALID);
00823     break;
00824   case USB_EP_FLAGS_TYPE_BULK:
00825     USB->EPR[hw_ep] = EPR_INVARIANT(USB->EPR[hw_ep]) | USB_EPxR_SW_BUF_TX;
00826     break;
00827   case USB_EP_FLAGS_TYPE_ISO:
00828     break;
00829   }
00830 /*   printf("start_transmit: %04x\n", USB->EPR[hw_ep]); */
00831   return res;
00832 }
00833 
00834 static void
00835 start_transfer(USBEndpoint *ep)
00836 {
00837   int res;
00838   while (1) {
00839     if (!(ep->addr & 0x80) && (IS_BULK_EP(ep) || IS_INTERRUPT_EP(ep))) {
00840       if (ep->buffer && (ep->buffer->flags & USB_BUFFER_HALT)) {
00841         if (ep->status & 0x01) return ;
00842         ep->status |= 0x01;
00843         stall_bulk_out(EP_HW_NUM(ep->addr));
00844         return;
00845       }
00846     }
00847     if (!(ep->flags & USB_EP_FLAGS_RECV_PENDING)) break;
00848     res = handle_pending_receive(ep);
00849     if (res & USB_READ_NOTIFY) {
00850       notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
00851     }
00852     if (res & USB_READ_BLOCK) return;
00853     if (ep->flags & USB_EP_FLAGS_DOUBLE) {
00854       ep->flags &= ~USB_EP_FLAGS_DOUBLE;
00855     } else {
00856       ep->flags &= ~(USB_EP_FLAGS_RECV_PENDING|USB_EP_FLAGS_SETUP_PENDING);
00857     }
00858     if (res & USB_READ_FAIL) {
00859       /* Only fails for control endpoints */
00860       usb_arch_control_stall(ep->addr);
00861       return;
00862     }
00863   }
00864   if (ep->addr == 0x02)
00865     PRINTF("start EPR: %04x ep->flags: %02x\n",
00866            (unsigned int)USB->EPR[EP_HW_NUM(ep->addr)],
00867            (unsigned int)ep->flags);
00868   if (ep->flags & (USB_EP_FLAGS_TRANSMITTING | USB_EP_FLAGS_RECEIVING)) {
00869     if (!IS_BULK_EP(ep) || (ep->flags & USB_EP_FLAGS_DOUBLE)) {
00870       PRINTF("Busy\n");
00871       return;
00872     }
00873   }
00874   if (ep->status & 0x01) return; /* Don't start transfer if halted */
00875   if (ep->buffer) {
00876     if (ep->buffer->flags & USB_BUFFER_IN) {
00877       res = start_transmit(ep);
00878       if (res & USB_READ_NOTIFY) {
00879         notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION);
00880       }
00881     } else {
00882       start_receive(ep);
00883     }
00884   }
00885 }
00886 
00887 
00888 static void
00889 transfer_complete(unsigned int hw_ep) {
00890   uint32_t epr =  USB->EPR[hw_ep];
00891   USBEndpoint *ep = &usb_endpoints[hw_ep];
00892   if (epr &USB_EP0R_CTR_RX) {
00893     PRINTF("Received packet %lx %04x\n", USB_EP_BUF_DESC(hw_ep)->COUNT_RX, (int)USB->EPR[hw_ep]);
00894     if (epr & USB_EP0R_SETUP) {
00895       PRINTF("SETUP\n"); 
00896       ep->flags |= USB_EP_FLAGS_SETUP_PENDING;
00897     }
00898 
00899     if (IS_BULK_EP(ep)) {
00900       if ((epr ^ (epr >> 8)) & USB_EP0R_DTOG_TX) {
00901         ep->flags &= ~USB_EP_FLAGS_DOUBLE;
00902       } else {
00903         ep->flags |= USB_EP_FLAGS_DOUBLE;
00904         ep->flags &= ~USB_EP_FLAGS_RECEIVING;
00905       }
00906     } else {
00907       ep->flags &= ~USB_EP_FLAGS_RECEIVING;
00908     }
00909     ep->flags |= USB_EP_FLAGS_RECV_PENDING;
00910     if (IS_CONTROL_EP(ep)) epr &= ~USB_EPxR_EP_STATUS_OUT;
00911     USB->EPR[hw_ep] = EPR_INVARIANT(epr) & ~USB_EP0R_CTR_RX;
00912 #if 0
00913     if (ep->flags & USB_EP_FLAGS_DOUBLE) {
00914       printf("Double\n");
00915     }
00916 #endif
00917 
00918     start_transfer(ep);
00919   }
00920   if (epr &USB_EP0R_CTR_TX) {
00921      PRINTF("Sent packet\n"); 
00922     if (ep->flags & USB_EP_FLAGS_DOUBLE) {
00923       ep->flags &= ~USB_EP_FLAGS_DOUBLE;
00924     } else {
00925       ep->flags &= ~USB_EP_FLAGS_TRANSMITTING;
00926     }
00927     USB->EPR[hw_ep] = EPR_INVARIANT(USB->EPR[hw_ep]) & ~USB_EP0R_CTR_TX;
00928     start_transfer(ep);
00929   }
00930   
00931 }
00932 
00933 
00934 void
00935 usb_set_ep_event_process(unsigned char addr, struct process *p)
00936 {
00937   USBEndpoint *ep = &usb_endpoints[EP_INDEX(addr)];
00938   ep->event_process = p;
00939 }
00940 
00941 /* Select what process should be polled when a global event occurs */
00942 void
00943 usb_arch_set_global_event_process(struct process *p)
00944 {
00945   event_process = p;
00946 }
00947 
00948 unsigned int
00949 usb_arch_get_global_events(void)
00950 {
00951   unsigned int e;
00952   USB_DISABLE_INT;
00953   e = events;
00954   events = 0;
00955   USB_DISABLE_INT;
00956   return e;
00957 }
00958 
00959 unsigned int
00960 usb_get_ep_events(unsigned char addr)
00961 {
00962   unsigned int e;
00963   unsigned int ei = EP_HW_NUM(addr);
00964   USB_DISABLE_INT;
00965   e = usb_endpoints[ei].events;
00966   usb_endpoints[ei].events = 0;
00967   USB_ENABLE_INT;
00968   return e;
00969 }
00970 
00971 
00972 void
00973 usb_submit_recv_buffer(unsigned char ep_addr, USBBuffer *buffer)
00974 {
00975   USBBuffer **tailp;
00976   USBEndpoint *ep = &usb_endpoints[EP_INDEX(ep_addr)];
00977   if (!(ep->flags & USB_EP_FLAGS_ENABLED)) return;
00978   /* PRINTF("buffer: %p\n", ep->buffer); */
00979   /* dbg_drain(); */
00980   USB_DISABLE_INT;
00981   tailp = (USBBuffer**)&ep->buffer;
00982   while(*tailp) {
00983     tailp = &(*tailp)->next;
00984   }
00985   *tailp = buffer;
00986   while(buffer) {
00987     buffer->flags |= USB_BUFFER_SUBMITTED;
00988     buffer = buffer->next;
00989   }
00990   start_transfer(ep);
00991   
00992   USB_ENABLE_INT;
00993 }
00994 
00995 void
00996 usb_submit_xmit_buffer(unsigned char ep_addr, USBBuffer *buffer)
00997 {
00998   USBBuffer **tailp;
00999   USBEndpoint *ep = &usb_endpoints[EP_INDEX(ep_addr)];
01000   if (!(ep->flags & USB_EP_FLAGS_ENABLED)) return;
01001   /* PRINTF("usb_submit_xmit_buffer %d\n", buffer->left); */
01002   USB_DISABLE_INT;
01003   tailp = (USBBuffer**)&ep->buffer;
01004   while(*tailp) {
01005     tailp = &(*tailp)->next;
01006   }
01007   *tailp = buffer;
01008   while(buffer) {
01009     buffer->flags |= USB_BUFFER_SUBMITTED | USB_BUFFER_IN;
01010     buffer = buffer->next;
01011   }
01012   start_transfer(ep);
01013   USB_ENABLE_INT;
01014 }
01015 
01016 void
01017 usb_arch_discard_all_buffers(unsigned char ep_addr)
01018 {
01019   uint32_t ints;
01020   USBBuffer *buffer;
01021   volatile USBEndpoint *ep = &usb_endpoints[EP_INDEX(ep_addr)];
01022   ints = usb_save_disable_int();
01023   buffer = ep->buffer;
01024   ep->buffer = NULL;
01025 #if 0
01026   /* Set both directions to NAK */
01027   USB->EPR[EP_HW_NUM(ep_addr)] =
01028     EPR_TOGGLE_SET(USB->EPR[EP_HW_NUM(ep_addr)],
01029                    USB_EP0R_STAT_RX|USB_EP0R_STAT_TX,
01030                    USB_EPxR_STAT_TX_NAK| USB_EPxR_STAT_RX_NAK);
01031   ep->flags &= ~(USB_EP_FLAGS_RECV_PENDING|USB_EP_FLAGS_SETUP_PENDING);
01032 #endif
01033   ep->flags &= ~(USB_EP_FLAGS_RECV_PENDING | USB_EP_FLAGS_SETUP_PENDING
01034                  | USB_EP_FLAGS_DOUBLE);
01035   usb_restore_int(ints);
01036   while(buffer) {
01037     buffer->flags &= ~USB_BUFFER_SUBMITTED;
01038     buffer = buffer->next;
01039   }
01040 }
01041 uint16_t
01042 usb_arch_get_ep_status(uint8_t addr)
01043 {
01044   if (EP_INDEX(addr) > USB_MAX_ENDPOINTS) return 0;
01045   return usb_endpoints[EP_INDEX(addr)].status;
01046 }
01047 
01048 void
01049 usb_arch_set_configuration(uint8_t usb_configuration_value)
01050 {
01051   /* Nothing needs to be done */
01052 }
01053 
01054 void
01055 usb_arch_control_stall(unsigned char addr)
01056 {
01057   if (EP_INDEX(addr) > USB_MAX_ENDPOINTS) return;
01058   uint32_t epr =  USB->EPR[EP_HW_NUM(addr)];
01059   USB->EPR[EP_HW_NUM(addr)] = EPR_TOGGLE_SET(epr,USB_EP0R_STAT_RX|USB_EP0R_STAT_TX, USB_EPxR_STAT_RX_STALL | USB_EPxR_STAT_TX_STALL);
01060 }
01061 
01062 /* Not for control endpoints */
01063 void
01064 usb_arch_halt_endpoint(unsigned char ep_addr, int halt)
01065 {
01066   if (EP_INDEX(ep_addr) > USB_MAX_ENDPOINTS) return;
01067   if (!usb_endpoints[EP_INDEX(ep_addr)].flags & USB_EP_FLAGS_ENABLED) return;
01068   USB_DISABLE_INT;
01069   if (halt) {
01070     if (!(usb_endpoints[EP_INDEX(ep_addr)].status & 0x01)) {
01071       usb_endpoints[EP_INDEX(ep_addr)].status |= 0x01;
01072       if (ep_addr & 0x80) {
01073         stall_bulk_in(EP_HW_NUM(ep_addr));
01074       } else {
01075         stall_bulk_out(EP_HW_NUM(ep_addr));
01076       }
01077     }
01078   } else {
01079     USBEndpoint *ep = &usb_endpoints[EP_INDEX(ep_addr)];
01080     if (ep->status & 0x01) {
01081       ep->status &= ~0x01;
01082       PRINTF("HALT clear restart EPR: %04x %p %p\n",
01083              (unsigned int)USB->EPR[EP_HW_NUM(ep_addr)],
01084              ep->buffer, ep->buffer->next);
01085       /* Restore toggle state for double buffered endpoint */
01086       if (IS_BULK_EP(ep)) {
01087         volatile uint32_t *eprp = &USB->EPR[EP_HW_NUM(ep_addr)];
01088         if (ep_addr & 0x80) {
01089           ep->flags &= ~(USB_EP_FLAGS_DOUBLE |USB_EP_FLAGS_TRANSMITTING);
01090           
01091           *eprp =(EPR_TOGGLE_SET(*eprp,(USB_EP0R_STAT_TX | USB_EP0R_DTOG_TX 
01092                                         | USB_EPxR_SW_BUF_TX),
01093                                  USB_EPxR_STAT_TX_VALID)); 
01094         } else {
01095           ep->flags &= ~(USB_EP_FLAGS_DOUBLE | USB_EP_FLAGS_RECEIVING
01096                          | USB_EP_FLAGS_RECV_PENDING);
01097 
01098           *eprp =(EPR_TOGGLE_SET(*eprp,(USB_EP0R_STAT_RX | USB_EP0R_DTOG_RX 
01099                                         | USB_EPxR_SW_BUF_RX),
01100                                  USB_EPxR_STAT_RX_VALID|USB_EPxR_SW_BUF_RX));
01101           *eprp = EPR_INVARIANT(*eprp) | USB_EPxR_SW_BUF_RX;
01102           
01103         }
01104       }
01105       /* Release HALT buffer */
01106       if (ep->buffer && (ep->buffer->flags & USB_BUFFER_HALT)) {
01107         ep->buffer->flags &= ~USB_BUFFER_SUBMITTED;
01108         if (ep->buffer->flags & USB_BUFFER_NOTIFY) {
01109           notify_ep_process(ep,USB_EP_EVENT_NOTIFICATION);
01110         }
01111         ep->buffer = ep->buffer->next;
01112       }
01113       /* Restart transmission */
01114       start_transfer(&usb_endpoints[EP_INDEX(ep_addr)]);
01115       PRINTF("HALT clear restart EPR: %04x %p %p\n",
01116              (unsigned int)USB->EPR[EP_HW_NUM(ep_addr)],
01117              ep->buffer, ep->buffer->next);
01118       
01119     }
01120   }
01121   USB_ENABLE_INT;
01122 }
01123 
01124 void
01125 usb_arch_set_address(unsigned char addr)
01126 {
01127   USB->DADDR = 0x80 | addr;  
01128 }
01129 
01130 void
01131 USB_HP_CAN_TX_handler(void) __attribute__((interrupt));
01132 
01133 void
01134 USB_HP_CAN_TX_handler(void)
01135 {
01136   uint32_t status = USB->ISTR;
01137   if (status & USB_ISTR_CTR) {
01138     transfer_complete(status & USB_ISTR_EP_ID);
01139   }
01140 }
01141 
01142 void
01143 USB_LP_CAN_RX0_handler(void) __attribute__((interrupt));
01144 void
01145 USB_LP_CAN_RX0_handler(void)
01146 {
01147   uint32_t status = USB->ISTR;
01148   if (status & USB_ISTR_CTR) {
01149     transfer_complete(status & USB_ISTR_EP_ID);
01150     /* PRINTF("Transfer complete ep %ld\n", status & USB_ISTR_EP_ID); */
01151   } else if (status & USB_ISTR_PMAOVR) {
01152     PRINTF("PMAOVR\n");
01153     USB->ISTR &= ~USB_ISTR_PMAOVR;
01154   } else if (status & USB_ISTR_ERR) {
01155     PRINTF("ERR\n");
01156     USB->ISTR &= ~USB_ISTR_ERR;
01157   } else if (status & USB_ISTR_WKUP) {
01158     PRINTF("WKUP\n");
01159     USB->ISTR &= ~USB_ISTR_WKUP;
01160     USB->CNTR &= ~USB_CNTR_FSUSP;
01161     notify_process(USB_EVENT_RESUME);
01162   } else if (status & USB_ISTR_SUSP) {
01163     PRINTF("SUSP\n");
01164     USB->ISTR &= ~USB_ISTR_SUSP;
01165     USB->CNTR |= USB_CNTR_FSUSP;
01166     notify_process(USB_EVENT_SUSPEND);
01167   } else if (status & USB_ISTR_RESET) {
01168     PRINTF("RESET\n");
01169     USB->ISTR &= ~USB_ISTR_RESET;
01170     usb_arch_reset();
01171     notify_process(USB_EVENT_RESET);
01172   }
01173 }
01174 
01175 void
01176 usb_arch_toggle_SW_BUF_RX()
01177 {
01178   USB->EPR[2] = EPR_INVARIANT(USB->EPR[2]) | USB_EPxR_SW_BUF_RX;
01179 }
01180 
01181 int 
01182 usb_arch_send_pending(uint8_t ep_addr)
01183 {
01184   return usb_endpoints[EP_INDEX(ep_addr)].flags & USB_EP_FLAGS_TRANSMITTING;
01185 }

Generated on Mon Apr 11 14:23:35 2011 for Contiki 2.5 by  doxygen 1.6.1