switch to setup for Arduino Boards Manager

This commit is contained in:
Erik Tylek Kettenburg
2015-06-23 12:42:35 -07:00
parent bc55c9bb45
commit 6ca6b114d5
3581 changed files with 93 additions and 51 deletions

View File

@@ -0,0 +1,96 @@
/*
TinyWireM.cpp - a wrapper class for TWI/I2C Master library for the ATtiny on Arduino
1/21/2011 BroHogan - brohoganx10 at gmail dot com
**** See TinyWireM.h for Credits and Usage information ****
This library is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 2.1 of the License, or any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
*/
extern "C" {
//#include "USI_TWI_Master.h"
//#include <USI_TWI_Master.h>
//#include <USI_TWI_Master\USI_TWI_Master.h>
//#include <USI_TWI_Master/USI_TWI_Master.h>
}
#include "USI_TWI_Master.h"
#include "TinyWireM.h"
// Initialize Class Variables //////////////////////////////////////////////////
uint8_t USI_TWI::USI_Buf[USI_BUF_SIZE]; // holds I2C send and receive data
uint8_t USI_TWI::USI_BufIdx = 0; // current number of bytes in the send buff
uint8_t USI_TWI::USI_LastRead = 0; // number of bytes read so far
uint8_t USI_TWI::USI_BytesAvail = 0; // number of bytes requested but not read
// Constructors ////////////////////////////////////////////////////////////////
USI_TWI::USI_TWI(){
}
// Public Methods //////////////////////////////////////////////////////////////
void USI_TWI::begin(){ // initialize I2C lib
USI_TWI_Master_Initialise();
}
void USI_TWI::beginTransmission(uint8_t slaveAddr){ // setup address & write bit
USI_BufIdx = 0;
USI_Buf[USI_BufIdx] = (slaveAddr<<TWI_ADR_BITS) | USI_SEND;
}
void USI_TWI::send(uint8_t data){ // buffers up data to send
if (USI_BufIdx >= USI_BUF_SIZE) return; // dont blow out the buffer
USI_BufIdx++; // inc for next byte in buffer
USI_Buf[USI_BufIdx] = data;
}
uint8_t USI_TWI::endTransmission(){ // actually sends the buffer
bool xferOK = false;
uint8_t errorCode = 0;
xferOK = USI_TWI_Start_Read_Write(USI_Buf,USI_BufIdx+1); // core func that does the work
USI_BufIdx = 0;
if (xferOK) return 0;
else { // there was an error
errorCode = USI_TWI_Get_State_Info(); // this function returns the error number
return errorCode;
}
}
uint8_t USI_TWI::requestFrom(uint8_t slaveAddr, uint8_t numBytes){ // setup for receiving from slave
bool xferOK = false;
uint8_t errorCode = 0;
USI_LastRead = 0;
USI_BytesAvail = numBytes; // save this off in a global
numBytes++; // add extra byte to transmit header
USI_Buf[0] = (slaveAddr<<TWI_ADR_BITS) | USI_RCVE; // setup address & Rcve bit
xferOK = USI_TWI_Start_Read_Write(USI_Buf,numBytes); // core func that does the work
// USI_Buf now holds the data read
if (xferOK) return 0;
else { // there was an error
errorCode = USI_TWI_Get_State_Info(); // this function returns the error number
return errorCode;
}
}
uint8_t USI_TWI::receive(){ // returns the bytes received one at a time
USI_LastRead++; // inc first since first uint8_t read is in USI_Buf[1]
return USI_Buf[USI_LastRead];
}
uint8_t USI_TWI::available(){ // the bytes available that haven't been read yet
return USI_BytesAvail - (USI_LastRead);
}
// Preinstantiate Objects //////////////////////////////////////////////////////
USI_TWI TinyWireM = USI_TWI();

View File

@@ -0,0 +1,67 @@
/*
TinyWireM.h - a wrapper(+) class for TWI/I2C Master library for the ATtiny on Arduino
1/21/2011 BroHogan - brohoganx10 at gmail dot com
Thanks to 'jkl' for the gcc version of Atmel's USI_TWI_Master code
http://www.cs.cmu.edu/~dst/ARTSI/Create/PC%20Comm/
I added Atmel's original Device dependant defines section back into USI_TWI_Master.h
NOTE! - It's very important to use pullups on the SDA & SCL lines! More so than with the Wire lib.
USAGE is modeled after the standard Wire library . . .
Put in setup():
TinyWireM.begin(){ // initialize I2C lib
To Send:
TinyWireM.beginTransmission(uint8_t slaveAddr){ // setup slave's address (7 bit address - same as Wire)
TinyWireM.send(uint8_t data){ // buffer up bytes to send - can be called multiple times
someByte = TinyWireM.endTransmission(){ // actually send the bytes in the buffer
// returns (optional) 0 = sucess or see USI_TWI_Master.h for error codes
To Receive:
someByte = TinyWireM.requestFrom(uint8_t slaveAddr, uint8_t numBytes){ // reads 'numBytes' from slave's address
// (usage optional) returns 0= success or see USI_TWI_Master.h for error codes
someByte = TinyWireM.receive(){ // returns the next byte in the received buffer - called multiple times
someByte = TinyWireM.available(){ // returns the number of unread bytes in the received buffer
TODO: (by others!)
- merge this class with TinyWireS for master & slave support in one library
This library is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 2.1 of the License, or any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
*/
#ifndef TinyWireM_h
#define TinyWireM_h
#include <inttypes.h>
#define USI_SEND 0 // indicates sending to TWI
#define USI_RCVE 1 // indicates receiving from TWI
#define USI_BUF_SIZE 16 // bytes in message buffer
class USI_TWI
{
private:
static uint8_t USI_Buf[]; // holds I2C send and receive data
static uint8_t USI_BufIdx; // current number of bytes in the send buff
static uint8_t USI_LastRead; // number of bytes read so far
static uint8_t USI_BytesAvail; // number of bytes requested but not read
public:
USI_TWI();
void begin();
void beginTransmission(uint8_t);
void send(uint8_t);
uint8_t endTransmission();
uint8_t requestFrom(uint8_t, uint8_t);
uint8_t receive();
uint8_t available();
};
extern USI_TWI TinyWireM;
#endif

