update for I2C

This commit is contained in:
morgan 2016-06-30 20:09:11 -07:00
parent a92b011492
commit a242fa3b31
5 changed files with 63 additions and 132 deletions

View File

@ -119,28 +119,24 @@ volatile long bouncer = 0;
* @see A1846S_DEFAULT_ADDRESS * @see A1846S_DEFAULT_ADDRESS
*/ */
HamShield::HamShield() { HamShield::HamShield() {
devAddr = A1; // devAddr is the chip select pin used by the HamShield devAddr = A1846S_DEV_ADDR_SENLOW;
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 chip select pin for HamShield * @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 cs_pin) { HamShield::HamShield(uint8_t address) {
devAddr = cs_pin; 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.

View File

@ -263,7 +263,7 @@ class HamShield {
static HamShield *sHamShield; // HamShield singleton, used for ISRs mostly static HamShield *sHamShield; // HamShield singleton, used for ISRs mostly
HamShield(); HamShield();
HamShield(uint8_t cs_pin); HamShield(uint8_t address);
void initialize(); void initialize();
bool testConnection(); bool testConnection();

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,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) 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.beginTransmission(devAddr);
regAddr = regAddr | (1 << 7); Wire.requestFrom((int)devAddr, 2); // length=words, this wants bytes
//cli(); bool msb = true; // starts with MSB, then LSB
digitalWrite(devAddr, 0); //PORTC &= ~(1<<1); //devAddr used as chip select for (; Wire.available() && count < 1 && (timeout == 0 || millis() - t1 < timeout);) {
//sei(); if (msb) {
for (int i = 0; i < 8; i++) { // first byte is bits 15-8 (MSb=15)
temp = ((regAddr & (0x80 >> i)) != 0); data[0] = Wire.read() << 8;
cli(); } else {
PORTC &= ~(1<<5); //digitalWrite(CLK, 0); // second byte is bits 7-0 (LSb=0)
sei(); data[0] |= Wire.read();
//digitalWrite(DAT, regAddr & (0x80 >> i)); count++;
temp = (PORTC & ~(1<<4)) + (temp << 4); }
cli(); msb = !msb;
PORTC = temp; }
sei();
delayMicroseconds(9); Wire.endTransmission();
cli();
PORTC |= (1<<5); //digitalWrite(CLK, 1); if (timeout > 0 && millis() - t1 >= timeout && count < 1) count = -1; // timeout
sei();
delayMicroseconds(9); return count;
}
// 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;
} }
@ -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) 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,60 +85,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();
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;
} }

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,6 +1,16 @@
# HamShield # 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 HamShield Arduino Library and Example Sketches