#define CFG_TUD_ENABLED 1 #define CFG_TUD_CDC 1 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 1 #define CFG_TUD_VIDEO 0 #include // [vendor_device.h] // - void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes); // + bool tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes); // [vendor_device.c] // - TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes) { // + TU_ATTR_WEAK bool tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes) { return true; // - tud_vendor_tx_cb(itf, (uint16_t) xferred_bytes); // + bool fin=tud_vendor_tx_cb(itf, (uint16_t) xferred_bytes); // - tu_edpt_stream_write_zlp_if_needed(rhport, &p_vendor->tx.stream, xferred_bytes); // + if(fin) tu_edpt_stream_write_zlp_if_needed(rhport, &p_vendor->tx.stream, xferred_bytes); // CH32V203K8T6 #define GPIB_DIO1 PB7 // GPIB 1 : I/O data bit 1 #define GPIB_DIO2 PA0 // GPIB 2 : I/O data bit 2 #define GPIB_DIO3 PA1 // GPIB 3 : I/O data bit 3 #define GPIB_DIO4 PA2 // GPIB 4 : I/O data bit 4 #define GPIB_DIO5 PB6 // GPIB 13 : I/O data bit 5 #define GPIB_DIO6 PB5 // GPIB 14 : I/O data bit 6 #define GPIB_DIO7 PB4 // GPIB 15 : I/O data bit 7 #define GPIB_DIO8 PB3 // GPIB 16 : I/O data bit 8 #define GPIB_REN PA15 // GPIB 17 : Remote ENable #define GPIB_EOI PA10 // GPIB 5 : End Or Identify #define GPIB_DAV PA9 // GPIB 6 : DAta Valid #define GPIB_NRFD PA8 // GPIB 7 : Not Ready For Data #define GPIB_NDAC PA4 // GPIB 8 : Not Data ACcepted #define GPIB_IFC PB0 // GPIB 9 : InterFace Clear #define GPIB_SRQ PB1 // GPIB 10 : Service ReQuest #define GPIB_ATN PA3 // GPIB 11 : ATteNtion // control request commands #define GPIB_DIO_LINE 0x40+0 #define GPIB_EOI_LINE 0x40+5 #define GPIB_DAV_LINE 0x40+6 #define GPIB_NRFD_LINE 0x40+7 #define GPIB_NDAC_LINE 0x40+8 #define GPIB_IFC_LINE 0x40+9 #define GPIB_SRQ_LINE 0x40+10 #define GPIB_ATN_LINE 0x40+11 #define GPIB_REN_LINE 0x40+17 #define GPIB_READ 0x80 #define GPIB_WRITING 0x81 #define GPIB_READING 0x82 #define GPIB_READY 0x83 #define GPIB_LEN 0x84 #define GPIB_EOS 0x85 #define GPIB_REOS 0x86 #define GPIB_TIMEOUT 0x87 #define GPIB_TTLSZ 0x88 #define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) static uint8_t gpib_buf[BULK_PACKET_SIZE]; static uint8_t data[2]; static volatile uint8_t _writing = false; static volatile uint8_t _reading = false; static volatile uint8_t _ready = false; static volatile uint8_t _len = 0; static volatile uint8_t _eos = 0x0a; // end of string static volatile uint8_t _reos = false; // read end of string static volatile uint16_t _timeout = 1000; // ms static volatile uint16_t _ttlsz = 0; // total size to read class My_USBD_Interface : public Adafruit_USBD_Interface { public: uint16_t getInterfaceDescriptor( uint8_t itfnum_deprecated, uint8_t *buf, uint16_t bufsize) { (void)itfnum_deprecated; if (!buf) return TUD_VENDOR_DESC_LEN; uint8_t const itfnum = TinyUSBDevice.allocInterface(1); uint8_t const ep_in = TinyUSBDevice.allocEndpoint(TUSB_DIR_IN); uint8_t const ep_out = TinyUSBDevice.allocEndpoint(TUSB_DIR_OUT); uint8_t desc[] = { TUD_VENDOR_DESCRIPTOR(itfnum, _strid, ep_out, ep_in, BULK_PACKET_SIZE)}; uint16_t const len = sizeof(desc); if (bufsize < len) return 0; memcpy(buf, desc, len); return len; } }; My_USBD_Interface intf; uint8_t set_num(uint32_t ch, uint8_t num){ // nagative logic if(num==0){pinMode(ch, INPUT_PULLUP); return digitalRead(ch);} //high and read else {digitalWrite(ch, LOW); pinMode(ch, OUTPUT_OD); return LOW;} //low } uint8_t gpib_write_dio(uint8_t x) { //negative logic in set_num set_num(GPIB_DIO1,bitRead(x,0)); set_num(GPIB_DIO2,bitRead(x,1)); set_num(GPIB_DIO3,bitRead(x,2)); set_num(GPIB_DIO4,bitRead(x,3)); set_num(GPIB_DIO5,bitRead(x,4)); set_num(GPIB_DIO6,bitRead(x,5)); set_num(GPIB_DIO7,bitRead(x,6)); set_num(GPIB_DIO8,bitRead(x,7)); return x; } uint8_t gpib_read_dio() { //negative logic uint8_t x = 0; bitWrite(x,0,!set_num(GPIB_DIO1,0)); bitWrite(x,1,!set_num(GPIB_DIO2,0)); bitWrite(x,2,!set_num(GPIB_DIO3,0)); bitWrite(x,3,!set_num(GPIB_DIO4,0)); bitWrite(x,4,!set_num(GPIB_DIO5,0)); bitWrite(x,5,!set_num(GPIB_DIO6,0)); bitWrite(x,6,!set_num(GPIB_DIO7,0)); bitWrite(x,7,!set_num(GPIB_DIO8,0)); return x; } bool gpib_wait(uint16_t ch, uint8_t hl){ unsigned long count=_timeout; count*=1000; // ms to us set_num(ch,0); while(hl == digitalRead(ch) && --count){delayMicroseconds(1);} return count==0; // true if timeout } bool gpib_write_byte(uint8_t data) {// return true if error if(gpib_wait(GPIB_NDAC,HIGH)) return true; //until (LOW == NDAC) gpib_write_dio(data); // output data to DIO if(gpib_wait(GPIB_NRFD,LOW)) return true; //until (HIGH == NRFD) set_num(GPIB_DAV,1); // validate data if(gpib_wait(GPIB_NDAC,LOW)) return true; //until (HIGH == NDAC) set_num(GPIB_DAV,0); gpib_write_dio(0); // delayMicroseconds(30); return false; } bool gpib_read_byte(uint8_t *data) {// return true when end or error bool ret; set_num(GPIB_NRFD,0); // prepare to listen if(gpib_wait(GPIB_DAV,HIGH)) return true; //until (LOW == DAV) set_num(GPIB_NRFD,1); // Ready for data *data = gpib_read_dio(); // input data from DIO ret=(LOW == set_num(GPIB_EOI,0)); // check EOI set_num(GPIB_NDAC,0); // data accepted if(gpib_wait(GPIB_DAV,LOW)) return true; //until (HIGH == DAV) set_num(GPIB_NDAC,1); ret |= _reos && ( *data == _eos); return ret; } uint16_t gpib_write(uint8_t* buffer, uint16_t len){ uint16_t pos; _writing=true; for(pos=0;posbRequest; // nothing to with DATA & ACK stage if (stage != CONTROL_STAGE_SETUP) return true; switch (request->bmRequestType_bit.type) { case TUSB_REQ_TYPE_VENDOR: uint16_t value=request->wValue; uint8_t len=1; switch ( cmd ) { case GPIB_DIO_LINE : data[0]=(value)? gpib_write_dio(value) : gpib_read_dio(); break; case GPIB_EOI_LINE : data[0]=set_num(GPIB_EOI,value); break; case GPIB_DAV_LINE : data[0]=set_num(GPIB_DAV,value); break; case GPIB_NRFD_LINE : data[0]=set_num(GPIB_NRFD,value); break; case GPIB_NDAC_LINE : data[0]=set_num(GPIB_NDAC,value); break; case GPIB_IFC_LINE : data[0]=set_num(GPIB_IFC,value); break; case GPIB_SRQ_LINE : data[0]=set_num(GPIB_SRQ,value); break; case GPIB_ATN_LINE : data[0]=set_num(GPIB_ATN,value); break; case GPIB_REN_LINE : data[0]=set_num(GPIB_REN,value); break; case GPIB_READ : gpib_read_byte(data); break; case GPIB_WRITING : if(value)_writing=value & 0xff; data[0]=_writing; break; case GPIB_READING : if(value)_reading=value & 0xff; data[0]=_reading; break; case GPIB_READY : if(value)_ready=value & 0xff; data[0]=_ready; break; case GPIB_LEN : if(value)_len=value & 0xff; data[0]=_len; break; case GPIB_EOS : if(value)_eos=value & 0xff; data[0]=_eos; break; case GPIB_REOS : if(value)_reos=value & 0xff; data[0]=_reos; break; case GPIB_TIMEOUT : if(value)_timeout=value; data[0]=_timeout&0xff; data[1]=_timeout>>8;len=2; break; case GPIB_TTLSZ : if(value)_ttlsz=value; data[0]=_ttlsz&0xff; data[1]=_ttlsz>>8;len=2; break; default: len=0; } return tud_control_xfer(rhport, request, (void*) data, len); break; case TUSB_REQ_TYPE_CLASS: tud_control_status(rhport, request); // response with status OK return true; break; default: // stall unknown request return false; } if ( stage == CONTROL_STAGE_SETUP ) { } else if ( stage == CONTROL_STAGE_DATA ) { return true; } else { return true; } // CONTROL_STAGE_STATUS return true; }