Alrighty, this is the most I could condense my code and still send it out to my SPI connected device.
Arduino
#include <SPI.h> //SPI library for Arduino
#include <math.h>
#include <string.h>
//Teensy 3.6 Constants
uint8_t chipSelectPin = 15;
bool GO = false;
char startMarker = '<';
char endMarker = '>';
const int ArbMem = 50e3;
uint16_t Istim = 0;
// Intan Constants
uint8_t stimRegisters[] = {32, 33};
uint16_t MagicNumbers[] = {0xAAAA, 0x00FF};
uint16_t nonMagicNumbers[] = {0x0000, 0x0000};
uint16_t StimNull = 0x8000;
uint8_t PolReg = 44;
uint16_t PolSet;
uint8_t OnOffReg = 42;
uint8_t negRegisters[] = {64, 65, 66, 67,
68, 69, 70, 71,
72, 73, 74, 75,
76, 77, 78, 79
};
uint8_t posRegisters[] = {96, 97, 98, 99,
100, 101, 102, 103,
104, 105, 106, 107,
108, 109, 110, 111
};
uint8_t registerValues[] = { 0,
1,
2,
3,
4,
5,
6,
7,
8,
10,
12,
34,
35,
36,
37,
42,
44,
46,
48
};
uint16_t initializationValues[] = { 0x00C7,
0x051A,
0x0040,
0x0080,
0x1A26,
0x1F05,
0x3638,
0x3638,
0xFFFF,
0x0000,
0xFFFF,
0x000F,
0x00FF,
0x0080,
0x4F00,
0x0000,
0x0000,
0x0000,
0x0000
};
uint16_t LD;
uint32_t N;
char SendCode[2];
uint8_t ArbHeap[ArbMem] = {};
bool ArbPol[ArbMem] = {};
uint8_t pairs;
uint8_t ElecPairs[2] = {};
double freq;
double amp;
void setup() {
SPI.begin();
delay(10);
Serial.begin(115200);
pinMode (chipSelectPin, OUTPUT);
SPI.beginTransaction(SPISettings(17e6, MSBFIRST, SPI_MODE0));
digitalWrite(chipSelectPin, HIGH);
delay(1000);
StimOff();
for ( int c = 0; c < (int)sizeof(registerValues); c++) {
writeRHS(registerValues[c], initializationValues[c]);
}
NullStim();
delay(10);
}
void loop() {
if (GO) {
UpdateStim();
}
if (Serial.available() > 0) {
UNOSerialEvent();
}
}
void UNOSerialEvent()
byte temp[8];
ElecPairs[1] = 4;
ElecPairs[0] = 5;
byte rb = Serial.read();
if (rb == startMarker) {
Serial.flush();
for (int c = 0; c < 8; c++) {
temp[c] = Serial.read();
}
freq = byteToDouble(temp);
// get amplitude value second
for (int c = 0; c < 8; c++) {
temp[c] = Serial.read();
}
amp = byteToDouble(temp);
makeSine(freq, amp);
GO = true;
}
rb = Serial.read();
}
void UpdateStim(void) {
uint16_t Amp;
uint16_t PolState = readRHS(PolReg);
Amp = ArbHeap[Istim];
// Set Polarity
if (ArbPol[Istim]) {
PolState = setBit( PolState, ElecPairs[1], 1);
PolState = setBit( PolState, ElecPairs[0], 0);
} else {
PolState = setBit( PolState, ElecPairs[1], 0);
PolState = setBit( PolState, ElecPairs[0], 1);
}
// Send Stim values over
if (ArbPol[Istim]) {
writeRHS( posRegisters[ElecPairs[1]], Amp);
writeRHS( negRegisters[ElecPairs[0]], Amp);
} else {
writeRHS( posRegisters[ElecPairs[0]], Amp);
writeRHS( negRegisters[ElecPairs[1]], Amp);
}
writeRHS(PolReg, PolState);
clearComplianceMonitor();
delayMicroseconds(LD);
Istim++;
if (Istim >= N) {
Istim = 0;
}
}
void StimOff(void) {
readRHS(255);
writeRHS(stimRegisters[0], nonMagicNumbers[0]);
writeRHS(stimRegisters[1], nonMagicNumbers[1]);
writeRHS(38, 0xFFFF);
clearRHS();
}
void NullStim(void) {
for ( int c = 0; c < (int)sizeof(negRegisters); c++) {
writeRHS(negRegisters[c], StimNull);
writeRHS(posRegisters[c], StimNull);
}
writeRHS(stimRegisters[0], MagicNumbers[0]);
writeRHS(stimRegisters[1], MagicNumbers[1]);
clearComplianceMonitor();
writeRHS(OnOffReg, 0xFFFF);
clearComplianceMonitor();
}
void makeSine(double Freq, double Amp) {
double Stim;
uint8_t Trim = 0x80;
double tld = 14.25;
uint32_t FreqUpdate = floor(1 / (tld * 1e-6));
uint16_t FreqB = 50;
N = (uint32_t)(FreqUpdate / FreqB);
LD = floor(tld * ((FreqB / Freq) - 1));
for ( int c = 0; c < (int)N; c++) {
Stim = Amp * sin((2.0 * PI * ((double)c)) / (double)N);
if (Stim >= 0) {
ArbPol[c] = true;
} else {
ArbPol[c] = false;
}
ArbHeap[c] = ADC_RHS(Stim, Trim);
}
}
uint16_t setBit(uint16_t value, uint8_t bitnum, uint8_t setVal) {
if (setVal == 1) {
value = (value | (1 << bitnum));
} else {
value = (value & ~(1 << bitnum));
}
return value;
}
uint16_t ADC_RHS(double Stim, uint8_t Trim) {
uint16_t DStim = (uint16_t)round(abs(Stim)*100);
return (((uint16_t) Trim) << 8) + DStim;
}
//======================= Converter functions =============================
double byteToDouble(byte doubleNbyte[8]) {
union {
double Out;
byte In[8];
} U ;
for (int c = 0; c < 8; c++) {
U.In[c] = doubleNbyte[c];
}
return U.Out;
}
void writeRHS(int registerNumber, uint16_t dataOut) {
uint16_t writeMask = 0b1000000000000000 | registerNumber;
digitalWrite(chipSelectPin, LOW);
SPI.transfer16(writeMask);
SPI.transfer16(dataOut);
digitalWrite(chipSelectPin, HIGH);
}
uint16_t readRHS(int registerNumber) {
uint16_t dataIn;
uint16_t readMask = 0b1100000000000000 | registerNumber;
digitalWrite(chipSelectPin, LOW);
SPI.transfer16(readMask);
dataIn = SPI.transfer16(0);
digitalWrite(chipSelectPin, HIGH);
return dataIn;
}
void clearRHS() {
uint16_t clearCommand = 0b0110101000000000;
digitalWrite(chipSelectPin, LOW);
SPI.transfer16(clearCommand);
SPI.transfer16(0);
digitalWrite(chipSelectPin, HIGH);
}
void clearComplianceMonitor() {
uint16_t readMask = 0b1111000000000000;
digitalWrite(chipSelectPin, LOW);
SPI.transfer16(readMask);
SPI.transfer16(0);
digitalWrite(chipSelectPin, HIGH);
}
Matlab
SerialID = serial('COM5','BaudRate',115200);
fopen(SerialID);
fwrite(SerialID,'<','char');
fwrite(SerialID,10.0);
fwrite(SerialID,2.55);
fwrite(SerialID,'>','char');
fclose(SerialID);