Expand cdc-acm with additional feature methods

This commit is contained in:
Andrew J. Kroll 2015-03-18 05:36:55 -04:00
parent da03f22741
commit 32e2932c2c
3 changed files with 72 additions and 13 deletions

View file

@ -30,21 +30,20 @@ bNumEP(1),
qNextPollTime(0),
bPollEnable(false),
ready(false) {
_enhanced_status = enhanced_features(); // Set up features
for(uint8_t i = 0; i < ACM_MAX_ENDPOINTS; i++) {
epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
//epInfo[i].bmNakPower = USB_NAK_NOWAIT;
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
epInfo[i].bmNakPower = (i == epDataInIndex) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
//if (!i)
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
}
if(pUsb)
pUsb->RegisterDeviceClass(this);
}
uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);
uint8_t buf[constBufSize];
@ -170,6 +169,13 @@ uint8_t ACM::Init(uint8_t parent, uint8_t port, bool lowspeed) {
if(rcode)
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);
if(rcode)

View file

@ -129,11 +129,34 @@ class CDCAsyncOper {
public:
virtual uint8_t OnInit(ACM *pacm) {
return 0;
};
//virtual void OnDataRcvd(ACM *pacm, uint8_t nbytes, uint8_t *dataptr) = 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
@ -151,8 +174,9 @@ protected:
uint8_t bDataIface; // Data interface value
uint8_t bNumEP; // total number of EP in the configuration
uint32_t qNextPollTime; // next poll time
bool bPollEnable; // poll enable flag
bool ready; //device ready indicator
volatile bool bPollEnable; // poll enable flag
volatile bool ready; //device ready indicator
tty_features _enhanced_status; // current status
EpInfo epInfo[ACM_MAX_ENDPOINTS];
@ -170,7 +194,7 @@ public:
uint8_t SendBreak(uint16_t duration);
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 SndData(uint16_t nbytes, uint8_t *dataptr);
@ -179,6 +203,10 @@ public:
uint8_t Release();
uint8_t Poll();
bool available(void) {
};
virtual uint8_t GetAddress() {
return bAddress;
};
@ -187,6 +215,36 @@ public:
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
void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
};

View file

@ -30,9 +30,7 @@ wFTDIType(0) {
epInfo[i].epAddr = 0;
epInfo[i].maxPktSize = (i) ? 0 : 8;
epInfo[i].epAttribs = 0;
//if (!i)
epInfo[i].bmNakPower = USB_NAK_MAX_POWER;
epInfo[i].bmNakPower = (i==epDataInIndex) ? USB_NAK_NOWAIT: USB_NAK_MAX_POWER;
}
if(pUsb)
pUsb->RegisterDeviceClass(this);
@ -46,11 +44,8 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
uint8_t rcode;
UsbDevice *p = 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_intf; // number of interfaces
AddressPool &addrPool = pUsb->GetAddressPool();