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; dtr << true;
} }
/********************************************************************* cdc_class::cdc_class() noexcept : BaseLayer(), dtr (GPIOA, 0), TxRing(), Ready(false) {
* @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) {
pInstance = this; pInstance = this;
USBFS_DevConfig = 0; USBFS_DevConfig = 0;
USBFS_DevAddr = 0; USBFS_DevAddr = 0;
@ -186,7 +114,7 @@ void cdc_class::init() {
delay_init(); delay_init();
USBFS_RCC_Init( ); USBFS_RCC_Init( );
USBFS_Device_Init( true ); USBFS_Device_Init( true );
while (!USBFS_DevEnumStatus); while (!USBFS_DevEnumStatus) delay_us(10'000);
} }
__always_inline void cdc_class::InTokenHandler(const uint8_t intst) { __always_inline void cdc_class::InTokenHandler(const uint8_t intst) {
switch ( intst & ( USBFS_UIS_TOKEN_MASK | USBFS_UIS_ENDP_MASK ) ) { switch ( intst & ( USBFS_UIS_TOKEN_MASK | USBFS_UIS_ENDP_MASK ) ) {
@ -657,22 +585,24 @@ void cdc_class::cdc_irq() {
} }
} }
void cdc_class::TxDataDeal() { 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 */ if (USBFS_Endp_Busy [DEF_UEP3]) return;
} uint32_t n;
/* Pozor - funkce je blokující, lze použít jen v hlavní smyčce programu, ne v přerušení */ char * ptr = reinterpret_cast<char*>(USBFS_EP3_Buf);
uint32_t cdc_class::Down (const char * data, const uint32_t len) { for (n=0u; n<DEF_USBD_ENDP3_SIZE; n++) {
if ((!Ready) or (!USBFS_DevEnumStatus)) return 0; if (!TxRing.Read (ptr [n])) break;
uint32_t rem = len; }
const uint32_t max = DEF_USBD_ENDP3_SIZE; USBFSD->UEP3_TX_LEN = n;
const uint8_t * ptr = reinterpret_cast<const uint8_t*> (data); if (n) {
while (rem) { USBFS_Endp_Busy [DEF_UEP3] = 1u;
const uint32_t chunk = rem > max ? max : rem; USBFSD->UEP3_TX_CTRL = (USBFSD->UEP3_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
if (USBFS_Endp_DataUp (DEF_UEP3, ptr, chunk, DEF_UEP_CPY_LOAD)) { } else {
delay_us(10); // čekej dokud je USBFS_Endp_Busy USBFSD->UEP3_TX_CTRL = (USBFSD->UEP3_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_NAK;
} else {
ptr += chunk;
rem -= chunk;
}
} }
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 #define CDC_CLASS_H
#include "baselayer.h" #include "baselayer.h"
#include "gpio.h" #include "gpio.h"
#include "fifo.h"
#include "system.h" #include "system.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -12,10 +13,6 @@ extern "C" {
/******************************************************************************/ /******************************************************************************/
/* Global Define */ /* Global Define */
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
/* end-point number */ /* end-point number */
#define DEF_UEP_IN 0x80 #define DEF_UEP_IN 0x80
#define DEF_UEP_OUT 0x00 #define DEF_UEP_OUT 0x00
@ -53,12 +50,12 @@ extern "C" {
/** @class cdc_class /** @class cdc_class
* V postatě je to převzato z originálního balíku od wch.nc, ale ten * 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í * 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 * přidáno odhadem.
* po USB, je potřeba to odladit. Nicméně se to enumeruje a pro výpisy je to celkem použitelné.
*/ */
class cdc_class : public BaseLayer { class cdc_class : public BaseLayer {
GpioClass dtr; GpioClass dtr;
bool Ready; FIFO<char, 128> TxRing;
bool Ready;
const uint8_t * pUSBFS_Descr; const uint8_t * pUSBFS_Descr;
/* Setup Request */ /* Setup Request */
volatile uint8_t USBFS_SetupReqCode; volatile uint8_t USBFS_SetupReqCode;
@ -82,12 +79,12 @@ class cdc_class : public BaseLayer {
explicit cdc_class () noexcept; explicit cdc_class () noexcept;
void init (); void init ();
void cdc_irq (); 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; uint32_t Down(const char * data, const uint32_t len) override;
protected: protected:
void USBFS_Device_Init( bool sta ); void USBFS_Device_Init( bool sta );
void USBFS_Device_Endp_Init (); 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 TxDataDeal ();
void TransferHandler (); void TransferHandler ();
void InTokenHandler (const uint8_t intst); void InTokenHandler (const uint8_t intst);
void OutTokenHandler (const uint8_t intst); void OutTokenHandler (const uint8_t intst);