sn32: usb hal cleanup (#42)

* import helper header

* seperate usb buf init

* move usb init in chibios driver
handle the address set in a more elegant way

* clean up some code
move through sn32_usb
use macros for ep dir

* handle the setup interrupt

* report back the frame no
wake up directly

* further deviate from usbhw.c
call registers directly
use chibios for reset
interrupt party time

* flag update

* switch n/ack to simple macros

* even more native

* bye sonix mess

* bring functions up to the docs

* usb stop, setup error handling

* further cleanup

remove dead code
cleanup headers
add missing connect/dc functionality
bring ep0 init to platform correct

* usb restart is now working

* attempt to fix wakeup

* no more delay on init

* fix the usb wakeup

* improve the wakeup

* make sure the direction is not set before init

* only mess with one ep

* need to enable the bus override too in order to control it

* driver block checks

* allow wakeup time override

* dynamic sram allocation

* remove useless ep naming

* testing: remove packet limits

* guard all i/o ops

* better wakeup/suspend handling

* remove dead code

* code cleanup

* make sure all ep's are handled
This commit is contained in:
dexter93 2022-03-03 13:09:04 +02:00 committed by Dimitris Mantzouranis
parent c391c7d09c
commit dd16d2583d
10 changed files with 475 additions and 974 deletions

View File

@ -65,7 +65,3 @@ void boardInit(void) {
SN_SYS0->EXRSTCTRL_b.RESETDIS = 1; // Disable RESET
SN_SYS0->SWDCTRL_b.SWDDIS = 1; // Disable SWD
}
void restart_usb_driver(USBDriver *usbp) {
// Do nothing. Restarting the USB driver on these boards breaks it.
}

View File

@ -58,7 +58,3 @@ void __early_init(void) {
void boardInit(void) {
SN_SYS0->SWDCTRL_b.SWDDIS = 1; // Disable SWD
}
void restart_usb_driver(USBDriver *usbp) {
// Do nothing. Restarting the USB driver on these boards breaks it.
}

View File

@ -65,7 +65,3 @@ void boardInit(void) {
SN_SYS0->EXRSTCTRL_b.RESETDIS = 1; // Disable RESET
SN_SYS0->SWDCTRL_b.SWDDIS = 1; // Disable SWD
}
void restart_usb_driver(USBDriver *usbp) {
// Do nothing. Restarting the USB driver on these boards breaks it.
}

View File

@ -65,7 +65,3 @@ void boardInit(void) {
SN_SYS0->EXRSTCTRL_b.RESETDIS = 1; // Disable RESET
SN_SYS0->SWDCTRL_b.SWDDIS = 1; // Disable SWD
}
void restart_usb_driver(USBDriver *usbp) {
// Do nothing. Restarting the USB driver on these boards breaks it.
}

View File

@ -1,4 +1,3 @@
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/LLD/SN32F2xx/USB/hal_usb_lld.c
PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/LLD/SN32F2xx/USB/usbhw.c
PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/LLD/SN32F2xx/USB

File diff suppressed because it is too large Load Diff

View File

@ -28,21 +28,25 @@
#if (HAL_USE_USB == TRUE) || defined(__DOXYGEN__)
#include "sn32_usb.h"
#include "usbhw.h"
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Maximum endpoint address.
*/
#define USB_MAX_ENDPOINTS USB_ENDPOINTS_NUMBER
/**
* @brief Status stage handling method.
*/
#define USB_EP0_STATUS_STAGE USB_EP0_STATUS_STAGE_SW
/**
* @brief The address can be changed immediately upon packet reception.
* @brief This device requires the address change after the status packet.
*/
#define USB_SET_ADDRESS_MODE USB_EARLY_SET_ADDRESS
#define USB_SET_ADDRESS_MODE USB_LATE_SET_ADDRESS
/**
* @brief Method for set address acknowledge.
@ -62,8 +66,8 @@
* @details If set to @p TRUE the support for USB1 is included.
* @note The default is @p FALSE.
*/
#if !defined(PLATFORM_USB_USE_USB1) || defined(__DOXYGEN__)
#define PLATFORM_USB_USE_USB1 TRUE
#if !defined(SN32_USB_USE_USB1) || defined(__DOXYGEN__)
#define SN32_USB_USE_USB1 TRUE
#endif
/**
@ -72,6 +76,13 @@
#if !defined(SN32_USB_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define SN32_USB_IRQ_PRIORITY 3
#endif
/**
* @brief Host wake-up procedure duration.
*/
#if !defined(SN32_USB_HOST_WAKEUP_DURATION) || defined(__DOXYGEN__)
#define SN32_USB_HOST_WAKEUP_DURATION 2
#endif
/** @} */
/*===========================================================================*/
@ -195,7 +206,6 @@ typedef struct {
*/
USBOutEndpointState *out_state;
/* End of the mandatory fields.*/
/* End of the mandatory fields.*/
/**
* @brief Reserved field, not currently used.
* @note Initialize this field to 1 in order to be forward compatible.
@ -332,7 +342,7 @@ struct USBDriver {
*
* @notapi
*/
#define usb_lld_get_frame_number(usbp) 0
#define usb_lld_get_frame_number(usbp) (SN32_USB->FRMNO & mskFRAME_NO)
/**
* @brief Returns the exact size of a receive transaction.
@ -356,50 +366,39 @@ struct USBDriver {
*
* @api
*/
#define usb_lld_connect_bus(usbp)
#define usb_lld_connect_bus(usbp) \
do { \
SN32_USB->CFG |= mskDPPU_EN; \
} while (false)
/**
* @brief Disconnect the USB device.
*
* @api
*/
#define usb_lld_disconnect_bus(usbp)
#define usb_lld_disconnect_bus(usbp) \
do { \
SN32_USB->CFG &= ~mskDPPU_EN; \
} while (false)
/**
* @brief Start of host wake-up procedure.
*
* @notapi
*/
#define usb_lld_wakeup_host(usbp) { \
USB_RemoteWakeUp(); \
}
#define usb_lld_wakeup_host(usbp) \
do { \
SN32_USB->SGCTL = (mskBUS_DRVEN|mskBUS_K_STATE); \
osalThreadSleepMilliseconds(SN32_USB_HOST_WAKEUP_DURATION); \
SN32_USB->SGCTL &= ~mskBUS_DRVEN; \
} while (false)
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
/* Descriptor related */
/* bmAttributes in Endpoint Descriptor */
#define USB_ENDPOINT_TYPE_MASK 0x03
#define USB_ENDPOINT_TYPE_CONTROL 0x00
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
#define USB_ENDPOINT_TYPE_BULK 0x02
#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
#define USB_ENDPOINT_SYNC_MASK 0x0C
#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00
#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04
#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08
#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C
#define USB_ENDPOINT_USAGE_MASK 0x30
#define USB_ENDPOINT_USAGE_DATA 0x00
#define USB_ENDPOINT_USAGE_FEEDBACK 0x10
#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20
#define USB_ENDPOINT_USAGE_RESERVED 0x30
/* bEndpointAddress in Endpoint Descriptor */
#define USB_ENDPOINT_DIRECTION_MASK 0x80
#if (PLATFORM_USB_USE_USB1 == TRUE) && !defined(__DOXYGEN__)
#if (SN32_USB_USE_USB1 == TRUE) && !defined(__DOXYGEN__)
extern USBDriver USBD1;
#endif
@ -424,6 +423,8 @@ extern "C" {
void usb_lld_stall_in(USBDriver *usbp, usbep_t ep);
void usb_lld_clear_out(USBDriver *usbp, usbep_t ep);
void usb_lld_clear_in(USBDriver *usbp, usbep_t ep);
void handleACK(USBDriver* usbp, usbep_t ep);
void handleNAK(USBDriver* usbp, usbep_t ep);
#ifdef __cplusplus
}
#endif

View File

@ -15,10 +15,9 @@
*/
/**
* @file USBv1/sn32_usb.h
* @file USB/sn32_usb.h
* @brief SN32 USB registers layout header.
* @note This file requires definitions from the ST STM32 header files
* sn32f124x.h
* @note This file requires definitions from the SN32 header files
*
* @addtogroup USB
* @{
@ -27,32 +26,88 @@
#ifndef SN32_USB_H
#define SN32_USB_H
// TODO: ENDPOINTS nubmer is chip dependent and needs to be organized better
#include "usbhw.h"
/**
* @brief Number of the available endpoints.
* @details This value does not include the endpoint 0 which is always present.
*/
#define USB_MAX_ENDPOINTS 4
#define HAL_MAX_ENDPOINTS 6
#if (defined(SN32F240B) || defined(SN32F260))
#define USB_ENDPOINTS_NUMBER 4
#define SN32_USB_PMA_SIZE 256
#elif (defined(SN32F280) || defined(SN32F290))
#define USB_ENDPOINTS_NUMBER HAL_MAX_ENDPOINTS
#define SN32_USB_PMA_SIZE 512
#else
#error "USB driver not supported in the selected device"
#endif
/**
* @brief USB registers block.
*/
typedef struct {
volatile uint32_t INTEN; /*!< (@ 0x00000000) Offset:0x00 USB Interrupt Enable Register */
volatile uint32_t INSTS; /*!< (@ 0x00000004) Offset:0x04 USB Interrupt Event Status Register */
volatile uint32_t INSTSC; /*!< (@ 0x00000008) Offset:0x08 USB Interrupt Event Status Clear Register */
volatile uint32_t ADDR; /*!< (@ 0x0000000C) Offset:0x0C USB Device Address Register */
volatile uint32_t CFG; /*!< (@ 0x00000010) Offset:0x10 USB Configuration Register */
volatile uint32_t SGCTL; /*!< (@ 0x00000014) Offset:0x14 USB Signal Control Register */
volatile uint32_t EPCTL[HAL_MAX_ENDPOINTS +1]; /*!< (@ 0x00000018) Offset:0x18 USB Endpoint 0-6 Control Registers */
volatile uint32_t RESERVED[2];
volatile uint32_t EPTOGGLE; /*!< (@ 0x0000003C) Offset:0x3C USB Endpoint Data Toggle Register */
volatile uint32_t RESERVED1[2];
volatile uint32_t EPBUFOS[HAL_MAX_ENDPOINTS]; /*!< (@ 0x00000048) Offset:0x48 USB Endpoint 1-6 Buffer Offset Registers */
volatile uint32_t FRMNO; /*!< (@ 0x00000060) Offset:0x60 USB Frame Number Register */
volatile uint32_t PHYPRM; /*!< (@ 0x00000064) Offset:0x64 USB PHY Parameter Register */
volatile uint32_t RESERVED3;
volatile uint32_t PHYPRM2; /*!< (@ 0x0000006C) Offset:0x6C USB PHY Parameter 2 Register */
volatile uint32_t PS2CTL; /*!< (@ 0x00000070) Offset:0x70 PS/2 Control Register */
volatile uint32_t RESERVED4;
volatile uint32_t RWADDR; /*!< (@ 0x00000078) Offset:0x78 USB Read/Write Address Register */
volatile uint32_t RWDATA; /*!< (@ 0x0000007C) Offset:0x7C USB Read/Write Data Register */
volatile uint32_t RWSTATUS; /*!< (@ 0x00000080) Offset:0x80 USB Read/Write Status Register */
volatile uint32_t RWADDR2; /*!< (@ 0x00000084) Offset:0x84 USB Read/Write Address Register 2 */
volatile uint32_t RWDATA2; /*!< (@ 0x00000088) Offset:0x88 USB Read/Write Data Register 2 */
volatile uint32_t RWSTATUS2; /*!< (@ 0x0000008C) Offset:0x8C USB Read/Write Status Register 2 */
} sn32_usb_t; /*!< Size = 144 (0x90) */
/** @} */
/**
* @brief USB registers block numeric address.
*/
#define SN32_USB_BASE SN_USB_BASE
#define SN32_USB_BASE SN_USB_BASE
/**
* @brief USB RAM numeric address.
*/
#define SN32_USBRAM_BASE SN_USB_BASE + 0x100
#define SN32_USBRAM_BASE (SN_USB_BASE + 0x100)
/**
* @brief Pointer to the USB registers block.
*/
// #define SN32_USB ((sn32_usb_t *)SN32_USB_BASE)
#define SN32_USB ((sn32_usb_t *)SN32_USB_BASE)
/**
* @brief Pointer to the USB RAM.
*/
#define SN32_USBRAM ((sn32_usb_pma_t *)SN32_USBRAM_BASE)
#define SN32_USBRAM ((sn32_usb_pma_t *)SN32_USBRAM_BASE)
#define mskEPn_NAK(ep) (0x1<<(ep -1))
#define mskEPn_ACK(ep) (0x1<<(8+(ep-1)))
#define mskEPn_DIR(ep) (0x1<<(ep-1))
#define mskEPn_DATA_TOGGLE(ep) (0x1<<(ep-1))
#define EPCTL_SET_STAT_ACK(ep, bBytecnt) \
SN32_USB->EPCTL[ep] = (mskEPn_ENDP_EN|mskEPn_ENDP_STATE_ACK|bBytecnt)
#define EPCTL_SET_STAT_NAK(ep) \
SN32_USB->EPCTL[ep] = (mskEPn_ENDP_EN)
#define EPCTL_SET_STAT_STALL(ep) \
SN32_USB->EPCTL[ep] = (mskEPn_ENDP_EN|mskEPn_ENDP_STATE_STALL)
#define EPCTL_TOGGLE(ep) \
SN32_USB->EPTOGGLE = mskEPn_DATA_TOGGLE(ep)
#define USB_SET_BUFFER_OFST(ep, addr) \
SN32_USB->EPBUFOS[ep-1] = addr
#endif /* SN32_USB_H */

View File

@ -1,381 +0,0 @@
/*----------------------------------------------------------------------------
* U S B - K e r n e l
*----------------------------------------------------------------------------
* Name: usbhw.c
* Purpose: USB Custom User Module
* Version: V1.01
* Date: 2017/07
*------------------------------------------------------------------------------*/
#include <SN32F2xx.h>
#include "SN32F200_Def.h"
#include <sn32_sys1.h>
#include "usbhw.h"
const uint32_t wUSB_EPnOffset[5] = {
0, EP1_BUFFER_OFFSET_VALUE,
EP2_BUFFER_OFFSET_VALUE, EP3_BUFFER_OFFSET_VALUE,
EP4_BUFFER_OFFSET_VALUE};
const uint32_t wUSB_EPnMaxPacketSize[5] = {
USB_EP0_PACKET_SIZE, USB_EP1_PACKET_SIZE,
USB_EP2_PACKET_SIZE, USB_EP3_PACKET_SIZE,
USB_EP4_PACKET_SIZE};
/*****************************************************************************
* Description :Setting USB for different Power domain
*****************************************************************************/
#define System_Power_Supply System_Work_at_5_0V // only 3.3V, 5V
#define System_Work_at_3_3V 0
#define System_Work_at_5_0V 1
/*****************************************************************************
* Function : USB_Init
* Description : 1. setting IDLE_TIME, REPORT_PROTOCOL, S_USB_EP0setupdata.wUSB_Status
* 2. set EP1~EP6 FIFO RAM address.
* 3. save EP1~EP6 FIFO RAM point address.
* 4. save EP1~EP6 Package Size.
* 5. Enable USB function and setting EP1~EP6 Direction.
* 6. NEVER REMOVE !! USB D+/D- Dischage
* 7. Enable USB PHY and USB interrupt.
* Input : None
* Output : None
* Return : None
* Note : None
*****************************************************************************/
void USB_Init(void)
{
uint32_t wTmp;
/* Initialize clock and Enable USB PHY. */
SystemInit();
SystemCoreClockUpdate();
sys1EnableUSB(); // Enable USB Clock
/* Initialize USB EP1~EP4 RAM Start address base on 64-bytes. */
USB_EPnBufferOffset(1, EP1_BUFFER_OFFSET_VALUE);
USB_EPnBufferOffset(2, EP2_BUFFER_OFFSET_VALUE);
USB_EPnBufferOffset(3, EP3_BUFFER_OFFSET_VALUE);
USB_EPnBufferOffset(4, EP4_BUFFER_OFFSET_VALUE);
/* Enable the USB Interrupt */
SN_USB->INTEN = (mskBUS_IE|mskUSB_IE|mskEPnACK_EN|mskBUSWK_IE);
SN_USB->INTEN |= mskEP1_NAK_EN;
SN_USB->INTEN |= mskEP2_NAK_EN;
SN_USB->INTEN |= mskEP3_NAK_EN;
SN_USB->INTEN |= mskEP4_NAK_EN;
SN_USB->INTEN |= mskUSB_SOF_IE;
NVIC_ClearPendingIRQ(USB_IRQn);
NVIC_EnableIRQ(USB_IRQn);
/* BUS_DRVEN = 0, BUS_DP = 1, BUS_DN = 0 */
SN_USB->SGCTL = mskBUS_J_STATE;
#if (System_Power_Supply == System_Work_at_5_0V)
//----------------------------------//
//Setting USB for System work at 5V //
//----------------------------------//
//VREG33_EN = 1, PHY_EN = 1, DPPU_EN = 1, SIE_EN = 1, ESD_EN = 1
wTmp = (mskVREG33_EN|mskPHY_EN|mskDPPU_EN|mskSIE_EN|mskESD_EN);
#elif (System_Power_Supply == System_Work_at_3_3V)
//------------------------------------//
//Setting USB for System work at 3.3V //
//------------------------------------//
//VREG33_EN = 0, PHY_EN = 1, DPPU_EN = 1, SIE_EN = 1, ESD_EN = 1
wTmp = (mskVREG33_DIS|mskPHY_EN|mskDPPU_EN|mskSIE_EN|mskESD_EN);
#endif
//** Delay for the connection between Device and Host
// UT_MAIN_DelayNms(50);
// chThdSleepMilliseconds(50);
//** Setting USB Configuration Register
SN_USB->CFG = wTmp;
SN_USB->PHYPRM = 0x80000000; // PHY parameter
SN_USB->PHYPRM2 = 0x00004004; // PHY parameter 2
}
/*****************************************************************************
* Function : USB_ClrEPnToggle
* Description : USB Clear EP1~EP6 toggle bit to DATA0
* write 1: toggle bit Auto.
* write 0: clear EPn toggle bit to DATA0
* Input : hwEPNum ->EP1~EP6
* Output : None
* Return : None
* Note : None
*****************************************************************************/
void USB_ClrEPnToggle(uint32_t hwEPNum)
{
SN_USB->EPTOGGLE &= ~(0x1<<hwEPNum);
}
/*****************************************************************************
* Function : USB_EPnDisable
* Description : Disable EP1~EP4
* Input : wEPNum
* Output : None
* Return : None
* Note : None
*****************************************************************************/
void USB_EPnDisable(uint32_t wEPNum)
{
volatile uint32_t *pEPn_ptr;
if(wEPNum > USB_EP4)
return;
pEPn_ptr = &SN_USB->EP0CTL + wEPNum;
*pEPn_ptr = 0; //** SET DISABLE. No handshake IN/OUT token.
}
/*****************************************************************************
* Function : USB_EPnNak
* Description : SET EP1~EP4 is NAK.
* For IN will handshake NAK to IN token.
* For OUT will handshake NAK to OUT token.
* Input : wEPNum
* Output : None
* Return : None
* Note : None
*****************************************************************************/
void USB_EPnNak(uint32_t wEPNum)
{
volatile uint32_t *pEPn_ptr;
if(wEPNum > USB_EP4)
return;
pEPn_ptr = &SN_USB->EP0CTL + wEPNum;
*pEPn_ptr = mskEPn_ENDP_EN; //** SET NAK
}
/*****************************************************************************
* Function : USB_EPnAck
* Description : SET EP1~EP4 is ACK.
* For IN will handshake bBytent to IN token.
* For OUT will handshake ACK to OUT token.
* Input : wEPNum:EP1~EP4.
* bBytecnt: Byte Number of Handshake.
* Output : None
* Return : None
* Note : None
*****************************************************************************/
void USB_EPnAck(uint32_t wEPNum, uint8_t bBytecnt)
{
volatile uint32_t *pEPn_ptr;
if (wEPNum > USB_EP4)
return;
pEPn_ptr = &SN_USB->EP0CTL + wEPNum;
*pEPn_ptr = (mskEPn_ENDP_EN|mskEPn_ENDP_STATE_ACK|bBytecnt);
}
/*****************************************************************************
* Function : USB_EPnStall
* Description : SET EP1~EP4 is STALL.
* For IN will handshake STALL to IN token.
* For OUT will handshake STALL to OUT token.
* Input : wEPNum:EP1~EP4.
* Output : None
* Return : None
* Note : None
*****************************************************************************/
void USB_EPnStall(uint32_t wEPNum)
{
volatile uint32_t *pEPn_ptr;
if(wEPNum > USB_EP4) //** wEPNum != EP0~EP4
return;
pEPn_ptr = &SN_USB->EP0CTL + wEPNum;
if (wEPNum == USB_EP0)
{
if(SN_USB->INSTS & mskEP0_PRESETUP)
return;
}
*pEPn_ptr = (mskEPn_ENDP_EN|mskEPn_ENDP_STATE_STALL);
}
/*****************************************************************************
* Function : USB_EPnEnabled
* Description : check if EP0~EP4 enabled or not
* Input : wEPNum:EP0~EP4.
* Output : None
* Return : true - enabled/false - disabled
* Note : None
*****************************************************************************/
_Bool USB_EPnEnabled(uint32_t wEPNum)
{
volatile uint32_t *pEPn_ptr;
if(wEPNum > USB_EP4) //** wEPNum != EP0~EP4
return 0;
pEPn_ptr = &SN_USB->EP0CTL + wEPNum;
return (((*pEPn_ptr) & mskEPn_ENDP_EN) == mskEPn_ENDP_EN);
}
/*****************************************************************************
* Function : USB_EPnStalled
* Description : GET EP0~EP4 state.
* Input : wEPNum:EP0~EP4.
* Output : None
* Return : mskEPn_ENDP_STATE
* Note : None
*****************************************************************************/
_Bool USB_EPnStalled(uint32_t wEPNum)
{
volatile uint32_t *pEPn_ptr;
if(wEPNum > USB_EP4) //** wEPNum != EP0~EP4
return 0;
pEPn_ptr = &SN_USB->EP0CTL + wEPNum;
return (((*pEPn_ptr) & mskEPn_ENDP_STATE) == mskEPn_ENDP_STATE_STALL);
}
/*****************************************************************************
* Function : USB_RemoteWakeUp
* Description : USB Remote wakeup: USB D+/D- siganl is J-K state.
* Input : None
* Output : None
* Return : None
* Note : None
*****************************************************************************/
void USB_RemoteWakeUp()
{
__USB_JSTATE_DRIVER; //** J state ;Full speed D+ = 1, D- = 0
USB_DelayJstate();
__USB_KSTATE_DRIVER; //** K state ;Full speed D+ = 0, D- = 1
USB_DelayKstate();
SN_USB->SGCTL &= ~mskBUS_DRVEN;
}
/*****************************************************************************
* Function : USB_DelayJstate
* Description : For J state delay. about 180us
* Input : None
* Output : None
* Return : None
* Note : None
*****************************************************************************/
void USB_DelayJstate()
{
uint32_t i = 1500>>SN_SYS0->AHBCP;
while(i--);
}
/*****************************************************************************
* Function : USB_DelayKstate
* Description : For K state delay. about 9~10ms
* Input : None
* Output : None
* Return : None
* Note : None
*****************************************************************************/
void USB_DelayKstate()
{
uint32_t i = 80000>>SN_SYS0->AHBCP; //** 10ms @ 12~48MHz
while(i--); //** require delay 1ms ~ 15ms
}
/*****************************************************************************
* Function : USB_EPnBufferOffset
* Description : SET EP1~EP4 RAM point address
* Input : wEPNum: EP1~EP4
* wAddr of device address
* Output : None
* Return : None
* Note : None
*****************************************************************************/
void USB_EPnBufferOffset(uint32_t wEPNum, uint32_t wAddr)
{
volatile uint32_t *pEPn_ptr;
if ((wEPNum > USB_EP0) && (wEPNum <= USB_EP4)) //** wEPNum = EP1 ~ EP4
{
pEPn_ptr = &SN_USB->EP1BUFOS; //** Assign point to EP1 RAM address
*(pEPn_ptr+wEPNum-1) = wAddr; //** SET point to EPn RAM address
}
}
/*****************************************************************************
* Function : USB_ReturntoNormal
* Description : Enable USB IHRC and switch system into IHRC
* Enable PHY/ESD protect
* Input : None
* Output : None
* Return : None
* Note : None
*****************************************************************************/
void USB_ReturntoNormal(void)
{
if(((SN_FLASH->LPCTRL)&0xF)!=0x05) // avoid MCU run 48MHz call this function occur HF
SystemInit();
SystemCoreClockUpdate();
USB_WakeupEvent();
}
/*****************************************************************************
* Function : USB_ResetEvent
* Description : recevice USB bus reset to Initial parameter
* Input : None
* Output : None
* Return : None
* Note : None
*****************************************************************************/
void USB_ResetEvent(void)
{
uint32_t wLoop;
__USB_CLRINSTS(0xFFFFFFFF); //** Clear all USB Event status
__USB_SETADDRESS(0); //** Set USB address = 0
USB_EPnStall(USB_EP0); //** Set EP0 enable & INOUTSTALL
for (wLoop=USB_EP1; wLoop<=USB_EP4; wLoop++)
USB_EPnDisable(wLoop); //** Set EP1~EP4 disable & NAK
}
/*****************************************************************************
* Function : USB_WakeupEvent
* Description : Enable USB CLK and PHY
* Input : None
* Output : None
* Return : None
* Note : None
*****************************************************************************/
void USB_WakeupEvent(void)
{
__USB_PHY_ENABLE; //** enable ESD_EN & PHY_EN
__USB_CLRINSTS(mskBUS_WAKEUP); //** Clear BUS_WAKEUP
}
/*****************************************************************************
* Function : USB_SuspendEvent
* Description : puts MCU in sleep mode
* Input : None
* Output : None
* Return : None
* Note : None
*****************************************************************************/
void USB_SuspendEvent(void)
{
__USB_PHY_DISABLE;
SN_USB->INTEN = 0;
//** switch ILRC
SN_SYS0->CLKCFG = 0x01;
//** check ILRC status
while((SN_SYS0->CLKCFG & 0x10) != 0x10);
//** switch SYSCLK / 4 DO NOT set SYSCLK / 1 or SYSCLK / 2!!!!
SN_SYS0->AHBCP = 2;
//** disable IHRC
SN_SYS0->ANBCTRL = 0;
SN_USB->INTEN = (mskBUS_IE|mskUSB_IE|mskEPnACK_EN|mskBUSWK_IE);
SN_USB->INTEN |= mskEP1_NAK_EN;
SN_USB->INTEN |= mskEP2_NAK_EN;
SN_USB->INTEN |= mskEP3_NAK_EN;
SN_USB->INTEN |= mskEP4_NAK_EN;
SN_USB->INTEN |= mskUSB_SOF_IE;
SN_PMU->CTRL = 0x04;
}

View File

@ -4,34 +4,15 @@
#ifndef __USBHW_H__
#define __USBHW_H__
/* USB Remote Wakeup I/O Define */
/* USB Remote Wakeup I/O Port Define, Default P1.5 */
#define REMOTE_WAKEUP_IO_P0 DISABLE
#define REMOTE_WAKEUP_IO_P1 ENABLE
#define REMOTE_WAKEUP_IO_P2 DISABLE
#define REMOTE_WAKEUP_IO_P3 DISABLE
/* USB Remote Wakeup I/O Bit Define */
#define REMOTE_WAKEUP_IO_P0_BIT 0x0000
#define REMOTE_WAKEUP_IO_P1_BIT 0x0020
#define REMOTE_WAKEUP_IO_P2_BIT 0x0000
#define REMOTE_WAKEUP_IO_P3_BIT 0x0000
/* USB EPn NAK interrupt */
#define EP1_NAK_IE DISABLE
#define EP2_NAK_IE DISABLE
#define EP3_NAK_IE DISABLE
#define EP4_NAK_IE DISABLE
/* USB SOF interrupt */
#define SOF_IE DISABLE
/* USB Interrupt Enable Bit Definitions <USB_INTEN> */
#define mskEP1_NAK_EN (0x1<<0)
#define mskEP2_NAK_EN (0x1<<1)
#define mskEP3_NAK_EN (0x1<<2)
#define mskEP4_NAK_EN (0x1<<3)
#define mskEPnACK_EN (0x1<<4)
#define mskEP5_NAK_EN (0x1<<4)
#define mskEP6_NAK_EN (0x1<<5)
#define mskEPnACK_EN (0x1<<6)
#define mskBUSWK_IE (0x1<<28)
#define mskUSB_IE (0x1<<29)
#define mskUSB_SOF_IE (0x1<<30)
@ -42,10 +23,17 @@
#define mskEP2_NAK (0x1<<1)
#define mskEP3_NAK (0x1<<2)
#define mskEP4_NAK (0x1<<3)
#define mskEP5_NAK (0x1<<4)
#define mskEP6_NAK (0x1<<5)
#define mskEP1_ACK (0x1<<8)
#define mskEP2_ACK (0x1<<9)
#define mskEP3_ACK (0x1<<10)
#define mskEP4_ACK (0x1<<11)
#define mskEP5_ACK (0x1<<12)
#define mskEP6_ACK (0x1<<13)
#define mskERR_TIMEOUT (0x1<<17)
#define mskERR_SETUP (0x1<<18)
#define mskEP0_OUT_STALL (0x1<<19)
@ -68,6 +56,9 @@
#define mskEP2_DIR (0x1<<1)
#define mskEP3_DIR (0x1<<2)
#define mskEP4_DIR (0x1<<3)
#define mskEP5_DIR (0x1<<4)
#define mskEP6_DIR (0x1<<5)
#define mskDIS_PDEN (0x1<<26)
#define mskESD_EN (0x1<<27)
#define mskSIE_EN (0x1<<28)
@ -108,8 +99,8 @@
/* Rx & Tx Packet Length Definitions */
#define PKT_LNGTH_MASK 0x000003FF
/* nUsb_Status Register Definitions */
/* nUsb_Status Register Definitions */
#define mskBUSRESET (0x1<<0)
#define mskBUSSUSPEND (0x1<<1)
#define mskBUSRESUME (0x1<<2)
@ -130,82 +121,6 @@
#define mskINITREPEAT (0x1<<17)
#define mskREMOTE_WAKEUP_ACT (0x1<<18)
//ISP KERNEL MODE
#define RETURN_KERNEL_0 0x5AA555AA
#define RETURN_KERNEL_1 0xCC3300FF
/*********Marco function***************/
//USB device address set
#define __USB_SETADDRESS(addr) (SN_USB->ADDR = addr)
//USB INT status register clear
#define __USB_CLRINSTS(Clrflag) (SN_USB->INSTSC = Clrflag)
//USB EP0_IN token set STALL
#define __USB_EP0INSTALL_EN (SN_USB->EP0CTL |= mskEP0_IN_STALL_EN)
//USB EP0_OUT token set STALL
#define __USB_EP0OUTSTALL_EN (SN_USB->EP0CTL |= mskEP0_OUT_STALL_EN)
//USB bus driver J state
#define __USB_JSTATE_DRIVER (SN_USB->SGCTL = (mskBUS_DRVEN|mskBUS_J_STATE))
//USB bus driver K state
#define __USB_KSTATE_DRIVER (SN_USB->SGCTL = (mskBUS_DRVEN|mskBUS_K_STATE))
//USB PHY set enable
#define __USB_PHY_ENABLE (SN_USB->CFG |= (mskESD_EN|mskPHY_EN))
//USB PHY set Disable
#define __USB_PHY_DISABLE (SN_USB->CFG &= ~(mskESD_EN|mskPHY_EN))
/***************************************/
/* TODO: orgaize better since this is MCU dependent:
* 240b has 1+4 EPs/256 Bytes USB SRAM
* 240 has 1+6 EPs/512 Bytes USB SRAM
* 260 has 1+4 EPs/256 Bytes USB SRAM
* */
// USB EPn Buffer Offset Register
#define EP1_BUFFER_OFFSET_VALUE 0x40
#define EP2_BUFFER_OFFSET_VALUE 0x80
#define EP3_BUFFER_OFFSET_VALUE 0xC0
#define EP4_BUFFER_OFFSET_VALUE 0xE0
/* USB Endpoint Max Packet Size */
#define USB_EP0_PACKET_SIZE 64 // only 8, 64
#define USB_EP1_PACKET_SIZE 0x40
#define USB_EP2_PACKET_SIZE 0x40
#define USB_EP3_PACKET_SIZE 0x20
#define USB_EP4_PACKET_SIZE 0x20
/* USB Endpoint Direction */
#define USB_DIRECTION_OUT 0
#define USB_DIRECTION_IN 1
/* USB Endpoint Address */
#define USB_EP0 0x0
#define USB_EP1 0x1
#define USB_EP2 0x2
#define USB_EP3 0x3
#define USB_EP4 0x4
extern const uint32_t wUSB_EPnOffset[];
extern const uint32_t wUSB_EPnMaxPacketSize[];
/* USB Hardware Functions */
extern void USB_Init(void);
extern void USB_ClrEPnToggle(uint32_t wEPNum);
extern void USB_EPnDisable(uint32_t wEPNum);
extern void USB_EPnNak(uint32_t wEPNum);
extern void USB_EPnAck(uint32_t wEPNum, uint8_t bBytecnt);
extern void USB_EPnStall(uint32_t wEPNum);
extern _Bool USB_EPnEnabled(uint32_t wEPNum);
extern _Bool USB_EPnStalled(uint32_t wEPNum);
extern void USB_RemoteWakeUp(void);
extern void USB_DelayJstate(void);
extern void USB_DelayKstate(void);
extern void USB_EPnBufferOffset(uint32_t wEPNum, uint32_t wAddr);
/* USB IRQ Functions*/
extern void USB_ReturntoNormal(void);
extern void USB_ResetEvent(void);
extern void USB_WakeupEvent(void);
extern void USB_SuspendEvent(void);
#endif /* __USBHW_H__ */