mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
Expand cdc-acm with additional feature methods
This commit is contained in:
parent
da03f22741
commit
32e2932c2c
3 changed files with 72 additions and 13 deletions
14
cdcacm.cpp
14
cdcacm.cpp
|
@ -30,21 +30,20 @@ bNumEP(1),
|
||||||
qNextPollTime(0),
|
qNextPollTime(0),
|
||||||
bPollEnable(false),
|
bPollEnable(false),
|
||||||
ready(false) {
|
ready(false) {
|
||||||
|
_enhanced_status = enhanced_features(); // Set up features
|
||||||
for(uint8_t i = 0; i < ACM_MAX_ENDPOINTS; i++) {
|
for(uint8_t i = 0; i < ACM_MAX_ENDPOINTS; i++) {
|
||||||
epInfo[i].epAddr = 0;
|
epInfo[i].epAddr = 0;
|
||||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||||
epInfo[i].epAttribs = 0;
|
epInfo[i].epAttribs = 0;
|
||||||
//epInfo[i].bmNakPower = USB_NAK_NOWAIT;
|
epInfo[i].bmNakPower = (i == epDataInIndex) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
|
||||||
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
|
||||||
|
|
||||||
//if (!i)
|
|
||||||
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
|
||||||
}
|
}
|
||||||
if(pUsb)
|
if(pUsb)
|
||||||
pUsb->RegisterDeviceClass(this);
|
pUsb->RegisterDeviceClass(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);
|
const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);
|
||||||
|
|
||||||
uint8_t buf[constBufSize];
|
uint8_t buf[constBufSize];
|
||||||
|
@ -170,6 +169,13 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
if(rcode)
|
if(rcode)
|
||||||
goto FailSetConfDescr;
|
goto FailSetConfDescr;
|
||||||
|
|
||||||
|
// Set up features status
|
||||||
|
_enhanced_status = enhanced_features();
|
||||||
|
half_duplex(false);
|
||||||
|
autoflowRTS(false);
|
||||||
|
autoflowDSR(false);
|
||||||
|
autoflowXON(false);
|
||||||
|
wide(false); // Always false, because this is only available in custom mode.
|
||||||
rcode = pAsync->OnInit(this);
|
rcode = pAsync->OnInit(this);
|
||||||
|
|
||||||
if(rcode)
|
if(rcode)
|
||||||
|
|
64
cdcacm.h
64
cdcacm.h
|
@ -129,11 +129,34 @@ class CDCAsyncOper {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual uint8_t OnInit(ACM *pacm) {
|
virtual uint8_t OnInit(ACM *pacm) {
|
||||||
|
return 0;
|
||||||
};
|
};
|
||||||
//virtual void OnDataRcvd(ACM *pacm, uint8_t nbytes, uint8_t *dataptr) = 0;
|
//virtual void OnDataRcvd(ACM *pacm, uint8_t nbytes, uint8_t *dataptr) = 0;
|
||||||
//virtual void OnDisconnected(ACM *pacm) = 0;
|
//virtual void OnDisconnected(ACM *pacm) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This structure is used to report the extended capabilities of the connected device.
|
||||||
|
* It is also used to report the current status.
|
||||||
|
* Regular CDC-ACM reports all as false.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
union {
|
||||||
|
uint8_t tty;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool enhanced : 1; // Do we have the ability to set/clear any features?
|
||||||
|
// Status and 8th bit in data stream.
|
||||||
|
// Presence only indicates feature is available, but this isn't used for CDC-ACM.
|
||||||
|
bool wide : 1;
|
||||||
|
bool autoflow_RTS : 1; // Has autoflow on RTS/CTS
|
||||||
|
bool autoflow_DSR : 1; // Has autoflow on DTR/DSR
|
||||||
|
bool autoflow_XON : 1; // Has autoflow XON/XOFF
|
||||||
|
bool half_duplex : 1; // Has half-duplex capability.
|
||||||
|
} __attribute__((packed));
|
||||||
|
};
|
||||||
|
} tty_features;
|
||||||
|
|
||||||
#define ACM_MAX_ENDPOINTS 4
|
#define ACM_MAX_ENDPOINTS 4
|
||||||
|
|
||||||
|
@ -151,8 +174,9 @@ protected:
|
||||||
uint8_t bDataIface; // Data interface value
|
uint8_t bDataIface; // Data interface value
|
||||||
uint8_t bNumEP; // total number of EP in the configuration
|
uint8_t bNumEP; // total number of EP in the configuration
|
||||||
uint32_t qNextPollTime; // next poll time
|
uint32_t qNextPollTime; // next poll time
|
||||||
bool bPollEnable; // poll enable flag
|
volatile bool bPollEnable; // poll enable flag
|
||||||
bool ready; //device ready indicator
|
volatile bool ready; //device ready indicator
|
||||||
|
tty_features _enhanced_status; // current status
|
||||||
|
|
||||||
EpInfo epInfo[ACM_MAX_ENDPOINTS];
|
EpInfo epInfo[ACM_MAX_ENDPOINTS];
|
||||||
|
|
||||||
|
@ -170,7 +194,7 @@ public:
|
||||||
uint8_t SendBreak(uint16_t duration);
|
uint8_t SendBreak(uint16_t duration);
|
||||||
uint8_t GetNotif(uint16_t *bytes_rcvd, uint8_t *dataptr);
|
uint8_t GetNotif(uint16_t *bytes_rcvd, uint8_t *dataptr);
|
||||||
|
|
||||||
// Methods for recieving and sending data
|
// Methods for receiving and sending data
|
||||||
uint8_t RcvData(uint16_t *nbytesptr, uint8_t *dataptr);
|
uint8_t RcvData(uint16_t *nbytesptr, uint8_t *dataptr);
|
||||||
uint8_t SndData(uint16_t nbytes, uint8_t *dataptr);
|
uint8_t SndData(uint16_t nbytes, uint8_t *dataptr);
|
||||||
|
|
||||||
|
@ -179,6 +203,10 @@ public:
|
||||||
uint8_t Release();
|
uint8_t Release();
|
||||||
uint8_t Poll();
|
uint8_t Poll();
|
||||||
|
|
||||||
|
bool available(void) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
virtual uint8_t GetAddress() {
|
virtual uint8_t GetAddress() {
|
||||||
return bAddress;
|
return bAddress;
|
||||||
};
|
};
|
||||||
|
@ -187,6 +215,36 @@ public:
|
||||||
return ready;
|
return ready;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
virtual tty_features enhanced_status(void) {
|
||||||
|
return _enhanced_status;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual tty_features enhanced_features(void) {
|
||||||
|
tty_features rv;
|
||||||
|
rv.enhanced = false;
|
||||||
|
rv.autoflow_RTS = false;
|
||||||
|
rv.autoflow_DSR = false;
|
||||||
|
rv.autoflow_XON = false;
|
||||||
|
rv.half_duplex = false;
|
||||||
|
rv.wide = false;
|
||||||
|
return rv;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void autoflowRTS(bool s) {
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void autoflowDSR(bool s) {
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void autoflowXON(bool s) {
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void half_duplex(bool s) {
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void wide(bool s) {
|
||||||
|
};
|
||||||
|
|
||||||
// UsbConfigXtracter implementation
|
// UsbConfigXtracter implementation
|
||||||
void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
|
void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,9 +30,7 @@ wFTDIType(0) {
|
||||||
epInfo[i].epAddr = 0;
|
epInfo[i].epAddr = 0;
|
||||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||||
epInfo[i].epAttribs = 0;
|
epInfo[i].epAttribs = 0;
|
||||||
|
epInfo[i].bmNakPower = (i==epDataInIndex) ? USB_NAK_NOWAIT: USB_NAK_MAX_POWER;
|
||||||
//if (!i)
|
|
||||||
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
|
|
||||||
}
|
}
|
||||||
if(pUsb)
|
if(pUsb)
|
||||||
pUsb->RegisterDeviceClass(this);
|
pUsb->RegisterDeviceClass(this);
|
||||||
|
@ -46,11 +44,8 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
uint8_t rcode;
|
uint8_t rcode;
|
||||||
UsbDevice *p = NULL;
|
UsbDevice *p = NULL;
|
||||||
EpInfo *oldep_ptr = NULL;
|
EpInfo *oldep_ptr = NULL;
|
||||||
//uint8_t len = 0;
|
|
||||||
//uint16_t cd_len = 0;
|
|
||||||
|
|
||||||
uint8_t num_of_conf; // number of configurations
|
uint8_t num_of_conf; // number of configurations
|
||||||
//uint8_t num_of_intf; // number of interfaces
|
|
||||||
|
|
||||||
AddressPool &addrPool = pUsb->GetAddressPool();
|
AddressPool &addrPool = pUsb->GetAddressPool();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue