This file contains the USBB low-level driver routines.
Definition in file usb_drv.c.
#include "usb_drv.h"
#include "usb_descriptors.h"
Go to the source code of this file.
Functions | |
void | host_disable_all_pipes (void) |
--------------------------------------------------------- ------------------ HOST --------------------------------- --------------------------------------------------------- | |
U32 | host_read_p_rxpacket (U8 p, void *rxbuf, U32 data_length, void **prxbuf) |
host_read_p_rxpacket | |
U32 | host_set_p_txpacket (U8 p, U8 txbyte, U32 data_length) |
host_set_p_txpacket | |
U32 | host_write_p_txpacket (U8 p, const void *txbuf, U32 data_length, const void **ptxbuf) |
host_write_p_txpacket | |
Status_bool_t | usb_init_device (void) |
--------------------------------------------------------- ------------------ DEVICE ------------------------------- --------------------------------------------------------- | |
U32 | usb_read_ep_rxpacket (U8 ep, void *rxbuf, U32 data_length, void **prxbuf) |
usb_read_ep_rxpacket | |
U32 | usb_set_ep_txpacket (U8 ep, U8 txbyte, U32 data_length) |
usb_set_ep_txpacket | |
U32 | usb_write_ep_txpacket (U8 ep, const void *txbuf, U32 data_length, const void **ptxbuf) |
usb_write_ep_txpacket | |
Variables | |
UnionVPtr | pep_fifo [MAX_PEP_NB] |
Pointers to the FIFO data registers of pipes/endpoints Use aggregated pointers to have several alignments available for a same address. |
void host_disable_all_pipes | ( | void | ) |
--------------------------------------------------------- ------------------ HOST --------------------------------- ---------------------------------------------------------
host_disable_all_pipes This function disables all pipes for the host controller. Useful to execute upon disconnection.
Definition at line 468 of file usb_drv.c.
References Host_disable_pipe, Host_disable_pipe_interrupt, Host_reset_pipe, Host_unallocate_memory, Is_host_pipe_enabled, and MAX_PEP_NB.
Referenced by usb_general_interrupt_non_naked(), and usb_host_task().
00469 { 00470 #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE 00471 Bool sav_glob_int_en; 00472 #endif 00473 U8 p; 00474 00475 #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE 00476 // Disable global interrupts 00477 if ((sav_glob_int_en = Is_global_interrupt_enabled())) Disable_global_interrupt(); 00478 #endif 00479 for (p = 0; p < MAX_PEP_NB; p++) 00480 { // Disable the pipe <p> (disable interrupt, free memory, reset pipe, ...) 00481 Host_disable_pipe_interrupt(p); 00482 Host_reset_pipe(p); 00483 Host_unallocate_memory(p); 00484 Host_disable_pipe(p); 00485 } 00486 #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE 00487 (void)Is_host_pipe_enabled(MAX_PEP_NB - 1); 00488 // Restore the global interrupts to the initial state 00489 if (sav_glob_int_en) Enable_global_interrupt(); 00490 #endif 00491 }
U32 host_read_p_rxpacket | ( | U8 | p, | |
void * | rxbuf, | |||
U32 | data_length, | |||
void ** | prxbuf | |||
) |
host_read_p_rxpacket
This function reads the selected pipe FIFO to the buffer pointed to by rxbuf, using as few accesses as possible.
p | Number of the addressed pipe | |
rxbuf | Address of buffer to write | |
data_length | Number of bytes to read | |
prxbuf | NULL or pointer to the buffer address to update |
Do not mix calls to this function with calls to indexed macros.
Definition at line 756 of file usb_drv.c.
References Host_byte_count, and pep_fifo.
Referenced by host_get_data(), host_transfer_control(), and usb_pipe_interrupt().
00757 { 00758 // Use aggregated pointers to have several alignments available for a same address 00759 UnionCVPtr p_fifo; 00760 UnionPtr rxbuf_cur; 00761 #if (!defined __OPTIMIZE_SIZE__) || !__OPTIMIZE_SIZE__ // Auto-generated when GCC's -Os command option is used 00762 StructCPtr rxbuf_end; 00763 #else 00764 UnionCPtr rxbuf_end; 00765 #endif // !__OPTIMIZE_SIZE__ 00766 00767 // Initialize pointers for copy loops and limit the number of bytes to copy 00768 p_fifo.u8ptr = pep_fifo[p].u8ptr; 00769 rxbuf_cur.u8ptr = rxbuf; 00770 rxbuf_end.u8ptr = rxbuf_cur.u8ptr + min(data_length, Host_byte_count(p)); 00771 #if (!defined __OPTIMIZE_SIZE__) || !__OPTIMIZE_SIZE__ // Auto-generated when GCC's -Os command option is used 00772 rxbuf_end.u16ptr = (U16 *)Align_down((U32)rxbuf_end.u8ptr, sizeof(U16)); 00773 rxbuf_end.u32ptr = (U32 *)Align_down((U32)rxbuf_end.u16ptr, sizeof(U32)); 00774 rxbuf_end.u64ptr = (U64 *)Align_down((U32)rxbuf_end.u32ptr, sizeof(U64)); 00775 00776 // If all addresses are aligned the same way with respect to 16-bit boundaries 00777 if (Get_align((U32)rxbuf_cur.u8ptr, sizeof(U16)) == Get_align((U32)p_fifo.u8ptr, sizeof(U16))) 00778 { 00779 // If pointer to reception buffer is not 16-bit aligned 00780 if (!Test_align((U32)rxbuf_cur.u8ptr, sizeof(U16))) 00781 { 00782 // Copy 8-bit data to reach 16-bit alignment 00783 if (rxbuf_cur.u8ptr < rxbuf_end.u8ptr) 00784 { 00785 // 8-bit accesses to FIFO data registers do require pointer post-increment 00786 *rxbuf_cur.u8ptr++ = *p_fifo.u8ptr++; 00787 } 00788 } 00789 00790 // If all addresses are aligned the same way with respect to 32-bit boundaries 00791 if (Get_align((U32)rxbuf_cur.u16ptr, sizeof(U32)) == Get_align((U32)p_fifo.u16ptr, sizeof(U32))) 00792 { 00793 // If pointer to reception buffer is not 32-bit aligned 00794 if (!Test_align((U32)rxbuf_cur.u16ptr, sizeof(U32))) 00795 { 00796 // Copy 16-bit data to reach 32-bit alignment 00797 if (rxbuf_cur.u16ptr < rxbuf_end.u16ptr) 00798 { 00799 // 16-bit accesses to FIFO data registers do require pointer post-increment 00800 *rxbuf_cur.u16ptr++ = *p_fifo.u16ptr++; 00801 } 00802 } 00803 00804 // If pointer to reception buffer is not 64-bit aligned 00805 if (!Test_align((U32)rxbuf_cur.u32ptr, sizeof(U64))) 00806 { 00807 // Copy 32-bit data to reach 64-bit alignment 00808 if (rxbuf_cur.u32ptr < rxbuf_end.u32ptr) 00809 { 00810 // 32-bit accesses to FIFO data registers do not require pointer post-increment 00811 *rxbuf_cur.u32ptr++ = *p_fifo.u32ptr; 00812 } 00813 } 00814 00815 // Copy 64-bit-aligned data 00816 while (rxbuf_cur.u64ptr < rxbuf_end.u64ptr) 00817 { 00818 // 64-bit accesses to FIFO data registers do not require pointer post-increment 00819 *rxbuf_cur.u64ptr++ = *p_fifo.u64ptr; 00820 } 00821 00822 // Copy 32-bit-aligned data 00823 if (rxbuf_cur.u32ptr < rxbuf_end.u32ptr) 00824 { 00825 // 32-bit accesses to FIFO data registers do not require pointer post-increment 00826 *rxbuf_cur.u32ptr++ = *p_fifo.u32ptr; 00827 } 00828 } 00829 00830 // Copy remaining 16-bit data if some 00831 while (rxbuf_cur.u16ptr < rxbuf_end.u16ptr) 00832 { 00833 // 16-bit accesses to FIFO data registers do require pointer post-increment 00834 *rxbuf_cur.u16ptr++ = *p_fifo.u16ptr++; 00835 } 00836 } 00837 00838 #endif // !__OPTIMIZE_SIZE__ 00839 00840 // Copy remaining 8-bit data if some 00841 while (rxbuf_cur.u8ptr < rxbuf_end.u8ptr) 00842 { 00843 // 8-bit accesses to FIFO data registers do require pointer post-increment 00844 *rxbuf_cur.u8ptr++ = *p_fifo.u8ptr++; 00845 } 00846 00847 // Save current position in FIFO data register 00848 pep_fifo[p].u8ptr = (volatile U8 *)p_fifo.u8ptr; 00849 00850 // Return the updated buffer address and the number of non-copied bytes 00851 if (prxbuf) *prxbuf = rxbuf_cur.u8ptr; 00852 return data_length - (rxbuf_cur.u8ptr - (U8 *)rxbuf); 00853 }
U32 host_set_p_txpacket | ( | U8 | p, | |
U8 | txbyte, | |||
U32 | data_length | |||
) |
host_set_p_txpacket
This function fills the selected pipe FIFO with a constant byte, using as few accesses as possible.
p | Number of the addressed pipe | |
txbyte | Byte to fill the pipe with | |
data_length | Number of bytes to write |
Do not mix calls to this function with calls to indexed macros.
Definition at line 512 of file usb_drv.c.
References Host_byte_count, Host_get_pipe_size, and pep_fifo.
00513 { 00514 // Use aggregated pointers to have several alignments available for a same address 00515 UnionVPtr p_fifo_cur; 00516 #if (!defined __OPTIMIZE_SIZE__) || !__OPTIMIZE_SIZE__ // Auto-generated when GCC's -Os command option is used 00517 StructCVPtr p_fifo_end; 00518 Union64 txval; 00519 #else 00520 UnionCVPtr p_fifo_end; 00521 union 00522 { 00523 U8 u8[1]; 00524 } txval; 00525 #endif // !__OPTIMIZE_SIZE__ 00526 00527 // Initialize pointers for write loops and limit the number of bytes to write 00528 p_fifo_cur.u8ptr = pep_fifo[p].u8ptr; 00529 p_fifo_end.u8ptr = p_fifo_cur.u8ptr + 00530 min(data_length, Host_get_pipe_size(p) - Host_byte_count(p)); 00531 #if (!defined __OPTIMIZE_SIZE__) || !__OPTIMIZE_SIZE__ // Auto-generated when GCC's -Os command option is used 00532 p_fifo_end.u16ptr = (U16 *)Align_down((U32)p_fifo_end.u8ptr, sizeof(U16)); 00533 p_fifo_end.u32ptr = (U32 *)Align_down((U32)p_fifo_end.u16ptr, sizeof(U32)); 00534 p_fifo_end.u64ptr = (U64 *)Align_down((U32)p_fifo_end.u32ptr, sizeof(U64)); 00535 #endif // !__OPTIMIZE_SIZE__ 00536 txval.u8[0] = txbyte; 00537 #if (!defined __OPTIMIZE_SIZE__) || !__OPTIMIZE_SIZE__ // Auto-generated when GCC's -Os command option is used 00538 txval.u8[1] = txval.u8[0]; 00539 txval.u16[1] = txval.u16[0]; 00540 txval.u32[1] = txval.u32[0]; 00541 00542 // If pointer to FIFO data register is not 16-bit aligned 00543 if (!Test_align((U32)p_fifo_cur.u8ptr, sizeof(U16))) 00544 { 00545 // Write 8-bit data to reach 16-bit alignment 00546 if (p_fifo_cur.u8ptr < p_fifo_end.u8ptr) 00547 { 00548 *p_fifo_cur.u8ptr++ = txval.u8[0]; 00549 } 00550 } 00551 00552 // If pointer to FIFO data register is not 32-bit aligned 00553 if (!Test_align((U32)p_fifo_cur.u16ptr, sizeof(U32))) 00554 { 00555 // Write 16-bit data to reach 32-bit alignment 00556 if (p_fifo_cur.u16ptr < p_fifo_end.u16ptr) 00557 { 00558 *p_fifo_cur.u16ptr++ = txval.u16[0]; 00559 } 00560 } 00561 00562 // If pointer to FIFO data register is not 64-bit aligned 00563 if (!Test_align((U32)p_fifo_cur.u32ptr, sizeof(U64))) 00564 { 00565 // Write 32-bit data to reach 64-bit alignment 00566 if (p_fifo_cur.u32ptr < p_fifo_end.u32ptr) 00567 { 00568 *p_fifo_cur.u32ptr++ = txval.u32[0]; 00569 } 00570 } 00571 00572 // Write 64-bit-aligned data 00573 while (p_fifo_cur.u64ptr < p_fifo_end.u64ptr) 00574 { 00575 *p_fifo_cur.u64ptr++ = txval.u64; 00576 } 00577 00578 // Write remaining 32-bit data if some 00579 if (p_fifo_cur.u32ptr < p_fifo_end.u32ptr) 00580 { 00581 *p_fifo_cur.u32ptr++ = txval.u32[0]; 00582 } 00583 00584 // Write remaining 16-bit data if some 00585 if (p_fifo_cur.u16ptr < p_fifo_end.u16ptr) 00586 { 00587 *p_fifo_cur.u16ptr++ = txval.u16[0]; 00588 } 00589 00590 // Write remaining 8-bit data if some 00591 if (p_fifo_cur.u8ptr < p_fifo_end.u8ptr) 00592 { 00593 *p_fifo_cur.u8ptr++ = txval.u8[0]; 00594 } 00595 00596 #else 00597 00598 // Write remaining 8-bit data if some 00599 while (p_fifo_cur.u8ptr < p_fifo_end.u8ptr) 00600 { 00601 *p_fifo_cur.u8ptr++ = txval.u8[0]; 00602 } 00603 00604 #endif // !__OPTIMIZE_SIZE__ 00605 00606 // Compute the number of non-written bytes 00607 data_length -= p_fifo_cur.u8ptr - pep_fifo[p].u8ptr; 00608 00609 // Save current position in FIFO data register 00610 pep_fifo[p].u8ptr = p_fifo_cur.u8ptr; 00611 00612 // Return the number of non-written bytes 00613 return data_length; 00614 }
U32 host_write_p_txpacket | ( | U8 | p, | |
const void * | txbuf, | |||
U32 | data_length, | |||
const void ** | ptxbuf | |||
) |
host_write_p_txpacket
This function writes the buffer pointed to by txbuf to the selected pipe FIFO, using as few accesses as possible.
p | Number of the addressed pipe | |
txbuf | Address of buffer to read | |
data_length | Number of bytes to write | |
ptxbuf | NULL or pointer to the buffer address to update |
Do not mix calls to this function with calls to indexed macros.
Definition at line 636 of file usb_drv.c.
References Host_byte_count, Host_get_pipe_size, and pep_fifo.
Referenced by host_send_data(), host_send_data_interrupt(), host_transfer_control(), and usb_pipe_interrupt().
00637 { 00638 // Use aggregated pointers to have several alignments available for a same address 00639 UnionVPtr p_fifo; 00640 UnionCPtr txbuf_cur; 00641 #if (!defined __OPTIMIZE_SIZE__) || !__OPTIMIZE_SIZE__ // Auto-generated when GCC's -Os command option is used 00642 StructCPtr txbuf_end; 00643 #else 00644 UnionCPtr txbuf_end; 00645 #endif // !__OPTIMIZE_SIZE__ 00646 00647 // Initialize pointers for copy loops and limit the number of bytes to copy 00648 p_fifo.u8ptr = pep_fifo[p].u8ptr; 00649 txbuf_cur.u8ptr = txbuf; 00650 txbuf_end.u8ptr = txbuf_cur.u8ptr + 00651 min(data_length, Host_get_pipe_size(p) - Host_byte_count(p)); 00652 #if (!defined __OPTIMIZE_SIZE__) || !__OPTIMIZE_SIZE__ // Auto-generated when GCC's -Os command option is used 00653 txbuf_end.u16ptr = (U16 *)Align_down((U32)txbuf_end.u8ptr, sizeof(U16)); 00654 txbuf_end.u32ptr = (U32 *)Align_down((U32)txbuf_end.u16ptr, sizeof(U32)); 00655 txbuf_end.u64ptr = (U64 *)Align_down((U32)txbuf_end.u32ptr, sizeof(U64)); 00656 00657 // If all addresses are aligned the same way with respect to 16-bit boundaries 00658 if (Get_align((U32)txbuf_cur.u8ptr, sizeof(U16)) == Get_align((U32)p_fifo.u8ptr, sizeof(U16))) 00659 { 00660 // If pointer to transmission buffer is not 16-bit aligned 00661 if (!Test_align((U32)txbuf_cur.u8ptr, sizeof(U16))) 00662 { 00663 // Copy 8-bit data to reach 16-bit alignment 00664 if (txbuf_cur.u8ptr < txbuf_end.u8ptr) 00665 { 00666 // 8-bit accesses to FIFO data registers do require pointer post-increment 00667 *p_fifo.u8ptr++ = *txbuf_cur.u8ptr++; 00668 } 00669 } 00670 00671 // If all addresses are aligned the same way with respect to 32-bit boundaries 00672 if (Get_align((U32)txbuf_cur.u16ptr, sizeof(U32)) == Get_align((U32)p_fifo.u16ptr, sizeof(U32))) 00673 { 00674 // If pointer to transmission buffer is not 32-bit aligned 00675 if (!Test_align((U32)txbuf_cur.u16ptr, sizeof(U32))) 00676 { 00677 // Copy 16-bit data to reach 32-bit alignment 00678 if (txbuf_cur.u16ptr < txbuf_end.u16ptr) 00679 { 00680 // 16-bit accesses to FIFO data registers do require pointer post-increment 00681 *p_fifo.u16ptr++ = *txbuf_cur.u16ptr++; 00682 } 00683 } 00684 00685 // If pointer to transmission buffer is not 64-bit aligned 00686 if (!Test_align((U32)txbuf_cur.u32ptr, sizeof(U64))) 00687 { 00688 // Copy 32-bit data to reach 64-bit alignment 00689 if (txbuf_cur.u32ptr < txbuf_end.u32ptr) 00690 { 00691 // 32-bit accesses to FIFO data registers do not require pointer post-increment 00692 *p_fifo.u32ptr = *txbuf_cur.u32ptr++; 00693 } 00694 } 00695 00696 // Copy 64-bit-aligned data 00697 while (txbuf_cur.u64ptr < txbuf_end.u64ptr) 00698 { 00699 // 64-bit accesses to FIFO data registers do not require pointer post-increment 00700 *p_fifo.u64ptr = *txbuf_cur.u64ptr++; 00701 } 00702 00703 // Copy 32-bit-aligned data 00704 if (txbuf_cur.u32ptr < txbuf_end.u32ptr) 00705 { 00706 // 32-bit accesses to FIFO data registers do not require pointer post-increment 00707 *p_fifo.u32ptr = *txbuf_cur.u32ptr++; 00708 } 00709 } 00710 00711 // Copy remaining 16-bit data if some 00712 while (txbuf_cur.u16ptr < txbuf_end.u16ptr) 00713 { 00714 // 16-bit accesses to FIFO data registers do require pointer post-increment 00715 *p_fifo.u16ptr++ = *txbuf_cur.u16ptr++; 00716 } 00717 } 00718 00719 #endif // !__OPTIMIZE_SIZE__ 00720 00721 // Copy remaining 8-bit data if some 00722 while (txbuf_cur.u8ptr < txbuf_end.u8ptr) 00723 { 00724 // 8-bit accesses to FIFO data registers do require pointer post-increment 00725 *p_fifo.u8ptr++ = *txbuf_cur.u8ptr++; 00726 } 00727 00728 // Save current position in FIFO data register 00729 pep_fifo[p].u8ptr = p_fifo.u8ptr; 00730 00731 // Return the updated buffer address and the number of non-copied bytes 00732 if (ptxbuf) *ptxbuf = txbuf_cur.u8ptr; 00733 return data_length - (txbuf_cur.u8ptr - (U8 *)txbuf); 00734 }
Status_bool_t usb_init_device | ( | void | ) |
--------------------------------------------------------- ------------------ DEVICE ------------------------------- ---------------------------------------------------------
usb_init_device This function initializes the USB device controller and configures the Default Control Endpoint.
Definition at line 81 of file usb_drv.c.
References DIRECTION_OUT, EP_CONTROL, EP_CONTROL_LENGTH, Is_usb_endpoint_enabled, Is_usb_id_device, SINGLE_BANK, TYPE_CONTROL, and Usb_configure_endpoint.
Referenced by usb_general_interrupt_non_naked(), and usb_start_device().
00082 { 00083 return Is_usb_id_device() && !Is_usb_endpoint_enabled(EP_CONTROL) && 00084 Usb_configure_endpoint(EP_CONTROL, 00085 TYPE_CONTROL, 00086 DIRECTION_OUT, 00087 EP_CONTROL_LENGTH, 00088 SINGLE_BANK); 00089 }
U32 usb_read_ep_rxpacket | ( | U8 | ep, | |
void * | rxbuf, | |||
U32 | data_length, | |||
void ** | prxbuf | |||
) |
usb_read_ep_rxpacket
This function reads the selected endpoint FIFO to the buffer pointed to by rxbuf, using as few accesses as possible.
ep | Number of the addressed endpoint | |
rxbuf | Address of buffer to write | |
data_length | Number of bytes to read | |
prxbuf | NULL or pointer to the buffer address to update |
Do not mix calls to this function with calls to indexed macros.
Definition at line 354 of file usb_drv.c.
References pep_fifo, and Usb_byte_count.
Referenced by device_template_task().
00355 { 00356 // Use aggregated pointers to have several alignments available for a same address 00357 UnionCVPtr ep_fifo; 00358 UnionPtr rxbuf_cur; 00359 #if (!defined __OPTIMIZE_SIZE__) || !__OPTIMIZE_SIZE__ // Auto-generated when GCC's -Os command option is used 00360 StructCPtr rxbuf_end; 00361 #else 00362 StructCPtr rxbuf_end; 00363 #endif // !__OPTIMIZE_SIZE__ 00364 00365 // Initialize pointers for copy loops and limit the number of bytes to copy 00366 ep_fifo.u8ptr = pep_fifo[ep].u8ptr; 00367 rxbuf_cur.u8ptr = rxbuf; 00368 rxbuf_end.u8ptr = rxbuf_cur.u8ptr + min(data_length, Usb_byte_count(ep)); 00369 #if (!defined __OPTIMIZE_SIZE__) || !__OPTIMIZE_SIZE__ // Auto-generated when GCC's -Os command option is used 00370 rxbuf_end.u16ptr = (U16 *)Align_down((U32)rxbuf_end.u8ptr, sizeof(U16)); 00371 rxbuf_end.u32ptr = (U32 *)Align_down((U32)rxbuf_end.u16ptr, sizeof(U32)); 00372 rxbuf_end.u64ptr = (U64 *)Align_down((U32)rxbuf_end.u32ptr, sizeof(U64)); 00373 00374 // If all addresses are aligned the same way with respect to 16-bit boundaries 00375 if (Get_align((U32)rxbuf_cur.u8ptr, sizeof(U16)) == Get_align((U32)ep_fifo.u8ptr, sizeof(U16))) 00376 { 00377 // If pointer to reception buffer is not 16-bit aligned 00378 if (!Test_align((U32)rxbuf_cur.u8ptr, sizeof(U16))) 00379 { 00380 // Copy 8-bit data to reach 16-bit alignment 00381 if (rxbuf_cur.u8ptr < rxbuf_end.u8ptr) 00382 { 00383 // 8-bit accesses to FIFO data registers do require pointer post-increment 00384 *rxbuf_cur.u8ptr++ = *ep_fifo.u8ptr++; 00385 } 00386 } 00387 00388 // If all addresses are aligned the same way with respect to 32-bit boundaries 00389 if (Get_align((U32)rxbuf_cur.u16ptr, sizeof(U32)) == Get_align((U32)ep_fifo.u16ptr, sizeof(U32))) 00390 { 00391 // If pointer to reception buffer is not 32-bit aligned 00392 if (!Test_align((U32)rxbuf_cur.u16ptr, sizeof(U32))) 00393 { 00394 // Copy 16-bit data to reach 32-bit alignment 00395 if (rxbuf_cur.u16ptr < rxbuf_end.u16ptr) 00396 { 00397 // 16-bit accesses to FIFO data registers do require pointer post-increment 00398 *rxbuf_cur.u16ptr++ = *ep_fifo.u16ptr++; 00399 } 00400 } 00401 00402 // If pointer to reception buffer is not 64-bit aligned 00403 if (!Test_align((U32)rxbuf_cur.u32ptr, sizeof(U64))) 00404 { 00405 // Copy 32-bit data to reach 64-bit alignment 00406 if (rxbuf_cur.u32ptr < rxbuf_end.u32ptr) 00407 { 00408 // 32-bit accesses to FIFO data registers do not require pointer post-increment 00409 *rxbuf_cur.u32ptr++ = *ep_fifo.u32ptr; 00410 } 00411 } 00412 00413 // Copy 64-bit-aligned data 00414 while (rxbuf_cur.u64ptr < rxbuf_end.u64ptr) 00415 { 00416 // 64-bit accesses to FIFO data registers do not require pointer post-increment 00417 *rxbuf_cur.u64ptr++ = *ep_fifo.u64ptr; 00418 } 00419 00420 // Copy 32-bit-aligned data 00421 if (rxbuf_cur.u32ptr < rxbuf_end.u32ptr) 00422 { 00423 // 32-bit accesses to FIFO data registers do not require pointer post-increment 00424 *rxbuf_cur.u32ptr++ = *ep_fifo.u32ptr; 00425 } 00426 } 00427 00428 // Copy remaining 16-bit data if some 00429 while (rxbuf_cur.u16ptr < rxbuf_end.u16ptr) 00430 { 00431 // 16-bit accesses to FIFO data registers do require pointer post-increment 00432 *rxbuf_cur.u16ptr++ = *ep_fifo.u16ptr++; 00433 } 00434 } 00435 00436 #endif // !__OPTIMIZE_SIZE__ 00437 00438 // Copy remaining 8-bit data if some 00439 while (rxbuf_cur.u8ptr < rxbuf_end.u8ptr) 00440 { 00441 // 8-bit accesses to FIFO data registers do require pointer post-increment 00442 *rxbuf_cur.u8ptr++ = *ep_fifo.u8ptr++; 00443 } 00444 00445 // Save current position in FIFO data register 00446 pep_fifo[ep].u8ptr = (volatile U8 *)ep_fifo.u8ptr; 00447 00448 // Return the updated buffer address and the number of non-copied bytes 00449 if (prxbuf) *prxbuf = rxbuf_cur.u8ptr; 00450 return data_length - (rxbuf_cur.u8ptr - (U8 *)rxbuf); 00451 }
U32 usb_set_ep_txpacket | ( | U8 | ep, | |
U8 | txbyte, | |||
U32 | data_length | |||
) |
usb_set_ep_txpacket
This function fills the selected endpoint FIFO with a constant byte, using as few accesses as possible.
ep | Number of the addressed endpoint | |
txbyte | Byte to fill the endpoint with | |
data_length | Number of bytes to write |
Do not mix calls to this function with calls to indexed macros.
Definition at line 110 of file usb_drv.c.
References pep_fifo, Usb_byte_count, and Usb_get_endpoint_size.
00111 { 00112 // Use aggregated pointers to have several alignments available for a same address 00113 UnionVPtr ep_fifo_cur; 00114 #if (!defined __OPTIMIZE_SIZE__) || !__OPTIMIZE_SIZE__ // Auto-generated when GCC's -Os command option is used 00115 StructCVPtr ep_fifo_end; 00116 Union64 txval; 00117 #else 00118 UnionCVPtr ep_fifo_end; 00119 union 00120 { 00121 U8 u8[1]; 00122 } txval; 00123 #endif // !__OPTIMIZE_SIZE__ 00124 00125 // Initialize pointers for write loops and limit the number of bytes to write 00126 ep_fifo_cur.u8ptr = pep_fifo[ep].u8ptr; 00127 ep_fifo_end.u8ptr = ep_fifo_cur.u8ptr + 00128 min(data_length, Usb_get_endpoint_size(ep) - Usb_byte_count(ep)); 00129 #if (!defined __OPTIMIZE_SIZE__) || !__OPTIMIZE_SIZE__ // Auto-generated when GCC's -Os command option is used 00130 ep_fifo_end.u16ptr = (U16 *)Align_down((U32)ep_fifo_end.u8ptr, sizeof(U16)); 00131 ep_fifo_end.u32ptr = (U32 *)Align_down((U32)ep_fifo_end.u16ptr, sizeof(U32)); 00132 ep_fifo_end.u64ptr = (U64 *)Align_down((U32)ep_fifo_end.u32ptr, sizeof(U64)); 00133 #endif // !__OPTIMIZE_SIZE__ 00134 txval.u8[0] = txbyte; 00135 #if (!defined __OPTIMIZE_SIZE__) || !__OPTIMIZE_SIZE__ // Auto-generated when GCC's -Os command option is used 00136 txval.u8[1] = txval.u8[0]; 00137 txval.u16[1] = txval.u16[0]; 00138 txval.u32[1] = txval.u32[0]; 00139 00140 // If pointer to FIFO data register is not 16-bit aligned 00141 if (!Test_align((U32)ep_fifo_cur.u8ptr, sizeof(U16))) 00142 { 00143 // Write 8-bit data to reach 16-bit alignment 00144 if (ep_fifo_cur.u8ptr < ep_fifo_end.u8ptr) 00145 { 00146 *ep_fifo_cur.u8ptr++ = txval.u8[0]; 00147 } 00148 } 00149 00150 // If pointer to FIFO data register is not 32-bit aligned 00151 if (!Test_align((U32)ep_fifo_cur.u16ptr, sizeof(U32))) 00152 { 00153 // Write 16-bit data to reach 32-bit alignment 00154 if (ep_fifo_cur.u16ptr < ep_fifo_end.u16ptr) 00155 { 00156 *ep_fifo_cur.u16ptr++ = txval.u16[0]; 00157 } 00158 } 00159 00160 // If pointer to FIFO data register is not 64-bit aligned 00161 if (!Test_align((U32)ep_fifo_cur.u32ptr, sizeof(U64))) 00162 { 00163 // Write 32-bit data to reach 64-bit alignment 00164 if (ep_fifo_cur.u32ptr < ep_fifo_end.u32ptr) 00165 { 00166 *ep_fifo_cur.u32ptr++ = txval.u32[0]; 00167 } 00168 } 00169 00170 // Write 64-bit-aligned data 00171 while (ep_fifo_cur.u64ptr < ep_fifo_end.u64ptr) 00172 { 00173 *ep_fifo_cur.u64ptr++ = txval.u64; 00174 } 00175 00176 // Write remaining 32-bit data if some 00177 if (ep_fifo_cur.u32ptr < ep_fifo_end.u32ptr) 00178 { 00179 *ep_fifo_cur.u32ptr++ = txval.u32[0]; 00180 } 00181 00182 // Write remaining 16-bit data if some 00183 if (ep_fifo_cur.u16ptr < ep_fifo_end.u16ptr) 00184 { 00185 *ep_fifo_cur.u16ptr++ = txval.u16[0]; 00186 } 00187 00188 // Write remaining 8-bit data if some 00189 if (ep_fifo_cur.u8ptr < ep_fifo_end.u8ptr) 00190 { 00191 *ep_fifo_cur.u8ptr++ = txval.u8[0]; 00192 } 00193 00194 #else 00195 00196 // Write remaining 8-bit data if some 00197 while (ep_fifo_cur.u8ptr < ep_fifo_end.u8ptr) 00198 { 00199 *ep_fifo_cur.u8ptr++ = txval.u8[0]; 00200 } 00201 00202 #endif // !__OPTIMIZE_SIZE__ 00203 00204 // Compute the number of non-written bytes 00205 data_length -= ep_fifo_cur.u8ptr - pep_fifo[ep].u8ptr; 00206 00207 // Save current position in FIFO data register 00208 pep_fifo[ep].u8ptr = ep_fifo_cur.u8ptr; 00209 00210 // Return the number of non-written bytes 00211 return data_length; 00212 }
U32 usb_write_ep_txpacket | ( | U8 | ep, | |
const void * | txbuf, | |||
U32 | data_length, | |||
const void ** | ptxbuf | |||
) |
usb_write_ep_txpacket
This function writes the buffer pointed to by txbuf to the selected endpoint FIFO, using as few accesses as possible.
ep | Number of the addressed endpoint | |
txbuf | Address of buffer to read | |
data_length | Number of bytes to write | |
ptxbuf | NULL or pointer to the buffer address to update |
Do not mix calls to this function with calls to indexed macros.
Definition at line 234 of file usb_drv.c.
References pep_fifo, Usb_byte_count, and Usb_get_endpoint_size.
Referenced by device_template_task(), usb_get_descriptor(), and usb_set_feature().
00235 { 00236 // Use aggregated pointers to have several alignments available for a same address 00237 UnionVPtr ep_fifo; 00238 UnionCPtr txbuf_cur; 00239 #if (!defined __OPTIMIZE_SIZE__) || !__OPTIMIZE_SIZE__ // Auto-generated when GCC's -Os command option is used 00240 StructCPtr txbuf_end; 00241 #else 00242 UnionCPtr txbuf_end; 00243 #endif // !__OPTIMIZE_SIZE__ 00244 00245 // Initialize pointers for copy loops and limit the number of bytes to copy 00246 ep_fifo.u8ptr = pep_fifo[ep].u8ptr; 00247 txbuf_cur.u8ptr = txbuf; 00248 txbuf_end.u8ptr = txbuf_cur.u8ptr + 00249 min(data_length, Usb_get_endpoint_size(ep) - Usb_byte_count(ep)); 00250 #if (!defined __OPTIMIZE_SIZE__) || !__OPTIMIZE_SIZE__ // Auto-generated when GCC's -Os command option is used 00251 txbuf_end.u16ptr = (U16 *)Align_down((U32)txbuf_end.u8ptr, sizeof(U16)); 00252 txbuf_end.u32ptr = (U32 *)Align_down((U32)txbuf_end.u16ptr, sizeof(U32)); 00253 txbuf_end.u64ptr = (U64 *)Align_down((U32)txbuf_end.u32ptr, sizeof(U64)); 00254 00255 // If all addresses are aligned the same way with respect to 16-bit boundaries 00256 if (Get_align((U32)txbuf_cur.u8ptr, sizeof(U16)) == Get_align((U32)ep_fifo.u8ptr, sizeof(U16))) 00257 { 00258 // If pointer to transmission buffer is not 16-bit aligned 00259 if (!Test_align((U32)txbuf_cur.u8ptr, sizeof(U16))) 00260 { 00261 // Copy 8-bit data to reach 16-bit alignment 00262 if (txbuf_cur.u8ptr < txbuf_end.u8ptr) 00263 { 00264 // 8-bit accesses to FIFO data registers do require pointer post-increment 00265 *ep_fifo.u8ptr++ = *txbuf_cur.u8ptr++; 00266 } 00267 } 00268 00269 // If all addresses are aligned the same way with respect to 32-bit boundaries 00270 if (Get_align((U32)txbuf_cur.u16ptr, sizeof(U32)) == Get_align((U32)ep_fifo.u16ptr, sizeof(U32))) 00271 { 00272 // If pointer to transmission buffer is not 32-bit aligned 00273 if (!Test_align((U32)txbuf_cur.u16ptr, sizeof(U32))) 00274 { 00275 // Copy 16-bit data to reach 32-bit alignment 00276 if (txbuf_cur.u16ptr < txbuf_end.u16ptr) 00277 { 00278 // 16-bit accesses to FIFO data registers do require pointer post-increment 00279 *ep_fifo.u16ptr++ = *txbuf_cur.u16ptr++; 00280 } 00281 } 00282 00283 // If pointer to transmission buffer is not 64-bit aligned 00284 if (!Test_align((U32)txbuf_cur.u32ptr, sizeof(U64))) 00285 { 00286 // Copy 32-bit data to reach 64-bit alignment 00287 if (txbuf_cur.u32ptr < txbuf_end.u32ptr) 00288 { 00289 // 32-bit accesses to FIFO data registers do not require pointer post-increment 00290 *ep_fifo.u32ptr = *txbuf_cur.u32ptr++; 00291 } 00292 } 00293 00294 // Copy 64-bit-aligned data 00295 while (txbuf_cur.u64ptr < txbuf_end.u64ptr) 00296 { 00297 // 64-bit accesses to FIFO data registers do not require pointer post-increment 00298 *ep_fifo.u64ptr = *txbuf_cur.u64ptr++; 00299 } 00300 00301 // Copy 32-bit-aligned data 00302 if (txbuf_cur.u32ptr < txbuf_end.u32ptr) 00303 { 00304 // 32-bit accesses to FIFO data registers do not require pointer post-increment 00305 *ep_fifo.u32ptr = *txbuf_cur.u32ptr++; 00306 } 00307 } 00308 00309 // Copy remaining 16-bit data if some 00310 while (txbuf_cur.u16ptr < txbuf_end.u16ptr) 00311 { 00312 // 16-bit accesses to FIFO data registers do require pointer post-increment 00313 *ep_fifo.u16ptr++ = *txbuf_cur.u16ptr++; 00314 } 00315 } 00316 00317 #endif // !__OPTIMIZE_SIZE__ 00318 00319 // Copy remaining 8-bit data if some 00320 while (txbuf_cur.u8ptr < txbuf_end.u8ptr) 00321 { 00322 // 8-bit accesses to FIFO data registers do require pointer post-increment 00323 *ep_fifo.u8ptr++ = *txbuf_cur.u8ptr++; 00324 } 00325 00326 // Save current position in FIFO data register 00327 pep_fifo[ep].u8ptr = ep_fifo.u8ptr; 00328 00329 // Return the updated buffer address and the number of non-copied bytes 00330 if (ptxbuf) *ptxbuf = txbuf_cur.u8ptr; 00331 return data_length - (txbuf_cur.u8ptr - (U8 *)txbuf); 00332 }
UnionVPtr pep_fifo[MAX_PEP_NB] |
Pointers to the FIFO data registers of pipes/endpoints Use aggregated pointers to have several alignments available for a same address.
Definition at line 64 of file usb_drv.c.
Referenced by host_read_p_rxpacket(), host_set_p_txpacket(), host_write_p_txpacket(), usb_read_ep_rxpacket(), usb_set_ep_txpacket(), and usb_write_ep_txpacket().