Added tiny master
This commit is contained in:
commit
538884d1c7
131
tiny/master/i2c_master.c
Normal file
131
tiny/master/i2c_master.c
Normal file
@ -0,0 +1,131 @@
|
||||
#include "i2c_master.h"
|
||||
#include <avr/io.h>
|
||||
|
||||
uint8_t i2c_clock(uint8_t type);
|
||||
|
||||
void i2c_init(void)
|
||||
{
|
||||
// Define SCL and SDA as Output
|
||||
DDRB |= (1 << 0) | (1 << 2);
|
||||
|
||||
// Preload dataregister with "released level" data
|
||||
USIDR = 0xFF;
|
||||
|
||||
// Use SCL and SDA pins
|
||||
// Select clock sources
|
||||
USICR = (1 << USIWM1) | (1 << USICS1) | (1 << USICLK);
|
||||
|
||||
// Clear flags and reset counter
|
||||
USISR = (1 << USISIF) | (1 << USIOIF) | (1 << USIPF) | (1 << USIDC);
|
||||
}
|
||||
|
||||
uint8_t i2c_start(uint8_t address)
|
||||
{
|
||||
// FOR REPEATED START
|
||||
// Release SCL
|
||||
PORTB |= (1 << 2);
|
||||
// Verify that SCL becomes high
|
||||
while (!( PINB & (1 << 2) ));
|
||||
|
||||
// GENERATE START CONDITION
|
||||
// Force SDA LOW
|
||||
PORTB &= ~(1 << 0);
|
||||
|
||||
// Pull SCL LOW
|
||||
PORTB &= ~(1 << 2);
|
||||
// Release SDA
|
||||
PORTB |= (1 << 0);
|
||||
|
||||
return i2c_write(address);
|
||||
}
|
||||
|
||||
uint8_t i2c_write(uint8_t data)
|
||||
{
|
||||
// Pull SCL LOW
|
||||
PORTB &= ~(1 << 2);
|
||||
// Setup data
|
||||
USIDR = data;
|
||||
|
||||
// Send 8 bits on bus
|
||||
i2c_clock(8);
|
||||
|
||||
// Enable SDA as input
|
||||
DDRB &= ~(1 << 0);
|
||||
|
||||
// Receive 1 bit on bus & Check for NACK
|
||||
if (i2c_clock(1) & (1 << 0))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t i2c_read(uint8_t nack)
|
||||
{
|
||||
// Enable SDA as input.
|
||||
DDRB &= ~(1 << 0);
|
||||
// Read 8 bits
|
||||
uint8_t result = i2c_clock(8);
|
||||
|
||||
if (nack)
|
||||
{
|
||||
// Load NACK
|
||||
USIDR = 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Load ACK
|
||||
USIDR = 0x00;
|
||||
}
|
||||
|
||||
i2c_clock(1);
|
||||
return result;
|
||||
}
|
||||
|
||||
void i2c_stop(void)
|
||||
{
|
||||
// Pull SDA low
|
||||
PORTB &= ~(1 << 0);
|
||||
// Release SCL
|
||||
PORTB |= (1 << 2);
|
||||
// Wait for SCL to go high
|
||||
while (!( PINB & (1 << 2) ));
|
||||
|
||||
// Release SDA
|
||||
PORTB |= (1 << 0);
|
||||
}
|
||||
|
||||
uint8_t i2c_clock(uint8_t count)
|
||||
{
|
||||
uint8_t reg_temp = (1 << USISIF) | (1 << USIOIF) | (1 << USIPF) | (1 << USIDC);
|
||||
// Counter counts number of edges
|
||||
// Overflow signals end of transmission
|
||||
reg_temp |= 16 - (count * 2);
|
||||
|
||||
USISR = reg_temp;
|
||||
|
||||
// Set clock source & toggle clock prepare
|
||||
reg_temp = (1 << USIWM1) | (1 << USICS1) | (1 << USICLK) | (1 << USITC);
|
||||
do
|
||||
{
|
||||
// Generate positve SCL edge.
|
||||
USICR = reg_temp;
|
||||
|
||||
// Wait for SCL to go high
|
||||
while (!( PINB & (1 << 2)));
|
||||
|
||||
// Generate negative SCL edge
|
||||
USICR = reg_temp;
|
||||
}
|
||||
// Wait for counter overflow (all edges are completed)
|
||||
while (!( USISR & (1 << USIOIF)));
|
||||
|
||||
// Read data
|
||||
reg_temp = USIDR;
|
||||
// Load dataregister with "released level" data
|
||||
USIDR = 0xFF;
|
||||
|
||||
// Enable SDA as output
|
||||
DDRB |= (1 << 0);
|
||||
return reg_temp;
|
||||
}
|
||||
15
tiny/master/i2c_master.h
Normal file
15
tiny/master/i2c_master.h
Normal file
@ -0,0 +1,15 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef I2C_MASTER_H
|
||||
#define I2C_MASTER_H
|
||||
|
||||
#define I2C_READ 0x01
|
||||
#define I2C_WRITE 0x00
|
||||
|
||||
void i2c_init(void);
|
||||
uint8_t i2c_start(uint8_t address);
|
||||
uint8_t i2c_write(uint8_t data);
|
||||
uint8_t i2c_read(uint8_t nack);
|
||||
void i2c_stop(void);
|
||||
|
||||
#endif // I2C_MASTER_H
|
||||
Loading…
Reference in New Issue
Block a user