From 6800a95abed89ee796ab81f17ff14a2a0e91cd81 Mon Sep 17 00:00:00 2001 From: Ivan Olenichev <> Date: Sun, 9 Jan 2022 00:15:56 +0600 Subject: [PATCH] RISC_v update --- RISC-V/Include/build_config.h | 25 ++ RISC-V/Include/downstream_interface_def.h | 77 ++++ RISC-V/Include/downstream_msc.h | 27 ++ RISC-V/Include/downstream_spi.h | 84 ++++ RISC-V/Include/downstream_statemachine.h | 54 +++ RISC-V/Include/interrupts.h | 18 + RISC-V/Include/usb_host.h | 16 + RISC-V/Include/usbh_conf.h | 10 + RISC-V/Source/downstream_msc.c | 358 ++++++++++++++++ RISC-V/Source/downstream_spi.c | 475 ++++++++++++++++++++++ RISC-V/Source/interrupts.c | 23 ++ RISC-V/Source/main.c | 28 +- RISC-V/Source/usb_host.c | 36 ++ 13 files changed, 1219 insertions(+), 12 deletions(-) create mode 100644 RISC-V/Include/build_config.h create mode 100644 RISC-V/Include/downstream_interface_def.h create mode 100644 RISC-V/Include/downstream_msc.h create mode 100644 RISC-V/Include/downstream_spi.h create mode 100644 RISC-V/Include/downstream_statemachine.h create mode 100644 RISC-V/Include/interrupts.h create mode 100644 RISC-V/Include/usb_host.h create mode 100644 RISC-V/Source/downstream_msc.c create mode 100644 RISC-V/Source/downstream_spi.c create mode 100644 RISC-V/Source/interrupts.c create mode 100644 RISC-V/Source/usb_host.c diff --git a/RISC-V/Include/build_config.h b/RISC-V/Include/build_config.h new file mode 100644 index 0000000..f71a210 --- /dev/null +++ b/RISC-V/Include/build_config.h @@ -0,0 +1,25 @@ +/* + * build_config.h + * + * Created on: 23 окт. 2021 г. + * Author: ivan + */ + +#ifndef INCLUDE_BUILD_CONFIG_H_ +#define INCLUDE_BUILD_CONFIG_H_ + +#define CONFIG_MASS_STORAGE_ENABLED +#define CONFIG_MASS_STORAGE_WRITES_PERMITTED + +#define CONFIG_KEYBOARD_ENABLED +#define CONFIG_MOUSE_ENABLED + +#define CONFIG_READ_FLASH_TIME_MS 3000 //Enable read LED flashes for the specified length of time + +#define CONFIG_USB_ID_ENABLED + +//#define CONFIG_FLASH_RDP_ENABLE + + + +#endif /* INCLUDE_BUILD_CONFIG_H_ */ diff --git a/RISC-V/Include/downstream_interface_def.h b/RISC-V/Include/downstream_interface_def.h new file mode 100644 index 0000000..eec61a8 --- /dev/null +++ b/RISC-V/Include/downstream_interface_def.h @@ -0,0 +1,77 @@ +/* + * downstream_interface_def.h + * + * Created on: 24/07/2015 + * Author: Robert Fisk + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#ifndef INC_DOWNSTREAM_INTERFACE_DEF_H_ +#define INC_DOWNSTREAM_INTERFACE_DEF_H_ + + +//*************** +// Attention! +// Keep this file synchronised with upstream_interface_def.h +// in the Upstream project. +//*************** + + + +#define COMMAND_CLASS_DATA_FLAG 0x80 +#define COMMAND_CLASS_MASK ((uint8_t)(~COMMAND_CLASS_DATA_FLAG)) + + +typedef enum +{ + COMMAND_CLASS_INTERFACE, + COMMAND_CLASS_MASS_STORAGE, + COMMAND_CLASS_HID_MOUSE, + COMMAND_CLASS_HID_KEYBOARD, + //... + COMMAND_CLASS_ERROR +} +InterfaceCommandClassTypeDef; + + +typedef enum +{ + COMMAND_INTERFACE_ECHO, //Returns echo packet including all data + COMMAND_INTERFACE_NOTIFY_DEVICE //Returns COMMAND_CLASS_*** byte when downstream USB device is connected +} +InterfaceCommandInterfaceTypeDef; + + +typedef enum +{ + COMMAND_MSC_TEST_UNIT_READY, //Returns HAL_StatusTypeDef result + COMMAND_MSC_GET_CAPACITY, //Returns uint32_t blk_nbr, uint32_t blk_size + COMMAND_MSC_READ, //Returns data stream or error packet + COMMAND_MSC_WRITE, //Waits for data stream or returns error packet + COMMAND_MSC_DISCONNECT, //Returns same packet after sending Stop command to device + COMMAND_MSC_POLL_DISCONNECT //Returns same packet if device is still connected +} +InterfaceCommandMscTypeDef; + + +typedef enum +{ + COMMAND_HID_GET_REPORT, //Returns HID report from device + COMMAND_HID_SET_REPORT //Sends HID report to device. Simple ack packet contains no data. +} +InterfaceCommandHidTypeDef; + + +typedef enum +{ + COMMAND_ERROR_GENERIC, //Something went wrong, time to FREAKOUT + COMMAND_ERROR_DEVICE_DISCONNECTED, //Device unexpectedly disconnected +} +InterfaceCommandErrorTypeDef; + + + +#endif /* INC_DOWNSTREAM_INTERFACE_DEF_H_ */ diff --git a/RISC-V/Include/downstream_msc.h b/RISC-V/Include/downstream_msc.h new file mode 100644 index 0000000..708839d --- /dev/null +++ b/RISC-V/Include/downstream_msc.h @@ -0,0 +1,27 @@ + + +#ifndef INC_DOWNSTREAM_MSC_H_ +#define INC_DOWNSTREAM_MSC_H_ + + +#include "downstream_interface_def.h" +#include "downstream_spi.h" + + +#define MSC_SUPPORTED_BLOCK_SIZE 512 +#define MSC_FIXED_LUN 0 + + +typedef void (*DownstreamMSCCallbackPacketTypeDef)(DownstreamPacketTypeDef* receivedPacket, + uint16_t dataLength8); + + +InterfaceCommandClassTypeDef Downstream_MSC_ApproveConnectedDevice(void); +void Downstream_MSC_PacketProcessor(DownstreamPacketTypeDef* receivedPacket); +StatusTypeDef Downstream_MSC_PutStreamDataPacket(DownstreamPacketTypeDef* packetToSend, + uint32_t dataLength8); +StatusTypeDef Downstream_MSC_GetStreamDataPacket(DownstreamMSCCallbackPacketTypeDef callback); + + + +#endif /* INC_DOWNSTREAM_MSC_H_ */ diff --git a/RISC-V/Include/downstream_spi.h b/RISC-V/Include/downstream_spi.h new file mode 100644 index 0000000..828913f --- /dev/null +++ b/RISC-V/Include/downstream_spi.h @@ -0,0 +1,84 @@ +/* + * downstream_spi.h + * + * Created on: 24/07/2015 + * Author: Robert Fisk + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#ifndef INC_DOWNSTREAM_SPI_H_ +#define INC_DOWNSTREAM_SPI_H_ + + +#include "usbh_conf.h" + + +#define DOWNSTREAM_PACKET_HEADER_LEN (2) //Min length = CommandClass & Command bytes +#define DOWNSTREAM_PACKET_LEN (DOWNSTREAM_PACKET_HEADER_LEN + BOT_PAGE_LENGTH) +#define DOWNSTREAM_PACKET_LEN_MIN (DOWNSTREAM_PACKET_HEADER_LEN) + +#define DOWNSTREAM_PACKET_HEADER_LEN_16 (DOWNSTREAM_PACKET_HEADER_LEN / 2) +#define DOWNSTREAM_PACKET_LEN_16 (DOWNSTREAM_PACKET_LEN / 2) +#define DOWNSTREAM_PACKET_LEN_MIN_16 (DOWNSTREAM_PACKET_LEN_MIN / 2) + +#define DOWNSTREAM_SPI_FREAKOUT \ + do { \ + Downstream_PacketProcessor_FreakOut(); \ + DownstreamInterfaceState = DOWNSTREAM_INTERFACE_ERROR; \ + while (1); \ + } while (0); + + + +typedef enum +{ + DOWNSTREAM_INTERFACE_IDLE, + DOWNSTREAM_INTERFACE_RX_SIZE_WAIT, + DOWNSTREAM_INTERFACE_RX_PACKET_WAIT, + DOWNSTREAM_INTERFACE_TX_SIZE_WAIT, + DOWNSTREAM_INTERFACE_TX_PACKET_WAIT, + DOWNSTREAM_INTERFACE_ERROR +} +InterfaceStateTypeDef; + + +typedef enum +{ + NOT_BUSY, + BUSY +} +PacketBusyTypeDef; + + +typedef struct +{ + PacketBusyTypeDef Busy; //Everything after Busy should be word-aligned + uint16_t Length16 __attribute__ ((aligned (4))); //Packet length includes CommandClass, Command, and Data + uint8_t CommandClass; + uint8_t Command; + uint8_t Data[BOT_PAGE_LENGTH]; //Should (must?) be word-aligned, for USB copy routine +} +DownstreamPacketTypeDef; + + + +typedef void (*FreePacketCallbackTypeDef)(DownstreamPacketTypeDef* freePacket); +typedef void (*SpiPacketReceivedCallbackTypeDef)(DownstreamPacketTypeDef* receivedPacket); + + +void Downstream_InitSPI(void); +StatusTypeDef Downstream_GetFreePacket(FreePacketCallbackTypeDef callback); +DownstreamPacketTypeDef* Downstream_GetFreePacketImmediately(void); +void Downstream_ReleasePacket(DownstreamPacketTypeDef* packetToRelease); +StatusTypeDef Downstream_ReceivePacket(SpiPacketReceivedCallbackTypeDef callback); +StatusTypeDef Downstream_TransmitPacket(DownstreamPacketTypeDef* packetToWrite); +void Downstream_SPIProcess(void); + +void DMA_SPI_TxRxCpltCallback(void); +//void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi); + + +#endif /* INC_DOWNSTREAM_SPI_H_ */ diff --git a/RISC-V/Include/downstream_statemachine.h b/RISC-V/Include/downstream_statemachine.h new file mode 100644 index 0000000..a0830a4 --- /dev/null +++ b/RISC-V/Include/downstream_statemachine.h @@ -0,0 +1,54 @@ +/* + * downstream_statemachine.h + * + * Created on: 2/08/2015 + * Author: Robert Fisk + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#ifndef INC_DOWNSTREAM_STATEMACHINE_H_ +#define INC_DOWNSTREAM_STATEMACHINE_H_ + + +#include "usb_host.h" +#include "usbh_core.h" +#include "downstream_spi.h" + + +typedef enum +{ + STATE_DEVICE_NOT_READY, + STATE_DEVICE_READY, //Go here if HOST_USER_CLASS_ACTIVE callback arrives first + STATE_WAIT_DEVICE_READY, //Go here if COMMAND_INTERFACE_NOTIFY_DEVICE message arrives first + STATE_ACTIVE, + STATE_ERROR +} DownstreamStateTypeDef; + + + +#define DOWNSTREAM_STATEMACHINE_FREAKOUT \ + do { \ + USB_Host_Disconnect(); \ + /*LED_SetState(LED_STATUS_FLASH_ERROR);*/ \ + /*DownstreamState = STATE_ERROR; */ \ + while (1); \ +} while (0); + + + + +void Downstream_InitStateMachine(void); +void Downstream_HostUserCallback(usbh_host *phost, uint8_t id); +void Downstream_PacketProcessor(DownstreamPacketTypeDef* receivedPacket); +void Downstream_PacketProcessor_GenericErrorReply(DownstreamPacketTypeDef* replyPacket); +void Downstream_PacketProcessor_ClassReply(DownstreamPacketTypeDef* replyPacket); +void Downstream_PacketProcessor_NotifyDisconnectReplyRequired(void); +void Downstream_PacketProcessor_CheckNotifyDisconnectReply(void); +void Downstream_PacketProcessor_SetErrorState(void); +void Downstream_PacketProcessor_FreakOut(void); + + +#endif /* INC_DOWNSTREAM_STATEMACHINE_H_ */ diff --git a/RISC-V/Include/interrupts.h b/RISC-V/Include/interrupts.h new file mode 100644 index 0000000..da24f2f --- /dev/null +++ b/RISC-V/Include/interrupts.h @@ -0,0 +1,18 @@ +/* + * interrupts.h + * + * Created on: 23 окт. 2021 г. + * Author: ivan + */ + +#ifndef INCLUDE_INTERRUPTS_H_ +#define INCLUDE_INTERRUPTS_H_ + +#include "gd32vf103.h" + +/* function declarations */ +/* DMA0_Channel0 handle function */ +void DMA0_Channel1_IRQHandler(void); +void DMA0_Channel2_IRQHandler(void); + +#endif /* INCLUDE_INTERRUPTS_H_ */ diff --git a/RISC-V/Include/usb_host.h b/RISC-V/Include/usb_host.h new file mode 100644 index 0000000..8acb572 --- /dev/null +++ b/RISC-V/Include/usb_host.h @@ -0,0 +1,16 @@ +/* + * usb_host.h + * + * Created on: 23 окт. 2021 г. + * Author: ivan + */ + +#ifndef INCLUDE_USB_HOST_H_ +#define INCLUDE_USB_HOST_H_ + +void USB_Host_Init(void); +void USB_Host_Process(void); +void USB_Host_Disconnect(void); + + +#endif /* INCLUDE_USB_HOST_H_ */ diff --git a/RISC-V/Include/usbh_conf.h b/RISC-V/Include/usbh_conf.h index ae12fd4..df53214 100644 --- a/RISC-V/Include/usbh_conf.h +++ b/RISC-V/Include/usbh_conf.h @@ -39,4 +39,14 @@ OF SUCH DAMAGE. #define USBH_MAX_INTERFACES_NUM 2 #define USBH_MSC_MPS_SIZE 0x200 +#define BOT_PAGE_LENGTH 512 + +typedef enum +{ + STATUS_OK = 0x00, + STATUS_ERROR = 0x01, + STATUS_BUSY = 0x02, + STATUS_TIMEOUT = 0x03 +} StatusTypeDef; + #endif /* __USBH_CONF_H */ diff --git a/RISC-V/Source/downstream_msc.c b/RISC-V/Source/downstream_msc.c new file mode 100644 index 0000000..b7a460a --- /dev/null +++ b/RISC-V/Source/downstream_msc.c @@ -0,0 +1,358 @@ +/* + * downstream_msc.c + * + * Created on: 8/08/2015 + * Author: Robert Fisk + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + + +#include "downstream_msc.h" +#include "downstream_interface_def.h" +#include "downstream_statemachine.h" +#include "downstream_spi.h" +//#include "usbh_msc.h" +#include "usbh_msc_core.h" +#include "build_config.h" + + +#ifdef CONFIG_MASS_STORAGE_ENABLED + +extern USBH_HandleTypeDef hUsbHostFS; //Hard-link ourselves to usb_host.c + + +//Stuff we need to save for our callbacks to use: +DownstreamMSCCallbackPacketTypeDef GetStreamDataCallback; +uint32_t ByteCount; +DownstreamPacketTypeDef* ReadStreamPacket; +uint8_t ReadStreamBusy; + + +static void Downstream_MSC_PacketProcessor_TestUnitReady(DownstreamPacketTypeDef* receivedPacket); +static void Downstream_MSC_PacketProcessor_TestUnitReadyCallback(USBH_StatusTypeDef result); +static void Downstream_MSC_PacketProcessor_GetCapacity(DownstreamPacketTypeDef* receivedPacket); +static void Downstream_MSC_PacketProcessor_BeginRead(DownstreamPacketTypeDef* receivedPacket); +static void Downstream_MSC_PacketProcessor_BeginWrite(DownstreamPacketTypeDef* receivedPacket); +static void Downstream_MSC_PacketProcessor_RdWrCompleteCallback(USBH_StatusTypeDef result); +static void Downstream_MSC_GetStreamDataPacketCallback(DownstreamPacketTypeDef* receivedPacket); +static void Downstream_MSC_PacketProcessor_Disconnect(DownstreamPacketTypeDef* receivedPacket); +static void Downstream_MSC_PacketProcessor_DisconnectCallback(USBH_StatusTypeDef result); + + +//High-level checks on the connected device. We don't want some weirdly +//configured device to bomb our USB stack, accidentally or otherwise. +InterfaceCommandClassTypeDef Downstream_MSC_ApproveConnectedDevice(void) +{ + MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData; + + if (MSC_Handle->unit[MSC_FIXED_LUN].error != MSC_OK) + { + return COMMAND_CLASS_INTERFACE; //fail + } + + if ((MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == 0) || + (MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == UINT32_MAX)) + { + return COMMAND_CLASS_INTERFACE; //fail + } + + if (MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size != MSC_SUPPORTED_BLOCK_SIZE) + { + return COMMAND_CLASS_INTERFACE; //fail + } + + return COMMAND_CLASS_MASS_STORAGE; //success! +} + + +void Downstream_MSC_PacketProcessor(DownstreamPacketTypeDef* receivedPacket) +{ + switch (receivedPacket->Command) + { + case COMMAND_MSC_TEST_UNIT_READY: + Downstream_MSC_PacketProcessor_TestUnitReady(receivedPacket); + break; + + case COMMAND_MSC_GET_CAPACITY: + Downstream_MSC_PacketProcessor_GetCapacity(receivedPacket); + break; + + case COMMAND_MSC_READ: + Downstream_MSC_PacketProcessor_BeginRead(receivedPacket); + break; + +#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED + case COMMAND_MSC_WRITE: + Downstream_MSC_PacketProcessor_BeginWrite(receivedPacket); + break; +#endif + + case COMMAND_MSC_DISCONNECT: + Downstream_MSC_PacketProcessor_Disconnect(receivedPacket); + break; + + case COMMAND_MSC_POLL_DISCONNECT: + Downstream_PacketProcessor_ClassReply(receivedPacket); //Device is still connected, so send the packet straight back + break; + + default: + Downstream_PacketProcessor_FreakOut(); + } + +} + + +static void Downstream_MSC_PacketProcessor_TestUnitReady(DownstreamPacketTypeDef* receivedPacket) +{ + Downstream_ReleasePacket(receivedPacket); + + if (USBH_MSC_UnitIsReady(&hUsbHostFS, + MSC_FIXED_LUN, + Downstream_MSC_PacketProcessor_TestUnitReadyCallback) != USBH_BUSY) + { + Downstream_MSC_PacketProcessor_TestUnitReadyCallback(USBH_FAIL); + } +} + + +static void Downstream_MSC_PacketProcessor_TestUnitReadyCallback(USBH_StatusTypeDef result) +{ + DownstreamPacketTypeDef* freePacket; + + freePacket = Downstream_GetFreePacketImmediately(); + freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE; + freePacket->Command = COMMAND_MSC_TEST_UNIT_READY; + freePacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1; + + if (result == USBH_OK) + { + freePacket->Data[0] = HAL_OK; + } + else + { + freePacket->Data[0] = HAL_ERROR; + } + Downstream_PacketProcessor_ClassReply(freePacket); +} + + + +static void Downstream_MSC_PacketProcessor_GetCapacity(DownstreamPacketTypeDef* receivedPacket) +{ + MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData; + + receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + (8 / 2); + *(uint32_t*)&(receivedPacket->Data[0]) = MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr; + *(uint32_t*)&(receivedPacket->Data[4]) = (uint32_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size; + Downstream_PacketProcessor_ClassReply(receivedPacket); +} + + + +static void Downstream_MSC_PacketProcessor_BeginRead(DownstreamPacketTypeDef* receivedPacket) +{ + uint64_t readBlockAddress; + uint32_t readBlockCount; + uint64_t readByteCount; + MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData; + + if (receivedPacket->Length16 != (DOWNSTREAM_PACKET_HEADER_LEN_16 + ((4 * 3) / 2))) + { + Downstream_PacketProcessor_FreakOut(); + return; + } + + LED_SetState(LED_STATUS_FLASH_READWRITE); + readBlockAddress = *(uint64_t*)&(receivedPacket->Data[0]); + readBlockCount = *(uint32_t*)&(receivedPacket->Data[8]); + readByteCount = readBlockCount * MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size; + if ((readBlockAddress >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) || + ((readBlockAddress + readBlockCount - 1) >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) || + (readByteCount > UINT32_MAX)) + { + Downstream_PacketProcessor_FreakOut(); + return; + } + + receivedPacket->Data[0] = HAL_ERROR; + receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1; + if (USBH_MSC_Read(&hUsbHostFS, + MSC_FIXED_LUN, + (uint32_t)readBlockAddress, + readBlockCount, + Downstream_MSC_PacketProcessor_RdWrCompleteCallback) == USBH_BUSY) + { + Downstream_ReleasePacket(receivedPacket); + return; + } + + //Fail: + Downstream_PacketProcessor_ClassReply(receivedPacket); +} + + +static void Downstream_MSC_PacketProcessor_RdWrCompleteCallback(USBH_StatusTypeDef result) +{ + if (result != USBH_OK) + { + Downstream_GetFreePacket(Downstream_PacketProcessor_GenericErrorReply); + return; + } + Downstream_ReceivePacket(Downstream_PacketProcessor); +} + + + +#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED +static void Downstream_MSC_PacketProcessor_BeginWrite(DownstreamPacketTypeDef* receivedPacket) +{ + uint64_t writeBlockAddress; + uint32_t writeBlockCount; + uint64_t writeByteCount; + MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData; + + if (receivedPacket->Length16 != (DOWNSTREAM_PACKET_HEADER_LEN_16 + ((4 * 3) / 2))) + { + Downstream_PacketProcessor_FreakOut(); + return; + } + + writeBlockAddress = *(uint64_t*)&(receivedPacket->Data[0]); + writeBlockCount = *(uint32_t*)&(receivedPacket->Data[8]); + writeByteCount = writeBlockCount * MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size; + if ((writeBlockAddress >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) || + ((writeBlockAddress + writeBlockCount - 1) >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) || + (writeByteCount > UINT32_MAX)) + { + Downstream_PacketProcessor_FreakOut(); + return; + } + + ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use + ReadStreamBusy = 0; + ByteCount = (uint32_t)writeByteCount; + + receivedPacket->Data[0] = HAL_ERROR; + receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1; + + //Our host stack has no way to detect if write-protection is enabled. + //So currently we can't return HAL_BUSY to Upstream in this situation. + if (USBH_MSC_Write(&hUsbHostFS, + MSC_FIXED_LUN, + (uint32_t)writeBlockAddress, + writeBlockCount, + Downstream_MSC_PacketProcessor_RdWrCompleteCallback) == USBH_BUSY) + { + Downstream_ReleasePacket(receivedPacket); + return; + } + + //Fail: + Downstream_PacketProcessor_ClassReply(receivedPacket); +} +#endif + + +//Used by USB MSC host driver +StatusTypeDef Downstream_MSC_PutStreamDataPacket(DownstreamPacketTypeDef* packetToSend, + uint32_t dataLength8) +{ + if ((dataLength8 % 2) != 0) + { + return HAL_ERROR; + } + + packetToSend->Length16 = (dataLength8 / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16; + packetToSend->CommandClass = COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG; + packetToSend->Command = COMMAND_MSC_READ; + return Downstream_TransmitPacket(packetToSend); +} + + +#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED +//Used by USB MSC host driver +StatusTypeDef Downstream_MSC_GetStreamDataPacket(DownstreamMSCCallbackPacketTypeDef callback) +{ + GetStreamDataCallback = callback; + + if (ReadStreamBusy != 0) + { + return HAL_OK; + } + ReadStreamBusy = 1; + + if (ReadStreamPacket && GetStreamDataCallback) //Do we have a stored packet and an address to send it? + { + Downstream_MSC_GetStreamDataPacketCallback(ReadStreamPacket); //Send it now! + ReadStreamPacket = NULL; + return HAL_OK; //Our callback will call us again, so we don't need to get a packet in this case. + } + return Downstream_ReceivePacket(Downstream_MSC_GetStreamDataPacketCallback); +} + + +void Downstream_MSC_GetStreamDataPacketCallback(DownstreamPacketTypeDef* receivedPacket) +{ + uint16_t dataLength8; + + ReadStreamBusy = 0; + if (GetStreamDataCallback == NULL) + { + ReadStreamPacket = receivedPacket; //We used up our callback already, so save this one for later. + return; + } + + dataLength8 = (receivedPacket->Length16 - DOWNSTREAM_PACKET_HEADER_LEN_16) * 2; + + if ((receivedPacket->CommandClass != (COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG)) || //Must be MSC command with data flag set + (receivedPacket->Command != COMMAND_MSC_WRITE) || //Must be write command + (receivedPacket->Length16 <= DOWNSTREAM_PACKET_HEADER_LEN_16) || //Should be at least one data byte in the packet. + (dataLength8 > ByteCount)) + { + Downstream_PacketProcessor_FreakOut(); + return; + } + + ByteCount -= dataLength8; + GetStreamDataCallback(receivedPacket, dataLength8); //usb_msc_scsi will use this packet, so don't release now + if (ByteCount > 0) + { + Downstream_MSC_GetStreamDataPacket(NULL); //Try to get the next packet now, before USB asks for it + } + +} +#endif //#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED + + + +static void Downstream_MSC_PacketProcessor_Disconnect(DownstreamPacketTypeDef* receivedPacket) +{ + Downstream_ReleasePacket(receivedPacket); + + USBH_MSC_StartStopUnit(&hUsbHostFS, + MSC_FIXED_LUN, + MSC_START_STOP_EJECT_FLAG, + Downstream_MSC_PacketProcessor_DisconnectCallback); +} + + + +static void Downstream_MSC_PacketProcessor_DisconnectCallback(USBH_StatusTypeDef result) +{ + DownstreamPacketTypeDef* freePacket; + + if (result == USBH_OK) + { + freePacket = Downstream_GetFreePacketImmediately(); + freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE; + freePacket->Command = COMMAND_MSC_DISCONNECT; + freePacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16; + Downstream_PacketProcessor_ClassReply(freePacket); + } +} + +#endif //#ifdef CONFIG_MASS_STORAGE_ENABLED + diff --git a/RISC-V/Source/downstream_spi.c b/RISC-V/Source/downstream_spi.c new file mode 100644 index 0000000..4f5d688 --- /dev/null +++ b/RISC-V/Source/downstream_spi.c @@ -0,0 +1,475 @@ +/* + * upstream_spi.c + * + * Created on: 24/07/2015 + * Author: Robert Fisk + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + + +#include "downstream_interface_def.h" +#include "downstream_spi.h" +#include "downstream_statemachine.h" +#include "gd32vf103.h" +#include "gd32vf103v_eval.h" + + +//SPI_HandleTypeDef Hspi1; +DownstreamPacketTypeDef DownstreamPacket0; +DownstreamPacketTypeDef DownstreamPacket1; +DownstreamPacketTypeDef* CurrentWorkingPacket; +DownstreamPacketTypeDef* NextTxPacket = NULL; + +InterfaceStateTypeDef DownstreamInterfaceState = DOWNSTREAM_INTERFACE_IDLE; +FreePacketCallbackTypeDef PendingFreePacketCallback = NULL; //Indicates someone is waiting for a packet buffer to become available +SpiPacketReceivedCallbackTypeDef ReceivePacketCallback = NULL; //Indicates someone is waiting for a received packet + +uint32_t TemporaryIncomingPacketLength = 0; +uint8_t SpiInterruptCompleted = 0; + + +StatusTypeDef Downstream_CheckPreparePacketReception(void); +void Downstream_PrepareReceivePacketSize(DownstreamPacketTypeDef* freePacket); + + + +void Downstream_InitSPI(void) +{ + DownstreamPacket0.Busy = NOT_BUSY; + DownstreamPacket1.Busy = NOT_BUSY; + + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_AF); + rcu_periph_clock_enable(RCU_DMA0); + rcu_periph_clock_enable(RCU_SPI0); + + gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 |GPIO_PIN_6| GPIO_PIN_7); + gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_4); + + dma_parameter_struct dma_init_struct; + + /* SPI0 transmit dma config:DMA0-DMA_CH2 */ + dma_deinit(DMA0, DMA_CH2); + dma_struct_para_init(&dma_init_struct); + + dma_init_struct.periph_addr = (uint32_t)&SPI_DATA(SPI0); + dma_init_struct.memory_addr = (uint32_t)spi0_send_array; + dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; + dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; + dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; + dma_init_struct.priority = DMA_PRIORITY_LOW; + dma_init_struct.number = ARRAYSIZE; + dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; + dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; + dma_init(DMA0, DMA_CH2, &dma_init_struct); + /* configure DMA mode */ + dma_circulation_disable(DMA0, DMA_CH2); + dma_memory_to_memory_disable(DMA0, DMA_CH2); + dma_interrupt_enable(DMA0, DMA_CH2, DMA_INT_FTF); + + /* SPI0 receive dma config:DMA0-DMA_CH1 */ + dma_deinit(DMA0, DMA_CH1); + dma_init_struct.periph_addr = (uint32_t)&SPI_DATA(SPI0); + dma_init_struct.memory_addr = (uint32_t)spi0_receive_array; + dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY; + dma_init_struct.priority = DMA_PRIORITY_HIGH; + dma_init(DMA0, DMA_CH1, &dma_init_struct); + /* configure DMA mode */ + dma_circulation_disable(DMA0, DMA_CH1); + dma_memory_to_memory_disable(DMA0, DMA_CH1); + dma_interrupt_enable(DMA0, DMA_CH1, DMA_INT_FTF); + + spi_parameter_struct spi_init_struct; + /* deinitilize SPI and the parameters */ + spi_i2s_deinit(SPI0); + spi_struct_para_init(&spi_init_struct); + + /* SPI0 parameter config */ + spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX; + spi_init_struct.device_mode = SPI_SLAVE; + spi_init_struct.frame_size = SPI_FRAMESIZE_16BIT; + spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE; + spi_init_struct.nss = SPI_NSS_SOFT; + spi_init_struct.prescale = SPI_PSC_2; + spi_init_struct.endian = SPI_ENDIAN_LSB; + + spi_init(SPI0, &spi_init_struct); + spi_crc_polynomial_set(SPI0,7); + spi_enable(SPI0); + + /* DMA channel enable */ + dma_channel_enable(DMA0, DMA_CH1); + dma_channel_enable(DMA0, DMA_CH2); + + /* SPI DMA enable */ + spi_dma_enable(SPI0, SPI_DMA_TRANSMIT); + spi_dma_enable(SPI0, SPI_DMA_RECEIVE); + + eclic_irq_enable(DMA1_Channel0_IRQn,1,0); + spi_i2s_interrupt_enable(SPI0, SPI_I2S_INT_TBE); +} + + +//Used by downstream state machine and USB host classes. +StatusTypeDef Downstream_GetFreePacket(FreePacketCallbackTypeDef callback) +{ + if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR) + { + return STATUS_ERROR; + } + + //Do we already have a queued callback? + if (PendingFreePacketCallback != NULL) + { + DOWNSTREAM_SPI_FREAKOUT; + return STATUS_ERROR; + } + + //Check if there is a free buffer now + if (DownstreamPacket0.Busy == NOT_BUSY) + { + DownstreamPacket0.Busy = BUSY; + callback(&DownstreamPacket0); + return STATUS_OK; + } + if (DownstreamPacket1.Busy == NOT_BUSY) + { + DownstreamPacket1.Busy = BUSY; + callback(&DownstreamPacket1); + return STATUS_OK; + } + + //Otherwise save requested address for when a buffer becomes free in the future + PendingFreePacketCallback = callback; + return STATUS_OK; +} + + + +DownstreamPacketTypeDef* Downstream_GetFreePacketImmediately(void) +{ + if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR) + { + return NULL; + } + + //We are expecting a free buffer now + if (DownstreamPacket0.Busy == NOT_BUSY) + { + DownstreamPacket0.Busy = BUSY; + return &DownstreamPacket0; + } + if (DownstreamPacket1.Busy == NOT_BUSY) + { + DownstreamPacket1.Busy = BUSY; + return &DownstreamPacket1; + } + + //Should not happen: + DOWNSTREAM_SPI_FREAKOUT; + return NULL; +} + + + +//Used by Downstream state machine and USB host classes. +void Downstream_ReleasePacket(DownstreamPacketTypeDef* packetToRelease) +{ + FreePacketCallbackTypeDef tempCallback; + + if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR) + { + return; + } + + if ((packetToRelease != &DownstreamPacket0) && + (packetToRelease != &DownstreamPacket1)) + { + DOWNSTREAM_SPI_FREAKOUT; + return; + } + + if (PendingFreePacketCallback != NULL) + { + tempCallback = PendingFreePacketCallback; //In extreme situations, running this callback can trigger another request for a free packet, + PendingFreePacketCallback = NULL; //thereby causing GetFreePacket to freak out. So we need to clear the callback indicator first. + tempCallback(packetToRelease); + } + else + { + packetToRelease->Busy = NOT_BUSY; + } +} + + +//Used by Downstream state machine and USB classes. +//Ok to call when idle or transmitting. +//Not OK to call when receiving or awaiting reception. +StatusTypeDef Downstream_ReceivePacket(SpiPacketReceivedCallbackTypeDef callback) +{ + if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR) + { + return STATUS_ERROR; + } + + if ((DownstreamInterfaceState == DOWNSTREAM_INTERFACE_RX_SIZE_WAIT) || + (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_RX_PACKET_WAIT) || + (ReceivePacketCallback != NULL)) + { + DOWNSTREAM_SPI_FREAKOUT; + return STATUS_ERROR; + } + + ReceivePacketCallback = callback; + return Downstream_CheckPreparePacketReception(); +} + + +//Internal use only +StatusTypeDef Downstream_CheckPreparePacketReception(void) +{ + if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR) + { + return STATUS_ERROR; + } + + if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_IDLE) + { + DownstreamInterfaceState = DOWNSTREAM_INTERFACE_RX_SIZE_WAIT; + return Downstream_GetFreePacket(Downstream_PrepareReceivePacketSize); + } + return STATUS_OK; +} + + +//Internal use only +void Downstream_PrepareReceivePacketSize(DownstreamPacketTypeDef* freePacket) +{ + if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR) + { + return; + } + + if (DownstreamInterfaceState != DOWNSTREAM_INTERFACE_RX_SIZE_WAIT) + { + DOWNSTREAM_SPI_FREAKOUT; + return; + } + CurrentWorkingPacket = freePacket; + CurrentWorkingPacket->Length16 = 0; + if (HAL_SPI_TransmitReceive_DMA(&Hspi1, + (uint8_t*)&CurrentWorkingPacket->Length16, + (uint8_t*)&CurrentWorkingPacket->Length16, + 2) != HAL_OK) //We only need to read one word, but the peripheral library freaks out... + { + DOWNSTREAM_SPI_FREAKOUT; + return; + } + + UPSTREAM_TX_REQUEST_ASSERT; +} + + + +//Used by Downstream state machine and USB classes. +//Call when idle or transmitting. +//It doesn't make sense to call when receiving or awaiting reception. +StatusTypeDef Downstream_TransmitPacket(DownstreamPacketTypeDef* packetToWrite) +{ + if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR) + { + return STATUS_ERROR; + } + + //Sanity checks + if ((packetToWrite != &DownstreamPacket0) && + (packetToWrite != &DownstreamPacket1)) + { + DOWNSTREAM_SPI_FREAKOUT; + return STATUS_ERROR; + } + if ((packetToWrite->Busy != BUSY) || + (packetToWrite->Length16 < DOWNSTREAM_PACKET_LEN_MIN_16) || + (packetToWrite->Length16 > DOWNSTREAM_PACKET_LEN_16)) + { + DOWNSTREAM_SPI_FREAKOUT; + return STATUS_ERROR; + } + if (NextTxPacket != NULL) + { + DOWNSTREAM_SPI_FREAKOUT; + return STATUS_ERROR; + } + + switch (DownstreamInterfaceState) + { + case DOWNSTREAM_INTERFACE_TX_SIZE_WAIT: + case DOWNSTREAM_INTERFACE_TX_PACKET_WAIT: + NextTxPacket = packetToWrite; + break; + + case DOWNSTREAM_INTERFACE_IDLE: + DownstreamInterfaceState = DOWNSTREAM_INTERFACE_TX_SIZE_WAIT; + CurrentWorkingPacket = packetToWrite; + + if (HAL_SPI_TransmitReceive_DMA(&Hspi1, + (uint8_t*)&CurrentWorkingPacket->Length16, + (uint8_t*)&TemporaryIncomingPacketLength, + 2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out... + { + DOWNSTREAM_SPI_FREAKOUT; + return STATUS_ERROR; + } + UPSTREAM_TX_REQUEST_ASSERT; + break; + + default: + DOWNSTREAM_SPI_FREAKOUT; + return STATUS_ERROR; + } + + return STATUS_OK; +} + + + +//Do stuff at main loop priority after SPI transaction is complete +void Downstream_SPIProcess(void) +{ + SpiPacketReceivedCallbackTypeDef tempPacketCallback; + + if (SpiInterruptCompleted == 0) + { + return; + } + SpiInterruptCompleted = 0; + + if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR) + { + return; + } + + //Finished transmitting packet size + if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_TX_SIZE_WAIT) + { + if ((uint16_t)TemporaryIncomingPacketLength != 0) + { + //Currently we just freak out if Upstream sends us an unexpected command. + //Theoretically we could reset our downstream state machine and accept the new command... + DOWNSTREAM_SPI_FREAKOUT; + return; + } + + DownstreamInterfaceState = DOWNSTREAM_INTERFACE_TX_PACKET_WAIT; + if (HAL_SPI_TransmitReceive_DMA(&Hspi1, + &CurrentWorkingPacket->CommandClass, + &CurrentWorkingPacket->CommandClass, + ((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK) + { + DOWNSTREAM_SPI_FREAKOUT; + return; + } + UPSTREAM_TX_REQUEST_ASSERT; + return; + } + + //Finished transmitting packet body + if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_TX_PACKET_WAIT) + { + Downstream_ReleasePacket(CurrentWorkingPacket); + if (NextTxPacket != NULL) + { + //NextTxPacket has already passed the checks in Downstream_TransmitPacket. + //So we just need to pass it to HAL_SPI_Transmit_DMA. + DownstreamInterfaceState = DOWNSTREAM_INTERFACE_TX_SIZE_WAIT; + CurrentWorkingPacket = NextTxPacket; + NextTxPacket = NULL; + if (HAL_SPI_TransmitReceive_DMA(&Hspi1, + (uint8_t*)&CurrentWorkingPacket->Length16, + (uint8_t*)&TemporaryIncomingPacketLength, + 2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out... + { + DOWNSTREAM_SPI_FREAKOUT; + return; + } + UPSTREAM_TX_REQUEST_ASSERT; + return; + } + + DownstreamInterfaceState = DOWNSTREAM_INTERFACE_IDLE; + if (ReceivePacketCallback != NULL) + { + Downstream_CheckPreparePacketReception(); + } + return; + } + + + if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_RX_SIZE_WAIT) + { + if ((CurrentWorkingPacket->Length16 < DOWNSTREAM_PACKET_LEN_MIN_16) || + (CurrentWorkingPacket->Length16 > DOWNSTREAM_PACKET_LEN_16)) + { + DOWNSTREAM_SPI_FREAKOUT; + return; + } + DownstreamInterfaceState = DOWNSTREAM_INTERFACE_RX_PACKET_WAIT; + if (HAL_SPI_TransmitReceive_DMA(&Hspi1, + &CurrentWorkingPacket->CommandClass, + &CurrentWorkingPacket->CommandClass, + ((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK) + { + DOWNSTREAM_SPI_FREAKOUT; + return; + } + UPSTREAM_TX_REQUEST_ASSERT; + return; + } + + if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_RX_PACKET_WAIT) + { + DownstreamInterfaceState = DOWNSTREAM_INTERFACE_IDLE; + if (ReceivePacketCallback == NULL) + { + DOWNSTREAM_SPI_FREAKOUT; + return; + } + //Packet processor may want to receive another packet immediately, + //so clear ReceivePacketCallback before the call. + //It is the callback's responsibility to release the packet buffer we are passing to it! + tempPacketCallback = ReceivePacketCallback; + ReceivePacketCallback = NULL; + tempPacketCallback(CurrentWorkingPacket); + return; + } + + + //case default: + DOWNSTREAM_SPI_FREAKOUT; +} + + + +//Called at the end of the SPI TxRx DMA transfer, +//at DMA2 interrupt priority. Assume *hspi points to our hspi1. +//We use TxRx to send our reply packet to check if Upstream was trying +//to send us a packet at the same time. +//We also TxRx our packet body because the SPI silicon is buggy at the end of +//a transmit-only DMA transfer with CRC! (it does not clear RXNE flag on request) +void DMA_SPI_TxRxCpltCallback(void) +{ + UPSTREAM_TX_REQUEST_DEASSERT; + SpiInterruptCompleted = 1; +} + + + +//Something bad happened! Possibly CRC error... +/*void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) +{ + DOWNSTREAM_SPI_FREAKOUT; +}*/ + diff --git a/RISC-V/Source/interrupts.c b/RISC-V/Source/interrupts.c new file mode 100644 index 0000000..2c66804 --- /dev/null +++ b/RISC-V/Source/interrupts.c @@ -0,0 +1,23 @@ +/* + * interrupts.c + * + * Created on: 23 окт. 2021 г. + * Author: ivan + */ + +#include "interrupts.h" +#include "downstream_spi.h" + +/* DMA0_Channel0 handle function */ +//receive +void DMA0_Channel1_IRQHandler(void){ + if(dma_interrupt_flag_get(DMA0, DMA_CH1, DMA_INT_FLAG_FTF)){ + DMA_SPI_TxRxCpltCallback(); + dma_interrupt_flag_clear(DMA0, DMA_CH1, DMA_INT_FLAG_G); + } +} +//transmit +void DMA0_Channel2_IRQHandler(void){ + +} + diff --git a/RISC-V/Source/main.c b/RISC-V/Source/main.c index e604348..f1be548 100644 --- a/RISC-V/Source/main.c +++ b/RISC-V/Source/main.c @@ -36,25 +36,27 @@ OF SUCH DAMAGE. #include "drv_usb_core.h" #include "usbh_usr.h" #include "usbh_msc_core.h" +#include "gd32vf103v_eval.h" +#include "usb_host.h" #include #include #include -usb_core_driver usbh_msc_core; +/*usb_core_driver usbh_msc_core; +void Downstream_HostUserCallback(usbh_host *phost, uint8_t id){ + //dummy + return; +} usbh_host usb_host = { .class_cb = &usbh_msc_cb, .usr_cb = &user_callback_funs, - + .pUser=&Downstream_HostUserCallback }; -usbh_host hUsbHostFS; +usbh_host hUsbHostFS;*/ -void Downstream_HostUserCallback(usbh_host *phost, uint8_t id){ - //dummy - return; -} /** * @brief Main routine for HID mouse / keyboard class application @@ -68,20 +70,22 @@ int main(void) eclic_priority_group_set(ECLIC_PRIGROUP_LEVEL2_PRIO2); - usb_rcu_config(); +// usb_rcu_config(); - usb_timer_init(); +// usb_timer_init(); /* configure GPIO pin used for switching VBUS power and charge pump I/O */ // usb_vbus_config(); - usbh_init (&usbh_msc_core, USB_CORE_ENUM_FS, &usb_host,Downstream_HostUserCallback); +// usbh_init (&usbh_msc_core, USB_CORE_ENUM_FS, &usb_host); /* enable interrupts */ - usb_intr_config(); +// usb_intr_config(); + USB_Host_Init(); while (1) { /* Host state handler */ - usbh_core_task (&usbh_msc_core, &usb_host); +// usbh_core_task (&usbh_msc_core, &usb_host); + USB_Host_Process(); } } diff --git a/RISC-V/Source/usb_host.c b/RISC-V/Source/usb_host.c new file mode 100644 index 0000000..d0f0143 --- /dev/null +++ b/RISC-V/Source/usb_host.c @@ -0,0 +1,36 @@ +/* + * usb_host.c + * + * Created on: 23 окт. 2021 г. + * Author: ivan + */ +#include "drv_usb_hw.h" +#include "drv_usb_core.h" +#include "usbh_usr.h" +#include "usbh_msc_core.h" +#include "gd32vf103v_eval.h" +#include "downstream_statemachine.h" + +usb_core_driver usbh_msc_core; + +usbh_host usb_host = { + .class_cb = &usbh_msc_cb, + .usr_cb = &user_callback_funs, + .pUser=&Downstream_HostUserCallback +}; + +usbh_host hUsbHostFS; + +void USB_Host_Init(void){ + usb_rcu_config(); + usb_timer_init(); + usbh_init(&usbh_msc_core, USB_CORE_ENUM_FS, &usb_host); + usb_intr_config(); +} +void USB_Host_Process(void){ + usbh_core_task (&usbh_msc_core, &usb_host); +} +void USB_Host_Disconnect(void){ + usbh_deinit(&usbh_msc_core, &usb_host); +} +