diff --git a/bit_train/bit_train.ino b/bit_train/bit_train.ino new file mode 100644 index 0000000..ab172cb --- /dev/null +++ b/bit_train/bit_train.ino @@ -0,0 +1,365 @@ +//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; + } +}