diff --git a/src/HamShield.cpp b/src/HamShield.cpp index ada36a4..1c8c196 100644 --- a/src/HamShield.cpp +++ b/src/HamShield.cpp @@ -3,13 +3,20 @@ // 11/22/2013 by Morgan Redfield // 04/26/2015 various changes Casey Halverson -#include "Arduino.h" #include "HamShield.h" +#include "stdint.h" +#include "math.h" + +#if defined(__AVR__) #include -// #include +#define MORSE_TABLE_PROGMEM +#else + // get rid of progmem for now and just put these tables in flash/program space + #define PROGMEM +#endif + /* don't change this regulatory value, use dangerMode() and safeMode() instead */ - bool restrictions = true; /* channel lookup tables */ @@ -31,7 +38,6 @@ unsigned int morse_dot_millis = 100; // It will occupy 108 bytes of memory (or program memory if defined) #define MORSE_TABLE_LENGTH 54 -#define MORSE_TABLE_PROGMEM #ifndef MORSE_TABLE_PROGMEM const struct asciiMorse { char ascii; @@ -119,8 +125,9 @@ const unsigned char AFSK_space[] PROGMEM = { 140, 228, 250, 166, 53, 0, 53, 166, * @see A1846S_ADDRESS_AD0_LOW * @see A1846S_ADDRESS_AD0_HIGH */ -HamShield::HamShield(uint8_t cs_pin = nSEN, uint8_t clk_pin = CLK, uint8_t dat_pin = DAT) { +HamShield::HamShield(uint8_t cs_pin = nSEN, uint8_t clk_pin = CLK, uint8_t dat_pin = DAT, uint8_t pwm_pin = HAMSHIELD_PWM_PIN) { devAddr = cs_pin; + hs_pwm_pin = pwm_pin; HSsetPins(cs_pin, clk_pin, dat_pin); } @@ -193,13 +200,13 @@ void HamShield::initialize(bool narrowBand) { // calibration tx_data = 0x00A4; HSwriteWord(devAddr, 0x30, tx_data); - delay(100); + HSdelay(100); tx_data = 0x00A6; HSwriteWord(devAddr, 0x30, tx_data); - delay(100); + HSdelay(100); tx_data = 0x0006; HSwriteWord(devAddr, 0x30, tx_data); - delay(100); + HSdelay(100); // set band width @@ -209,7 +216,7 @@ void HamShield::initialize(bool narrowBand) { setupWideBand(); } - delay(100); + HSdelay(100); /* // setup default values @@ -397,15 +404,9 @@ bool HamShield::testConnection() { * to 7FH, and then write value to the address subtracted by * 80H. Finally write 0x0000 to 7FH * Example: writing 85H register address is 0x001F . - * Move 7FH 0x0001{ - -} - * Move 05H 0x001F{ - -} 05H=85H-80H - * Move 7FH 0x0000{ - -} + * Move 7FH 0x0001{} + * Move 05H 0x001F{} 05H=85H-80H + * Move 7FH 0x0000{} */ uint16_t HamShield::readCtlReg() { @@ -416,7 +417,7 @@ uint16_t HamShield::readCtlReg() { void HamShield::softReset() { uint16_t tx_data = 0x1; HSwriteWord(devAddr, A1846S_CTL_REG, tx_data); - delay(100); // Note: see A1846S setup info for timing guidelines + HSdelay(100); // Note: see A1846S setup info for timing guidelines tx_data = 0x4; HSwriteWord(devAddr, A1846S_CTL_REG, tx_data); } @@ -540,7 +541,7 @@ void HamShield::setTX(bool on_noff){ //setGpioHi(4); // V1 - delay(50); // delay required by AU1846 + HSdelay(50); // delay required by AU1846 } HSwriteBitW(devAddr, A1846S_CTL_REG, A1846S_TX_MODE_BIT, on_noff); @@ -562,7 +563,7 @@ void HamShield::setRX(bool on_noff){ setGpioLow(4); // V1 setGpioLow(5); // V2 - delay(50); // delay required by AU1846 + HSdelay(50); // delay required by AU1846 } HSwriteBitW(devAddr, A1846S_CTL_REG, A1846S_RX_MODE_BIT, on_noff); @@ -1066,10 +1067,10 @@ void HamShield::lookForTone(uint16_t t_hz) { float tone_hz = (float) t_hz; float Fs = 6400000/1024; float k = floor(tone_hz/Fs*127 + 0.5); - uint16_t t = (uint16_t) (round(2.0*cos(2.0*PI*k/127)*1024)); + uint16_t t = (uint16_t) (round(2.0*cos(2.0*M_PI*k/127)*1024)); float k2 = floor(2*tone_hz/Fs*127+0.5); - uint16_t h = (uint16_t) (round(2.0*cos(2.0*PI*k2/127)*1024)); + uint16_t h = (uint16_t) (round(2.0*cos(2.0*M_PI*k2/127)*1024)); // set tone HSwriteWord(devAddr, 0x68, t); @@ -1370,8 +1371,12 @@ bool HamShield::frequency_float(float freq_khz) { /* FRS Lookup Table */ bool HamShield::setFRSChannel(uint8_t channel) { - if(channel < 15) { + if(channel < 15) { +#if defined(__AVR__) setFrequency(pgm_read_dword_near(FRS + channel)); +#else + setFrequency(FRS[channel]); +#endif return true; } return false; @@ -1382,11 +1387,19 @@ bool HamShield::setFRSChannel(uint8_t channel) { bool HamShield::setGMRSChannel(uint8_t channel) { if((channel > 8) & (channel < 16)) { channel = channel - 7; // we start with 0, to try to avoid channel 8 being nothing - setFrequency(pgm_read_dword_near(FRS + channel)); +#if defined(__AVR__) + setFrequency(pgm_read_dword_near(FRS + channel)); +#else + setFrequency(FRS[channel]); +#endif return true; } if(channel < 9) { - setFrequency(pgm_read_dword_near(GMRS + channel)); +#if defined(__AVR__) + setFrequency(pgm_read_dword_near(GMRS + channel)); +#else + setFrequency(GMRS[channel]); +#endif return true; } return false; @@ -1396,7 +1409,11 @@ bool HamShield::setGMRSChannel(uint8_t channel) { bool HamShield::setMURSChannel(uint8_t channel) { if(channel < 6) { - setFrequency(pgm_read_dword_near(MURS + channel)); +#if defined(__AVR__) + setFrequency(pgm_read_dword_near(MURS + channel)); +#else + setFrequency(MURS[channel]); +#endif return true; } } @@ -1405,7 +1422,11 @@ bool HamShield::setMURSChannel(uint8_t channel) { bool HamShield::setWXChannel(uint8_t channel) { if(channel < 8) { - setFrequency(pgm_read_dword_near(WX + channel)); +#if defined(__AVR__) + setFrequency(pgm_read_dword_near(WX + channel)); +#else + setFrequency(WX[channel]); +#endif setModeReceive(); // turn off squelch? // channel bandwidth? @@ -1421,7 +1442,7 @@ uint8_t HamShield::scanWXChannel() { int16_t toprssi = 0; for(int x = 0; x < 8; x++) { setWXChannel(x); - delay(100); + HSdelay(100); int16_t rssi = readRSSI(); if(rssi > toprssi) { toprssi = rssi; channel = x; } } @@ -1527,13 +1548,13 @@ Does not take in account the millis() overflow bool HamShield::waitForChannel(long timeout = 0, long breakwindow = 0, int setRSSI = HAMSHIELD_EMPTY_CHANNEL_RSSI) { int16_t rssi = 0; // Set RSSI to max received signal for(int x = 0; x < 20; x++) { rssi = readRSSI(); } // "warm up" to get past RSSI hysteresis - long timer = millis() + timeout; // Setup the timeout value + long timer = HSmillis() + timeout; // Setup the timeout value if(timeout == 0) { timer = 4294967295; } // If we want to wait forever, set it to the max millis() - while(timer > millis()) { // while our timer is not timed out. + while(timer > HSmillis()) { // while our timer is not timed out. rssi = readRSSI(); // Read signal strength if(rssi < setRSSI) { // If the channel is empty, lets see if anyone breaks in. - timer = millis() + breakwindow; - while(timer > millis()) { + timer = HSmillis() + breakwindow; + while(timer > HSmillis()) { rssi = readRSSI(); if(rssi > setRSSI) { return false; } // Someone broke into the channel, abort. } return true; // It passed the test...channel is open. @@ -1577,13 +1598,13 @@ void HamShield::morseOut(char buffer[HAMSHIELD_MORSE_BUFFER_SIZE]) { // We delay by 4 here, if we previously sent a symbol. Otherwise 7. // This could probably just be always 7 and go relatively unnoticed. if(prev == 0 || prev == ' '){ - //tone(HAMSHIELD_PWM_PIN, 6000, morse_dot_millis * 7); - noTone(HAMSHIELD_PWM_PIN); - delay(morse_dot_millis*7); + //tone(hs_pwm_pin, 6000, morse_dot_millis * 7); + HSnoTone(hs_pwm_pin); + HSdelay(morse_dot_millis*7); } else { - //tone(HAMSHIELD_PWM_PIN, 6000, morse_dot_millis * 4); - noTone(HAMSHIELD_PWM_PIN); - delay(morse_dot_millis*4); + //tone(hs_pwm_pin, 6000, morse_dot_millis * 4); + HSnoTone(hs_pwm_pin); + HSdelay(morse_dot_millis*4); } continue; } @@ -1592,22 +1613,22 @@ void HamShield::morseOut(char buffer[HAMSHIELD_MORSE_BUFFER_SIZE]) { if(bits) { // If it is a valid character... do { if(bits & 1) { - tone(HAMSHIELD_PWM_PIN, morse_freq, morse_dot_millis * 3); - delay(morse_dot_millis*3); + HStone(hs_pwm_pin, morse_freq, morse_dot_millis * 3); + HSdelay(morse_dot_millis*3); } else { - tone(HAMSHIELD_PWM_PIN, morse_freq, morse_dot_millis); - delay(morse_dot_millis); + HStone(hs_pwm_pin, morse_freq, morse_dot_millis); + HSdelay(morse_dot_millis); } - //tone(HAMSHIELD_PWM_PIN, 6000, morse_dot_millis); - noTone(HAMSHIELD_PWM_PIN); - delay(morse_dot_millis); + //tone(hs_pwm_pin, 6000, morse_dot_millis); + HSnoTone(hs_pwm_pin); + HSdelay(morse_dot_millis); bits >>= 1; // Shift into the next symbol } while(bits != 1); // Wait for 1 termination to be all we have left } // End of character - //tone(HAMSHIELD_PWM_PIN, 6000, morse_dot_millis * 3); - noTone(HAMSHIELD_PWM_PIN); - delay(morse_dot_millis * 3); + //tone(hs_pwm_pin, 6000, morse_dot_millis * 3); + HSnoTone(hs_pwm_pin); + HSdelay(morse_dot_millis * 3); } return; } @@ -1674,7 +1695,7 @@ void HamShield::SSTVVISCode(int code) { toneWait(1900,300); toneWait(1200,30); for(int x = 0; x < 7; x++) { - if(bitRead(code,x)) { toneWait(1100,30); } else { toneWait(1300,30); } + if(code&(1< // HamShield constants #define HAMSHIELD_MORSE_BUFFER_SIZE 80 // Char buffer size for morse code text -#define HAMSHIELD_AUX_BUTTON 2 // Pin assignment for AUX button -#define HAMSHIELD_PWM_PIN 3 // Pin assignment for PWM output #define HAMSHIELD_EMPTY_CHANNEL_RSSI -110 // Default threshold where channel is considered "clear" -// button modes -#define PTT_MODE 1 -#define RESET_MODE 2 - // Device Registers #define A1846S_CTL_REG 0x30 // control register #define A1846S_CLK_MODE_REG 0x04 // clk_mode @@ -230,10 +220,7 @@ class HamShield { public: - // public singleton for ISRs to reference - static HamShield *sHamShield; // HamShield singleton, used for ISRs mostly - - HamShield(uint8_t cs_pin = nSEN, uint8_t clk_pin = CLK, uint8_t dat_pin = DAT); + HamShield(uint8_t cs_pin = nSEN, uint8_t clk_pin = CLK, uint8_t dat_pin = DAT, uint8_t pwm_pin = HAMSHIELD_PWM_PIN); void initialize(); // defaults to 12.5kHz void initialize(bool narrowBand); // select 12.5kHz if true or 25kHz if false @@ -509,6 +496,7 @@ class HamShield { private: uint8_t devAddr; + uint8_t hs_pwm_pin; uint16_t radio_i2c_buf[4]; bool tx_active; bool rx_active; diff --git a/src/HamShield_comms.cpp b/src/HamShield_comms.cpp index c803185..9738d37 100644 --- a/src/HamShield_comms.cpp +++ b/src/HamShield_comms.cpp @@ -5,6 +5,8 @@ #include "HamShield_comms.h" +#include "Arduino.h" +//#include "I2Cdev.h" uint8_t ncs_pin = nSEN; uint8_t clk_pin = CLK; @@ -131,4 +133,25 @@ bool HSwriteWord(uint8_t devAddr, uint8_t regAddr, uint16_t data) digitalWrite(devAddr, 1); //PORTC |= (1<<1); //CS return true; +} + +// Hardware abstraction +unsigned long HSmillis(){ + return millis(); +} +void HSdelay(unsigned long ms) { + delay(ms); +} +void HSdelayMicroseconds(unsigned int us) { + delayMicroseconds(us); +} + +void HStone(uint8_t pin, unsigned int frequency) { + tone(pin, frequency); +} +void HStone(uint8_t pin, unsigned int frequency, unsigned long duration) { + tone(pin, frequency, duration); +} +void HSnoTone(uint8_t pin) { + noTone(pin); } \ No newline at end of file diff --git a/src/HamShield_comms.h b/src/HamShield_comms.h index 3132b7e..8993a28 100644 --- a/src/HamShield_comms.h +++ b/src/HamShield_comms.h @@ -4,12 +4,14 @@ #ifndef _HAMSHIELD_COMMS_H_ #define _HAMSHIELD_COMMS_H_ -#include "Arduino.h" -//#include "I2Cdev.h" +#include "stdint.h" + +#include "Arduino.h" +#define nSEN A1 //15 // +#define CLK A5 //19 // +#define DAT A4 //18 // +#define HAMSHIELD_PWM_PIN 3 // Pin assignment for PWM output -#define nSEN A1 -#define CLK A5 -#define DAT A4 void HSsetPins(uint8_t ncs, uint8_t clk, uint8_t dat); @@ -21,4 +23,16 @@ bool HSwriteBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data bool HSwriteBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data); bool HSwriteWord(uint8_t devAddr, uint8_t regAddr, uint16_t data); + +// hardware abstraction layer + +unsigned long HSmillis(); +void HSdelay(unsigned long ms); +void HSdelayMicroseconds(unsigned int us); + +void HStone(uint8_t pin, unsigned int frequency); +void HStone(uint8_t pin, unsigned int frequency, unsigned long duration); +void HSnoTone(uint8_t pin); + + #endif /* _HAMSHIELD_COMMS_H_ */ \ No newline at end of file