bit_train_teensy_41/bit_train/bit_train.ino

366 lines
16 KiB
Arduino
Raw Normal View History

2022-12-14 10:46:23 +01:00
//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 <Arduino.h>
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
2022-12-14 11:51:12 +01:00
const int numBits = 500;
2022-12-14 10:46:23 +01:00
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<receivedVal ) {
uint64_t send_spikes_now = getCnt();
if (send_spikes_now - send_spikes_time > 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<receivedVal ) {
uint64_t testnow = getCnt();
if (testnow - testtime > 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;
}
}