You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

101 lines
3.2 KiB

/**
* @file transfers.c
* @author Dean Netherton
* @brief A simplest implementation of common usb transfer functions, based on the CH376S chip
* @details For a basic walkthrough of the usb protocol see https://www.beyondlogic.org/usbnutshell/usb1.shtml
* @version 1.0
* @date 2023-09-22
*
* @copyright Copyright (c) 2023
*
*/
#include "dev_transfers.h"
#include "ch376.h"
#include "delay.h"
#include "protocol.h"
#include <stdlib.h>
/**
* @brief Perform a USB control transfer (in or out)
* See https://www.beyondlogic.org/usbnutshell/usb4.shtml for a description of the USB control transfer
*
* @param device the usb device
* @param cmd_packet Pointer to the setup packet - top bit of bmRequestType indicate data direction
* @param buffer Pointer of data to send or receive into
* @return usb_error USB_ERR_OK if all good, otherwise specific error code
*/
usb_error usbdev_control_transfer(device_config *const device, const setup_packet *const cmd_packet, uint8_t *const buffer) {
return usb_control_transfer(cmd_packet, buffer, device->address, device->max_packet_size);
}
usb_error usbdev_blk_out_trnsfer(device_config *const dev, const uint8_t *const buffer, const uint16_t buffer_size) {
usb_error result;
endpoint_param *const endpoint = &dev->endpoints[ENDPOINT_BULK_OUT];
result = usb_data_out_transfer(buffer, buffer_size, dev->address, endpoint);
if (result == USB_ERR_STALL) {
usbtrn_clear_endpoint_halt(endpoint->number, dev->address, dev->max_packet_size);
endpoint->toggle = 0;
return USB_ERR_STALL;
}
RETURN_CHECK(result);
}
usb_error usbdev_bulk_in_transfer(device_config *const dev, uint8_t *const buffer, uint8_t *const buffer_size) {
usb_error result;
endpoint_param *const endpoint = &dev->endpoints[ENDPOINT_BULK_IN];
result = usb_data_in_transfer_n(buffer, buffer_size, dev->address, endpoint);
if (result == USB_ERR_STALL) {
usbtrn_clear_endpoint_halt(endpoint->number, dev->address, dev->max_packet_size);
endpoint->toggle = 0;
return USB_ERR_STALL;
}
RETURN_CHECK(result);
}
usb_error usbdev_dat_in_trnsfer(device_config *const device,
uint8_t *const buffer,
const uint16_t buffer_size,
const usb_endpoint_type endpoint_type) {
usb_error result;
endpoint_param *const endpoint = &device->endpoints[endpoint_type];
result = usb_data_in_transfer(buffer, buffer_size, device->address, endpoint);
if (result == USB_ERR_STALL) {
usbtrn_clear_endpoint_halt(endpoint->number, device->address, device->max_packet_size);
endpoint->toggle = 0;
return USB_ERR_STALL;
}
RETURN_CHECK(result);
}
usb_error usbdev_dat_in_trnsfer_0(device_config *const device, uint8_t *const buffer, const uint8_t buffer_size) __sdcccall(1) {
usb_error result;
endpoint_param *const endpoint = &device->endpoints[0];
result = usb_data_in_transfer(buffer, buffer_size, device->address, endpoint);
if (result == USB_ERR_STALL) {
usbtrn_clear_endpoint_halt(endpoint->number, device->address, device->max_packet_size);
endpoint->toggle = 0;
return USB_ERR_STALL;
}
RETURN_CHECK(result);
}