SyterKit 0.4.0.x
SyterKit is a bare-metal framework
Loading...
Searching...
No Matches
Macros | Functions | Variables
usb.c File Reference
#include <io.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <types.h>
#include <common.h>
#include <log.h>
#include <mmu.h>
#include <sys-clk.h>
#include "usb.h"
#include "usb_controller.h"
#include "usb_defs.h"
#include "usb_device.h"
Include dependency graph for usb.c:

Macros

#define SUNXI_USB_EP0_BUFFER_SIZE   (512)
 
#define HIGH_SPEED_EP_MAX_PACKET_SIZE   (512)
 
#define FULL_SPEED_EP_MAX_PACKET_SIZE   (64)
 
#define BULK_FIFOSIZE   (512)
 
#define RX_BUFF_SIZE   (512)
 
#define SUNXI_USB_CTRL_EP_INDEX   0
 
#define SUNXI_USB_BULK_IN_EP_INDEX   1 /* tx */
 
#define SUNXI_USB_BULK_OUT_EP_INDEX   2 /* rx */
 

Functions

static void sunxi_usb_clear_all_irq (void)
 Clear all USB interrupts.
 
static void sunxi_usb_read_complete (uint64_t husb, uint32_t ep_type, uint32_t complete)
 Handle the completion of a USB data read operation.
 
static void sunxi_usb_write_complete (uint64_t husb, uint32_t ep_type, uint32_t complete)
 Handle USB write complete event.
 
static int sunxi_usb_write_fifo (uint8_t *buffer, uint32_t buffer_size)
 Write data to the USB FIFO.
 
static int sunxi_usb_read_ep0_data (void *buffer, uint32_t data_type)
 Read data from endpoint 0 of the USB device.
 
static int sunxi_usb_perform_set_address (uint8_t address)
 Set the USB device address.
 
static int ep0_recv_op (void)
 Receive and process data on EP0.
 
static int eptx_send_op ()
 Send data on EP0.
 
static void sunxi_usb_recv_by_dma_isr (void *p_arg)
 
static void sunxi_usb_send_by_dma_isr (void *p_arg)
 
static int eprx_recv_op (void)
 
void sunxi_usb_attach_module (uint32_t device_type)
 Attach a module to the USB controller.
 
int sunxi_usb_init ()
 Initialize the USB controller.
 
void sunxi_usb_ep_reset (void)
 Reset all endpoints of the USB controller.
 
void sunxi_usb_irq ()
 Handle the USB interrupt.
 
void sunxi_usb_attach ()
 Attach the USB device to the USB controller.
 
int sunxi_usb_extern_loop ()
 Run the USB device state machine loop once.
 
void sunxi_usb_bulk_ep_reset ()
 Reset the bulk endpoints of the USB controller.
 
int sunxi_usb_start_recv_by_dma (void *mem_base, uint32_t length)
 Start receiving data by DMA.
 
void sunxi_usb_send_setup (uint32_t length, void *buffer)
 Send a setup packet.
 
int sunxi_usb_set_address (uint32_t address)
 Set USB device address.
 
int sunxi_usb_send_data (void *buffer, uint32_t buffer_size)
 Send data over USB.
 
int sunxi_usb_get_ep_max (void)
 Get the maximum number of endpoints.
 
int sunxi_usb_get_ep_in_type (void)
 Get the IN endpoint type.
 
int sunxi_usb_get_ep_out_type (void)
 Get the OUT endpoint type.
 
void sunxi_usb_dump (uint32_t usbc_base, uint32_t ep_index)
 Dump the USB controller registers for a specific endpoint.
 

Variables

static uint8_t sunxi_usb_ep0_buffer [SUNXI_USB_EP0_BUFFER_SIZE]
 
static sunxi_ubuf_t sunxi_ubuf
 
sunxi_udc_t sunxi_udc_source
 
sunxi_usb_setup_req_tsunxi_udev_active
 
static uint8_t usb_dma_trans_unaliged_bytes
 
static uint8_tusb_dma_trans_unaligned_buf
 
static int dma_rec_flag
 
static uint64_t dma_rec_addr
 