View File

@@ -0,0 +1,343 @@
/*****************************************************************************
*
*
* File USI_TWI_Master.c compiled with gcc
* Date Friday, 10/31/08 Boo!
* Updated by jkl
*
* AppNote : AVR310 - Using the USI module as a TWI Master
*
* Extensively modified to provide complete I2C driver.
*
*Notes:
* - T4_TWI and T2_TWI delays are modified to work with 1MHz default clock
* and now use hard code values. They would need to change
* for other clock rates. Refer to the Apps Note.
*
* 12/17/08 Added USI_TWI_Start_Memory_Read Routine -jkl
* Note msg buffer will have slave adrs ( with write bit set) and memory adrs;
* length should be these two bytes plus the number of bytes to read.
****************************************************************************/
#include <avr/interrupt.h>
#if defined (__AVR_ATtiny45__) || defined (__AVR_ATtiny85__)
#define F_CPU 16500000UL
#elif defined (__AVR_ATtiny87__) || defined (__AVR_ATtiny167__)
#define F_CPU 16000000UL // Sets up the default speed for delay.h
#endif
#include <util/delay.h>
#include <avr/io.h>
#include "USI_TWI_Master.h"
unsigned char USI_TWI_Start_Transceiver_With_Data( unsigned char * , unsigned char );
unsigned char USI_TWI_Master_Transfer( unsigned char );
unsigned char USI_TWI_Master_Stop( void );
unsigned char USI_TWI_Master_Start( void );
union USI_TWI_state
{
unsigned char errorState; // Can reuse the TWI_state for error states since it will not be needed if there is an error.
struct
{
unsigned char addressMode : 1;
unsigned char masterWriteDataMode : 1;
unsigned char memReadMode : 1;
unsigned char unused : 5;
};
} USI_TWI_state;
/*---------------------------------------------------------------
USI TWI single master initialization function
---------------------------------------------------------------*/
void USI_TWI_Master_Initialise( void )
{
PORT_USI |= (1<<PIN_USI_SDA); // Enable pullup on SDA, to set high as released state.
PORT_USI |= (1<<PIN_USI_SCL); // Enable pullup on SCL, to set high as released state.
DDR_USI |= (1<<PIN_USI_SCL); // Enable SCL as output.
DDR_USI |= (1<<PIN_USI_SDA); // Enable SDA as output.
USIDR = 0xFF; // Preload dataregister with "released level" data.
USICR = (0<<USISIE)|(0<<USIOIE)| // Disable Interrupts.
(1<<USIWM1)|(0<<USIWM0)| // Set USI in Two-wire mode.
(1<<USICS1)|(0<<USICS0)|(1<<USICLK)| // Software stobe as counter clock source
(0<<USITC);
USISR = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| // Clear flags,
(0x0<<USICNT0); // and reset counter.
}
/*---------------------------------------------------------------
Use this function to get hold of the error message from the last transmission
---------------------------------------------------------------*/
unsigned char USI_TWI_Get_State_Info( void )
{
return ( USI_TWI_state.errorState ); // Return error state.
}
/*---------------------------------------------------------------
USI Random (memory) Read function. This function sets up for call
to USI_TWI_Start_Transceiver_With_Data which does the work.
Doesn't matter if read/write bit is set or cleared, it'll be set
correctly in this function.
The msgSize is passed to USI_TWI_Start_Transceiver_With_Data.
Success or error code is returned. Error codes are defined in
USI_TWI_Master.h
---------------------------------------------------------------*/
unsigned char USI_TWI_Start_Random_Read( unsigned char *msg, unsigned char msgSize)
{
*(msg) &= ~(TRUE<<TWI_READ_BIT); // clear the read bit if it's set
USI_TWI_state.errorState = 0;
USI_TWI_state.memReadMode = TRUE;
return (USI_TWI_Start_Transceiver_With_Data( msg, msgSize));
}
/*---------------------------------------------------------------
USI Normal Read / Write Function
Transmit and receive function. LSB of first byte in buffer
indicates if a read or write cycles is performed. If set a read
operation is performed.
Function generates (Repeated) Start Condition, sends address and
R/W, Reads/Writes Data, and verifies/sends ACK.
Success or error code is returned. Error codes are defined in
USI_TWI_Master.h
---------------------------------------------------------------*/
unsigned char USI_TWI_Start_Read_Write( unsigned char *msg, unsigned char msgSize)
{
USI_TWI_state.errorState = 0; // Clears all mode bits also
return (USI_TWI_Start_Transceiver_With_Data( msg, msgSize));
}
/*---------------------------------------------------------------
USI Transmit and receive function. LSB of first byte in buffer
indicates if a read or write cycles is performed. If set a read
operation is performed.
Function generates (Repeated) Start Condition, sends address and
R/W, Reads/Writes Data, and verifies/sends ACK.
This function also handles Random Read function if the memReadMode
bit is set. In that case, the function will:
The address in memory will be the second
byte and is written *without* sending a STOP.
Then the Read bit is set (lsb of first byte), the byte count is
adjusted (if needed), and the function function starts over by sending
the slave address again and reading the data.
Success or error code is returned. Error codes are defined in
USI_TWI_Master.h
---------------------------------------------------------------*/
unsigned char USI_TWI_Start_Transceiver_With_Data( unsigned char *msg, unsigned char msgSize)
{
unsigned char const tempUSISR_8bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| // Prepare register value to: Clear flags, and
(0x0<<USICNT0); // set USI to shift 8 bits i.e. count 16 clock edges.
unsigned char const tempUSISR_1bit = (1<<USISIF)|(1<<USIOIF)|(1<<USIPF)|(1<<USIDC)| // Prepare register value to: Clear flags, and
(0xE<<USICNT0); // set USI to shift 1 bit i.e. count 2 clock edges.
unsigned char *savedMsg;
unsigned char savedMsgSize;
//This clear must be done before calling this function so that memReadMode can be specified.
// USI_TWI_state.errorState = 0; // Clears all mode bits also
USI_TWI_state.addressMode = TRUE; // Always true for first byte
#ifdef PARAM_VERIFICATION
if(msg > (unsigned char*)RAMEND) // Test if address is outside SRAM space
{
USI_TWI_state.errorState = USI_TWI_DATA_OUT_OF_BOUND;
return (FALSE);
}
if(msgSize <= 1) // Test if the transmission buffer is empty
{
USI_TWI_state.errorState = USI_TWI_NO_DATA;
return (FALSE);
}
#endif
#ifdef NOISE_TESTING // Test if any unexpected conditions have arrived prior to this execution.
if( USISR & (1<<USISIF) )
{
USI_TWI_state.errorState = USI_TWI_UE_START_CON;
return (FALSE);
}
if( USISR & (1<<USIPF) )
{
USI_TWI_state.errorState = USI_TWI_UE_STOP_CON;
return (FALSE);
}
if( USISR & (1<<USIDC) )
{
USI_TWI_state.errorState = USI_TWI_UE_DATA_COL;
return (FALSE);
}
#endif
if ( !(*msg & (1<<TWI_READ_BIT)) ) // The LSB in the address byte determines if is a masterRead or masterWrite operation.
{
USI_TWI_state.masterWriteDataMode = TRUE;
}
// if (USI_TWI_state.memReadMode)
// {
savedMsg = msg;
savedMsgSize = msgSize;
// }
if ( !USI_TWI_Master_Start( ))
{
return (FALSE); // Send a START condition on the TWI bus.
}
/*Write address and Read/Write data */
do
{
/* If masterWrite cycle (or inital address tranmission)*/
if (USI_TWI_state.addressMode || USI_TWI_state.masterWriteDataMode)
{
/* Write a byte */
PORT_USI &= ~(1<<PIN_USI_SCL); // Pull SCL LOW.
USIDR = *(msg++); // Setup data.
USI_TWI_Master_Transfer( tempUSISR_8bit ); // Send 8 bits on bus.
/* Clock and verify (N)ACK from slave */
DDR_USI &= ~(1<<PIN_USI_SDA); // Enable SDA as input.
if( USI_TWI_Master_Transfer( tempUSISR_1bit ) & (1<<TWI_NACK_BIT) )
{
if ( USI_TWI_state.addressMode )
USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_ADDRESS;
else
USI_TWI_state.errorState = USI_TWI_NO_ACK_ON_DATA;
return (FALSE);
}
if ((!USI_TWI_state.addressMode) && USI_TWI_state.memReadMode)// means memory start address has been written
{
msg = savedMsg; // start at slave address again
*(msg) |= (TRUE<<TWI_READ_BIT); // set the Read Bit on Slave address
USI_TWI_state.errorState = 0;
USI_TWI_state.addressMode = TRUE; // Now set up for the Read cycle
msgSize = savedMsgSize; // Set byte count correctly
// NOte that the length should be Slave adrs byte + # bytes to read + 1 (gets decremented below)
if ( !USI_TWI_Master_Start( ))
{
USI_TWI_state.errorState = USI_TWI_BAD_MEM_READ;
return (FALSE); // Send a START condition on the TWI bus.
}
}
else
{
USI_TWI_state.addressMode = FALSE; // Only perform address transmission once.
}
}
/* Else masterRead cycle*/
else
{
/* Read a data byte */
DDR_USI &= ~(1<<PIN_USI_SDA); // Enable SDA as input.
*(msg++) = USI_TWI_Master_Transfer( tempUSISR_8bit );
/* Prepare to generate ACK (or NACK in case of End Of Transmission) */
if( msgSize == 1) // If transmission of last byte was performed.
{
USIDR = 0xFF; // Load NACK to confirm End Of Transmission.
}
else
{
USIDR = 0x00; // Load ACK. Set data register bit 7 (output for SDA) low.
}
USI_TWI_Master_Transfer( tempUSISR_1bit ); // Generate ACK/NACK.
}
}while( --msgSize) ; // Until all data sent/received.
if (!USI_TWI_Master_Stop())
{
return (FALSE); // Send a STOP condition on the TWI bus.
}
/* Transmission successfully completed*/
return (TRUE);
}
/*---------------------------------------------------------------
Core function for shifting data in and out from the USI.
Data to be sent has to be placed into the USIDR prior to calling
this function. Data read, will be return'ed from the function.
---------------------------------------------------------------*/
unsigned char USI_TWI_Master_Transfer( unsigned char temp )
{
USISR = temp; // Set USISR according to temp.
// Prepare clocking.
temp = (0<<USISIE)|(0<<USIOIE)| // Interrupts disabled
(1<<USIWM1)|(0<<USIWM0)| // Set USI in Two-wire mode.
(1<<USICS1)|(0<<USICS0)|(1<<USICLK)| // Software clock strobe as source.
(1<<USITC); // Toggle Clock Port.
do
{
_delay_us(T2_TWI);
USICR = temp; // Generate positve SCL edge.
while( !(PIN_USI & (1<<PIN_USI_SCL)) );// Wait for SCL to go high.
_delay_us(T4_TWI);
USICR = temp; // Generate negative SCL edge.
}while( !(USISR & (1<<USIOIF)) ); // Check for transfer complete.
_delay_us(T2_TWI);
temp = USIDR; // Read out data.
USIDR = 0xFF; // Release SDA.
DDR_USI |= (1<<PIN_USI_SDA); // Enable SDA as output.
return temp; // Return the data from the USIDR
}
/*---------------------------------------------------------------
Function for generating a TWI Start Condition.
---------------------------------------------------------------*/
unsigned char USI_TWI_Master_Start( void )
{
/* Release SCL to ensure that (repeated) Start can be performed */
PORT_USI |= (1<<PIN_USI_SCL); // Release SCL.
while( !(PORT_USI & (1<<PIN_USI_SCL)) ); // Verify that SCL becomes high.
_delay_us(T2_TWI);
/* Generate Start Condition */
PORT_USI &= ~(1<<PIN_USI_SDA); // Force SDA LOW.
_delay_us(T4_TWI);
PORT_USI &= ~(1<<PIN_USI_SCL); // Pull SCL LOW.
PORT_USI |= (1<<PIN_USI_SDA); // Release SDA.
#ifdef SIGNAL_VERIFY
if( !(USISR & (1<<USISIF)) )
{
USI_TWI_state.errorState = USI_TWI_MISSING_START_CON;
return (FALSE);
}
#endif
return (TRUE);
}
/*---------------------------------------------------------------
Function for generating a TWI Stop Condition. Used to release
the TWI bus.
---------------------------------------------------------------*/
unsigned char USI_TWI_Master_Stop( void )
{
PORT_USI &= ~(1<<PIN_USI_SDA); // Pull SDA low.
PORT_USI |= (1<<PIN_USI_SCL); // Release SCL.
while( !(PIN_USI & (1<<PIN_USI_SCL)) ); // Wait for SCL to go high.
_delay_us(T4_TWI);
PORT_USI |= (1<<PIN_USI_SDA); // Release SDA.
_delay_us(T2_TWI);
#ifdef SIGNAL_VERIFY
if( !(USISR & (1<<USIPF)) )
{
USI_TWI_state.errorState = USI_TWI_MISSING_STOP_CON;
return (FALSE);
}
#endif
return (TRUE);
}

