Files
RomWBW/Source/HBIOS/ch376-native/source-doc/base-drv/dev_transfers.c
Dean Netherton aacf98a82a ch376-native: fixes for windows build
* convert 0x??? hex literals to $??? literals
* More label shortening for windows tasm compatibility
2025-07-20 15:32:08 +10:00

107 lines
3.2 KiB
C

/**
* @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 "critical-section.h"
#include "delay.h"
#include "ez80-helpers.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_clr_ep_halt(endpoint->number, dev->address, dev->max_packet_size);
endpoint->toggle = 0;
return USB_ERR_STALL;
}
RETURN_CHECK(result);
done:
return 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_clr_ep_halt(endpoint->number, dev->address, dev->max_packet_size);
endpoint->toggle = 0;
return USB_ERR_STALL;
}
RETURN_CHECK(result);
done:
return 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_clr_ep_halt(endpoint->number, device->address, device->max_packet_size);
endpoint->toggle = 0;
return USB_ERR_STALL;
}
RETURN_CHECK(result);
done:
return result;
}
usb_error usbdev_dat_in_trnsfer_0(device_config *const device, uint8_t *const buffer, const uint8_t buffer_size) {
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_clr_ep_halt(endpoint->number, device->address, device->max_packet_size);
endpoint->toggle = 0;
return USB_ERR_STALL;
}
return result;
}