static uint64_t dma_rec_size
 

Macro Definition Documentation

◆ BULK_FIFOSIZE

#define BULK_FIFOSIZE   (512)

◆ FULL_SPEED_EP_MAX_PACKET_SIZE

#define FULL_SPEED_EP_MAX_PACKET_SIZE   (64)

◆ HIGH_SPEED_EP_MAX_PACKET_SIZE

#define HIGH_SPEED_EP_MAX_PACKET_SIZE   (512)

◆ RX_BUFF_SIZE

#define RX_BUFF_SIZE   (512)

◆ SUNXI_USB_BULK_IN_EP_INDEX

#define SUNXI_USB_BULK_IN_EP_INDEX   1 /* tx */

◆ SUNXI_USB_BULK_OUT_EP_INDEX

#define SUNXI_USB_BULK_OUT_EP_INDEX   2 /* rx */

◆ SUNXI_USB_CTRL_EP_INDEX

#define SUNXI_USB_CTRL_EP_INDEX   0

◆ SUNXI_USB_EP0_BUFFER_SIZE

#define SUNXI_USB_EP0_BUFFER_SIZE   (512)

Function Documentation

◆ ep0_recv_op()

static int ep0_recv_op ( void  )
static

Receive and process data on EP0.

This function receives and processes data on Endpoint 0 (EP0). It clears stall status, checks if setup end is cleared, and checks if the read data on EP0 is ready. Depending on the type of USB request, it performs different operations.

Returns
Returns 0 on success, or a negative error code on failure.

◆ eprx_recv_op()

static int eprx_recv_op ( void  )
static

◆ eptx_send_op()

static int eptx_send_op ( )
static

Send data on EP0.

This function send data on Endpoint 0 (EP0).

Returns
Returns 0 on success, or a negative error code on failure.

◆ sunxi_usb_attach()

void sunxi_usb_attach ( )

Attach the USB device to the USB controller.

This function attaches the USB device to the USB controller and enters a loop to handle USB events. It continuously checks for pending USB interrupts, handles the USB interrupt by calling sunxi_usb_irq(), and then processes the USB device state by calling sunxi_udev_active->state_loop(&sunxi_ubuf) multiple times.

Parameters
none
Returns
none

◆ sunxi_usb_attach_module()

void sunxi_usb_attach_module ( uint32_t  device_type)

Attach a module to the USB controller.

This function attaches a module to the USB controller. It registers the specified USB module and switches to the specified device type. Currently, two types of devices are supported: USB device detect and USB mass storage. If an unknown device type is specified, an error message is printed.

Parameters
device_typeThe type of the device to attach
  • SUNXI_USB_DEVICE_DETECT: USB device detect module
  • SUNXI_USB_DEVICE_MASS: USB mass storage module
Returns
none

◆ sunxi_usb_bulk_ep_reset()

void sunxi_usb_bulk_ep_reset ( )

Reset the bulk endpoints of the USB controller.

This function resets the bulk endpoints of the Allwinner A64 USB controller. It configures the bulk-in and bulk-out endpoints for data transfer. The steps involved are as follows:

  1. Get the index of the currently active endpoint.
  2. Configure the bulk-in endpoint for transmitting data to the host.
    • Set the transfer type to bulk (USBC_TS_TYPE_BULK).
    • Set the endpoint type to transmit (USBC_EP_TYPE_TX).
    • Set the maximum packet size for the endpoint based on sunxi_udc_source.bulk_ep_max.
    • Configure the FIFO buffer with a size of sunxi_udc_source.fifo_size and the base address sunxi_udc_source.bulk_out_addr.
    • Enable interrupts for the endpoint.
  3. Configure the bulk-out endpoint for receiving data from the host.
    • Set the transfer type to bulk (USBC_TS_TYPE_BULK).
    • Set the endpoint type to receive (USBC_EP_TYPE_RX).
    • Set the maximum packet size for the endpoint based on sunxi_udc_source.bulk_ep_max.
    • Configure the FIFO buffer with a size of sunxi_udc_source.fifo_size and the base address sunxi_udc_source.bulk_in_addr.
    • Enable interrupts for the endpoint.
  4. Restore the previously active endpoint.
