Last active
September 23, 2018 22:54
-
-
Save heborras/d019c390d33993eb883cadcbb128d956 to your computer and use it in GitHub Desktop.
A dev firmware for testing and characterizing the V2 board, SiPMs and slabs with an arduino DUE
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SPI.h> | |
#include <Wire.h> | |
//updated to include a whole bunch of extra functions 120818 | |
/* Cosmic Pi SPI test routines - Master version, slave is commented out below. Runs on an Arduino DUE, | |
Pinouts: | |
MOSI - MOSI | |
MISO - MISO | |
SCK - SCK | |
Pin 10 - Pin 10 (SS) | |
GND - GND | |
5V - 5V | |
The slave echoes the master byte in the next (16 bit) transmission. | |
SPI COMMUNICATION TRANSACTION LIST OF COMMANDS | |
WRITE OPERATIONS (FOR EACH WRITE, SLAVE MUST SEND BACK THE VALUE IT RECEIVES) | |
01 WRITE MSB(16 high bits) HV1_DUTY_CYCLE | |
02 WRITE LSB(16 low bits) HV1_DUTY_CYCLE | |
03 WRITE MSB(16 high bits) HV2_DUTY_CYCLE | |
04 WRITE LSB(16 low bits) HV2_DUTY_CYCLE | |
05 WRITE 16 bits LED_DUTY_CYCLE | |
READ OPERATIONS (FOR EACH READ, SLAVE MUST SEND BACK THE VALUE OF THE RELATED REGISTER) | |
06 READ MSB(16 high bits) HV1_DUTY_CYCLE | |
07 READ LSB(16 low bits) HV1_DUTY_CYCLE | |
08 READ MSB(16 high bits) HV2_DUTY_CYCLE | |
09 READ LSB(16 low bits) HV2_DUTY_CYCLE | |
10 READ 16 bits LED_DUTY_CYCLE | |
11 WRITE STATUS | |
12 READ STATUS | |
13 READ ADC CH1 | |
14 READ ADC CH2 | |
15 WRITE PWM PERIOD MSB | |
16 WRITE PWM PERIOD LSB | |
17 READ PWM PERIOD MSB | |
18 READ PWM PERIOD LSB | |
*/ | |
byte CMD = 1; | |
unsigned int duty_cycle_LED = 81; | |
unsigned int duty_cycle_channel_A = 100000; | |
unsigned int duty_cycle_channel_B = 200000; | |
unsigned int MSB; | |
unsigned int LSB; | |
byte val = 0; | |
//unsigned int response = 0; | |
unsigned int answer = 0; | |
byte PSU_parametrized = 0; | |
#define MCP4725_ADD0 0x60 | |
#define MCP4725_ADD1 0x61 | |
const int thresh1_default = 3000;//12 bit | |
const int thresh2_default = 3000;//12 bit integer | |
//int threshhigh = 0; | |
//setpoints for the HV | |
int HVset1 = 56; | |
int HVset2 = 56; | |
// pins for interrupts | |
const int TRIG_BOTH = 2; | |
const int S_TRIG_A = 3; | |
const int S_TRIG_B = 4; | |
bool coinc_interruts_enabled = true; | |
bool single_interruts_enabled = false; | |
// Thresholds via DAC | |
const bool useDAC = true; | |
void setup() { | |
//setup i2c and init dac's at a reasonable value | |
Wire.begin(); // join i2c bus (address optional for master) | |
//setup spi | |
pinMode(SS, OUTPUT); | |
SPI.begin(); | |
SPI.setBitOrder(MSBFIRST); | |
//SPI.setClockDivider(SPI_CLOCK_DIV128 ); | |
//begin serial | |
Serial.begin(115200); | |
Serial.setTimeout(65535); | |
// wait for the serial connection | |
while (!Serial){} | |
// set threshs to the default value | |
if (useDAC){ | |
analogWrite(DAC0, thresh1_default); | |
analogWrite(DAC1, thresh2_default); | |
Serial.println("Set threshold DAC CH1 to " + String(thresh2_default) + " AND CH2 to: " + String(thresh2_default)); | |
} else { | |
DacUpd(MCP4725_ADD0, thresh1_default); | |
DacUpd(MCP4725_ADD1, thresh2_default); | |
} | |
// directly setup the interrupts | |
toggle_coinc_interrupts(coinc_interruts_enabled); | |
} | |
void loop() { | |
Serial.println("Input a command!"); | |
Serial.println("[1= set thresh1 & thresh2, 2= set thrshold1, 3= set threshold2, 4= set HV ch1, 5 = set HV ch2, 6= set HV CH1 and CH2, 7 = set HV enables,\n 8= generic 2 part command, 9 = generic read, 10 = toggle coincidence interrupt, 11 = toggle single interrupts]"); | |
int cmd = readIntFromSerial(); | |
switch (cmd) { | |
case 1: | |
{ | |
Serial.println("Set a threshold value CH1 AND CH2 [1,4096]: "); | |
int value = readIntFromSerial(); | |
//setThreshold(3, value); | |
if (useDAC){ | |
analogWrite(DAC0, value); | |
analogWrite(DAC1, value); | |
Serial.println("Set threshold DAC CH1 AND CH2 to: " + String(value)); | |
} else { | |
DacUpd(MCP4725_ADD0, value); | |
DacUpd(MCP4725_ADD1, value); | |
} | |
break; | |
} | |
case 2: | |
{ | |
Serial.println("Set a threshold value CH1[1,4096]: "); | |
int value = readIntFromSerial(); | |
//setThreshold(3, value); | |
if (useDAC){ | |
analogWrite(DAC0, value); | |
Serial.println("Set threshold DAC CH1 to: " + String(value)); | |
} else { | |
DacUpd(MCP4725_ADD0, value); | |
} | |
break; | |
} | |
case 3: | |
{ | |
Serial.println("Set a threshold value CH2[1,4096]: "); | |
int value = readIntFromSerial(); | |
//setThreshold(3, value); | |
if (useDAC){ | |
analogWrite(DAC1, value); | |
Serial.println("Set threshold DAC CH2 to: " + String(value)); | |
} else { | |
DacUpd(MCP4725_ADD1, value); | |
} | |
break; | |
} | |
case 4: | |
{ | |
//MSB | |
Serial.println("Setting CH1 MSB to 0"); | |
int sendValue = 0; | |
//if (sendValue < HV_MAX_VAL) { | |
// Serial.print("HV Value is too high! Setting HV CH2 to:"); | |
// Serial.println(HV_MAX_VAL); | |
//send the command code | |
spi_exchange(1); | |
spi_exchange(sendValue); | |
//LSB | |
Serial.println("Input a voltage value CH1 LSB[1=highest,255=lowest,56=nominal]"); | |
sendValue = readIntFromSerial(); | |
//if (sendValue < HV_MAX_VAL) { | |
// Serial.print("HV Value is too high! Setting HV ch2 to:"); | |
// Serial.println(HV_MAX_VAL); | |
//send the command code | |
spi_exchange(2); | |
spi_exchange(sendValue); | |
break; | |
} | |
case 5: | |
{ | |
//MSB | |
Serial.println("Setting CH2 MSB to 0"); | |
int sendValue = 0; | |
//if (sendValue < HV_MAX_VAL) { | |
// Serial.print("HV Value is too high! Setting HV ch2 to:"); | |
// Serial.println(HV_MAX_VAL); | |
//send the command code | |
spi_exchange(3); | |
spi_exchange(sendValue); | |
//LSB | |
Serial.println("Input a voltage value CH2 LSB[1=highest,255=lowest,56=nominal]"); | |
sendValue = readIntFromSerial(); | |
//if (sendValue < HV_MAX_VAL) { | |
// Serial.print("HV Value is too high! Setting HV ch2 to:"); | |
// Serial.println(HV_MAX_VAL); | |
//send the command code | |
spi_exchange(4); | |
spi_exchange(sendValue); | |
break; | |
} | |
case 6: | |
{ | |
Serial.println("Input a voltage value CH1 AND CH2 LSB[1=highest,255=lowest,56=nominal]"); | |
int both_sendValue = readIntFromSerial(); | |
Serial.println("Setting CH1 MSB to 0"); | |
int sendValue = 0; | |
//if (sendValue < HV_MAX_VAL) { | |
// Serial.print("HV Value is too high! Setting HV CH2 to:"); | |
// Serial.println(HV_MAX_VAL); | |
//send the command code | |
spi_exchange(1); | |
spi_exchange(sendValue); | |
//LSB | |
Serial.println("Setting CH1 LSB to "+ String(both_sendValue)); | |
sendValue = both_sendValue; | |
//if (sendValue < HV_MAX_VAL) { | |
// Serial.print("HV Value is too high! Setting HV ch2 to:"); | |
// Serial.println(HV_MAX_VAL); | |
//send the command code | |
spi_exchange(2); | |
spi_exchange(sendValue); | |
Serial.println("Setting CH2 MSB to 0"); | |
sendValue = 0; | |
//if (sendValue < HV_MAX_VAL) { | |
// Serial.print("HV Value is too high! Setting HV ch2 to:"); | |
// Serial.println(HV_MAX_VAL); | |
//send the command code | |
spi_exchange(3); | |
spi_exchange(sendValue); | |
//LSB | |
Serial.println("Setting CH2 LSB to "+ String(both_sendValue)); | |
sendValue = both_sendValue; | |
//if (sendValue < HV_MAX_VAL) { | |
// Serial.print("HV Value is too high! Setting HV ch2 to:"); | |
// Serial.println(HV_MAX_VAL); | |
//send the command code | |
spi_exchange(4); | |
spi_exchange(sendValue); | |
break; | |
} | |
case 7: | |
{ | |
Serial.println("disabling HV"); | |
spi_exchange(11); | |
spi_exchange(0); | |
Serial.println("enabling HV"); | |
spi_exchange(11); | |
spi_exchange(3); | |
break; | |
} | |
//generic command sender | |
case 8: | |
{ | |
Serial.println("Input a command to send"); | |
Serial.println(" 01 WRITE MSB(16 high bits) HV1_DUTY_CYCLE"); | |
Serial.println(" 02 WRITE LSB(16 low bits) HV1_DUTY_CYCLE"); | |
Serial.println(" 03 WRITE MSB(16 high bits) HV2_DUTY_CYCLE"); | |
Serial.println(" 04 WRITE LSB(16 low bits) HV2_DUTY_CYCLE"); | |
Serial.println(" 05 WRITE 16 bits LED_DUTY_CYCLE"); | |
Serial.println(" 11 WRITE STATUS"); | |
Serial.println(" 15 WRITE PWM PERIOD MSB"); | |
Serial.println(" 16 WRITE PWM PERIOD LSB"); | |
int sendValue = readIntFromSerial(); | |
//if (sendValue < HV_MAX_VAL) { | |
// Serial.print("HV Value is too high! Setting HV ch2 to:"); | |
// Serial.println(HV_MAX_VAL); | |
//send the command code | |
spi_exchange(sendValue); | |
Serial.println("Input a value to send"); | |
sendValue = readIntFromSerial(); | |
spi_exchange(sendValue); | |
break; | |
} | |
//generic command sender | |
case 9: | |
{ | |
Serial.println("Input a value to read"); | |
Serial.println(" 06 READ MSB(16 high bits) HV1_DUTY_CYCLE"); | |
Serial.println(" 07 READ LSB(16 low bits) HV1_DUTY_CYCLE"); | |
Serial.println(" 08 READ MSB(16 high bits) HV2_DUTY_CYCLE"); | |
Serial.println(" 09 READ LSB(16 low bits) HV2_DUTY_CYCLE"); | |
Serial.println(" 10 READ 16 bits LED_DUTY_CYCLE"); | |
Serial.println(" 12 READ STATUS"); | |
Serial.println(" 13 READ ADC CH1"); | |
Serial.println(" 14 READ ADC CH2"); | |
Serial.println(" 17 READ PWM PERIOD MSB"); | |
Serial.println(" 18 READ PWM PERIOD LSB"); | |
int sendValue = readIntFromSerial(); | |
//if (sendValue < HV_MAX_VAL) { | |
// Serial.print("HV Value is too high! Setting HV ch2 to:"); | |
// Serial.println(HV_MAX_VAL); | |
//send the command code | |
spi_exchange(sendValue); | |
spi_exchange(0); //send a null to get the value we wanted back. | |
break; | |
} | |
case 10: | |
{ | |
coinc_interruts_enabled = !coinc_interruts_enabled; | |
toggle_coinc_interrupts(coinc_interruts_enabled); | |
break; | |
} | |
case 11: | |
{ | |
single_interruts_enabled = !single_interruts_enabled ; | |
toggle_single_interrupts(single_interruts_enabled); | |
break; | |
} | |
} | |
delay(500); | |
} | |
int spi_exchange(int data) { | |
digitalWrite(SS, LOW); | |
int response = SPI.transfer16(data); | |
Serial.println("SPI Master send command:" + String(data) + " Slave reply:" + String(response)); | |
digitalWrite(SS, HIGH); | |
delay(20); | |
return response; | |
} | |
int readIntFromSerial(){ | |
int val = Serial.parseInt(); | |
//while (val == 0){ | |
//delay(100); | |
//val = Serial.parseInt(); | |
//} | |
return val; | |
} | |
void DacUpd(int address, int packet1) | |
{ | |
Wire.beginTransmission(address); | |
Wire.write(64); // cmd to update the DAC | |
Wire.write(packet1 >> 4); // the 8 most significant bits... | |
Wire.write((packet1 & 15) << 4); // the 4 least significant bits... | |
byte error_code = Wire.endTransmission(); | |
switch (error_code) { | |
case 0:{ | |
Serial.print("Sucess! "); | |
break; | |
} | |
case 1:{ | |
Serial.print("ERROR: Data Too long. "); | |
break; | |
} | |
case 2:{ | |
Serial.print("ERROR: NACK on ADDR. "); | |
break; | |
} | |
case 3:{ | |
Serial.print("ERROR: NACK on DATA. "); | |
break; | |
} | |
case 4:{ | |
Serial.print("ERROR: Other Error. "); | |
break; | |
} | |
} | |
Serial.println("I2C ADDR:" + String(address) + " DATA:" + String(packet1)); | |
} | |
// ---- Functions for the interrupt routines | |
void printTimeAndPin(int pin, String name){ | |
// print when and which pin was interrupted | |
unsigned long mil = millis(); | |
unsigned long mic = micros(); | |
Serial.print("T="); | |
Serial.print(mil); | |
Serial.print(":"); | |
Serial.print(mic); | |
Serial.print(";P="); | |
Serial.print(pin); | |
Serial.print(";n="); | |
Serial.println(name); | |
} | |
void toggle_coinc_interrupts(bool enable){ | |
if (enable) { | |
pinMode(TRIG_BOTH, INPUT); //set the interrupt pin for trigger as high impedance, probably not required | |
attachInterrupt(digitalPinToInterrupt(TRIG_BOTH), [=] () {printTimeAndPin(TRIG_BOTH, "TRIG_BOTH");}, RISING); | |
Serial.println("Attached coincidence interrupts!"); | |
} else { | |
detachInterrupt(digitalPinToInterrupt(TRIG_BOTH)); | |
Serial.println("Detached coincidence interrupts!"); | |
} | |
} | |
void toggle_single_interrupts(bool enable){ | |
if (enable) { | |
pinMode(S_TRIG_A, INPUT); //set the interrupt pin for trigger as high impedance, probably not required | |
pinMode(S_TRIG_B, INPUT); //set the interrupt pin for trigger as high impedance, probably not required | |
attachInterrupt(digitalPinToInterrupt(S_TRIG_A), [=] () {printTimeAndPin(S_TRIG_A, "S_TRIG_A");}, RISING); | |
attachInterrupt(digitalPinToInterrupt(S_TRIG_B), [=] () {printTimeAndPin(S_TRIG_B, "S_TRIG_B");}, RISING); | |
Serial.println("Attached single interrupts!"); | |
} else { | |
detachInterrupt(digitalPinToInterrupt(S_TRIG_A)); | |
detachInterrupt(digitalPinToInterrupt(S_TRIG_B)); | |
Serial.println("Detached single interrupts!"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment