Merge remote-tracking branch 'origin/master' into usbtmc
This commit is contained in:
		
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -15,3 +15,7 @@ latex | |||||||
| test_old/ | test_old/ | ||||||
| tests_obsolete/ | tests_obsolete/ | ||||||
| _build | _build | ||||||
|  | # coverity intermediate files | ||||||
|  | cov-int | ||||||
|  | # cppcheck build directories | ||||||
|  | *-build-dir | ||||||
|   | |||||||
| @@ -147,31 +147,33 @@ | |||||||
|  * Checks, structs, defines, function definitions, etc. |  * Checks, structs, defines, function definitions, etc. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| TU_VERIFY_STATIC((MAX_EP_COUNT) <= STFSDEV_EP_COUNT,"Only 8 endpoints supported on the hardware"); | TU_VERIFY_STATIC((MAX_EP_COUNT) <= STFSDEV_EP_COUNT, "Only 8 endpoints supported on the hardware"); | ||||||
|  |  | ||||||
| TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) + (DCD_STM32_BTABLE_LENGTH))<=(PMA_LENGTH), | TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) + (DCD_STM32_BTABLE_LENGTH))<=(PMA_LENGTH), | ||||||
|     "BTABLE does not fit in PMA RAM"); |     "BTABLE does not fit in PMA RAM"); | ||||||
|  |  | ||||||
| TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligned to 8 bytes"); | TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligned to 8 bytes"); | ||||||
|  |  | ||||||
| // Max size of a USB FS packet is 64... |  | ||||||
| #define MAX_PACKET_SIZE 64 |  | ||||||
|  |  | ||||||
|  |  | ||||||
| // One of these for every EP IN & OUT, uses a bit of RAM.... | // One of these for every EP IN & OUT, uses a bit of RAM.... | ||||||
| typedef struct | typedef struct | ||||||
| { | { | ||||||
|   uint8_t * buffer; |   uint8_t * buffer; | ||||||
|   uint16_t total_len; |   uint16_t total_len; | ||||||
|   uint16_t queued_len; |   uint16_t queued_len; | ||||||
|  |   uint16_t max_packet_size; | ||||||
| } xfer_ctl_t; | } xfer_ctl_t; | ||||||
|  |  | ||||||
| static xfer_ctl_t xfer_status[MAX_EP_COUNT][2]; | static xfer_ctl_t xfer_status[MAX_EP_COUNT][2]; | ||||||
| #define XFER_CTL_BASE(_epnum, _dir) &xfer_status[_epnum][_dir] |  | ||||||
|  | static xfer_ctl_t* xfer_ctl_ptr(uint32_t epnum, uint32_t dir) | ||||||
|  | { | ||||||
|  |   return &xfer_status[epnum][dir]; | ||||||
|  | } | ||||||
|  |  | ||||||
| static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[6]; | static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[6]; | ||||||
|  |  | ||||||
| static uint8_t newDADDR; // Used to set the new device address during the CTR IRQ handler | static uint8_t newDADDR; // Used to set the new device address during the CTR IRQ handler | ||||||
|  | static uint8_t remoteWakeCountdown; // When wake is requested | ||||||
|  |  | ||||||
| // EP Buffers assigned from end of memory location, to minimize their chance of crashing | // EP Buffers assigned from end of memory location, to minimize their chance of crashing | ||||||
| // into the stack. | // into the stack. | ||||||
| @@ -224,7 +226,7 @@ void dcd_init (uint8_t rhport) | |||||||
|   for(uint32_t i=0; i<STFSDEV_EP_COUNT; i++) |   for(uint32_t i=0; i<STFSDEV_EP_COUNT; i++) | ||||||
|   { |   { | ||||||
|     // This doesn't clear all bits since some bits are "toggle", but does set the type to DISABLED. |     // This doesn't clear all bits since some bits are "toggle", but does set the type to DISABLED. | ||||||
|     PCD_GET_ENDPOINT(USB,i) = 0u; |     pcd_set_endpoint(USB,i,0u); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Initialize the BTABLE for EP0 at this point (though setting up the EP0R is unneeded) |   // Initialize the BTABLE for EP0 at this point (though setting up the EP0R is unneeded) | ||||||
| @@ -233,7 +235,7 @@ void dcd_init (uint8_t rhport) | |||||||
|   { |   { | ||||||
|     pma[PMA_STRIDE*(DCD_STM32_BTABLE_BASE + i)] = 0u; |     pma[PMA_STRIDE*(DCD_STM32_BTABLE_BASE + i)] = 0u; | ||||||
|   } |   } | ||||||
|   USB->CNTR |= USB_CNTR_RESETM | USB_CNTR_SOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; |   USB->CNTR |= USB_CNTR_RESETM | USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; | ||||||
|   dcd_handle_bus_reset(); |   dcd_handle_bus_reset(); | ||||||
|  |  | ||||||
|   // And finally enable pull-up, which may trigger the RESET IRQ if the host is connected. |   // And finally enable pull-up, which may trigger the RESET IRQ if the host is connected. | ||||||
| @@ -251,12 +253,8 @@ void dcd_int_enable (uint8_t rhport) | |||||||
| { | { | ||||||
|   (void)rhport; |   (void)rhport; | ||||||
| #if defined(STM32F0) | #if defined(STM32F0) | ||||||
|   NVIC_SetPriority(USB_IRQn, 0); |  | ||||||
|   NVIC_EnableIRQ(USB_IRQn); |   NVIC_EnableIRQ(USB_IRQn); | ||||||
| #elif defined(STM32F3) | #elif defined(STM32F3) | ||||||
|   NVIC_SetPriority(USB_HP_CAN_TX_IRQn, 0); |  | ||||||
|   NVIC_SetPriority(USB_LP_CAN_RX0_IRQn, 0); |  | ||||||
|   NVIC_SetPriority(USBWakeUp_IRQn, 0); |  | ||||||
|   NVIC_EnableIRQ(USB_HP_CAN_TX_IRQn); |   NVIC_EnableIRQ(USB_HP_CAN_TX_IRQn); | ||||||
|   NVIC_EnableIRQ(USB_LP_CAN_RX0_IRQn); |   NVIC_EnableIRQ(USB_LP_CAN_RX0_IRQn); | ||||||
|   NVIC_EnableIRQ(USBWakeUp_IRQn); |   NVIC_EnableIRQ(USBWakeUp_IRQn); | ||||||
| @@ -276,6 +274,10 @@ void dcd_int_disable(uint8_t rhport) | |||||||
| #else | #else | ||||||
| #error Unknown arch in USB driver | #error Unknown arch in USB driver | ||||||
| #endif | #endif | ||||||
|  |   // I'm not convinced that memory synchronization is completely necessary, but | ||||||
|  |   // it isn't a bad idea. | ||||||
|  |   __DSB(); | ||||||
|  |   __ISB(); | ||||||
| } | } | ||||||
|  |  | ||||||
| // Receive Set Address request, mcu port must also include status IN response | // Receive Set Address request, mcu port must also include status IN response | ||||||
| @@ -302,6 +304,9 @@ void dcd_set_config (uint8_t rhport, uint8_t config_num) | |||||||
| void dcd_remote_wakeup(uint8_t rhport) | void dcd_remote_wakeup(uint8_t rhport) | ||||||
| { | { | ||||||
|   (void) rhport; |   (void) rhport; | ||||||
|  |  | ||||||
|  |   USB->CNTR |= (uint16_t)USB_CNTR_RESUME; | ||||||
|  |   remoteWakeCountdown = 4u; // required to be 1 to 15 ms, ESOF should trigger every 1ms. | ||||||
| } | } | ||||||
|  |  | ||||||
| // I'm getting a weird warning about missing braces here that I don't | // I'm getting a weird warning about missing braces here that I don't | ||||||
| @@ -334,7 +339,7 @@ static void dcd_handle_bus_reset(void) | |||||||
|   // Clear all EPREG (or maybe this is automatic? I'm not sure) |   // Clear all EPREG (or maybe this is automatic? I'm not sure) | ||||||
|   for(uint32_t i=0; i<STFSDEV_EP_COUNT; i++) |   for(uint32_t i=0; i<STFSDEV_EP_COUNT; i++) | ||||||
|   { |   { | ||||||
|     PCD_GET_ENDPOINT(USB,i) = 0u; |     pcd_set_endpoint(USB,i,0u); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8*MAX_EP_COUNT; // 8 bytes per endpoint (two TX and two RX words, each) |   ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8*MAX_EP_COUNT; // 8 bytes per endpoint (two TX and two RX words, each) | ||||||
| @@ -342,13 +347,13 @@ static void dcd_handle_bus_reset(void) | |||||||
|   dcd_edpt_open (0, &ep0IN_desc); |   dcd_edpt_open (0, &ep0IN_desc); | ||||||
|   newDADDR = 0u; |   newDADDR = 0u; | ||||||
|   USB->DADDR = USB_DADDR_EF; // Set enable flag, and leaving the device address as zero. |   USB->DADDR = USB_DADDR_EF; // Set enable flag, and leaving the device address as zero. | ||||||
|   PCD_SET_EP_RX_STATUS(USB, 0, USB_EP_RX_VALID); // And start accepting SETUP on EP0 |   pcd_set_ep_rx_status(USB, 0, USB_EP_RX_VALID); // And start accepting SETUP on EP0 | ||||||
| } | } | ||||||
|  |  | ||||||
| // FIXME: Defined to return uint16 so that ASSERT can be used, even though a return value is not needed. | // FIXME: Defined to return uint16 so that ASSERT can be used, even though a return value is not needed. | ||||||
| static uint16_t dcd_ep_ctr_handler(void) | static uint16_t dcd_ep_ctr_handler(void) | ||||||
| { | { | ||||||
|   uint16_t count=0U; |   uint32_t count=0U; | ||||||
|   uint8_t EPindex; |   uint8_t EPindex; | ||||||
|   __IO uint16_t wIstr; |   __IO uint16_t wIstr; | ||||||
|   __IO uint16_t wEPVal = 0U; |   __IO uint16_t wEPVal = 0U; | ||||||
| @@ -370,9 +375,9 @@ static uint16_t dcd_ep_ctr_handler(void) | |||||||
|       { |       { | ||||||
|         /* DIR = 0  => IN  int */ |         /* DIR = 0  => IN  int */ | ||||||
|         /* DIR = 0 implies that (EP_CTR_TX = 1) always  */ |         /* DIR = 0 implies that (EP_CTR_TX = 1) always  */ | ||||||
|         PCD_CLEAR_TX_EP_CTR(USB, 0); |         pcd_clear_tx_ep_ctr(USB, 0); | ||||||
|  |  | ||||||
|         xfer_ctl_t * xfer = XFER_CTL_BASE(EPindex,TUSB_DIR_IN); |         xfer_ctl_t * xfer = xfer_ctl_ptr(EPindex,TUSB_DIR_IN); | ||||||
|  |  | ||||||
|         if((xfer->total_len == xfer->queued_len)) |         if((xfer->total_len == xfer->queued_len)) | ||||||
|         { |         { | ||||||
| @@ -381,12 +386,12 @@ static uint16_t dcd_ep_ctr_handler(void) | |||||||
|           { |           { | ||||||
|             // Delayed setting of the DADDR after the 0-len DATA packet acking the request is sent. |             // Delayed setting of the DADDR after the 0-len DATA packet acking the request is sent. | ||||||
|             reg16_clear_bits(&USB->DADDR, USB_DADDR_ADD); |             reg16_clear_bits(&USB->DADDR, USB_DADDR_ADD); | ||||||
|             USB->DADDR |= (uint16_t)newDADDR; // leave the enable bit set |             USB->DADDR = (uint16_t)(USB->DADDR | newDADDR); // leave the enable bit set | ||||||
|             newDADDR = 0; |             newDADDR = 0; | ||||||
|           } |           } | ||||||
|           if(xfer->total_len == 0) // Probably a status message? |           if(xfer->total_len == 0) // Probably a status message? | ||||||
|           { |           { | ||||||
|             PCD_CLEAR_RX_DTOG(USB,EPindex); |             pcd_clear_rx_dtog(USB,EPindex); | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
| @@ -399,10 +404,10 @@ static uint16_t dcd_ep_ctr_handler(void) | |||||||
|         /* DIR = 1 & CTR_RX       => SETUP or OUT int */ |         /* DIR = 1 & CTR_RX       => SETUP or OUT int */ | ||||||
|         /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ |         /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ | ||||||
|  |  | ||||||
|         xfer_ctl_t *xfer = XFER_CTL_BASE(EPindex,TUSB_DIR_OUT); |         xfer_ctl_t *xfer = xfer_ctl_ptr(EPindex,TUSB_DIR_OUT); | ||||||
|  |  | ||||||
|         //ep = &hpcd->OUT_ep[0]; |         //ep = &hpcd->OUT_ep[0]; | ||||||
|         wEPVal = PCD_GET_ENDPOINT(USB, EPindex); |         wEPVal = pcd_get_endpoint(USB, EPindex); | ||||||
|  |  | ||||||
|         if ((wEPVal & USB_EP_SETUP) != 0U) // SETUP |         if ((wEPVal & USB_EP_SETUP) != 0U) // SETUP | ||||||
|         { |         { | ||||||
| @@ -410,38 +415,38 @@ static uint16_t dcd_ep_ctr_handler(void) | |||||||
|           // user memory, to allow for the 32-bit access that memcpy performs. |           // user memory, to allow for the 32-bit access that memcpy performs. | ||||||
|           uint8_t userMemBuf[8]; |           uint8_t userMemBuf[8]; | ||||||
|           /* Get SETUP Packet*/ |           /* Get SETUP Packet*/ | ||||||
|           count = PCD_GET_EP_RX_CNT(USB, EPindex); |           count = pcd_get_ep_rx_cnt(USB, EPindex); | ||||||
|           //TU_ASSERT_ERR(count == 8); |           //TU_ASSERT_ERR(count == 8); | ||||||
|           dcd_read_packet_memory(userMemBuf, *PCD_EP_RX_ADDRESS_PTR(USB,EPindex), 8); |           dcd_read_packet_memory(userMemBuf, *pcd_ep_rx_address_ptr(USB,EPindex), 8); | ||||||
|           /* SETUP bit kept frozen while CTR_RX = 1*/ |           /* SETUP bit kept frozen while CTR_RX = 1*/ | ||||||
|           dcd_event_setup_received(0, (uint8_t*)userMemBuf, true); |           dcd_event_setup_received(0, (uint8_t*)userMemBuf, true); | ||||||
|           PCD_CLEAR_RX_EP_CTR(USB, EPindex); |           pcd_clear_rx_ep_ctr(USB, EPindex); | ||||||
|         } |         } | ||||||
|         else if ((wEPVal & USB_EP_CTR_RX) != 0U) // OUT |         else if ((wEPVal & USB_EP_CTR_RX) != 0U) // OUT | ||||||
|         { |         { | ||||||
|  |  | ||||||
|           PCD_CLEAR_RX_EP_CTR(USB, EPindex); |           pcd_clear_rx_ep_ctr(USB, EPindex); | ||||||
|  |  | ||||||
|           /* Get Control Data OUT Packet */ |           /* Get Control Data OUT Packet */ | ||||||
|           count = PCD_GET_EP_RX_CNT(USB,EPindex); |           count = pcd_get_ep_rx_cnt(USB,EPindex); | ||||||
|  |  | ||||||
|           if (count != 0U) |           if (count != 0U) | ||||||
|           { |           { | ||||||
|             dcd_read_packet_memory(xfer->buffer, *PCD_EP_RX_ADDRESS_PTR(USB,EPindex), count); |             dcd_read_packet_memory(xfer->buffer, *pcd_ep_rx_address_ptr(USB,EPindex), count); | ||||||
|             xfer->queued_len = (uint16_t)(xfer->queued_len + count); |             xfer->queued_len = (uint16_t)(xfer->queued_len + count); | ||||||
|           } |           } | ||||||
|  |  | ||||||
|           /* Process Control Data OUT status Packet*/ |           /* Process Control Data OUT status Packet*/ | ||||||
|           if(EPindex == 0u && xfer->total_len == 0u) |           if(EPindex == 0u && xfer->total_len == 0u) | ||||||
|           { |           { | ||||||
|              PCD_CLEAR_EP_KIND(USB,0); // Good, so allow non-zero length packets now. |              pcd_clear_ep_kind(USB,0); // Good, so allow non-zero length packets now. | ||||||
|           } |           } | ||||||
|           dcd_event_xfer_complete(0, EPindex, xfer->total_len, XFER_RESULT_SUCCESS, true); |           dcd_event_xfer_complete(0, EPindex, xfer->total_len, XFER_RESULT_SUCCESS, true); | ||||||
|  |  | ||||||
|           PCD_SET_EP_RX_CNT(USB, EPindex, CFG_TUD_ENDPOINT0_SIZE); |           pcd_set_ep_rx_cnt(USB, EPindex, CFG_TUD_ENDPOINT0_SIZE); | ||||||
|           if(EPindex == 0u && xfer->total_len == 0u) |           if(EPindex == 0u && xfer->total_len == 0u) | ||||||
|           { |           { | ||||||
|             PCD_SET_EP_RX_STATUS(USB, EPindex, USB_EP_RX_VALID);// Await next SETUP |             pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID);// Await next SETUP | ||||||
|           } |           } | ||||||
|  |  | ||||||
|         } |         } | ||||||
| @@ -452,27 +457,27 @@ static uint16_t dcd_ep_ctr_handler(void) | |||||||
|     { |     { | ||||||
|  |  | ||||||
|       /* process related endpoint register */ |       /* process related endpoint register */ | ||||||
|       wEPVal = PCD_GET_ENDPOINT(USB, EPindex); |       wEPVal = pcd_get_endpoint(USB, EPindex); | ||||||
|       if ((wEPVal & USB_EP_CTR_RX) != 0U) // OUT |       if ((wEPVal & USB_EP_CTR_RX) != 0U) // OUT | ||||||
|       { |       { | ||||||
|         /* clear int flag */ |         /* clear int flag */ | ||||||
|         PCD_CLEAR_RX_EP_CTR(USB, EPindex); |         pcd_clear_rx_ep_ctr(USB, EPindex); | ||||||
|  |  | ||||||
|         xfer_ctl_t * xfer = XFER_CTL_BASE(EPindex,TUSB_DIR_OUT); |         xfer_ctl_t * xfer = xfer_ctl_ptr(EPindex,TUSB_DIR_OUT); | ||||||
|  |  | ||||||
|         //ep = &hpcd->OUT_ep[EPindex]; |         //ep = &hpcd->OUT_ep[EPindex]; | ||||||
|  |  | ||||||
|         count = PCD_GET_EP_RX_CNT(USB, EPindex); |         count = pcd_get_ep_rx_cnt(USB, EPindex); | ||||||
|         if (count != 0U) |         if (count != 0U) | ||||||
|         { |         { | ||||||
|           dcd_read_packet_memory(&(xfer->buffer[xfer->queued_len]), |           dcd_read_packet_memory(&(xfer->buffer[xfer->queued_len]), | ||||||
|               *PCD_EP_RX_ADDRESS_PTR(USB,EPindex), count); |               *pcd_ep_rx_address_ptr(USB,EPindex), count); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         /*multi-packet on the NON control OUT endpoint */ |         /*multi-packet on the NON control OUT endpoint */ | ||||||
|         xfer->queued_len = (uint16_t)(xfer->queued_len + count); |         xfer->queued_len = (uint16_t)(xfer->queued_len + count); | ||||||
|  |  | ||||||
|         if ((count < 64) || (xfer->queued_len == xfer->total_len)) |         if ((count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) | ||||||
|         { |         { | ||||||
|           /* RX COMPLETE */ |           /* RX COMPLETE */ | ||||||
|           dcd_event_xfer_complete(0, EPindex, xfer->queued_len, XFER_RESULT_SUCCESS, true); |           dcd_event_xfer_complete(0, EPindex, xfer->queued_len, XFER_RESULT_SUCCESS, true); | ||||||
| @@ -481,14 +486,14 @@ static uint16_t dcd_ep_ctr_handler(void) | |||||||
|         } |         } | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|           uint16_t remaining = (uint16_t)(xfer->total_len - xfer->queued_len); |           uint32_t remaining = (uint32_t)xfer->total_len - (uint32_t)xfer->queued_len; | ||||||
|           if(remaining >=64) { |           if(remaining >= xfer->max_packet_size) { | ||||||
|             PCD_SET_EP_RX_CNT(USB, EPindex,64); |             pcd_set_ep_rx_cnt(USB, EPindex,xfer->max_packet_size); | ||||||
|           } else { |           } else { | ||||||
|             PCD_SET_EP_RX_CNT(USB, EPindex,remaining); |             pcd_set_ep_rx_cnt(USB, EPindex,remaining); | ||||||
|           } |           } | ||||||
|  |  | ||||||
|           PCD_SET_EP_RX_STATUS(USB, EPindex, USB_EP_RX_VALID); |           pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|       } /* if((wEPVal & EP_CTR_RX) */ |       } /* if((wEPVal & EP_CTR_RX) */ | ||||||
| @@ -496,9 +501,9 @@ static uint16_t dcd_ep_ctr_handler(void) | |||||||
|       if ((wEPVal & USB_EP_CTR_TX) != 0U) // IN |       if ((wEPVal & USB_EP_CTR_TX) != 0U) // IN | ||||||
|       { |       { | ||||||
|         /* clear int flag */ |         /* clear int flag */ | ||||||
|         PCD_CLEAR_TX_EP_CTR(USB, EPindex); |         pcd_clear_tx_ep_ctr(USB, EPindex); | ||||||
|  |  | ||||||
|         xfer_ctl_t * xfer = XFER_CTL_BASE(EPindex,TUSB_DIR_IN); |         xfer_ctl_t * xfer = xfer_ctl_ptr(EPindex,TUSB_DIR_IN); | ||||||
|  |  | ||||||
|         if (xfer->queued_len  != xfer->total_len) // data remaining in transfer? |         if (xfer->queued_len  != xfer->total_len) // data remaining in transfer? | ||||||
|         { |         { | ||||||
| @@ -532,10 +537,10 @@ static void dcd_fs_irqHandler(void) { | |||||||
|   } |   } | ||||||
|   if (int_status & USB_ISTR_WKUP) |   if (int_status & USB_ISTR_WKUP) | ||||||
|   { |   { | ||||||
|  |  | ||||||
|     reg16_clear_bits(&USB->CNTR, USB_CNTR_LPMODE); |     reg16_clear_bits(&USB->CNTR, USB_CNTR_LPMODE); | ||||||
|     reg16_clear_bits(&USB->CNTR, USB_CNTR_FSUSP); |     reg16_clear_bits(&USB->CNTR, USB_CNTR_FSUSP); | ||||||
|     reg16_clear_bits(&USB->ISTR, USB_ISTR_WKUP); |     reg16_clear_bits(&USB->ISTR, USB_ISTR_WKUP); | ||||||
|  |     dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (int_status & USB_ISTR_SUSP) |   if (int_status & USB_ISTR_SUSP) | ||||||
| @@ -546,12 +551,25 @@ static void dcd_fs_irqHandler(void) { | |||||||
|  |  | ||||||
|     /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ |     /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ | ||||||
|     reg16_clear_bits(&USB->ISTR, USB_ISTR_SUSP); |     reg16_clear_bits(&USB->ISTR, USB_ISTR_SUSP); | ||||||
|  |     dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if(int_status & USB_ISTR_SOF) { |   if(int_status & USB_ISTR_SOF) { | ||||||
|     reg16_clear_bits(&USB->ISTR, USB_ISTR_SOF); |     reg16_clear_bits(&USB->ISTR, USB_ISTR_SOF); | ||||||
|     dcd_event_bus_signal(0, DCD_EVENT_SOF, true); |     dcd_event_bus_signal(0, DCD_EVENT_SOF, true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   if(int_status & USB_ISTR_ESOF) { | ||||||
|  |     if(remoteWakeCountdown == 1u) | ||||||
|  |     { | ||||||
|  |       USB->CNTR &= (uint16_t)(~USB_CNTR_RESUME); | ||||||
|  |     } | ||||||
|  |     if(remoteWakeCountdown > 0u) | ||||||
|  |     { | ||||||
|  |       remoteWakeCountdown--; | ||||||
|  |     } | ||||||
|  |     reg16_clear_bits(&USB->ISTR, USB_ISTR_ESOF); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| //--------------------------------------------------------------------+ | //--------------------------------------------------------------------+ | ||||||
| @@ -566,47 +584,55 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc | |||||||
|   (void)rhport; |   (void)rhport; | ||||||
|   uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); |   uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); | ||||||
|   uint8_t const dir   = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); |   uint8_t const dir   = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); | ||||||
|  |   const uint16_t epMaxPktSize = p_endpoint_desc->wMaxPacketSize.size; | ||||||
|   // Isochronous not supported (yet), and some other driver assumptions. |   // Isochronous not supported (yet), and some other driver assumptions. | ||||||
|   TU_ASSERT(p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); |  | ||||||
|   TU_ASSERT(p_endpoint_desc->wMaxPacketSize.size <= MAX_PACKET_SIZE); |  | ||||||
|   TU_ASSERT(epnum < MAX_EP_COUNT); |  | ||||||
|   TU_ASSERT((p_endpoint_desc->wMaxPacketSize.size %2) == 0); |  | ||||||
|  |  | ||||||
|  // __IO uint16_t * const epreg = &(EPREG(epnum)); |   TU_ASSERT(p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); | ||||||
|  |   TU_ASSERT(epnum < MAX_EP_COUNT); | ||||||
|  |  | ||||||
|   // Set type |   // Set type | ||||||
|   switch(p_endpoint_desc->bmAttributes.xfer) { |   switch(p_endpoint_desc->bmAttributes.xfer) { | ||||||
|   case TUSB_XFER_CONTROL: |   case TUSB_XFER_CONTROL: | ||||||
|     PCD_SET_EPTYPE(USB, epnum, USB_EP_CONTROL); break; |     pcd_set_eptype(USB, epnum, USB_EP_CONTROL); | ||||||
|   case TUSB_XFER_ISOCHRONOUS: |     break; | ||||||
|     PCD_SET_EPTYPE(USB, epnum, USB_EP_ISOCHRONOUS); break; | #if (0) | ||||||
|  |   case TUSB_XFER_ISOCHRONOUS: // FIXME: Not yet supported | ||||||
|  |     pcd_set_eptype(USB, epnum, USB_EP_ISOCHRONOUS); break; | ||||||
|  |     break; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|   case TUSB_XFER_BULK: |   case TUSB_XFER_BULK: | ||||||
|     PCD_SET_EPTYPE(USB, epnum, USB_EP_BULK); break; |     pcd_set_eptype(USB, epnum, USB_EP_BULK); | ||||||
|  |     break; | ||||||
|  |  | ||||||
|   case TUSB_XFER_INTERRUPT: |   case TUSB_XFER_INTERRUPT: | ||||||
|     PCD_SET_EPTYPE(USB, epnum, USB_EP_INTERRUPT); break; |     pcd_set_eptype(USB, epnum, USB_EP_INTERRUPT); | ||||||
|  |     break; | ||||||
|  |  | ||||||
|   default: |   default: | ||||||
|     TU_ASSERT(false); |     TU_ASSERT(false); | ||||||
|  |     return false; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   PCD_SET_EP_ADDRESS(USB, epnum, epnum); |   pcd_set_ep_address(USB, epnum, epnum); | ||||||
|   PCD_CLEAR_EP_KIND(USB,0); // Be normal, for now, instead of only accepting zero-byte packets |   pcd_clear_ep_kind(USB,0); // Be normal, for now, instead of only accepting zero-byte packets | ||||||
|  |  | ||||||
|   if(dir == TUSB_DIR_IN) |   if(dir == TUSB_DIR_IN) | ||||||
|   { |   { | ||||||
|     *PCD_EP_TX_ADDRESS_PTR(USB, epnum) = ep_buf_ptr; |     *pcd_ep_tx_address_ptr(USB, epnum) = ep_buf_ptr; | ||||||
|     PCD_SET_EP_RX_CNT(USB, epnum, p_endpoint_desc->wMaxPacketSize.size); |     pcd_set_ep_tx_cnt(USB, epnum, p_endpoint_desc->wMaxPacketSize.size); | ||||||
|     PCD_CLEAR_TX_DTOG(USB, epnum); |     pcd_clear_tx_dtog(USB, epnum); | ||||||
|     PCD_SET_EP_TX_STATUS(USB,epnum,USB_EP_TX_NAK); |     pcd_set_ep_tx_status(USB,epnum,USB_EP_TX_NAK); | ||||||
|   } |   } | ||||||
|   else |   else | ||||||
|   { |   { | ||||||
|     *PCD_EP_RX_ADDRESS_PTR(USB, epnum) = ep_buf_ptr; |     *pcd_ep_rx_address_ptr(USB, epnum) = ep_buf_ptr; | ||||||
|     PCD_SET_EP_RX_CNT(USB, epnum, p_endpoint_desc->wMaxPacketSize.size); |     pcd_set_ep_rx_cnt(USB, epnum, p_endpoint_desc->wMaxPacketSize.size); | ||||||
|     PCD_CLEAR_RX_DTOG(USB, epnum); |     pcd_clear_rx_dtog(USB, epnum); | ||||||
|     PCD_SET_EP_RX_STATUS(USB, epnum, USB_EP_RX_NAK); |     pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_NAK); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   xfer_ctl_ptr(epnum, dir)->max_packet_size = epMaxPktSize; | ||||||
|   ep_buf_ptr = (uint16_t)(ep_buf_ptr + p_endpoint_desc->wMaxPacketSize.size); // increment buffer pointer |   ep_buf_ptr = (uint16_t)(ep_buf_ptr + p_endpoint_desc->wMaxPacketSize.size); // increment buffer pointer | ||||||
|  |  | ||||||
|   return true; |   return true; | ||||||
| @@ -618,15 +644,16 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix) | |||||||
| { | { | ||||||
|   uint16_t len = (uint16_t)(xfer->total_len - xfer->queued_len); |   uint16_t len = (uint16_t)(xfer->total_len - xfer->queued_len); | ||||||
|  |  | ||||||
|   if(len > 64u) // max packet size for FS transfer |   if(len > xfer->max_packet_size) // max packet size for FS transfer | ||||||
|   { |   { | ||||||
|     len = 64u; |     len = xfer->max_packet_size; | ||||||
|   } |   } | ||||||
|   dcd_write_packet_memory(*PCD_EP_TX_ADDRESS_PTR(USB,ep_ix), &(xfer->buffer[xfer->queued_len]), len); |   uint16_t oldAddr = *pcd_ep_tx_address_ptr(USB,ep_ix); | ||||||
|  |   dcd_write_packet_memory(oldAddr, &(xfer->buffer[xfer->queued_len]), len); | ||||||
|   xfer->queued_len = (uint16_t)(xfer->queued_len + len); |   xfer->queued_len = (uint16_t)(xfer->queued_len + len); | ||||||
|  |  | ||||||
|   PCD_SET_EP_TX_CNT(USB,ep_ix,len); |   pcd_set_ep_tx_cnt(USB,ep_ix,len); | ||||||
|   PCD_SET_EP_TX_STATUS(USB, ep_ix, USB_EP_TX_VALID); |   pcd_set_ep_tx_status(USB, ep_ix, USB_EP_TX_VALID); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) | bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) | ||||||
| @@ -636,7 +663,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t | |||||||
|   uint8_t const epnum = tu_edpt_number(ep_addr); |   uint8_t const epnum = tu_edpt_number(ep_addr); | ||||||
|   uint8_t const dir   = tu_edpt_dir(ep_addr); |   uint8_t const dir   = tu_edpt_dir(ep_addr); | ||||||
|  |  | ||||||
|   xfer_ctl_t * xfer = XFER_CTL_BASE(epnum,dir); |   xfer_ctl_t * xfer = xfer_ctl_ptr(epnum,dir); | ||||||
|  |  | ||||||
|   xfer->buffer = buffer; |   xfer->buffer = buffer; | ||||||
|   xfer->total_len = total_bytes; |   xfer->total_len = total_bytes; | ||||||
| @@ -649,15 +676,15 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t | |||||||
|     if (epnum == 0 && buffer == NULL) |     if (epnum == 0 && buffer == NULL) | ||||||
|     { |     { | ||||||
|         xfer->buffer = (uint8_t*)_setup_packet; |         xfer->buffer = (uint8_t*)_setup_packet; | ||||||
|         PCD_SET_EP_KIND(USB,0); // Expect a zero-byte INPUT |         pcd_set_ep_kind(USB,0); // Expect a zero-byte INPUT | ||||||
|     } |     } | ||||||
|     if(total_bytes > 64) |     if(total_bytes > xfer->max_packet_size) | ||||||
|     { |     { | ||||||
|       PCD_SET_EP_RX_CNT(USB,epnum,64); |       pcd_set_ep_rx_cnt(USB,epnum,xfer->max_packet_size); | ||||||
|     } else { |     } else { | ||||||
|       PCD_SET_EP_RX_CNT(USB,epnum,total_bytes); |       pcd_set_ep_rx_cnt(USB,epnum,total_bytes); | ||||||
|     } |     } | ||||||
|     PCD_SET_EP_RX_STATUS(USB, epnum, USB_EP_RX_VALID); |     pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_VALID); | ||||||
|   } |   } | ||||||
|   else // IN |   else // IN | ||||||
|   { |   { | ||||||
| @@ -671,14 +698,14 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) | |||||||
|   (void)rhport; |   (void)rhport; | ||||||
|  |  | ||||||
|   if (ep_addr == 0) { // CTRL EP0 (OUT for setup) |   if (ep_addr == 0) { // CTRL EP0 (OUT for setup) | ||||||
|     PCD_SET_EP_TX_STATUS(USB,ep_addr, USB_EP_TX_STALL); |     pcd_set_ep_tx_status(USB,ep_addr, USB_EP_TX_STALL); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (ep_addr & 0x80) { // IN |   if (ep_addr & 0x80) { // IN | ||||||
|     ep_addr &= 0x7F; |     ep_addr &= 0x7F; | ||||||
|     PCD_SET_EP_TX_STATUS(USB,ep_addr, USB_EP_TX_STALL); |     pcd_set_ep_tx_status(USB,ep_addr, USB_EP_TX_STALL); | ||||||
|   } else { // OUT |   } else { // OUT | ||||||
|     PCD_SET_EP_RX_STATUS(USB,ep_addr, USB_EP_RX_STALL); |     pcd_set_ep_rx_status(USB,ep_addr, USB_EP_RX_STALL); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -687,24 +714,24 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) | |||||||
|   (void)rhport; |   (void)rhport; | ||||||
|   if (ep_addr == 0) |   if (ep_addr == 0) | ||||||
|   { |   { | ||||||
|     PCD_SET_EP_TX_STATUS(USB,ep_addr, USB_EP_TX_NAK); |     pcd_set_ep_tx_status(USB,ep_addr, USB_EP_TX_NAK); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (ep_addr & 0x80) |   if (ep_addr & 0x80) | ||||||
|   { // IN |   { // IN | ||||||
|     ep_addr &= 0x7F; |     ep_addr &= 0x7F; | ||||||
|  |  | ||||||
|     PCD_SET_EP_TX_STATUS(USB,ep_addr, USB_EP_TX_NAK); |     pcd_set_ep_tx_status(USB,ep_addr, USB_EP_TX_NAK); | ||||||
|  |  | ||||||
|     /* Reset to DATA0 if clearing stall condition. */ |     /* Reset to DATA0 if clearing stall condition. */ | ||||||
|     PCD_CLEAR_TX_DTOG(USB,ep_addr); |     pcd_clear_tx_dtog(USB,ep_addr); | ||||||
|   } |   } | ||||||
|   else |   else | ||||||
|   { // OUT |   { // OUT | ||||||
|     /* Reset to DATA0 if clearing stall condition. */ |     /* Reset to DATA0 if clearing stall condition. */ | ||||||
|     PCD_CLEAR_RX_DTOG(USB,ep_addr); |     pcd_clear_rx_dtog(USB,ep_addr); | ||||||
|  |  | ||||||
|     PCD_SET_EP_RX_STATUS(USB,ep_addr, USB_EP_RX_VALID); |     pcd_set_ep_rx_status(USB,ep_addr, USB_EP_RX_VALID); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -721,18 +748,11 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) | |||||||
|   */ |   */ | ||||||
| static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, size_t wNBytes) | static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, size_t wNBytes) | ||||||
| { | { | ||||||
|   uint32_t n =  ((uint32_t)((uint32_t)wNBytes + 1U)) >> 1U; |   uint32_t n =  ((uint32_t)wNBytes + 1U) >> 1U; | ||||||
|   uint32_t i; |   uint32_t i; | ||||||
|   uint16_t temp1, temp2; |   uint16_t temp1, temp2; | ||||||
|   const uint8_t * srcVal; |   const uint8_t * srcVal; | ||||||
|  |  | ||||||
| #ifdef DEBUG |  | ||||||
| #  if (DCD_STM32_BTABLE_BASE > 0u) |  | ||||||
|      TU_ASSERT(dst >= DCD_STM32_BTABLE_BASE); |  | ||||||
| #  endif |  | ||||||
|   TU_ASSERT(((dst%2) == 0) && (dst + wNBytes) <= (DCD_STM32_BTABLE_BASE + DCD_STM32_BTABLE_LENGTH)); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|   // The GCC optimizer will combine access to 32-bit sizes if we let it. Force |   // The GCC optimizer will combine access to 32-bit sizes if we let it. Force | ||||||
|   // it volatile so that it won't do that. |   // it volatile so that it won't do that. | ||||||
|   __IO uint16_t *pdwVal; |   __IO uint16_t *pdwVal; | ||||||
| @@ -767,14 +787,6 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wN | |||||||
|   __IO const uint16_t *pdwVal; |   __IO const uint16_t *pdwVal; | ||||||
|   uint32_t temp; |   uint32_t temp; | ||||||
|  |  | ||||||
| #ifdef DEBUG |  | ||||||
| #  if (DCD_STM32_BTABLE_BASE > 0u) |  | ||||||
|      TU_ASSERT(src >= DCD_STM32_BTABLE_BASE); |  | ||||||
| #  endif |  | ||||||
|   TU_ASSERT(((src%2) == 0) && (src + wNBytes) <= (DCD_STM32_BTABLE_BASE + DCD_STM32_BTABLE_LENGTH)); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   pdwVal = &pma[PMA_STRIDE*(src>>1)]; |   pdwVal = &pma[PMA_STRIDE*(src>>1)]; | ||||||
|   uint8_t *dstVal = (uint8_t*)dst; |   uint8_t *dstVal = (uint8_t*)dst; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -46,7 +46,7 @@ | |||||||
|     defined(STM32F072xB) | \ |     defined(STM32F072xB) | \ | ||||||
|     defined(STM32F078xx) |     defined(STM32F078xx) | ||||||
| #include "stm32f0xx.h" | #include "stm32f0xx.h" | ||||||
| #define PMA_LENGTH 1024 | #define PMA_LENGTH (1024u) | ||||||
| // F0x2 models are crystal-less | // F0x2 models are crystal-less | ||||||
| // All have internal D+ pull-up | // All have internal D+ pull-up | ||||||
| // 070RB:    2 x 16 bits/word memory     LPM Support, BCD Support | // 070RB:    2 x 16 bits/word memory     LPM Support, BCD Support | ||||||
| @@ -55,7 +55,7 @@ | |||||||
|       defined(STM32F103x6) | defined(STM32F103xB) | \ |       defined(STM32F103x6) | defined(STM32F103xB) | \ | ||||||
|       defined(STM32F103xE) | defined(STM32F103xB) |       defined(STM32F103xE) | defined(STM32F103xB) | ||||||
| #include "stm32f1xx.h" | #include "stm32f1xx.h" | ||||||
| #define PMA_LENGTH 512u | #define PMA_LENGTH (512u) | ||||||
| // NO internal Pull-ups | // NO internal Pull-ups | ||||||
| //         *B, and *C:    2 x 16 bits/word | //         *B, and *C:    2 x 16 bits/word | ||||||
| #error The F102/F103 driver is expected not to work, but it might? Try it? | #error The F102/F103 driver is expected not to work, but it might? Try it? | ||||||
| @@ -64,7 +64,7 @@ | |||||||
|       defined(STM32F303xB) | defined(STM32F303xC) | \ |       defined(STM32F303xB) | defined(STM32F303xC) | \ | ||||||
|       defined(STM32F373xC) |       defined(STM32F373xC) | ||||||
| #include "stm32f3xx.h" | #include "stm32f3xx.h" | ||||||
| #define PMA_LENGTH 512u | #define PMA_LENGTH (512u) | ||||||
| // NO internal Pull-ups | // NO internal Pull-ups | ||||||
| //         *B, and *C:    1 x 16 bits/word | //         *B, and *C:    1 x 16 bits/word | ||||||
| // PMA dedicated to USB (no sharing with CAN) | // PMA dedicated to USB (no sharing with CAN) | ||||||
| @@ -72,7 +72,7 @@ | |||||||
|       defined(STM32F302xD) | defined(STM32F302xE) | \ |       defined(STM32F302xD) | defined(STM32F302xE) | \ | ||||||
|       defined(STM32F303xD) | defined(STM32F303xE) | \ |       defined(STM32F303xD) | defined(STM32F303xE) | \ | ||||||
| #include "stm32f3xx.h" | #include "stm32f3xx.h" | ||||||
| #define PMA_LENGTH 1024u | #define PMA_LENGTH (1024u) | ||||||
| // NO internal Pull-ups | // NO internal Pull-ups | ||||||
| // *6, *8, *D, and *E:    2 x 16 bits/word     LPM Support | // *6, *8, *D, and *E:    2 x 16 bits/word     LPM Support | ||||||
| // When CAN clock is enabled, USB can use first 768 bytes ONLY. | // When CAN clock is enabled, USB can use first 768 bytes ONLY. | ||||||
| @@ -83,9 +83,9 @@ | |||||||
|  |  | ||||||
| // For purposes of accessing the packet | // For purposes of accessing the packet | ||||||
| #if ((PMA_LENGTH) == 512u) | #if ((PMA_LENGTH) == 512u) | ||||||
| #  define PMA_STRIDE (2u) | #define PMA_STRIDE  (2u) | ||||||
| #elif ((PMA_LENGTH) == 1024u) | #elif ((PMA_LENGTH) == 1024u) | ||||||
| #  define PMA_STRIDE (1u) | #define PMA_STRIDE  (1u) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| // And for type-safety create a new macro for the volatile address of PMAADDR | // And for type-safety create a new macro for the volatile address of PMAADDR | ||||||
| @@ -93,32 +93,75 @@ | |||||||
| // Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden) | // Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden) | ||||||
| static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; | static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; | ||||||
|  |  | ||||||
| /* SetENDPOINT */ | // prototypes | ||||||
| #define PCD_SET_ENDPOINT(USBx, bEpNum,wRegValue)  (*((__IO uint16_t *)(((uint32_t)(&(USBx)->EP0R + (bEpNum) * 2U))))= (uint16_t)(wRegValue)) | static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpNum); | ||||||
| /* GetENDPOINT */ | static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpNum); | ||||||
| #define PCD_GET_ENDPOINT(USBx, bEpNum)            (*((__IO uint16_t *)(((uint32_t)(&(USBx)->EP0R + (bEpNum) * 2U))))) | static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wRegValue); | ||||||
| #define PCD_SET_EPTYPE(USBx, bEpNum,wType) (PCD_SET_ENDPOINT((USBx), (bEpNum),\ |  | ||||||
|                                   (((((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & ((uint32_t)(USB_EP_T_MASK))) | ((uint32_t)(wType))) | USB_EP_CTR_RX | USB_EP_CTR_TX))) |  | ||||||
| #define PCD_GET_EPTYPE(USBx, bEpNum) (((uint16_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & USB_EP_T_FIELD) |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* SetENDPOINT */ | ||||||
|  | static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wRegValue) | ||||||
|  | { | ||||||
|  |   __O uint16_t *reg = (__O uint16_t *)((&USBx->EP0R) + bEpNum*2u); | ||||||
|  |   *reg = (uint16_t)wRegValue; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* GetENDPOINT */ | ||||||
|  | static inline uint16_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpNum) { | ||||||
|  |   __I uint16_t *reg = (__I uint16_t *)((&USBx->EP0R) + bEpNum*2u); | ||||||
|  |   return *reg; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wType) | ||||||
|  | { | ||||||
|  |   uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); | ||||||
|  |   regVal &= (uint32_t)USB_EP_T_MASK; | ||||||
|  |   regVal |= wType; | ||||||
|  |   regVal |= USB_EP_CTR_RX | USB_EP_CTR_TX; // These clear on write0, so must set high | ||||||
|  |   pcd_set_endpoint(USBx, bEpNum, regVal); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline uint32_t pcd_get_eptype(USB_TypeDef * USBx, uint32_t bEpNum) | ||||||
|  | { | ||||||
|  |   uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); | ||||||
|  |   regVal &= USB_EP_T_FIELD; | ||||||
|  |   return regVal; | ||||||
|  | } | ||||||
| /** | /** | ||||||
|   * @brief  Clears bit CTR_RX / CTR_TX in the endpoint register. |   * @brief  Clears bit CTR_RX / CTR_TX in the endpoint register. | ||||||
|   * @param  USBx USB peripheral instance register address. |   * @param  USBx USB peripheral instance register address. | ||||||
|   * @param  bEpNum Endpoint Number. |   * @param  bEpNum Endpoint Number. | ||||||
|   * @retval None |   * @retval None | ||||||
|   */ |   */ | ||||||
| #define PCD_CLEAR_RX_EP_CTR(USBx, bEpNum)   (PCD_SET_ENDPOINT((USBx), (bEpNum),\ | static inline void pcd_clear_rx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpNum) | ||||||
|                                    PCD_GET_ENDPOINT((USBx), (bEpNum)) & 0x7FFFU & USB_EPREG_MASK)) | { | ||||||
| #define PCD_CLEAR_TX_EP_CTR(USBx, bEpNum)   (PCD_SET_ENDPOINT((USBx), (bEpNum),\ |   uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); | ||||||
|                                    PCD_GET_ENDPOINT((USBx), (bEpNum)) & 0xFF7FU & USB_EPREG_MASK)) |   regVal &= 0x7FFFu & USB_EPREG_MASK; | ||||||
|  |   pcd_set_endpoint(USBx, bEpNum, regVal); | ||||||
|  | } | ||||||
|  | static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpNum) | ||||||
|  | { | ||||||
|  |   uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); | ||||||
|  |   regVal &= regVal & 0xFF7FU & USB_EPREG_MASK; | ||||||
|  |   pcd_set_endpoint(USBx, bEpNum,regVal); | ||||||
|  | } | ||||||
| /** | /** | ||||||
|   * @brief  gets counter of the tx buffer. |   * @brief  gets counter of the tx buffer. | ||||||
|   * @param  USBx USB peripheral instance register address. |   * @param  USBx USB peripheral instance register address. | ||||||
|   * @param  bEpNum Endpoint Number. |   * @param  bEpNum Endpoint Number. | ||||||
|   * @retval Counter value |   * @retval Counter value | ||||||
|   */ |   */ | ||||||
| #define PCD_GET_EP_TX_CNT(USBx, bEpNum)((uint16_t)(*PCD_EP_TX_CNT_PTR((USBx), (bEpNum))) & 0x3ffU) | static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpNum) | ||||||
| #define PCD_GET_EP_RX_CNT(USBx, bEpNum)((uint16_t)(*PCD_EP_RX_CNT_PTR((USBx), (bEpNum))) & 0x3ffU) | { | ||||||
|  |   __I uint16_t *regPtr = pcd_ep_tx_cnt_ptr(USBx, bEpNum); | ||||||
|  |   return *regPtr & 0x3ffU; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpNum) | ||||||
|  | { | ||||||
|  |   __I uint16_t *regPtr = pcd_ep_rx_cnt_ptr(USBx, bEpNum); | ||||||
|  |   return *regPtr & 0x3ffU; | ||||||
|  | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   * @brief  Sets counter of rx buffer with no. of blocks. |   * @brief  Sets counter of rx buffer with no. of blocks. | ||||||
| @@ -127,38 +170,30 @@ static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; | |||||||
|   * @param  wNBlocks no. of Blocks. |   * @param  wNBlocks no. of Blocks. | ||||||
|   * @retval None |   * @retval None | ||||||
|   */ |   */ | ||||||
| #define PCD_CALC_BLK32(dwReg,wCount,wNBlocks) {\ |  | ||||||
|     (wNBlocks) = (uint32_t)((wCount) >> 5U);\ |  | ||||||
|     if(((wCount) & 0x1fU) == 0U)\ |  | ||||||
|     {                                                  \ |  | ||||||
|       (wNBlocks)--;\ |  | ||||||
|     }                                                  \ |  | ||||||
|     *pdwReg = (uint16_t)((uint16_t)((wNBlocks) << 10U) | (uint16_t)0x8000U); \ |  | ||||||
|   }/* PCD_CALC_BLK32 */ |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #define PCD_CALC_BLK2(dwReg,wCount,wNBlocks) {\ |  | ||||||
|     (wNBlocks) = (uint32_t)((wCount) >> 1U); \ |  | ||||||
|     if(((wCount) & 0x1U) != 0U)\ |  | ||||||
|     {                                                  \ |  | ||||||
|       (wNBlocks)++;\ |  | ||||||
|     }                                                  \ |  | ||||||
|     *pdwReg = (uint16_t)((wNBlocks) << 10U);\ |  | ||||||
|   }/* PCD_CALC_BLK2 */ |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #define PCD_SET_EP_CNT_RX_REG(dwReg,wCount)  {\ |  | ||||||
|     uint32_t wNBlocks;\ |  | ||||||
|     if((wCount) > 62U)                                \ |  | ||||||
|     {                                                \ |  | ||||||
|       PCD_CALC_BLK32((dwReg),(wCount),wNBlocks)     \ |  | ||||||
|     }                                                \ |  | ||||||
|     else                                             \ |  | ||||||
|     {                                                \ |  | ||||||
|       PCD_CALC_BLK2((dwReg),(wCount),wNBlocks)     \ |  | ||||||
|     }                                                \ |  | ||||||
|   }/* PCD_SET_EP_CNT_RX_REG */ |  | ||||||
|  |  | ||||||
|  | static inline void pcd_set_ep_cnt_rx_reg(__O uint16_t * pdwReg, size_t wCount)  { | ||||||
|  |   uint32_t wNBlocks; | ||||||
|  |   if(wCount > 62u) | ||||||
|  |   { | ||||||
|  |     wNBlocks = wCount >> 5u; | ||||||
|  |     if((wCount & 0x1fU) == 0u) | ||||||
|  |     { | ||||||
|  |       wNBlocks--; | ||||||
|  |     } | ||||||
|  |     wNBlocks = wNBlocks << 10u; | ||||||
|  |     wNBlocks |= 0x8000u; // Mark block size as 32byte | ||||||
|  |     *pdwReg = (uint16_t)wNBlocks; | ||||||
|  |   } | ||||||
|  |   else | ||||||
|  |   { | ||||||
|  |     wNBlocks = wCount >> 1u; | ||||||
|  |     if((wCount & 0x1U) != 0u) | ||||||
|  |     { | ||||||
|  |       wNBlocks++; | ||||||
|  |     } | ||||||
|  |     *pdwReg = (uint16_t)((wNBlocks) << 10u); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -168,23 +203,52 @@ static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; | |||||||
|   * @param  bAddr Address. |   * @param  bAddr Address. | ||||||
|   * @retval None |   * @retval None | ||||||
|   */ |   */ | ||||||
| #define PCD_SET_EP_ADDRESS(USBx, bEpNum,bAddr) PCD_SET_ENDPOINT((USBx), (bEpNum),\ | static inline void pcd_set_ep_address(USB_TypeDef * USBx,  uint32_t bEpNum, uint32_t bAddr) | ||||||
|     USB_EP_CTR_RX|USB_EP_CTR_TX|(((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & USB_EPREG_MASK) | (bAddr)) | { | ||||||
|  |   uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); | ||||||
|  |   regVal &= USB_EPREG_MASK; | ||||||
|  |   regVal |= bAddr; | ||||||
|  |   regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; | ||||||
|  |   pcd_set_endpoint(USBx, bEpNum,regVal); | ||||||
|  | } | ||||||
|  |  | ||||||
| #define PCD_BTABLE_WORD_PTR(USBx,x) (&(pma[PMA_STRIDE*((((USBx)->BTABLE)>>1) + x)])) | static inline __IO uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x) | ||||||
|  | { | ||||||
|  |   size_t total_word_offset = (((USBx)->BTABLE)>>1) + x; | ||||||
|  |   total_word_offset *= PMA_STRIDE; | ||||||
|  |   return &(pma[total_word_offset]); | ||||||
|  | } | ||||||
|  |  | ||||||
| // Pointers to the PMA table entries (using the ARM address space) | // Pointers to the PMA table entries (using the ARM address space) | ||||||
| #define PCD_EP_TX_ADDRESS_PTR(USBx, bEpNum) (PCD_BTABLE_WORD_PTR(USBx,(bEpNum)*4u + 0u)) | static inline __IO uint16_t* pcd_ep_tx_address_ptr(USB_TypeDef * USBx, uint32_t bEpNum) | ||||||
| #define PCD_EP_TX_CNT_PTR(USBx, bEpNum)     (PCD_BTABLE_WORD_PTR(USBx,(bEpNum)*4u + 1u)) | { | ||||||
|  |   return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 0u); | ||||||
|  | } | ||||||
|  | static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpNum) | ||||||
|  | { | ||||||
|  |   return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 1u); | ||||||
|  | } | ||||||
|  |  | ||||||
| #define PCD_EP_RX_ADDRESS_PTR(USBx, bEpNum) (PCD_BTABLE_WORD_PTR(USBx,(bEpNum)*4u + 2u)) | static inline __IO uint16_t* pcd_ep_rx_address_ptr(USB_TypeDef * USBx, uint32_t bEpNum) | ||||||
| #define PCD_EP_RX_CNT_PTR(USBx, bEpNum)     (PCD_BTABLE_WORD_PTR(USBx,(bEpNum)*4u + 3u)) | { | ||||||
|  |   return  pcd_btable_word_ptr(USBx,(bEpNum)*4u + 2u); | ||||||
|  | } | ||||||
|  |  | ||||||
| #define PCD_SET_EP_TX_CNT(USBx, bEpNum,wCount) (*PCD_EP_TX_CNT_PTR((USBx), (bEpNum)) = (wCount)) | static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpNum) | ||||||
| #define PCD_SET_EP_RX_CNT(USBx, bEpNum,wCount) do {\ | { | ||||||
|     __IO uint16_t *pdwReg =PCD_EP_RX_CNT_PTR((USBx),(bEpNum)); \ |   return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 3u); | ||||||
|     PCD_SET_EP_CNT_RX_REG((pdwReg), (wCount))\ | } | ||||||
|   } while(0) |  | ||||||
|  | static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx,  uint32_t bEpNum, uint32_t wCount) | ||||||
|  | { | ||||||
|  |   *pcd_ep_tx_cnt_ptr(USBx, bEpNum) = (uint16_t)wCount; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx,  uint32_t bEpNum, uint32_t wCount) | ||||||
|  | { | ||||||
|  |   __IO uint16_t *pdwReg = pcd_ep_rx_cnt_ptr((USBx),(bEpNum)); | ||||||
|  |   pcd_set_ep_cnt_rx_reg(pdwReg, wCount); | ||||||
|  | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   * @brief  sets the status for tx transfer (bits STAT_TX[1:0]). |   * @brief  sets the status for tx transfer (bits STAT_TX[1:0]). | ||||||
| @@ -193,21 +257,24 @@ static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; | |||||||
|   * @param  wState new state |   * @param  wState new state | ||||||
|   * @retval None |   * @retval None | ||||||
|   */ |   */ | ||||||
| #define PCD_SET_EP_TX_STATUS(USBx, bEpNum, wState) { register uint16_t _wRegVal;\ | static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx,  uint32_t bEpNum, uint32_t wState) | ||||||
|    \ | { | ||||||
|     _wRegVal = (uint32_t) (((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & USB_EPTX_DTOGMASK);\ |   uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); | ||||||
|    /* toggle first bit ? */     \ |   regVal &= USB_EPTX_DTOGMASK; | ||||||
|    if((USB_EPTX_DTOG1 & (wState))!= 0U)\ |  | ||||||
|    {                                                                            \ |   /* toggle first bit ? */ | ||||||
|      _wRegVal ^=(uint16_t) USB_EPTX_DTOG1;        \ |   if((USB_EPTX_DTOG1 & (wState))!= 0U) | ||||||
|    }                                                                            \ |   { | ||||||
|    /* toggle second bit ?  */         \ |     regVal ^= USB_EPTX_DTOG1; | ||||||
|    if((USB_EPTX_DTOG2 & ((uint32_t)(wState)))!= 0U)      \ |   } | ||||||
|    {                                                                            \ |   /* toggle second bit ?  */ | ||||||
|      _wRegVal ^=(uint16_t) USB_EPTX_DTOG2;        \ |   if((USB_EPTX_DTOG2 & ((uint32_t)(wState)))!= 0U) | ||||||
|    }                                                                            \ |   { | ||||||
|    PCD_SET_ENDPOINT((USBx), (bEpNum), (((uint32_t)(_wRegVal)) | USB_EP_CTR_RX|USB_EP_CTR_TX));\ |     regVal ^= USB_EPTX_DTOG2; | ||||||
|   } /* PCD_SET_EP_TX_STATUS */ |   } | ||||||
|  |   regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; | ||||||
|  |   pcd_set_endpoint(USBx, bEpNum, regVal); | ||||||
|  | } /* pcd_set_ep_tx_status */ | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   * @brief  sets the status for rx transfer (bits STAT_TX[1:0]) |   * @brief  sets the status for rx transfer (bits STAT_TX[1:0]) | ||||||
| @@ -216,22 +283,25 @@ static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; | |||||||
|   * @param  wState new state |   * @param  wState new state | ||||||
|   * @retval None |   * @retval None | ||||||
|   */ |   */ | ||||||
| #define PCD_SET_EP_RX_STATUS(USBx, bEpNum,wState) {\ |  | ||||||
|     register uint16_t _wRegVal;   \ | static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx,  uint32_t bEpNum, uint32_t wState) | ||||||
|     \ | { | ||||||
|     _wRegVal = (uint32_t) (((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & USB_EPRX_DTOGMASK);\ |   uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); | ||||||
|     /* toggle first bit ? */  \ |   regVal &= USB_EPRX_DTOGMASK; | ||||||
|     if((USB_EPRX_DTOG1 & (wState))!= 0U) \ |  | ||||||
|     {                                                                             \ |   /* toggle first bit ? */ | ||||||
|       _wRegVal ^= (uint16_t) USB_EPRX_DTOG1;  \ |   if((USB_EPRX_DTOG1 & wState)!= 0U) | ||||||
|     }                                                                             \ |   { | ||||||
|     /* toggle second bit ? */  \ |     regVal ^= USB_EPRX_DTOG1; | ||||||
|     if((USB_EPRX_DTOG2 & ((uint32_t)(wState)))!= 0U) \ |   } | ||||||
|     {                                                                             \ |   /* toggle second bit ? */ | ||||||
|       _wRegVal ^= (uint16_t) USB_EPRX_DTOG2;  \ |   if((USB_EPRX_DTOG2 & wState)!= 0U) | ||||||
|     }                                                                             \ |   { | ||||||
|     PCD_SET_ENDPOINT((USBx), (bEpNum), (((uint32_t)(_wRegVal)) | USB_EP_CTR_RX|USB_EP_CTR_TX)); \ |     regVal ^= USB_EPRX_DTOG2; | ||||||
|   } /* PCD_SET_EP_RX_STATUS */ |   } | ||||||
|  |   regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; | ||||||
|  |   pcd_set_endpoint(USBx, bEpNum, regVal); | ||||||
|  | } /* pcd_set_ep_rx_status */ | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   * @brief  Toggles DTOG_RX / DTOG_TX bit in the endpoint register. |   * @brief  Toggles DTOG_RX / DTOG_TX bit in the endpoint register. | ||||||
| @@ -239,10 +309,21 @@ static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; | |||||||
|   * @param  bEpNum Endpoint Number. |   * @param  bEpNum Endpoint Number. | ||||||
|   * @retval None |   * @retval None | ||||||
|   */ |   */ | ||||||
| #define PCD_RX_DTOG(USBx, bEpNum)    (PCD_SET_ENDPOINT((USBx), (bEpNum), \ | static inline void pcd_rx_dtog(USB_TypeDef * USBx,  uint32_t bEpNum) | ||||||
|                                    USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX | (((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & USB_EPREG_MASK))) | { | ||||||
| #define PCD_TX_DTOG(USBx, bEpNum)    (PCD_SET_ENDPOINT((USBx), (bEpNum), \ |   uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); | ||||||
|                                    USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX | (((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & USB_EPREG_MASK))) |   regVal &= USB_EPREG_MASK; | ||||||
|  |   regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX; | ||||||
|  |   pcd_set_endpoint(USBx, bEpNum, regVal); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline void pcd_tx_dtog(USB_TypeDef * USBx,  uint32_t bEpNum) | ||||||
|  | { | ||||||
|  |   uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); | ||||||
|  |   regVal &= USB_EPREG_MASK; | ||||||
|  |   regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX; | ||||||
|  |   pcd_set_endpoint(USBx, bEpNum, regVal); | ||||||
|  | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   * @brief  Clears DTOG_RX / DTOG_TX bit in the endpoint register. |   * @brief  Clears DTOG_RX / DTOG_TX bit in the endpoint register. | ||||||
| @@ -250,14 +331,24 @@ static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; | |||||||
|   * @param  bEpNum Endpoint Number. |   * @param  bEpNum Endpoint Number. | ||||||
|   * @retval None |   * @retval None | ||||||
|   */ |   */ | ||||||
| #define PCD_CLEAR_RX_DTOG(USBx, bEpNum)  if((((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & USB_EP_DTOG_RX) != 0)\ |  | ||||||
|                                          {                                                              \ | static inline void pcd_clear_rx_dtog(USB_TypeDef * USBx,  uint32_t bEpNum) | ||||||
|                                            PCD_RX_DTOG((USBx),(bEpNum));\ | { | ||||||
|  |   uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); | ||||||
|  |   if((regVal & USB_EP_DTOG_RX) != 0) | ||||||
|  |   { | ||||||
|  |     pcd_rx_dtog(USBx,bEpNum); | ||||||
|   } |   } | ||||||
| #define PCD_CLEAR_TX_DTOG(USBx, bEpNum)  if((((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & USB_EP_DTOG_TX) != 0)\ | } | ||||||
|                                          {\ |  | ||||||
|                                            PCD_TX_DTOG((USBx),(bEpNum));\ | static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx,  uint32_t bEpNum) | ||||||
|  | { | ||||||
|  |   uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); | ||||||
|  |   if((regVal & USB_EP_DTOG_TX) != 0) | ||||||
|  |   { | ||||||
|  |     pcd_tx_dtog(USBx,bEpNum); | ||||||
|   } |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   * @brief  set & clear EP_KIND bit. |   * @brief  set & clear EP_KIND bit. | ||||||
| @@ -265,11 +356,22 @@ static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; | |||||||
|   * @param  bEpNum Endpoint Number. |   * @param  bEpNum Endpoint Number. | ||||||
|   * @retval None |   * @retval None | ||||||
|   */ |   */ | ||||||
| #define PCD_SET_EP_KIND(USBx, bEpNum)    (PCD_SET_ENDPOINT((USBx), (bEpNum), \ |  | ||||||
|                                 (USB_EP_CTR_RX|USB_EP_CTR_TX|((((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) | USB_EP_KIND) & USB_EPREG_MASK)))) |  | ||||||
|  |  | ||||||
| #define PCD_CLEAR_EP_KIND(USBx, bEpNum)  (PCD_SET_ENDPOINT((USBx), (bEpNum), \ | static inline void pcd_set_ep_kind(USB_TypeDef * USBx,  uint32_t bEpNum) | ||||||
|                                 (USB_EP_CTR_RX|USB_EP_CTR_TX|((((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & USB_EPKIND_MASK))))) | { | ||||||
|  |   uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); | ||||||
|  |   regVal |= USB_EP_KIND; | ||||||
|  |   regVal &= USB_EPREG_MASK; | ||||||
|  |   regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; | ||||||
|  |   pcd_set_endpoint(USBx, bEpNum, regVal); | ||||||
|  | } | ||||||
|  | static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpNum) | ||||||
|  | { | ||||||
|  |   uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); | ||||||
|  |   regVal &= USB_EPKIND_MASK; | ||||||
|  |   regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; | ||||||
|  |   pcd_set_endpoint(USBx, bEpNum, regVal); | ||||||
|  | } | ||||||
|  |  | ||||||
| // This checks if the device has "LPM" | // This checks if the device has "LPM" | ||||||
| #if defined(USB_ISTR_L1REQ) | #if defined(USB_ISTR_L1REQ) | ||||||
| @@ -282,6 +384,6 @@ static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; | |||||||
|      USB_ISTR_RESET | USB_ISTR_SOF | USB_ISTR_ESOF | USB_ISTR_L1REQ_FORCED ) |      USB_ISTR_RESET | USB_ISTR_SOF | USB_ISTR_ESOF | USB_ISTR_L1REQ_FORCED ) | ||||||
|  |  | ||||||
| // Number of endpoints in hardware | // Number of endpoints in hardware | ||||||
| #define STFSDEV_EP_COUNT (8) | #define STFSDEV_EP_COUNT (8u) | ||||||
|  |  | ||||||
| #endif /* PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_ */ | #endif /* PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_ */ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Nathan Conrad
					Nathan Conrad