Parameters
none
Returns
none

◆ sunxi_usb_clear_all_irq()

static void sunxi_usb_clear_all_irq ( void  )
static

Clear all USB interrupts.

This function clears all pending USB interrupts, including endpoint transmit (TX) and receive (RX) interrupts, as well as miscellaneous interrupts.

◆ sunxi_usb_dump()

void sunxi_usb_dump ( uint32_t  usbc_base,
uint32_t  ep_index 
)

Dump the USB controller registers for a specific endpoint.

This function dumps the USB controller registers for a specific endpoint of the Allwinner A64 USB controller.

Parameters
usbc_baseThe base address of the USB controller
ep_indexThe index of the endpoint to dump registers for
Returns
none

◆ sunxi_usb_ep_reset()

void sunxi_usb_ep_reset ( )

Reset all endpoints of the USB controller.

This function resets all endpoints of the Allwinner A64 USB controller by calling the sunxi_usb_bulk_ep_reset() function to reset the bulk endpoints.

Parameters
none
Returns
none

◆ sunxi_usb_extern_loop()

int sunxi_usb_extern_loop ( )

Run the USB device state machine loop once.

This function runs the USB device state machine loop once by calling sunxi_udev_active->state_loop(&sunxi_ubuf) and returning the result.

Parameters
none
Returns
The result of sunxi_udev_active->state_loop(&sunxi_ubuf)

◆ sunxi_usb_get_ep_in_type()

int sunxi_usb_get_ep_in_type ( void  )

Get the IN endpoint type.

This function returns the type of the IN endpoint.

Returns
The IN endpoint type

◆ sunxi_usb_get_ep_max()

int sunxi_usb_get_ep_max ( void  )

Get the maximum number of endpoints.

This function returns the maximum number of endpoints supported by the USB controller.

Returns
The maximum number of endpoints

◆ sunxi_usb_get_ep_out_type()

int sunxi_usb_get_ep_out_type ( void  )

Get the OUT endpoint type.

This function returns the type of the OUT endpoint.

Returns
The OUT endpoint type

◆ sunxi_usb_init()

int sunxi_usb_init ( )

Initialize the USB controller.

This function initializes the USB controller. It first checks if it can successfully initialize the USB device, then initializes the UDC controller source and requests DMA channels for data sending and receiving. Next, it configures the USB device by setting the transfer mode and speed, configuring DMA, etc. Finally, it enables interrupts and opens the USB device.

Returns
0 on success, -1 on failure
Parameters
none

◆ sunxi_usb_irq()

void sunxi_usb_irq ( )

Handle the USB interrupt.

This function is responsible for handling various USB interrupts, including RESET, RESUME, SUSPEND, DISCONNECT, SOF, endpoint 0 (EP0), and data transfers for both transmit (TX) and receive (RX) endpoints. It also handles DMA interrupts for both TX and RX endpoints.

Parameters
None
Returns
None

◆ sunxi_usb_perform_set_address()

static int sunxi_usb_perform_set_address ( uint8_t  address)
static

Set the USB device address.

This function sets the USB device address and updates the speed and FIFO size based on the transfer mode of the USB controller.

Parameters
addressThe USB device address to be set.
Returns
Returns SUNXI_USB_REQ_SUCCESSED on success, or a negative error code on failure.

◆ sunxi_usb_read_complete()

static void sunxi_usb_read_complete ( uint64_t  husb,
uint32_t  ep_type,
uint32_t  complete 
)
static

Handle the completion of a USB data read operation.

This function handles the completion of a USB data read operation, updating the status and clearing any relevant interrupts.

Parameters
husbThe USB controller handle.
ep_typeThe type of endpoint where the read operation was performed.
completeA flag indicating whether the read operation completed successfully or not.

◆ sunxi_usb_read_ep0_data()

static int sunxi_usb_read_ep0_data ( void *  buffer,
uint32_t  data_type 
)
static

Read data from endpoint 0 of the USB device.

This function reads data from endpoint 0 of the USB device and stores it in the provided buffer.

