change Down unblocked

This commit is contained in:
Kizarm 2024-10-12 15:33:16 +02:00
parent 7905132333
commit 360871f7fb
2 changed files with 27 additions and 100 deletions

View file

@ -103,79 +103,7 @@ void cdc_class::USBFS_Device_Init( bool sta ) {
dtr << true;
}
/*********************************************************************
* @fn USBFS_Endp_DataUp
*
* @brief USBFS device data upload
*
* @return none
*/
uint8_t cdc_class::USBFS_Endp_DataUp(uint8_t endp, const uint8_t * pbuf, uint16_t len, uint8_t mod) {
uint8_t endp_mode;
uint8_t buf_load_offset;
/* DMA config, endp_ctrl config, endp_len config */
if( (endp>=DEF_UEP1) && (endp<=DEF_UEP7) ) {
if( USBFS_Endp_Busy[ endp ] == 0 ) {
if( (endp == DEF_UEP1) || (endp == DEF_UEP4) ) {
/* endp1/endp4 */
endp_mode = USBFSD_UEP_MOD(0);
if( endp == DEF_UEP1 ) {
endp_mode = (uint8_t)(endp_mode>>4);
}
} else if( (endp == DEF_UEP2) || (endp == DEF_UEP3) ) {
/* endp2/endp3 */
endp_mode = USBFSD_UEP_MOD(1);
if( endp == DEF_UEP3 ) {
endp_mode = (uint8_t)(endp_mode>>4);
}
} else if( (endp == DEF_UEP5) || (endp == DEF_UEP6) ) {
/* endp5/endp6 */
endp_mode = USBFSD_UEP_MOD(2);
if( endp == DEF_UEP6 ) {
endp_mode = (uint8_t)(endp_mode>>4);
}
} else {
/* endp7 */
endp_mode = USBFSD_UEP_MOD(3);
}
if( endp_mode & USBFSD_UEP_TX_EN ) {
if( endp_mode & USBFSD_UEP_RX_EN ) {
buf_load_offset = 64;
} else {
buf_load_offset = 0;
}
if( buf_load_offset == 0 ) {
if( mod == DEF_UEP_DMA_LOAD ) {
/* DMA mode */
USBFSD_UEP_DMA(endp) = (uint16_t)(size_t)pbuf;
} else {
/* copy mode */
memcpy( USBFSD_UEP_BUF(endp), pbuf, len );
}
} else {
memcpy( USBFSD_UEP_BUF(endp)+buf_load_offset, pbuf, len );
}
/* Set end-point busy */
USBFS_Endp_Busy[ endp ] = 0x01;
/* tx length */
USBFSD_UEP_TLEN(endp) = len;
/* response ack */
USBFSD_UEP_CTRL(endp) = (USBFSD_UEP_CTRL(endp) & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
}
} else {
return 1;
}
} else {
return 1;
}
return 0;
}
cdc_class::cdc_class() noexcept : BaseLayer(), dtr (GPIOA, 0), Ready(false) {
cdc_class::cdc_class() noexcept : BaseLayer(), dtr (GPIOA, 0), TxRing(), Ready(false) {
pInstance = this;
USBFS_DevConfig = 0;
USBFS_DevAddr = 0;
@ -186,7 +114,7 @@ void cdc_class::init() {
delay_init();
USBFS_RCC_Init( );
USBFS_Device_Init( true );
while (!USBFS_DevEnumStatus);
while (!USBFS_DevEnumStatus) delay_us(10'000);
}
__always_inline void cdc_class::InTokenHandler(const uint8_t intst) {
switch ( intst & ( USBFS_UIS_TOKEN_MASK | USBFS_UIS_ENDP_MASK ) ) {
@ -657,22 +585,24 @@ void cdc_class::cdc_irq() {
}
}
void cdc_class::TxDataDeal() {
/* Asi by to mělo fungovat nějak přes frontu, ale zatím nevím jak to nastartovat, nepoužito */
}
/* Pozor - funkce je blokující, lze použít jen v hlavní smyčce programu, ne v přerušení */
uint32_t cdc_class::Down (const char * data, const uint32_t len) {
if ((!Ready) or (!USBFS_DevEnumStatus)) return 0;
uint32_t rem = len;
const uint32_t max = DEF_USBD_ENDP3_SIZE;
const uint8_t * ptr = reinterpret_cast<const uint8_t*> (data);
while (rem) {
const uint32_t chunk = rem > max ? max : rem;
if (USBFS_Endp_DataUp (DEF_UEP3, ptr, chunk, DEF_UEP_CPY_LOAD)) {
delay_us(10); // čekej dokud je USBFS_Endp_Busy
if (USBFS_Endp_Busy [DEF_UEP3]) return;
uint32_t n;
char * ptr = reinterpret_cast<char*>(USBFS_EP3_Buf);
for (n=0u; n<DEF_USBD_ENDP3_SIZE; n++) {
if (!TxRing.Read (ptr [n])) break;
}
USBFSD->UEP3_TX_LEN = n;
if (n) {
USBFS_Endp_Busy [DEF_UEP3] = 1u;
USBFSD->UEP3_TX_CTRL = (USBFSD->UEP3_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
} else {
ptr += chunk;
rem -= chunk;
USBFSD->UEP3_TX_CTRL = (USBFSD->UEP3_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_NAK;
}
}
return len;
}
uint32_t cdc_class::Down (const char * data, const uint32_t len) {
if (!Ready) return 0; /* DTR is clear */
uint32_t n;
for (n=0u; n<len; n++) { if (!TxRing.Write(data [n])) break; }
if (n) TxDataDeal();
return n;
}

View file

@ -2,6 +2,7 @@
#define CDC_CLASS_H
#include "baselayer.h"
#include "gpio.h"
#include "fifo.h"
#include "system.h"
#ifdef __cplusplus
extern "C" {
@ -12,10 +13,6 @@ extern "C" {
/******************************************************************************/
/* Global Define */
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
/* end-point number */
#define DEF_UEP_IN 0x80
#define DEF_UEP_OUT 0x00
@ -53,11 +50,11 @@ extern "C" {
/** @class cdc_class
* V postatě je to převzato z originálního balíku od wch.nc, ale ten
* je napsán dost "špagetově", interface je nesrozumitelné, takže je tam dost věcí
* přidáno odhadem. Zatím je to dost surové, musí tam být čekání pro odvysílání paketu
* po USB, je potřeba to odladit. Nicméně se to enumeruje a pro výpisy je to celkem použitelné.
* přidáno odhadem.
*/
class cdc_class : public BaseLayer {
GpioClass dtr;
FIFO<char, 128> TxRing;
bool Ready;
const uint8_t * pUSBFS_Descr;
/* Setup Request */
@ -82,11 +79,11 @@ class cdc_class : public BaseLayer {
explicit cdc_class () noexcept;
void init ();
void cdc_irq ();
/// Předěláno na neblokující, data se vyměňují přes FIFO, rychlejší
uint32_t Down(const char * data, const uint32_t len) override;
protected:
void USBFS_Device_Init( bool sta );
void USBFS_Device_Endp_Init ();
uint8_t USBFS_Endp_DataUp(uint8_t endp, const uint8_t *pbuf, uint16_t len, uint8_t mod);
void TxDataDeal ();
void TransferHandler ();
void InTokenHandler (const uint8_t intst);