View File

@@ -0,0 +1,122 @@
/*****************************************************************************
*
*
* File USI_TWI_Master.h compiled with gcc
* Date Friday, 10/31/08 Boo!
* Updated by jkl
*
*
* Supported devices : All device with USI module can be used.
* The example is written for the ATtiny2313
*
* AppNote : AVR310 - Using the USI module as a TWI Master
*
* This is modified to just do I2C communication on ATtiny2313 running at
* 1MHz. Fast mode is probably possible, but would need a faster clock
* and has not been tested.
*
* 12/15/08 Added declaration of USI_TWI_Start_Memory_Read -jkl
****************************************************************************/
//********** Defines **********//
// Defines controlling timing limits - SCL <= 100KHz.
#if defined (__AVR_ATtiny45__) || defined (__AVR_ATtiny85__)
#define SYS_CLK 16500.0 // [kHz] Default for ATtiny2313
#elif defined (__AVR_ATtiny87__) || defined (__AVR_ATtiny167__)
#define SYS_CLK 16000.0 // [kHz] Default for ATtiny2313
#endif
// For use with _delay_us()
#define T2_TWI 5 // >4,7us
#define T4_TWI 4 // >4,0us
// Defines error code generating
//#define PARAM_VERIFICATION
//#define NOISE_TESTING
#define SIGNAL_VERIFY // This should probably be on always.
/****************************************************************************
Bit and byte definitions
****************************************************************************/
#define TWI_READ_BIT 0 // Bit position for R/W bit in "address byte".
#define TWI_ADR_BITS 1 // Bit position for LSB of the slave address bits in the init byte.
#define TWI_NACK_BIT 0 // Bit position for (N)ACK bit.
// Note these have been renumbered from the Atmel Apps Note. Most likely errors are now
// lowest numbers so they're easily recognized as LED flashes.
#define USI_TWI_NO_DATA 0x08 // Transmission buffer is empty
#define USI_TWI_DATA_OUT_OF_BOUND 0x09 // Transmission buffer is outside SRAM space
#define USI_TWI_UE_START_CON 0x07 // Unexpected Start Condition
#define USI_TWI_UE_STOP_CON 0x06 // Unexpected Stop Condition
#define USI_TWI_UE_DATA_COL 0x05 // Unexpected Data Collision (arbitration)
#define USI_TWI_NO_ACK_ON_DATA 0x02 // The slave did not acknowledge all data
#define USI_TWI_NO_ACK_ON_ADDRESS 0x01 // The slave did not acknowledge the address
#define USI_TWI_MISSING_START_CON 0x03 // Generated Start Condition not detected on bus
#define USI_TWI_MISSING_STOP_CON 0x04 // Generated Stop Condition not detected on bus
#define USI_TWI_BAD_MEM_READ 0x0A // Error during external memory read
// Device dependant defines ADDED BACK IN FROM ORIGINAL ATMEL .H
#if defined(__AVR_AT90Mega169__) | defined(__AVR_ATmega169__) | \
defined(__AVR_AT90Mega165__) | defined(__AVR_ATmega165__) | \
defined(__AVR_ATmega325__) | defined(__AVR_ATmega3250__) | \
defined(__AVR_ATmega645__) | defined(__AVR_ATmega6450__) | \
defined(__AVR_ATmega329__) | defined(__AVR_ATmega3290__) | \
defined(__AVR_ATmega649__) | defined(__AVR_ATmega6490__)
#define DDR_USI DDRE
#define PORT_USI PORTE
#define PIN_USI PINE
#define PORT_USI_SDA PORTE5
#define PORT_USI_SCL PORTE4
#define PIN_USI_SDA PINE5
#define PIN_USI_SCL PINE4
#endif
#if defined(__AVR_ATtiny25__) | defined(__AVR_ATtiny45__) | defined(__AVR_ATtiny85__) | \
defined(__AVR_AT90Tiny26__) | defined(__AVR_ATtiny26__) | defined(__AVR_ATtiny167__) | \
defined(__AVR_ATtiny87__)
#define DDR_USI DDRB
#define PORT_USI PORTB
#define PIN_USI PINB
#define PORT_USI_SDA PORTB0
#define PORT_USI_SCL PORTB2
#define PIN_USI_SDA PINB0
#define PIN_USI_SCL PINB2
#endif
#if defined(__AVR_AT90Tiny2313__) | defined(__AVR_ATtiny2313__)
#define DDR_USI DDRB
#define PORT_USI PORTB
#define PIN_USI PINB
#define PORT_USI_SDA PORTB5
#define PORT_USI_SCL PORTB7
#define PIN_USI_SDA PINB5
#define PIN_USI_SCL PINB7
#endif
/* From the original .h
// Device dependant defines - These for ATtiny2313. // CHANGED FOR ATtiny85
#define DDR_USI DDRB
#define PORT_USI PORTB
#define PIN_USI PINB
#define PORT_USI_SDA PORTB0 // was PORTB5 - N/U
#define PORT_USI_SCL PORTB2 // was PORTB7 - N/U
#define PIN_USI_SDA PINB0 // was PINB5
#define PIN_USI_SCL PINB2 // was PINB7
*/
// General defines
#define TRUE 1
#define FALSE 0
//********** Prototypes **********//
void USI_TWI_Master_Initialise( void );
unsigned char USI_TWI_Start_Random_Read( unsigned char * , unsigned char );
unsigned char USI_TWI_Start_Read_Write( unsigned char * , unsigned char );
unsigned char USI_TWI_Get_State_Info( void );

