Вс сен 17, 2017 19:45:13
void USB_OTG_BSP_uDelay (const uint32_t usec)
{
__IO uint32_t count = 0;
const uint32_t utime = (120 * usec / 7);
do
{
if ( ++count > utime )
{
return ;
}
}
while (1);
}
Пн сен 18, 2017 06:22:18
Пн июл 27, 2020 15:15:04
RCC->AHBENR|=RCC_AHBENR_OTGFSEN;
OTG_FS_GENERAL->AHBCFG|=
OTG_FS_GENERAL_AHBCFG_GINT |
OTG_FS_GENERAL_AHBCFG_PTXFELVL |
OTG_FS_GENERAL_AHBCFG_TXFELVL |
0;
OTG_FS_GENERAL->USBCFG=
OTG_FS_GENERAL_USBCFG_FDMOD | //Force device mode
//OTG_FS_GENERAL_USBCFG_HNPCAP |
//OTG_FS_GENERAL_USBCFG_SRPCAP |
(5<<OTG_FS_GENERAL_USBCFG_TRDT_POS) | //какое то время
(5<<OTG_FS_GENERAL_USBCFG_TOCAL_POS) |
0;
OTG_FS_DEVICE->CFG=
OTG_FS_DEVICE_CFG_DSPD | //48МГц
//OTG_FS_DEVICE_CFG_NZLSOHSK | //
0;
OTG_FS_GENERAL->INTSTS=0xFFFFFFFF;
OTG_FS_GENERAL->INTMSK =
OTG_FS_GENERAL_INTMSK_USBRSTM | //– USB reset
//OTG_FS_GENERAL_INTMSK_ENUMDNEM | //Enumeration done
//OTG_FS_GENERAL_INTMSK_USBSUSPM | //USB suspend
//OTG_FS_GENERAL_INTMSK_SOFM |
//OTG_FS_GENERAL_INTMSK_RXFLVLM | //буфер приема не пустой
//OTG_FS_GENERAL_INTMSK_OEPM | //прерывание от OUT EP
0;
//включаем подтягивающий резистор DP вернее сенсор VbusB
OTG_FS_GENERAL->CCFG|=
OTG_FS_GENERAL_CCFG_VBUSBSEN |
0;
NVIC_SetPriority(OTG_FS_IRQn,15);
NVIC_EnableIRQ(OTG_FS_IRQn);
void USB_Reset(void)
{
//очистка FIFO
OTG_FS_GENERAL->RSTCTL=OTG_FS_GENERAL_RSTCTL_TXFFLSH | OTG_FS_GENERAL_RSTCTL_TXFNUM ;
while (OTG_FS_GENERAL->RSTCTL & OTG_FS_GENERAL_RSTCTL_TXFFLSH);
OTG_FS_GENERAL->RSTCTL=OTG_FS_GENERAL_RSTCTL_RXFFLSH;
while (OTG_FS_GENERAL->RSTCTL & OTG_FS_GENERAL_RSTCTL_RXFFLSH);
//----------
/*1. Set the NAK bit for all OUT endpoints
– SNAK = 1 in OTG_FS_DOEPCTLx (for all OUT endpoints)
*/
//OTG_FS_DEVICE->OUTEP[0].CTL=OTG_FS_DEVICE_ENDPOINT_CTL_SNAK;
OTG_FS_DEVICE->OUTEP[0].CTL=OTG_FS_DEVICE_ENDPOINT_CTL_CNAK;
OTG_FS_DEVICE->OUTEP[1].CTL=OTG_FS_DEVICE_ENDPOINT_CTL_SNAK;
OTG_FS_DEVICE->OUTEP[2].CTL=OTG_FS_DEVICE_ENDPOINT_CTL_SNAK;
OTG_FS_DEVICE->OUTEP[3].CTL=OTG_FS_DEVICE_ENDPOINT_CTL_SNAK;
//----------
/*
2. Unmask the following interrupt bits
– INEP0 = 1 in OTG_FS_DAINTMSK (control 0 IN endpoint)
– OUTEP0 = 1 in OTG_FS_DAINTMSK (control 0 OUT endpoint)
– STUP = 1 in DOEPMSK
– XFRC = 1 in DOEPMSK
– XFRC = 1 in DIEPMSK
– TOC = 1 in DIEPMSK
*/
OTG_FS_DEVICE->AINTMSK =
OTG_FS_DEVICE_AINTMSK_IEPINTM_0 |
OTG_FS_DEVICE_AINTMSK_OEPINTM_0 |
0;
OTG_FS_DEVICE->OEPMSK =
OTG_FS_DEVICE_OEPMSK_STUPM | //SETUP phase done mask
OTG_FS_DEVICE_OEPMSK_XFRCM | //XFRCM: Transfer completed interrupt mask
0;
OTG_FS_DEVICE->IEPMSK =
OTG_FS_DEVICE_IEPMSK_TOCM | //Timeout condition mask (Non-isochronous endpoints)
OTG_FS_DEVICE_IEPMSK_XFRCM | //XFRCM: Transfer completed interrupt mask
0;
//----------
/*
3. Set up the Data FIFO RAM for each of the FIFOs
– Program the OTG_FS_GRXFSIZ register, to be able to receive control OUT data
and setup data. If thresholding is not enabled, at a minimum, this must be equal to
1 max packet size of control endpoint 0 + 2 words (for the status of the control
OUT data packet) + 10 words (for setup packets).
– Program the OTG_FS_TX0FSIZ register (depending on the FIFO number chosen)
to be able to transmit control IN data. At a minimum, this must be equal to 1 max
packet size of control endpoint 0.
*/
OTG_FS_GENERAL->RXFSIZ = RX_FIFO_SIZE;//размер буфера для приема
OTG_FS_GENERAL->TX0FSIZ = (TX_EP0_FIFO_SIZE<<16) | RX_FIFO_SIZE;//размер буфера и адрес для передачи точки 0
//----------
/*
4. Program the following fields in the endpoint-specific registers for control OUT endpoint
0 to receive a SETUP packet
– STUPCNT = 3 in OTG_FS_DOEPTSIZ0 (to receive up to 3 back-to-back SETUP
packets)
*/
OTG_FS_DEVICE->OUTEP[0].TSIZ =
OTG_FS_DEVICE_ENDPOINT_TSIZ_STUPCNT_OUT0 |
OTG_FS_DEVICE_ENDPOINT_TSIZ_PKTCNT_OUT0 |
OTG_FS_DEVICE_ENDPOINT_TSIZ_XFRSIZ_OUT0 |
0;
OTG_FS_DEVICE->OUTEP[0].CTL=
//OTG_FS_DEVICE_ENDPOINT_CTL_EPENA | //включить точку
OTG_FS_DEVICE_ENDPOINT_CTL_CNAK | //сбросить NAK
0;
OTG_FS_DEVICE->OUTEP[0].CTL=OTG_FS_DEVICE_ENDPOINT_CTL_EPENA ; //включить точку
//----------
OTG_FS_GENERAL->INTMSK|=
//OTG_FS_GENERAL_INTMSK_USBRSTM | //– USB reset
OTG_FS_GENERAL_INTMSK_ENUMDNEM | //Enumeration done
//OTG_FS_GENERAL_INTMSK_USBSUSPM | //USB suspend
OTG_FS_GENERAL_INTMSK_SOFM |
OTG_FS_GENERAL_INTMSK_RXFLVLM | //буфер приема не пустой
OTG_FS_GENERAL_INTMSK_OEPM | //прерывание от OUT EP
0;
//----------
OTG_FS_DEVICE->OUTEP[0].CTL|=
OTG_FS_DEVICE_ENDPOINT_CTL_CNAK | //сбросить NAK
0;
};
Пн июл 27, 2020 15:21:16
Пн июл 27, 2020 15:37:00
Пн июл 27, 2020 16:20:20
static inline void Init()
{
otg_device()->DCTL = USB_OTG_DCTL_SDIS; //Отключиться от линии
otg_global()->GAHBCFG = USB_OTG_GAHBCFG_GINT;
otg_global()->GUSBCFG = USB_OTG_GUSBCFG_FDMOD | _VAL2FLD(USB_OTG_GUSBCFG_TRDT,6) | USB_OTG_GUSBCFG_PHYSEL;
otg_global()->GINTMSK = USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTSTS_RXFLVL;
otg_global()->GCCFG = USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_VBUSBSEN;
*otg_pcgcctl() = 0;
//Задать конфигурацию FIFO
otg_global()->GRXFSIZ = RX_FIFO_SIZE>>2;
otg_global()->DIEPTXF0_HNPTXFSIZ = ((TX_EP0_FIFO_SIZE<<14)&0xFFFF0000) | RX_FIFO_SIZE;
otg_global()->DIEPTXF[0] = ((TX_EP1_FIFO_SIZE<<14)&0xFFFF0000) | (RX_FIFO_SIZE+TX_EP0_FIFO_SIZE);
otg_global()->DIEPTXF[1] = ((TX_EP2_FIFO_SIZE<<14)&0xFFFF0000) | (RX_FIFO_SIZE+TX_EP0_FIFO_SIZE+TX_EP1_FIFO_SIZE);
otg_global()->DIEPTXF[2] = ((TX_EP3_FIFO_SIZE<<14)&0xFFFF0000) | (RX_FIFO_SIZE+TX_EP0_FIFO_SIZE+TX_EP1_FIFO_SIZE+TX_EP2_FIFO_SIZE);
otg_outep<0>()->DOEPTSIZ = _VAL2FLD(USB_OTG_DOEPTSIZ_STUPCNT,3) | _VAL2FLD(USB_OTG_DOEPTSIZ_PKTCNT,1) | _VAL2FLD(USB_OTG_DOEPTSIZ_XFRSIZ,64);
//Разрешить прерывания от USB
if (PUSB_BASE == USB_OTG_FS_PERIPH_BASE) NVIC_EnableIRQ(OTG_FS_IRQn);
#ifdef USB_OTG_HS_PERIPH_BASE
if (PUSB_BASE == USB_OTG_HS_PERIPH_BASE) NVIC_EnableIRQ(OTG_HS_IRQn);
#endif
otg_device()->DCTL &= ~USB_OTG_DCTL_SDIS; // Подключиться
}
static inline void Enumerate_Reset() // Обработчик прерывания RESET
{
//Разрешить прерывания для EP0 и EP1
otg_device()->DAINTMSK = _VAL2FLD(USB_OTG_DAINTMSK_IEPM,3) | _VAL2FLD(USB_OTG_DAINTMSK_OEPM,3);
otg_device()->DOEPMSK = USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM;
otg_device()->DIEPMSK = USB_OTG_DIEPMSK_XFRCM;
//Сбросить все TXFIFO
otg_global()->GRSTCTL = USB_OTG_GRSTCTL_TXFFLSH | USB_OTG_GRSTCTL_TXFNUM_ALL;
while (otg_global()->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH);
//Сбросить RXFIFO
otg_global()->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
while (otg_global()->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH);
//До энумерации адррес = 0
otg_device()->DCFG = _VAL2FLD(USB_OTG_DCFG_DAD,0) | USB_OTG_DCFG_DSPD_FSPEED;
}
Пн июл 27, 2020 18:57:58
Пн авг 24, 2020 19:37:23
Пн авг 24, 2020 21:36:35
Пн авг 24, 2020 21:52:15
Пн авг 24, 2020 22:38:03
Тут картинка интуитивно понятная.Kellya писал(а): Или я плохо разобрался с адресацией PMA
Пн авг 24, 2020 22:49:32
Тут картинка интуитивно понятная.Kellya писал(а): Или я плохо разобрался с адресацией PMA
Пн авг 24, 2020 23:02:27
Возможно тут вопрос к коду для УАРТ.Kellya писал(а): то по uart мне приходит уже не 4 байта, как раньше, а почему-то только 3
Пн авг 24, 2020 23:09:13
Пн авг 24, 2020 23:19:18
Возможно тут вопрос к коду для УАРТ.Kellya писал(а): то по uart мне приходит уже не 4 байта, как раньше, а почему-то только 3
Пн авг 24, 2020 23:20:25
Пн авг 24, 2020 23:28:59
Пн авг 24, 2020 23:49:44
Вт авг 25, 2020 00:03:09
Вт авг 25, 2020 09:35:11
template<uint32_t EPNum>
static inline void WriteEP(uint8_t *pData, uint32_t cnt)
{
if constexpr (EPNum==0)
{ // Очередь отправки только в EP0
if(cnt>=64)
{
WritePAM_TX<0>(pData, 64);
ep_tx_q_adr=pData+64;
//Размер очереди делаем на 1 больше, чтобы отправить ZLP в случае кратности 64
ep_tx_q_cnt=cnt-63;
}
else
WritePAM_TX<0>(pData, cnt);
}
else
WritePAM_TX<EPNum>(pData, cnt);
EPSetStatus<EPNum>(EP_TX_STAT::VALID);
}
template <uint32_t EPNum>
static inline void WritePAM_TX(uint8_t *pSrcData, const uint32_t cnt)
{
volatile PMA_WIDTH *pv = (PMA_WIDTH *) ep_tx_buf_adr[EPNum];
for(uint32_t n = 0; n < (cnt + 1) / 2; n++, pSrcData += 2)
{
if constexpr (sizeof(PMA_WIDTH)==2)
*pv++ = *(pSrcData) + ((*(pSrcData+1))<<8);
else
*pv++ = *((uint16_t *)pSrcData);
}
ep_buf_dscr[EPNum].COUNT_TX = cnt;
}
template<uint32_t EPNum>
static inline void EPSetStatus(EP_TX_STAT tx_stat)
{
*EPnR<EPNum>() = (*EPnR<EPNum>() ^ uint32_t(tx_stat)) & (USB_EPREG_MASK | USB_EPTX_STAT);
}
template<uint32_t EPNum>
static inline constexpr auto EPnR()
{
return (volatile uint32_t *)(USB_BASE + 4*EPNum);
}