Parameters
bufferPointer to the buffer where the read data will be stored.
data_typeOptional parameter indicating the type of data being read.
Returns
Returns 0 on success, or a negative error code on failure.

◆ sunxi_usb_recv_by_dma_isr()

static void sunxi_usb_recv_by_dma_isr ( void *  p_arg)
static

◆ sunxi_usb_send_by_dma_isr()

static void sunxi_usb_send_by_dma_isr ( void *  p_arg)
static

◆ sunxi_usb_send_data()

int sunxi_usb_send_data ( void *  buffer,
uint32_t  buffer_size 
)

Send data over USB.

This function sends data over USB. It sets the rx_ready_for_data flag to 0 in the sunxi_ubuf structure and calls sunxi_usb_write_fifo() to write the data to the USB FIFO.

Parameters
bufferThe buffer containing the data to send
buffer_sizeThe size of the data buffer
Returns
0 on success, -1 on failure

◆ sunxi_usb_send_setup()

void sunxi_usb_send_setup ( uint32_t  length,
void *  buffer 
)

Send a setup packet.

This function sends a setup packet over USB. If the length is zero, it sends a zero-length packet. Otherwise, it selects the appropriate FIFO, writes the packet to the FIFO, and calls sunxi_usb_write_complete() to handle the completion of the write operation.

Parameters
lengthThe length of the setup packet
bufferThe buffer containing the setup packet

◆ sunxi_usb_set_address()

int sunxi_usb_set_address ( uint32_t  address)

Set USB device address.

This function sets the USB device address to the specified address. It updates the address value in the sunxi_udc_source structure and calls usb_device_read_data_status() to handle the status phase of the control transfer.

Parameters
addressThe USB device address to set
Returns
SUNXI_USB_REQ_SUCCESSED on success

◆ sunxi_usb_start_recv_by_dma()

int sunxi_usb_start_recv_by_dma ( void *  mem_base,
uint32_t  length 
)

Start receiving data by DMA.

This function starts receiving data by DMA. It configures the USB controller to use DMA for receiving, flushes the cache, enables DMA transfer, and restores the active endpoint after the transfer is started.

Parameters
mem_baseThe base address of the memory buffer
lengthThe length of the data to be received
Returns
0 on success, -1 on failure

◆ sunxi_usb_write_complete()

static void sunxi_usb_write_complete ( uint64_t  husb,
uint32_t  ep_type,
uint32_t  complete 
)
static

Handle USB write complete event.

This function is called when a USB write operation is completed. It updates the write data status using usb_device_write_data_status(), waits for the transmit packet to be sent out, and clears the data end and IRQ if the endpoint type is EP0.

Parameters
husbThe USB handle
ep_typeThe type of the endpoint
completeThe completion status of the write operation
Returns
none

◆ sunxi_usb_write_fifo()

static int sunxi_usb_write_fifo ( uint8_t buffer,
uint32_t  buffer_size 
)
static

Write data to the USB FIFO.

This function writes data from the buffer to the USB FIFO. It selects the appropriate endpoint, calculates the transfer size, and repeatedly calls usb_controller_write_packet() to write data to the FIFO until all data is transferred. After each write, it calls sunxi_usb_write_complete() to handle the completion of the write operation.

Parameters
bufferThe buffer containing the data to be written
buffer_sizeThe size of the buffer
Returns
0 on success, -1 on failure

Variable Documentation

◆ dma_rec_addr

uint64_t dma_rec_addr
static

◆ dma_rec_flag

int dma_rec_flag
static

◆ dma_rec_size

uint64_t dma_rec_size
static

◆ sunxi_ubuf

◆ sunxi_udc_source

sunxi_udc_t sunxi_udc_source

◆ sunxi_udev_active

sunxi_usb_setup_req_t* sunxi_udev_active

◆ sunxi_usb_ep0_buffer

uint8_t sunxi_usb_ep0_buffer[SUNXI_USB_EP0_BUFFER_SIZE]
static

◆ usb_dma_trans_unaliged_bytes

uint8_t usb_dma_trans_unaliged_bytes
static

◆ usb_dma_trans_unaligned_buf

uint8_t* usb_dma_trans_unaligned_buf
static