View File

@@ -0,0 +1,78 @@
/* ATtiny85 as an I2C Master Ex1 BroHogan 1/21/11
* I2C master reading DS1621 temperature sensor. (display with leds)
* SETUP:
* ATtiny Pin 1 = (RESET) N/U ATtiny Pin 2 = (D3) LED3
* ATtiny Pin 3 = (D4) to LED1 ATtiny Pin 4 = GND
* ATtiny Pin 5 = SDA on DS1621 ATtiny Pin 6 = (D1) to LED2
* ATtiny Pin 7 = SCK on DS1621 ATtiny Pin 8 = VCC (2.7-5.5V)
* NOTE! - It's very important to use pullups on the SDA & SCL lines!
* DS1621 wired per data sheet. This ex assumes A0-A2 are set LOW for an addeess of 0x48
* TinyWireM USAGE & CREDITS: - see TinyWireM.h
* NOTES:
* The ATtiny85 + DS1621 draws 1.7mA @5V when leds are not on and not reading temp.
* Using sleep mode, they draw .2 @5V @ idle - see http://brownsofa.org/blog/archives/261
*/
#include <TinyWireM.h> // I2C Master lib for ATTinys which use USI
#define DS1621_ADDR 0x48 // 7 bit I2C address for DS1621 temperature sensor
#define LED1_PIN 4 // ATtiny Pin 3
#define LED2_PIN 1 // ATtiny Pin 6
#define LED3_PIN 3 // ATtiny Pin 2
int tempC = 0; // holds temp in C
int tempF = 0; // holds temp in F
void setup(){
pinMode(LED1_PIN,OUTPUT);
pinMode(LED2_PIN,OUTPUT);
pinMode(LED3_PIN,OUTPUT);
Blink(LED1_PIN,2); // show it's alive
TinyWireM.begin(); // initialize I2C lib
Init_Temp(); // Setup DS1621
delay (3000);
}
void loop(){
Get_Temp();
Blink(LED1_PIN,tempC/10); // blink 10's of temperature on LED 1
delay (1000);
Blink(LED2_PIN,tempC%10); // blink 1's of temperature on LED 2
delay (4000); // wait a few sec before next reading
}
void Init_Temp(){ // Setup the DS1621 for one-shot mode
TinyWireM.beginTransmission(DS1621_ADDR);
TinyWireM.send(0xAC); // Access Command Register
TinyWireM.send(B00000001); // Using one-shot mode for battery savings
//TinyWireM.send(B00000000); // if setting continious mode for fast reads
TinyWireM.endTransmission(); // Send to the slave
}
void Get_Temp(){ // Get the temperature from a DS1621
TinyWireM.beginTransmission(DS1621_ADDR);
TinyWireM.send(0xEE); // if one-shot, start conversions now
TinyWireM.endTransmission(); // Send 1 byte to the slave
delay(750); // if one-shot, must wait ~750 ms for conversion
TinyWireM.beginTransmission(DS1621_ADDR);
TinyWireM.send(0xAA); // read temperature (for either mode)
TinyWireM.endTransmission(); // Send 1 byte to the slave
TinyWireM.requestFrom(DS1621_ADDR,1); // Request 1 byte from slave
tempC = TinyWireM.receive(); // get the temperature
tempF = tempC * 9 / 5 + 32; // convert to Fahrenheit
}
void Blink(byte led, byte times){ // poor man's GUI
for (byte i=0; i< times; i++){
digitalWrite(led,HIGH);
delay (400);
digitalWrite(led,LOW);
delay (175);
}
}

