#define CFG_TUD_CDC 1 #define CFG_TUD_MSC 0 #define CFG_TUD_HID 0 #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 #include // 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 #define GPIBTIMEOUT 200000 //200ms char com[256] = ""; char delim[]="\r\n"; int p=0; // counter 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 0;} //low } void gpibLineStatus(void){ SerialTinyUSB.println("DAV="); SerialTinyUSB.println(set_num(GPIB_DAV,0)); SerialTinyUSB.println(", NDAC="); SerialTinyUSB.println(set_num(GPIB_NDAC,0)); SerialTinyUSB.println(", NRFD="); SerialTinyUSB.println(set_num(GPIB_NRFD,0)); SerialTinyUSB.println(", IFC="); SerialTinyUSB.println(set_num(GPIB_IFC,0)); SerialTinyUSB.println(", REN="); SerialTinyUSB.println(set_num(GPIB_REN,0)); SerialTinyUSB.println(", SRQ="); SerialTinyUSB.println(set_num(GPIB_SRQ,0)); SerialTinyUSB.println(", ATN="); SerialTinyUSB.println(set_num(GPIB_ATN,0)); SerialTinyUSB.println(", EOI="); SerialTinyUSB.println(set_num(GPIB_EOI,0)); SerialTinyUSB.println(", DIO8-1="); SerialTinyUSB.println(set_num(GPIB_DIO8,0)); SerialTinyUSB.println(set_num(GPIB_DIO7,0)); SerialTinyUSB.println(set_num(GPIB_DIO6,0)); SerialTinyUSB.println(set_num(GPIB_DIO5,0)); SerialTinyUSB.println(set_num(GPIB_DIO4,0)); SerialTinyUSB.println(set_num(GPIB_DIO3,0)); SerialTinyUSB.println(set_num(GPIB_DIO2,0)); SerialTinyUSB.println(set_num(GPIB_DIO1,0)); } byte get_dio() { //negative logic byte 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; } void set_dio(byte 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)); } void gpibAttention(){ // attention set_num(GPIB_ATN,1); delayMicroseconds(20); } void gpibAttentionEnd(){ // end of attention set_num(GPIB_ATN,0); delayMicroseconds(20); } boolean gpibWait(int ch, char hl){ unsigned long count=GPIBTIMEOUT; while(hl == digitalRead(ch) && --count){delayMicroseconds(1);} if(count==0){SerialTinyUSB.println("timeout error");} return count==0; } boolean gpibWrite(byte data) {// true if error set_num(GPIB_NDAC,0); if(gpibWait(GPIB_NDAC,HIGH)){return true;} //until (LOW == NDAC) set_dio(data); // output data to DIO set_num(GPIB_NRFD,0); if(gpibWait(GPIB_NRFD,LOW)){return true;} //until (HIGH == NRFD) set_num(GPIB_DAV,1); // validate data if(gpibWait(GPIB_NDAC,LOW)){return true;} //until (HIGH == NDAC) set_num(GPIB_DAV,0); set_dio(0); delayMicroseconds(30); return false; } boolean gpibRead(byte *data) { boolean ret; set_num(GPIB_NRFD,0); // prepare to listen set_num(GPIB_DAV,0); if(gpibWait(GPIB_DAV,HIGH)){*data=0;return true;} //until (LOW == DAV) set_num(GPIB_NRFD,1); // Ready for data *data = get_dio(); // read from DIO set_num(GPIB_EOI,0); ret=(LOW == digitalRead(GPIB_EOI)); // check EOI set_num(GPIB_NDAC,0); // data accepted if(gpibWait(GPIB_DAV,LOW)){*data=0;return true;} //until (HIGH == DAV) set_num(GPIB_NDAC,1); return ret; // return true when EOI==LOW or error } void gpibTalk(byte addr, char *str) { set_num(GPIB_EOI,0); gpibAttention(); if(gpibWrite(0x5F)){gpibAttentionEnd();return;} // untalk if(gpibWrite(0x3F)){gpibAttentionEnd();return;} // unlisten if(gpibWrite(0x40)){gpibAttentionEnd();return;} // talker address if(gpibWrite(0x20+addr)){gpibAttentionEnd();return;} // listener address gpibAttentionEnd(); // write string while (0 != *str) { if(0==*(str+1)){set_num(GPIB_EOI,1);} // end of string if(gpibWrite(*(str++))){set_num(GPIB_EOI,0);return;}; } set_num(GPIB_EOI,0); SerialTinyUSB.println("OK"); } void gpibListen(byte addr, char *str) { *str=0; set_num(GPIB_EOI,0); gpibAttention(); if(gpibWrite(0x5F)){gpibAttentionEnd();return;} // untalk if(gpibWrite(0x3F)){gpibAttentionEnd();return;} // unlisten if(gpibWrite(0x40+addr)){gpibAttentionEnd();return;} // talker address if(gpibWrite(0x20)){gpibAttentionEnd();return;} // listener address set_num(GPIB_NRFD,1); set_num(GPIB_NDAC,1); delayMicroseconds(10); gpibAttentionEnd(); // recieve data p = strlen(delim); do { if(gpibRead(str++)){*str=0;break;} //EOI *str=0; } while (strcmp(str-p, delim)); } void gpibSerialPoll(byte addr, char *str) { //read one status byte *str=0; gpibAttention(); if(gpibWrite(0x5F)){gpibAttentionEnd();return;} // untalk if(gpibWrite(0x3F)){gpibAttentionEnd();return;} // unlisten if(gpibWrite(0x18)){gpibAttentionEnd();return;} // Serial Poll Enable if(gpibWrite(0x40+addr)){gpibAttentionEnd();return;} // talker address set_num(GPIB_NRFD,1); set_num(GPIB_NDAC,1); delayMicroseconds(10); gpibAttentionEnd(); gpibRead(str++); *str=0; gpibAttention(); if(gpibWrite(0x19)){gpibAttentionEnd();return;} // Serial Poll Disable if(gpibWrite(0x5F)){gpibAttentionEnd();return;} // untalk gpibAttentionEnd(); } void gpibIFC(void) { set_num(GPIB_IFC,1); set_num(GPIB_REN,0); delayMicroseconds(128); set_num(GPIB_IFC,0); SerialTinyUSB.println("IFC"); } void gpibREN(char value) { set_num(GPIB_REN,value); SerialTinyUSB.println("REN"); } void gpibSRQ() { SerialTinyUSB.println("SRQ="); SerialTinyUSB.println(set_num(GPIB_SRQ,0)); } void gpibCmd(char cmd, char *str){ gpibAttention(); if(gpibWrite(cmd)){gpibAttentionEnd();return;} gpibAttentionEnd(); SerialTinyUSB.println(str); } void gpibCmdAdr(char addr,char cmd, char *str){ gpibAttention(); if(gpibWrite(0x3F)){gpibAttentionEnd();return;} // unlisten if(gpibWrite(0x20+addr)){gpibAttentionEnd();return;} // listener address if(gpibWrite(cmd)){gpibAttentionEnd();return;} gpibAttentionEnd(); SerialTinyUSB.println(str); } void gpibDelim(char par){ if(par==0){delim[0]=10,delim[1]=0;} // LF else if(par==1){delim[0]=13,delim[1]=0;} // CR else if(par==2){delim[0]=13,delim[1]=10;} // CR LF SerialTinyUSB.println("change delimiter"); } void setup() { if (!TinyUSBDevice.isInitialized()) { TinyUSBDevice.begin(0); } if (TinyUSBDevice.mounted()) { TinyUSBDevice.detach(); delay(10); TinyUSBDevice.attach(); } pinMode(GPIB_DIO1,INPUT_PULLUP); pinMode(GPIB_DIO5,INPUT_PULLUP); pinMode(GPIB_DIO2,INPUT_PULLUP); pinMode(GPIB_DIO6,INPUT_PULLUP); pinMode(GPIB_DIO3,INPUT_PULLUP); pinMode(GPIB_DIO7,INPUT_PULLUP); pinMode(GPIB_DIO4,INPUT_PULLUP); pinMode(GPIB_DIO8,INPUT_PULLUP); pinMode(GPIB_EOI, INPUT_PULLUP); pinMode(GPIB_REN, INPUT_PULLUP); set_num(GPIB_DIO1, 0); set_num(GPIB_DIO5, 0); set_num(GPIB_DIO2, 0); set_num(GPIB_DIO6, 0); set_num(GPIB_DIO3, 0); set_num(GPIB_DIO7, 0); set_num(GPIB_DIO4, 0); set_num(GPIB_DIO8, 0); set_num(GPIB_EOI, 0); set_num(GPIB_REN, 0); pinMode(GPIB_DAV, INPUT_PULLUP); pinMode(GPIB_NRFD,INPUT_PULLUP); pinMode(GPIB_NDAC,INPUT_PULLUP); set_num(GPIB_DAV, 0); set_num(GPIB_NRFD, 1); set_num(GPIB_NDAC, 1); set_num(GPIB_SRQ, 0); pinMode(GPIB_IFC, INPUT_PULLUP); pinMode(GPIB_ATN, INPUT_PULLUP); set_num(GPIB_IFC, 0); set_num(GPIB_ATN, 0); } void loop() { #ifdef TINYUSB_NEED_POLLING_TASK TinyUSBDevice.task(); #endif while (SerialTinyUSB.available()) { if (0x0a != (com[p++] =SerialTinyUSB.read())) {return;} com[p]=0; if(com[0]<'a'){ // upper case com[3]=0; // three character commands if (0 == strcmp("IFC", com)){ gpibIFC();} // InterFace Clear else if (0 == strcmp("SRQ", com)){ gpibSRQ();} // Service ReQuest else if (0 == strcmp("REN", com)){ gpibREN(1);} // Remote ENable else if (0 == strcmp("RDA", com)){ gpibREN(0);} // Remote DisAble else if (0 == strcmp("LLO", com)){ gpibCmd(0x11,"LLO");} // Local Lock Out else if (0 == strcmp("DCL", com)){ gpibCmd(0x14,"DCL");} // Device CLear else if (0 == strcmp("LIN", com)){ gpibLineStatus();} }else{ // lower case p=(com[1]-'0')*10+com[2]-'0'; // two character address or parameter if(p<0 || p>31){SerialTinyUSB.println("address error");p=0;return;} if ('l' == com[0]){gpibCmdAdr(p,0x01,"GTL");} //l99 Go To Local else if ('c' == com[0]){gpibCmdAdr(p,0x04,"SDC");} //c99 Selected Device Clear else if ('t' == com[0]){gpibCmdAdr(p,0x08,"GET");} //t99 Group Executed Trigger else if ('d' == com[0]){gpibDelim(p);} //d00-02 delimiter else if ('w' == com[0]){gpibTalk(p, com+3);} //w99option else if ('r' == com[0]){gpibListen(p, com);SerialTinyUSB.println(com);} //r99 else if ('s' == com[0]){gpibSerialPoll(p, com);SerialTinyUSB.println(com[0]);} //s99 } p=0; } }