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 ;
}
}