6 Commits

Author SHA1 Message Date
morgan
8e5a101b1f fix formatting, comments 2016-07-03 13:27:01 -07:00
morgan
bdd06ce525 updated readme 2016-07-03 13:23:03 -07:00
morgan
a242fa3b31 update for I2C 2016-06-30 20:09:11 -07:00
morgan
a92b011492 updating squelch and cs options 2016-06-30 19:33:40 -07:00
morgan
75e964289c use master for HS09 and above 2016-05-04 11:40:26 -07:00
morgan
fbd1003c44 updated kiss 2016-05-04 11:35:06 -07:00
6 changed files with 89 additions and 145 deletions

View File

@@ -123,24 +123,20 @@ HamShield::HamShield() {
sHamShield = this; sHamShield = this;
pinMode(A1, OUTPUT); pinMode(A1, OUTPUT);
digitalWrite(A1, HIGH); digitalWrite(A1, LOW);
pinMode(A4, OUTPUT);
pinMode(A5, OUTPUT);
} }
/** Specific address constructor. /** Specific address constructor.
* @param address I2C address * @param address the I2C address of the HamShield
* @see A1846S_DEFAULT_ADDRESS * @see A1846S_DEFAULT_ADDRESS
* @see A1846S_ADDRESS_AD0_LOW * @see A1846S_ADDRESS_AD0_LOW
* @see A1846S_ADDRESS_AD0_HIGH * @see A1846S_ADDRESS_AD0_HIGH
*/ */
HamShield::HamShield(uint8_t address) { HamShield::HamShield(uint8_t address) {
devAddr = address; devAddr = address;
pinMode(A1, OUTPUT); pinMode(A1, OUTPUT);
digitalWrite(A1, HIGH); digitalWrite(A1, LOW);
pinMode(A4, OUTPUT);
pinMode(A5, OUTPUT);
} }
/** Power on and prepare for general usage. /** Power on and prepare for general usage.
@@ -720,7 +716,7 @@ void HamShield::setCdcssCode(uint16_t code) {
uint16_t HamShield::getCdcssCode() { uint16_t HamShield::getCdcssCode() {
uint32_t oct_code; uint32_t oct_code;
HSreadWord(devAddr, A1846S_CDCSS_CODE_HI_REG, radio_i2c_buf); HSreadWord(devAddr, A1846S_CDCSS_CODE_HI_REG, radio_i2c_buf);
oct_code = (radio_i2c_buf[0] << 16); oct_code = ((uint32_t)radio_i2c_buf[0] << 16);
HSreadWord(devAddr, A1846S_CDCSS_CODE_LO_REG, radio_i2c_buf); HSreadWord(devAddr, A1846S_CDCSS_CODE_LO_REG, radio_i2c_buf);
oct_code += radio_i2c_buf[0]; oct_code += radio_i2c_buf[0];
@@ -747,23 +743,25 @@ bool HamShield::getSQState(){
} }
// SQ threshold // SQ threshold
void HamShield::setSQHiThresh(uint16_t sq_hi_threshold){ void HamShield::setSQHiThresh(int16_t sq_hi_threshold){
// Sq detect high th, rssi_cmp will be 1 when rssi>th_h_sq, unit 1/8dB // Sq detect high th, rssi_cmp will be 1 when rssi>th_h_sq, unit 1dB
HSwriteWord(devAddr, A1846S_SQ_OPEN_THRESH_REG, sq_hi_threshold); uint16_t sq = 137 + sq_hi_threshold;
HSwriteWord(devAddr, A1846S_SQ_OPEN_THRESH_REG, sq);
} }
uint16_t HamShield::getSQHiThresh(){ int16_t HamShield::getSQHiThresh(){
HSreadWord(devAddr, A1846S_SQ_OPEN_THRESH_REG, radio_i2c_buf); HSreadWord(devAddr, A1846S_SQ_OPEN_THRESH_REG, radio_i2c_buf);
return radio_i2c_buf[0]; return radio_i2c_buf[0] - 137;
} }
void HamShield::setSQLoThresh(uint16_t sq_lo_threshold){ void HamShield::setSQLoThresh(int16_t sq_lo_threshold){
// Sq detect low th, rssi_cmp will be 0 when rssi<th_l_sq && time delay meet, unit 1/8 dB // Sq detect low th, rssi_cmp will be 0 when rssi<th_l_sq && time delay meet, unit 1 dB
HSwriteWord(devAddr, A1846S_SQ_SHUT_THRESH_REG, sq_lo_threshold); uint16_t sq = 137 + sq_lo_threshold;
HSwriteWord(devAddr, A1846S_SQ_SHUT_THRESH_REG, sq);
} }
uint16_t HamShield::getSQLoThresh(){ int16_t HamShield::getSQLoThresh(){
HSreadWord(devAddr, A1846S_SQ_SHUT_THRESH_REG, radio_i2c_buf); HSreadWord(devAddr, A1846S_SQ_SHUT_THRESH_REG, radio_i2c_buf);
return radio_i2c_buf[0]; return radio_i2c_buf[0] - 137;
} }
// SQ out select // SQ out select

View File

@@ -8,8 +8,6 @@
#ifndef _HAMSHIELD_H_ #ifndef _HAMSHIELD_H_
#define _HAMSHIELD_H_ #define _HAMSHIELD_H_
//#include "I2Cdev_rda.h"
//#include "I2Cdev.h"
#include "HamShield_comms.h" #include "HamShield_comms.h"
#include "SimpleFIFO.h" #include "SimpleFIFO.h"
#include "AFSK.h" #include "AFSK.h"
@@ -242,7 +240,7 @@
#define ROBOT8BW 2 #define ROBOT8BW 2
#define SC2-180 55 #define SC2_180 55
#define MARTIN1 44 #define MARTIN1 44
// RTTY Frequencies // RTTY Frequencies
@@ -375,10 +373,10 @@ class HamShield {
bool getSQState(); bool getSQState();
// SQ threshold // SQ threshold
void setSQHiThresh(uint16_t sq_hi_threshold); // Sq detect high th, rssi_cmp will be 1 when rssi>th_h_sq, unit 1/8dB void setSQHiThresh(int16_t sq_hi_threshold); // Sq detect high th, rssi_cmp will be 1 when rssi>th_h_sq, unit 1dB
uint16_t getSQHiThresh(); int16_t getSQHiThresh();
void setSQLoThresh(uint16_t sq_lo_threshold); // Sq detect low th, rssi_cmp will be 0 when rssi<th_l_sq && time delay meet, unit 1/8 dB void setSQLoThresh(int16_t sq_lo_threshold); // Sq detect low th, rssi_cmp will be 0 when rssi<th_l_sq && time delay meet, unit 1dB
uint16_t getSQLoThresh(); int16_t getSQLoThresh();
// SQ out select // SQ out select
void setSQOutSel(); void setSQOutSel();

View File

@@ -1,5 +1,5 @@
/* /*
* Based loosely on I2Cdev by Jeff Rowberg, except for all kludgy bit-banging * Based loosely on I2Cdev by Jeff Rowberg
*/ */
#include "HamShield_comms.h" #include "HamShield_comms.h"
@@ -27,61 +27,35 @@ int8_t HSreadBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t l
int8_t HSreadWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data) int8_t HSreadWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data)
{ {
//return I2Cdev::readWord(devAddr, regAddr, data);
int8_t count = 0;
uint8_t temp; uint32_t t1 = millis();
uint16_t temp_dat; uint8_t timeout = 1000;
// bitbang for great justice!
*data = 0; Wire.beginTransmission(devAddr);
cli(); Wire.write(regAddr);
DDRC |= ((1<<5) | (1<<4)); // set direction to output Wire.endTransmission(false);
sei(); Wire.requestFrom((int)devAddr, 2); // length=words, this wants bytes
regAddr = regAddr | (1 << 7);
bool msb = true; // starts with MSB, then LSB
cli(); for (; Wire.available() && count < 1 && (timeout == 0 || millis() - t1 < timeout);) {
PORTC &= ~(1<<1); //digitalWrite(nSEN, 0); if (msb) {
sei(); // first byte is bits 15-8 (MSb=15)
for (int i = 0; i < 8; i++) { data[0] = Wire.read() << 8;
temp = ((regAddr & (0x80 >> i)) != 0); } else {
cli(); // second byte is bits 7-0 (LSb=0)
PORTC &= ~(1<<5); //digitalWrite(CLK, 0); data[0] |= Wire.read();
sei(); count++;
//digitalWrite(DAT, regAddr & (0x80 >> i)); }
temp = (PORTC & ~(1<<4)) + (temp << 4); msb = !msb;
cli(); }
PORTC = temp;
sei(); Wire.endTransmission();
delayMicroseconds(9);
cli(); if (timeout > 0 && millis() - t1 >= timeout && count < 1) count = -1; // timeout
PORTC |= (1<<5); //digitalWrite(CLK, 1);
sei(); return count;
delayMicroseconds(9);
}
// change direction of DAT
cli();
DDRC &= ~(1<<4); //pinMode(DAT, INPUT);
sei();
for (int i = 15; i >= 0; i--) {
cli();
PORTC &= ~(1<<5); //digitalWrite(CLK, 0);
sei();
delayMicroseconds(9);
cli();
PORTC |= (1<<5); //digitalWrite(CLK, 1);
sei();
cli();
temp_dat = ((PINC & (1<<4)) != 0);
sei();
temp_dat = temp_dat << i;
*data |= temp_dat; // digitalRead(DAT);
delayMicroseconds(9);
}
cli();
PORTC |= (1<<1);//digitalWrite(nSEN, 1);
DDRC &= ~((1<<5) | (1<<4)); // set direction all input (for ADC)
sei();
return 1;
} }
@@ -95,7 +69,7 @@ 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 HSwriteBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data)
{ {
uint16_t w; uint16_t w;
if (HSreadWord(devAddr, regAddr, &w) != 0) { if (HSreadWord(devAddr, regAddr, &w) != 0) {
uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1); uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1);
data <<= (bitStart - length + 1); // shift data into correct position data <<= (bitStart - length + 1); // shift data into correct position
@@ -110,59 +84,14 @@ uint16_t w;
bool HSwriteWord(uint8_t devAddr, uint8_t regAddr, uint16_t data) bool HSwriteWord(uint8_t devAddr, uint8_t regAddr, uint16_t data)
{ {
//return I2Cdev::writeWord(devAddr, regAddr, data); uint8_t status = 0;
uint8_t temp_reg; Wire.beginTransmission(devAddr);
uint16_t temp_dat; Wire.write(regAddr); // send address
//digitalWrite(13, HIGH); Wire.write((uint8_t)(data >> 8)); // send MSB
Wire.write((uint8_t)data); // send LSB
// bitbang for great justice!
cli(); status = Wire.endTransmission();
DDRC |= ((1<<5) | (1<<4)); // set direction all output return status == 0;
//PORTC |= (1<<5) & (1<<4);
sei();
regAddr = regAddr & ~(1 << 7);
cli();
PORTC &= ~(1<<1); //digitalWrite(nSEN, 0);
sei();
for (int i = 0; i < 8; i++) {
temp_reg = ((regAddr & (0x80 >> i)) != 0);
cli();
PORTC &= ~(1<<5); //digitalWrite(CLK, 0);
sei();
//digitalWrite(DAT, regAddr & (0x80 >> i));
temp_reg = (PORTC & ~(1<<4)) + (temp_reg << 4);
cli();
PORTC = temp_reg;
sei();
delayMicroseconds(8);
cli();
PORTC |= (1<<5); //digitalWrite(CLK, 1);
sei();
delayMicroseconds(10);
}
for (int i = 0; i < 16; i++) {
temp_dat = ((data & (0x8000 >> i)) != 0);
cli();
PORTC &= ~(1<<5); //digitalWrite(CLK, 0);
sei();
//digitalWrite(DAT, data & (0x80000 >> i));
temp_reg = (PORTC & ~(1<<4)) + (temp_dat << 4);
cli();
PORTC = temp_reg;
sei();
delayMicroseconds(7);
cli();
PORTC |= (1<<5); //digitalWrite(CLK, 1);
sei();
delayMicroseconds(10);
}
cli();
PORTC |= (1<<1); //digitalWrite(nSEN, 1);
DDRC &= ~((1<<5) | (1<<4)); // set direction to input for ADC
sei();
return true;
} }

View File

@@ -5,11 +5,7 @@
#define _HAMSHIELD_COMMS_H_ #define _HAMSHIELD_COMMS_H_
#include "Arduino.h" #include "Arduino.h"
//#include "I2Cdev.h" #include "Wire.h"
#define nSEN A1
#define CLK A5
#define DAT A4
int8_t HSreadBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data); int8_t HSreadBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data);
int8_t HSreadBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data); int8_t HSreadBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data);