View File

@@ -0,0 +1,96 @@
/* ATtiny85 as an I2C Master Ex2 BroHogan 1/21/11
* I2C master reading DS1621 temperature sensor. Display to I2C GPIO LED.
* SETUP:
* ATtiny Pin 1 = (RESET) N/U ATtiny Pin 2 = (D3) N/U
* ATtiny Pin 3 = (D4) to LED1 ATtiny Pin 4 = GND
* ATtiny Pin 5 = SDA on DS1621 & GPIO ATtiny Pin 6 = (D1) to LED2
* ATtiny Pin 7 = SCK on DS1621 & GPIO ATtiny Pin 8 = VCC (2.7-5.5V)
* NOTE! - It's very important to use pullups on the SDA & SCL lines!
* DS1621 wired per data sheet. This ex assumes A0-A2 are set LOW for an addeess of 0x48
* PCA8574A GPIO was used wired per instructions in "info" folder in the LiquidCrystal_I2C lib.
* This ex assumes A0-A2 are set HIGH for an addeess of 0x3F
* LiquidCrystal_I2C lib was modified for ATtiny - on Playground with TinyWireM lib.
* TinyWireM USAGE & CREDITS: - see TinyWireM.h
*/
//#define DEBUG
#include <TinyWireM.h> // I2C Master lib for ATTinys which use USI
#include <LiquidCrystal_I2C.h> // for LCD w/ GPIO MODIFIED for the ATtiny85
#define GPIO_ADDR 0x3F // (PCA8574A A0-A2 @5V) typ. A0-A3 Gnd 0x20 / 0x38 for A
#define DS1621_ADDR 0x48 // 7 bit I2C address for DS1621 temperature sensor
#define LED1_PIN 4 // ATtiny Pin 3
#define LED2_PIN 1 // ATtiny Pin 6
int tempC = 0; // holds temp in C
int tempF = 0; // holds temp in F
LiquidCrystal_I2C lcd(GPIO_ADDR,16,2); // set address & 16 chars / 2 lines
void setup(){
#ifdef DEBUG
pinMode(LED1_PIN,OUTPUT);
pinMode(LED2_PIN,OUTPUT);
Blink(LED1_PIN,2); // show it's alive
#endif
TinyWireM.begin(); // initialize I2C lib
Init_Temp(); // Setup DS1621
lcd.init(); // initialize the lcd
lcd.backlight(); // Print a message to the LCD.
lcd.print("Hello, Temp!");
delay (2000);
}
void loop(){
Get_Temp(); // read current temperature
lcd.clear(); // display it
lcd.print("C: ");
lcd.print(tempC,DEC);
lcd.setCursor(7,0);
lcd.print("F: ");
lcd.print(tempF,DEC);
#ifdef DEBUG
Blink(LED1_PIN,tempC/10); // blink 10's of temperature on LED 1
delay (1000);
Blink(LED2_PIN,tempC%10); // blink 1's of temperature on LED 2
#endif
delay (4000); // wait a few sec before next reading
}
void Init_Temp(){ // Setup the DS1621 for one-shot mode
TinyWireM.beginTransmission(DS1621_ADDR);
TinyWireM.send(0xAC); // Access Command Register
TinyWireM.send(B00000001); // Using one-shot mode for battery savings
//TinyWireM.send(B00000000); // if setting continious mode for fast reads
TinyWireM.endTransmission(); // Send to the slave
}
void Get_Temp(){ // Get the temperature from a DS1621
TinyWireM.beginTransmission(DS1621_ADDR);
TinyWireM.send(0xEE); // if one-shot, start conversions now
TinyWireM.endTransmission(); // Send 1 byte to the slave
delay(750); // if one-shot, must wait ~750 ms for conversion
TinyWireM.beginTransmission(DS1621_ADDR);
TinyWireM.send(0xAA); // read temperature (for either mode)
TinyWireM.endTransmission(); // Send 1 byte to the slave
TinyWireM.requestFrom(DS1621_ADDR,1); // Request 1 byte from slave
tempC = TinyWireM.receive(); // get the temperature
tempF = tempC * 9 / 5 + 32; // convert to Fahrenheit
}
#ifdef DEBUG
void Blink(byte led, byte times){ // poor man's GUI
for (byte i=0; i< times; i++){
digitalWrite(led,HIGH);
delay (400);
digitalWrite(led,LOW);
delay (175);
}
}
#endif

