You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
221 lines
5.2 KiB
C++
221 lines
5.2 KiB
C++
/*
|
|
HamHead CI-V Alpha Module
|
|
|
|
This is a test of multiple things, an initialization routine
|
|
as well as working with pointers. Pointers was easy; getting
|
|
communication working boiled down to catching all my forgotten
|
|
variables and such. Pointers are used so that we can just work
|
|
on one VFO variable that's mapped to whatever the current one
|
|
is.
|
|
|
|
This now gets the current VFO mode, writes it to a variable, then
|
|
switch cases it to set a string. I may do something similar to
|
|
automatically handle "valid" CI-V frames. I need to anyway for
|
|
transcieve data.
|
|
|
|
*/
|
|
#define DEBUG 0 //enables or disables debug(), debug2(), and debugln() debugging output
|
|
#if DEBUG == 1
|
|
#define debug(x) Serial.print(x)
|
|
#define debug2(x,y) Serial.print(x,y)
|
|
#define debugln(x) Serial.println(x)
|
|
#else
|
|
#define debug(x)
|
|
#define debug2(x,y)
|
|
#define debugln(x)
|
|
#endif
|
|
|
|
|
|
//#define MODE731 1 // Uncoment for 731/735 mode.
|
|
|
|
const byte numBytes = 32;
|
|
long dec[6];
|
|
byte rxbytes[numBytes];
|
|
unsigned long vfoa; // VFO A
|
|
unsigned long vfob; // VFO B
|
|
unsigned long vfos; // starting VFO
|
|
byte civ[9] = {0xFE, 0xFE, 0x88, 0xE0}; // civ array with preamble
|
|
byte endbyte = 0xFD; // I'm not keeping the endbyte in the array.
|
|
unsigned long *v; // pointer for whatever VFO we're in
|
|
String *m; // pointer for current VFO's mode
|
|
boolean newdata = false;
|
|
int bc;
|
|
long bcd[6];
|
|
String vam;
|
|
String vbm;
|
|
|
|
void setup() {
|
|
Serial1.begin(19200);
|
|
Serial.begin(9600);
|
|
Serial.println("Initalizing VFO Variables.");
|
|
debugln();
|
|
debugln("Getting Starting VFO...");
|
|
v = &vfos;
|
|
getvfo();
|
|
v = &vfoa;
|
|
m = &vam;
|
|
setvfo(0x00);
|
|
getvfo();
|
|
getmode();
|
|
v = &vfob;
|
|
m = &vbm;
|
|
setvfo(0x01);
|
|
getvfo();
|
|
getmode();
|
|
Serial.print("VFO A: ");
|
|
Serial.print(vfoa, DEC);
|
|
Serial.print(" - ");
|
|
Serial.print(vam);
|
|
Serial.println();
|
|
Serial.print("VFO B: ");
|
|
Serial.print(vfob, DEC);
|
|
Serial.print(" - ");
|
|
Serial.print(vbm);
|
|
debugln();
|
|
debugln("Reverting to initial VFO.");
|
|
setstartvfo();
|
|
debugln("Done.");
|
|
}
|
|
|
|
void loop() {
|
|
|
|
}
|
|
|
|
void getdata() {
|
|
byte rb;
|
|
debug("RX Bytes: ");
|
|
while (Serial1.available() > 0 && newdata == false) {
|
|
rb = Serial1.read();
|
|
if (rb == 0xFE) { // if it's a start byte we don't need it.
|
|
newdata = false; // make sure we keep looping
|
|
bc = 0; // i don't trust myself
|
|
} else if (rb == 0xFD) { // end of the frame
|
|
rxbytes[bc] = '\0'; // terminate the string
|
|
if (rxbytes[0]==0x88 || rxbytes[2] == 0xFB) { // check the array for echo at index 0 or ACK at index 3
|
|
newdata = false; // auto-echo ditch&ack
|
|
bc = 0;
|
|
}
|
|
else newdata = true;} // indicate there's new data}
|
|
else {
|
|
rxbytes[bc] = rb; // write the byte to the array
|
|
bc++; // increment byte counter
|
|
debug2(rb, HEX);
|
|
debug(" "); }
|
|
}
|
|
debugln();
|
|
}
|
|
|
|
long gogovfo() {
|
|
int i = 0;
|
|
long ggv;
|
|
#ifdef MODE731 // The IC-731/735, and I assume the 765/CI-IV, only send 4 bytes for frequency. We only need to account for index starting at 0.
|
|
bc--;
|
|
#else
|
|
bc -=2; // Everything after the 735 sends 5 bytes (unless you put the radio in 731 mode). We're HF only; this ditches the extra byte and index adjustment.
|
|
#endif
|
|
for (int x = bc; x > 2; x--) {
|
|
bcd[i] = (((rxbytes[x] >> 4) *10) + (rxbytes[x]&0xF));
|
|
i++; }
|
|
ggv = ((bcd[0]*1000000)+(bcd[1]*10000)+(bcd[2]*100)+(bcd[3]));
|
|
newdata = false;
|
|
return ggv;
|
|
}
|
|
|
|
void swapvfo() {
|
|
debugln("Sending VFO Swap");
|
|
send7(0x07, 0xB0); // VFO, SWAP A/B
|
|
Serial1.flush();
|
|
delay(50); // I'm assuming this is needed to wait for the radio to send data
|
|
getdata(); // I might be able to avoid all delay() if I do something with my loop.
|
|
}
|
|
void setvfo(byte vfo) {
|
|
|
|
if (vfo == 0x00) debugln ("Setting VFO A");
|
|
else debugln("Setting VFO B");
|
|
send7(0x07, vfo); // VFO, A or B (0x00 or 0x01)
|
|
Serial1.flush();
|
|
delay(50);
|
|
getdata(); // drop the echo
|
|
}
|
|
|
|
/*
|
|
|
|
the send# functions just replace the appropiate array index with whatever
|
|
was passed to it. It'd be nice if I could have one function with an additional
|
|
value of bytes; but something something "expects 2, sends 1" arguement error.
|
|
|
|
*/
|
|
void send6(byte cmd) {
|
|
civ[4]=cmd;
|
|
Serial1.write(civ,5);
|
|
Serial1.write(endbyte);
|
|
Serial1.flush();
|
|
delay(50);
|
|
}
|
|
|
|
void send7(byte cmd, byte data) {
|
|
civ[4] = cmd;
|
|
civ[5] = data;
|
|
Serial1.write(civ,6);
|
|
Serial1.write(endbyte);
|
|
Serial1.flush();
|
|
delay(50);
|
|
}
|
|
|
|
void getvfo() {
|
|
debugln("Sending VFO Read");
|
|
send6(0x03); // 03 is VFO read
|
|
Serial1.flush();
|
|
delay(50);
|
|
getdata(); // preload the vfo
|
|
*v = gogovfo(); // process and update
|
|
}
|
|
|
|
void getmode() {
|
|
int mode;
|
|
debugln("Getting Mode.");
|
|
send6(0x04); // 04 is mode read
|
|
getdata();
|
|
mode = (int) rxbytes[3]; // it's easy enough to just deal with mode as integer
|
|
switch (mode) {
|
|
case 0:
|
|
*m = "LSB";
|
|
break;
|
|
case 1:
|
|
*m = "USB";
|
|
break;
|
|
case 2:
|
|
*m = "AM";
|
|
break;
|
|
case 3:
|
|
*m = "CW";
|
|
break;
|
|
case 4:
|
|
*m = "RTTY";
|
|
break;
|
|
case 5:
|
|
*m = "FM";
|
|
break;
|
|
case 7:
|
|
*m = "CW-R";
|
|
break;
|
|
case 8:
|
|
*m = "RTTY-R";
|
|
break;
|
|
case 23:
|
|
*m = "D-Star DV";
|
|
break;
|
|
default:
|
|
*m = "INVALID";
|
|
break;
|
|
}
|
|
newdata = false;
|
|
}
|
|
|
|
void setstartvfo() {
|
|
Serial.println();
|
|
if (vfos == vfoa) {
|
|
Serial.println("Started on A");
|
|
setvfo(0x00);}
|
|
else Serial.println("Staying on B");
|
|
} |