View File

@@ -1,4 +1,27 @@
# HamShield # HamShield
Please note that I2C communications are not officially supported.
The RF transciever on the HamShield has trouble driving large I2C bus capacitances (over 40pF). What this means is that it works well if the transciever is on the same physical PCB as the microcontroller (assuming good layout), but works poorly as a daughterboard.
We recommend that you use the master branch, which uses a custom communications protocol. That custom protocol does not have the same bus capacitance limitation. You're welcome to play around with I2C if you want, but it may cause instability issues.
## Hardware Changes Necessary
The i2c-comms branch is not intended for use with a stock HamShield.
To use i2c communications with a HamShield 09 or above, you must first make several hardware changes to the board.
1. Remove R2
2. Short the pads of R17 (either with a wire or a low value resistor).
Then make sure that you pull the nCS pin correctly. Changing nCS changes the I2C address of the HamShield:
- nCS is logic high: A1846S_DEV_ADDR_SENHIGH 0b0101110
- nCS is logic low: A1846S_DEV_ADDR_SENLOW 0b1110001
HamShield Arduino Library and Example Sketches HamShield Arduino Library and Example Sketches
This repository is meant to be checked out into your Arduino application's libraries folder. After reloading the application, the library and example sketches should be available for use. This repository is meant to be checked out into your Arduino application's libraries folder. After reloading the application, the library and example sketches should be available for use.

View File

@@ -31,7 +31,7 @@ void setup() {
radio.initialize(); radio.initialize();
radio.setSQOff(); radio.setSQOff();
radio.setFrequency(144390); radio.frequency(144390);
//I2Cdev::writeWord(A1846S_DEV_ADDR_SENLOW, 0x44, 0x05FF); //I2Cdev::writeWord(A1846S_DEV_ADDR_SENLOW, 0x44, 0x05FF);
dds.start(); dds.start();