From a242fa3b3103e6a937b9747135851f6378b3a958 Mon Sep 17 00:00:00 2001 From: morgan Date: Thu, 30 Jun 2016 20:09:11 -0700 Subject: [PATCH] update for I2C --- HamShield.cpp | 20 +++--- HamShield.h | 2 +- HamShield_comms.cpp | 155 ++++++++++++-------------------------------- HamShield_comms.h | 6 +- README.md | 12 +++- 5 files changed, 63 insertions(+), 132 deletions(-) diff --git a/HamShield.cpp b/HamShield.cpp index 5aeb3c9..1e9c8ba 100644 --- a/HamShield.cpp +++ b/HamShield.cpp @@ -119,28 +119,24 @@ volatile long bouncer = 0; * @see A1846S_DEFAULT_ADDRESS */ HamShield::HamShield() { - devAddr = A1; // devAddr is the chip select pin used by the HamShield + devAddr = A1846S_DEV_ADDR_SENLOW; sHamShield = this; pinMode(A1, OUTPUT); - digitalWrite(A1, HIGH); - pinMode(A4, OUTPUT); - pinMode(A5, OUTPUT); + digitalWrite(A1, LOW); } /** Specific address constructor. - * @param chip select pin for HamShield + * @param address the I2C address of the HamShield * @see A1846S_DEFAULT_ADDRESS * @see A1846S_ADDRESS_AD0_LOW * @see A1846S_ADDRESS_AD0_HIGH */ -HamShield::HamShield(uint8_t cs_pin) { - devAddr = cs_pin; - - pinMode(A1, OUTPUT); - digitalWrite(A1, HIGH); - pinMode(A4, OUTPUT); - pinMode(A5, OUTPUT); +HamShield::HamShield(uint8_t address) { + devAddr = address; + + pinMode(A1, OUTPUT); + digitalWrite(A1, LOW); } /** Power on and prepare for general usage. diff --git a/HamShield.h b/HamShield.h index 14ad793..c606884 100644 --- a/HamShield.h +++ b/HamShield.h @@ -263,7 +263,7 @@ class HamShield { static HamShield *sHamShield; // HamShield singleton, used for ISRs mostly HamShield(); - HamShield(uint8_t cs_pin); + HamShield(uint8_t address); void initialize(); bool testConnection(); diff --git a/HamShield_comms.cpp b/HamShield_comms.cpp index bbf1381..45411f4 100644 --- a/HamShield_comms.cpp +++ b/HamShield_comms.cpp @@ -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" @@ -27,61 +27,36 @@ 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) { - //return I2Cdev::readWord(devAddr, regAddr, data); - - uint8_t temp; - uint16_t temp_dat; - // bitbang for great justice! - *data = 0; - cli(); - DDRC |= ((1<<5) | (1<<4)); // set direction to output - sei(); - regAddr = regAddr | (1 << 7); - - //cli(); - digitalWrite(devAddr, 0); //PORTC &= ~(1<<1); //devAddr used as chip select - //sei(); - for (int i = 0; i < 8; i++) { - temp = ((regAddr & (0x80 >> i)) != 0); - cli(); - PORTC &= ~(1<<5); //digitalWrite(CLK, 0); - sei(); - //digitalWrite(DAT, regAddr & (0x80 >> i)); - temp = (PORTC & ~(1<<4)) + (temp << 4); - cli(); - PORTC = temp; - sei(); - delayMicroseconds(9); - cli(); - PORTC |= (1<<5); //digitalWrite(CLK, 1); - sei(); - 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); - } - digitalWrite(devAddr, 1); //PORTC |= (1<<1);// CS - - cli(); - DDRC &= ~((1<<5) | (1<<4)); // set direction all input (for ADC) - sei(); - return 1; + + int8_t count = 0; + uint32_t t1 = millis(); + uint8_t timeout = 1000; + + Wire.beginTransmission(devAddr); + Wire.write(regAddr); + Wire.endTransmission(false); +// Wire.beginTransmission(devAddr); + Wire.requestFrom((int)devAddr, 2); // length=words, this wants bytes + + bool msb = true; // starts with MSB, then LSB + for (; Wire.available() && count < 1 && (timeout == 0 || millis() - t1 < timeout);) { + if (msb) { + // first byte is bits 15-8 (MSb=15) + data[0] = Wire.read() << 8; + } else { + // second byte is bits 7-0 (LSb=0) + data[0] |= Wire.read(); + count++; + } + msb = !msb; + } + + Wire.endTransmission(); + + if (timeout > 0 && millis() - t1 >= timeout && count < 1) count = -1; // timeout + + return count; + } @@ -95,7 +70,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) { -uint16_t w; + uint16_t w; if (HSreadWord(devAddr, regAddr, &w) != 0) { uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1); data <<= (bitStart - length + 1); // shift data into correct position @@ -110,60 +85,14 @@ uint16_t w; bool HSwriteWord(uint8_t devAddr, uint8_t regAddr, uint16_t data) { - //return I2Cdev::writeWord(devAddr, regAddr, data); - - uint8_t temp_reg; - uint16_t temp_dat; - - //digitalWrite(13, HIGH); - - // bitbang for great justice! - cli(); - DDRC |= ((1<<5) | (1<<4)); // set direction all output - //PORTC |= (1<<5) & (1<<4); - sei(); - regAddr = regAddr & ~(1 << 7); - - //cli(); - digitalWrite(devAddr, 0); // PORTC &= ~(1<<1); //CS - //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); - } - - digitalWrite(devAddr, 1); //PORTC |= (1<<1); //CS - - cli(); - DDRC &= ~((1<<5) | (1<<4)); // set direction to input for ADC - sei(); - return true; + uint8_t status = 0; + + Wire.beginTransmission(devAddr); + Wire.write(regAddr); // send address + + Wire.write((uint8_t)(data >> 8)); // send MSB + Wire.write((uint8_t)data); // send LSB + + status = Wire.endTransmission(); + return status == 0; } \ No newline at end of file diff --git a/HamShield_comms.h b/HamShield_comms.h index 853153e..88c557b 100644 --- a/HamShield_comms.h +++ b/HamShield_comms.h @@ -5,11 +5,7 @@ #define _HAMSHIELD_COMMS_H_ #include "Arduino.h" -//#include "I2Cdev.h" - -#define nSEN A1 -#define CLK A5 -#define DAT A4 +#include "Wire.h" 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); diff --git a/README.md b/README.md index 0a0e28c..11ae15b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,16 @@ # HamShield -The master branch is intended for use with HamShield hardware -09 and above. +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