//test-5000000 sends a pulse 5000000 times to all gpio outputs //GPIO-n-01110010010010010000100111110001111000111001110110 sends bit train from channel n to the spikebuffer (every true bit is 1 us high) //CONVERT-n1,n2,n3,n4 converts the data in the spikebuffer from channel n1,n2,n3,n4 to the output register buffer //SEND-n sends n bits of the output register buffer to the outputs //SPIKEBUFFER shows the contents of the spike buffer //REGBUFFER shows the contents of the output register buffer //REGCLR erases the content of te output register buffer //GPIOCLR-n erases the data in the spike buffer from channel n //SETTIMEBASE-10000 sets timebase to 10000 nano seconds // instellingen #include boolean newData = false; const byte numChars = 255; char receivedChars[numChars]; // an array to store the received data char receivedCommand[numChars]; // an array to store the received command char receivedValue[numChars]; // an array to store the received command const byte numBits = 500; bool gpio[40][numBits]; // storage of the gpio output spike train int gpiolen[40]; // number of bits per gpio output uint32_t receivedVal; int lencom = 0; int startdata = 0; int gpiopin; int portreg; int len; uint32_t spikecnt = 0; bool swap = 1; float nanosec = 1000000; float nanosec_cor = 1; int block = 0; int corcnt = 10; float nr_microsec =100000; byte gpionum[40] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39}; byte gpiobit[40] = {3, 2, 4, 5, 6, 8,10,17,16,11, 0, 2, 1, 3,18,19,23,22,17,16,26,27,24,25,12,13,30,31,18,31,23,22,12, 7,15,14,13,12,17,16}; byte gpioreg[40] = {6, 6, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 9, 8, 8, 7, 9, 8, 8, 8, 8, 8, 8}; uint32_t gpioportset[4][numBits]; //parallel storage of the gpio output state set uint32_t gpioportreset[4][numBits]; //parallel storage of the gpio output state reset uint32_t dr06 = 1<<3 | 1<<2 | 1<<18 | 1<<19| 1<<23 | 1<<22 | 1<<17 | 1<<16 | 1<<26 | 1<<27 | 1<<24 | 1<<25 | 1<<12 | 1<<13 | 1<<30 | 1<<31; uint32_t dr07 = 1<<10 | 1<<16 | 1<<17 | 1<<0 | 1<<2 | 1<<1 | 1<<3 | 1<<11 | 1<<12; uint32_t dr08 = 1<<18 | 1<<23 | 1<<22 | 1<<15 | 1<<14 | 1<<13 | 1<<12 | 1<<17 | 1<<16; uint32_t dr09 = 1<<4 | 1<<5 | 1<<6 | 1<<8 | 1<<31 | 1<<7; uint16_t clockfactor = 593; uint64_t testtime = 0; uint64_t testwindow = clockfactor; // 1us if teensy 4.1 is not overclocked // time in clock cycles // 600000000 ~ 1 second // interval for pulse test uint64_t send_spikes_time = 0; uint64_t send_spikes_window = clockfactor; // 1us if teensy 4.1 is not overclocked // time in clock cycles // 600000000 ~ 1 second // interval for pulse test void setup() { Serial.begin(115200); for (byte i = 0; i <= 39; i++) { pinMode( i, OUTPUT ); } delay(1000); } void loop() { recvWithEndMarker(); //delay(200); parseData(); } uint32_t oldLow = ARM_DWT_CYCCNT; uint32_t curHigh = 0; uint64_t getCnt() { uint32_t curLow = ARM_DWT_CYCCNT; if (curLow < oldLow) // we had a roll over { curHigh++; } oldLow = curLow; uint64_t curVal = ((uint64_t)curHigh << 32) | curLow; return curVal; } void recvWithEndMarker() { static byte ndx = 0; char endMarker = '\n'; char crMarker = '\r'; int value = 0; char rc; memset(receivedChars, 0, sizeof(receivedChars) / sizeof(receivedChars[0])); while (Serial.available() > 0 && newData == false) { rc = Serial.read(); if (rc != endMarker && rc != 0 && rc != crMarker && value == 0) { //Serial.print(rc,DEC); //Serial.print(" "); receivedChars[ndx] = rc; //Serial.print(ndx); Serial.print(" "); for (int i = 0; i <= 19; i++) {Serial.print(receivedChars[i]);} Serial.println(); ndx++; if (ndx >= numChars) { ndx = numChars - 1; } } else { receivedChars[ndx] = '\0'; // terminate the string //Serial.println("einde"); ndx = 0; newData = true; } } } void parseData() { //Serial port 1 if (newData == true) { memset(receivedValue, 0, sizeof(receivedValue) / sizeof(receivedValue[0])); //clear array memset(receivedCommand, 0, sizeof(receivedCommand) / sizeof(receivedCommand[0])); //clear array //Send spikes to memory if (strstr(strupr(receivedChars), "GPIO-") > 0) { //GPIO command lencom=5; strncpy ( receivedCommand, receivedChars, lencom ); strncpy ( receivedValue, receivedChars + lencom, 2 ); receivedVal = atoi(receivedValue); //GPIO number if(receivedVal>=0 && receivedVal<=39){ startdata =(receivedVal>9)+2+lencom; strncpy ( receivedValue, receivedChars + startdata, (numBits+10)-startdata); //bits int len = strlen(receivedValue); if (len>numBits) {len=numBits;} //max 'numBits' bits memset(gpio[receivedVal], 0, sizeof(gpio[receivedVal]) / sizeof(gpio[receivedVal][0])); //clear array for (int i = 0; i < len; i++) { if (receivedValue[i] == 48) {gpio[receivedVal][i] = false;} else {gpio[receivedVal][i] = true;} //convert char to bool } gpiolen[receivedVal] = len; //save number of bits Serial.print(receivedCommand); Serial.print(receivedVal); Serial.print("-"); Serial.print(receivedValue); Serial.println(); } else { Serial.println("GPIO number not allowed"); } } //send output state registers else if (strstr(strupr(receivedChars), "SEND-") > 0) { //GPIO command lencom=5; strncpy ( receivedCommand, receivedChars, lencom ); strncpy ( receivedValue, receivedChars + lencom, 25 ); receivedVal = atoi(receivedValue); //GPIO number spikecnt = 0; while( spikecnt send_spikes_window) { send_spikes_time = send_spikes_now; GPIO6_DR_SET = gpioportset[0][spikecnt]; // turn pins on with SET register GPIO6_DR_CLEAR = gpioportreset[0][spikecnt]; // turn pins off with CLEAR register GPIO7_DR_SET = gpioportset[1][spikecnt]; // turn pins on with SET register GPIO7_DR_CLEAR = gpioportreset[1][spikecnt]; // turn pins off with CLEAR register GPIO8_DR_SET = gpioportset[2][spikecnt]; // turn pins on with SET register GPIO8_DR_CLEAR = gpioportreset[2][spikecnt]; // turn pins off with CLEAR register GPIO9_DR_SET = gpioportset[3][spikecnt]; // turn pins on with SET register GPIO9_DR_CLEAR = gpioportreset[3][spikecnt]; // turn pins off with CLEAR register spikecnt++; } } Serial.print(receivedCommand); Serial.print("-"); Serial.print("DONE"); Serial.println(); } //test else if (strstr(strupr(receivedChars), "TEST-") > 0) { //GPIO command lencom=5; strncpy ( receivedCommand, receivedChars, lencom ); strncpy ( receivedValue, receivedChars + lencom, 25 ); receivedVal = atoi(receivedValue); //GPIO number swap = 1; spikecnt = 0; while( spikecnt testwindow) { testtime = testnow; if (swap == 1) {GPIO6_DR_SET = dr06;} // turn pins on with SET register 1<<12 if (swap == 0) {GPIO6_DR_CLEAR = dr06;} // turn pins off with CLEAR register if (swap == 1) {GPIO7_DR_SET = dr07;} // turn pins on with SET register if (swap == 0) {GPIO7_DR_CLEAR = dr07;} // turn pins off with CLEAR register if (swap == 1) {GPIO8_DR_SET = dr08;} // turn pins on with SET register if (swap == 0) {GPIO8_DR_CLEAR = dr08;} // turn pins off with CLEAR register if (swap == 1) {GPIO9_DR_SET = dr09;} // turn pins on with SET register if (swap == 0) {GPIO9_DR_CLEAR = dr09;} // turn pins off with CLEAR register swap = 1 - swap; spikecnt++; } } Serial.print(receivedCommand); Serial.print("-"); Serial.print("DONE"); Serial.println(); } //Send spikes to gpio else if (strstr(strupr(receivedChars), "CONVERT-") > 0) { //GPIO command lencom=8; strncpy ( receivedCommand, receivedChars, lencom ); strncpy ( receivedValue, receivedChars + lencom, 255-lencom); len = strlen(receivedValue); gpiopin = atoi(receivedValue); //find first pin in serial command Serial.println(gpiopin); portreg = gpioreg[gpiopin]-6; //select the port register for (int k = 0; k < numBits; k++) { if (k < gpiolen[gpiopin]){ if (gpio[gpiopin][k]==true) { gpioportset[portreg][k] = gpioportset[portreg][k] | 1 << gpiobit[gpiopin]; //build the register pattern } else { gpioportreset[portreg][k] = gpioportreset[portreg][k] | 1 << gpiobit[gpiopin]; //build the register pattern } } } while(strstr(receivedValue+1, ",")){ len = strlen(receivedValue); strncpy (receivedValue, strstr(receivedValue+1, ","), len ); gpiopin = atoi(receivedValue+1); //find next pin in serial command Serial.println(gpiopin); portreg = gpioreg[gpiopin]-6; //select the port register for (int k = 0; k < numBits; k++) { if (k < gpiolen[gpiopin]){ if (gpio[gpiopin][k]==true) { gpioportset[portreg][k] = gpioportset[portreg][k] | 1 << gpiobit[gpiopin]; //build the register pattern } else { gpioportreset[portreg][k] = gpioportreset[portreg][k] | 1 << gpiobit[gpiopin]; //build the register pattern } } } } } //clear gpio spike train else if (strstr(strupr(receivedChars), "GPIOCLR-") > 0) { //GPIO command lencom=8; strncpy ( receivedCommand, receivedChars, lencom ); strncpy ( receivedValue, receivedChars + lencom, 2 ); receivedVal = atoi(receivedValue); //GPIO number if(receivedVal>=0 && receivedVal<=39){ memset(gpio[receivedVal], 0, sizeof(gpio[receivedVal]) / sizeof(gpio[receivedVal][0])); gpiolen[receivedVal] = 0; } Serial.print(receivedCommand); Serial.print(receivedVal); Serial.print("-"); Serial.print("clr"); Serial.println(); } //set timebase else if (strstr(strupr(receivedChars), "SETTIMEBASE-") > 0) { //GPIO command lencom=12; strncpy ( receivedCommand, receivedChars, lencom ); strncpy ( receivedValue, receivedChars + lencom, 15 ); receivedVal = atoi(receivedValue); //GPIO number testwindow = receivedVal * clockfactor / 1000; send_spikes_window = receivedVal * clockfactor / 1000; Serial.print(receivedCommand); Serial.print(receivedVal); Serial.print("-"); Serial.print("nano seconds"); Serial.println(); } //clear output state registers else if (strstr(strupr(receivedChars), "REGCLR") > 0) { //GPIO command lencom=6; strncpy ( receivedCommand, receivedChars, lencom ); for (int k = 0; k < numBits; k++) { for (int i = 0; i <= 3; i++) { gpioportset[i][k] = 0; } } Serial.print(receivedCommand); Serial.print("-"); Serial.print("clr"); Serial.println(); } //show gpio spike buffer else if (strstr(strupr(receivedChars), "SPIKEBUFFER") > 0) { //GPIO command for (int i = 0; i <= 39; i++) { if(gpiolen[i] > 0) { Serial.print("GPIO-"); Serial.print(i); Serial.print(" "); for (int j = 0; j < gpiolen[i]; j++) { Serial.print(gpio[i][j]); } Serial.println(); } } } //show output state buffer else if (strstr(strupr(receivedChars), "REGBUFFER") > 0) { //GPIO command Serial.println("setbuffer"); for (int k = 0; k < numBits; k++) { Serial.print("reg 06 - "); if(k<10)Serial.print(" "); Serial.print(k); Serial.print(" "); for (int i = 31; i >= 0; i--) {Serial.print(bitRead(gpioportset[0][k], i));} Serial.print(" | "); Serial.print("reg 07 - "); if(k<10)Serial.print(" "); Serial.print(k); Serial.print(" "); for (int i = 31; i >= 0; i--) {Serial.print(bitRead(gpioportset[1][k], i));} Serial.print(" | "); Serial.print("reg 08 - "); if(k<10)Serial.print(" "); Serial.print(k); Serial.print(" "); for (int i = 31; i >= 0; i--) {Serial.print(bitRead(gpioportset[2][k], i));} Serial.print(" | "); Serial.print("reg 09 - "); if(k<10)Serial.print(" "); Serial.print(k); Serial.print(" "); for (int i = 31; i >= 0; i--) {Serial.print(bitRead(gpioportset[3][k], i));} Serial.print(" | "); Serial.println(); } Serial.println("resetbuffer"); for (int k = 0; k < numBits; k++) { Serial.print("reg 06 - "); if(k<10)Serial.print(" "); Serial.print(k); Serial.print(" "); for (int i = 31; i >= 0; i--) {Serial.print(bitRead(gpioportreset[0][k], i));} Serial.print(" | "); Serial.print("reg 07 - "); if(k<10)Serial.print(" "); Serial.print(k); Serial.print(" "); for (int i = 31; i >= 0; i--) {Serial.print(bitRead(gpioportreset[1][k], i));} Serial.print(" | "); Serial.print("reg 08 - "); if(k<10)Serial.print(" "); Serial.print(k); Serial.print(" "); for (int i = 31; i >= 0; i--) {Serial.print(bitRead(gpioportreset[2][k], i));} Serial.print(" | "); Serial.print("reg 09 - "); if(k<10)Serial.print(" "); Serial.print(k); Serial.print(" "); for (int i = 31; i >= 0; i--) {Serial.print(bitRead(gpioportreset[3][k], i));} Serial.print(" | "); Serial.println(); } } else { Serial.println("Not recognized as a command"); } newData = false; } }