View File

@@ -0,0 +1,199 @@
/* ATtiny85 as an I2C Master Ex3 BroHogan 1/22/11
* I2C master reading DS1621 temperature sensor & DS1307 RTC. Display to I2C GPIO LED.
* SETUP:
* ATtiny Pin 1 = (RESET) N/U ATtiny Pin 2 = (D3) N/U
* ATtiny Pin 3 = (D4) to LED1 ATtiny Pin 4 = GND
* ATtiny Pin 5 = SDA on all devices ATtiny Pin 6 = (D1) to LED2
* ATtiny Pin 7 = SCK on all devices ATtiny Pin 8 = VCC (2.7-5.5V)
* NOTE! - It's very important to use pullups on the SDA & SCL lines!
* DS1621 wired per data sheet. This ex assumes A0-A2 are set LOW for an addeess of 0x48
* DS1307 wired per data sheet. This ex assumes A0-A2 are set LOW for an addeess of 0x68
* PCA8574A GPIO was used wired per instructions in "info" folder in the LiquidCrystal_I2C lib.
* This ex assumes A0-A2 are set HIGH for an addeess of 0x3F
* LiquidCrystal_I2C lib was modified for ATtiny - on Playground with TinyWireM lib.
* TinyWireM USAGE & CREDITS: - see TinyWireM.h
*/
//#define DEBUG
#include <TinyWireM.h> // I2C Master lib for ATTinys which use USI
#include <LiquidCrystal_I2C.h> // for LCD w/ GPIO MODIFIED for the ATtiny85
#define GPIO_ADDR 0x3F // (PCA8574A A0-A2 @5V) typ. A0-A3 Gnd 0x20 / 0x38 for A
#define DS1307_ADDR 0x68 // I2C real time clock
#define DS1621_ADDR 0x48 // 7 bit I2C address for DS1621 temperature sensor
#define LED1_PIN 4 // ATtiny Pin 3
#define LED2_PIN 1 // ATtiny Pin 6
//#define HR24 true
int tempC = 0; // holds temp in C
int tempF = 0; // holds temp in F
byte seconds,minutes,hours,day_of_week,days,months,years,PM,hour12,DST;
char timeString[10]; // HH:MM 12 Hr. no AM/PM or 24 Hr (based on param)
char dateString[10]; // MM/DD or DD/MM (based on param)- no year
bool HR24; // 12/24 Hr Time and date
LiquidCrystal_I2C lcd(GPIO_ADDR,16,2); // set address & 16 chars / 2 lines
void setup(){
#ifdef DEBUG
pinMode(LED1_PIN,OUTPUT);
pinMode(LED2_PIN,OUTPUT);
Blink(LED1_PIN,3); // show it's alive
#endif
TinyWireM.begin(); // initialize I2C lib
Init_Temp(); // Setup DS1621
lcd.init(); // initialize the lcd
lcd.backlight(); // Print a message to the LCD.
lcd.print("Hello, Temp!");
delay (2000);
}
void loop(){
Get_Temp(); // read current temperature
Get_Time(); // read current time
lcd.clear(); // display it
lcd.print("C");
lcd.print((char)223);
lcd.print(": ");
lcd.print(tempC,DEC);
lcd.setCursor(9,0);
lcd.print("F");
lcd.print((char)223);
lcd.print(": ");
lcd.print(tempF,DEC);
lcd.setCursor(0,1);
lcd.print(timeString);
lcd.setCursor(9,1);
lcd.print(dateString);
#ifdef DEBUG
Blink(LED1_PIN,tempC/10); // blink 10's of temperature on LED 1
delay (1000);
Blink(LED2_PIN,tempC%10); // blink 1's of temperature on LED 2
#endif
HR24 = ! HR24; // flip the format
delay (4000); // wait a few sec before next reading
}
void Init_Temp(){ // Setup the DS1621 for one-shot mode
TinyWireM.beginTransmission(DS1621_ADDR);
TinyWireM.send(0xAC); // Access Command Register
TinyWireM.send(B00000001); // Using one-shot mode for battery savings
//TinyWireM.send(B00000000); // if setting continious mode for fast reads
TinyWireM.endTransmission(); // Send to the slave
}
void Get_Temp(){ // Get the temperature from a DS1621
TinyWireM.beginTransmission(DS1621_ADDR);
TinyWireM.send(0xEE); // if one-shot, start conversions now
TinyWireM.endTransmission(); // Send 1 byte to the slave
delay(750); // if one-shot, must wait ~750 ms for conversion
TinyWireM.beginTransmission(DS1621_ADDR);
TinyWireM.send(0xAA); // read temperature (for either mode)
TinyWireM.endTransmission(); // Send 1 byte to the slave
TinyWireM.requestFrom(DS1621_ADDR,1); // Request 1 byte from slave
tempC = TinyWireM.receive(); // get the temperature
tempF = tempC * 9 / 5 + 32; // convert to Fahrenheit
}
void Get_Time(){ // get the time and date from the DS1307 chip
byte wireRet = 0;
memset(timeString,0,sizeof(timeString)); // initialize the strings
memset(dateString,0,sizeof(dateString));
TinyWireM.beginTransmission(DS1307_ADDR); // reset DS1307 register pointer
TinyWireM.send(0);
wireRet = TinyWireM.endTransmission();
if (wireRet) { // report any send esrrors
lcd.clear();
lcd.print("SendError: ");
lcd.print(wireRet,DEC);
delay(1500);
}
wireRet = TinyWireM.requestFrom(DS1307_ADDR, 7); // request 7 bytes from DS1307
if (wireRet) { // report any receive esrrors
lcd.clear();
lcd.print("RcveError: ");
lcd.print(wireRet,DEC);
delay(1500);
}
#ifdef DEBUG
lcd.clear();
lcd.print("Before Reads: ");
lcd.print(TinyWireM.available(),DEC); // testing TinyWireM.available()
delay(1500);
#endif
seconds = bcdToDec(TinyWireM.receive()); // handle the 7 bytes received
minutes = bcdToDec(TinyWireM.receive());
hours = bcdToDec(TinyWireM.receive());
day_of_week = TinyWireM.receive();
days = bcdToDec(TinyWireM.receive());
months = bcdToDec(TinyWireM.receive());
years = bcdToDec(TinyWireM.receive());
#ifdef DEBUG
lcd.clear();
lcd.print("After Reads: ");
lcd.print(TinyWireM.available(),DEC); // testing TinyWireM.available()
delay(1500);
#endif
// deal with AM/PM global and 12 hour clock
if (hours >= 12) PM = true;
else PM = false;
if (hours > 12)hour12 = hours - 12;
else hour12 = hours;
if (hours == 0) hour12 = 12;
// make time string
if (HR24) AppendToString (hours,timeString); // add 24 hour time to string
else AppendToString (hour12,timeString); // add 12 hour time to string
strcat(timeString,":");
if (minutes < 10) strcat(timeString,"0");
AppendToString (minutes,timeString); // add MINUTES to string
if (!HR24){
if (hours >= 12) strcat(timeString," PM"); // deal with AM/PM
else strcat(timeString," AM");
}
// make date string
if (HR24)AppendToString (days,dateString); // add DAY to string
else AppendToString (months,dateString); // add MONTH to string
strcat(dateString,"/");
if (HR24)AppendToString (months,dateString); // add MONTH to string
else AppendToString (days,dateString); // add DAY to string
strcat(dateString,"/");
if (years < 10) strcat(dateString,"0");
AppendToString (years,dateString); // add YEAR to string
}
void AppendToString (byte bValue, char *pString){ // appends a byte to string passed
char tempStr[6];
memset(tempStr,'\0',sizeof(tempStr));
itoa(bValue,tempStr,10);
strcat(pString,tempStr);
}
byte bcdToDec(byte val) { // Convert binary coded decimal to normal decimal numbers
return ((val / 16 * 10) + (val % 16));
}
#ifdef DEBUG
void Blink(byte led, byte times){ // poor man's GUI
for (byte i=0; i< times; i++){
digitalWrite(led,HIGH);
delay (400);
digitalWrite(led,LOW);
delay (175);
}
}
#endif

View File

@@ -0,0 +1,29 @@
#######################################
# Syntax Coloring Map For TinyWireM
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
beginTransmission KEYWORD2
endTransmission KEYWORD2
requestFrom KEYWORD2
send KEYWORD2
receive KEYWORD2
#######################################
# Instances (KEYWORD2)
#######################################
TinyWireM KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################