Skip to content

Instantly share code, notes, and snippets.

@rmnk
Created March 9, 2014 15:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rmnk/86cbd56270eb316552df to your computer and use it in GitHub Desktop.
Save rmnk/86cbd56270eb316552df to your computer and use it in GitHub Desktop.
#define F_CPU 1000000UL
#include <stdint.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/cpufunc.h>
#define A 0x80
#define B 0x20
#define C 0x08
#define D 0x02
#define E 0x01
#define F 0x40
#define G 0x10
#define I2C_PORT PORTC
#define I2C_DDR DDRC
#define I2C_PIN PINC
#define SDA 4
#define SCL 5
uint8_t digits[16] = {
A | B | C | D | E | F, //0
B | C, //1
A | B | D | E | G, //2
A | B | C | D | G, //3
B | C | F | G, //4
A | C | D | F | G, //5
A | C | D | E | F | G, //6
A | B | C, //7
A | B | C | D | E | F | G, //8
A | B | C | D | F | G, //9
A | B | C | E | F | G, //a
C | D | E | F | G, //b
A | D | E | F, //c
B | C | D | E | G, //d
A | D | E | F | G, //e
A | E | F | G //f
};
void
set_led_digit(uint8_t id, uint8_t value)
{
DDRD = 0xff;
DDRB |= 1 << id;
PORTB &= 0xf8;
PORTB |= 1 << id;
PORTD = digits[value];
}
uint8_t
i2c_get_sda()
{
return (I2C_PIN >> SDA) & 0x01;
}
uint8_t
i2c_get_scl()
{
return (I2C_PIN >> SCL) & 0x01;
}
void
i2c_set_scl(const uint8_t value)
{
do {
if (value) {
I2C_DDR &= ~(1 << SCL);
} else {
I2C_DDR |= 1 << SCL;
}
} while (i2c_get_scl() != value);
}
void
i2c_set_sda(const uint8_t value)
{
do {
if (value) {
I2C_DDR &= ~(1 << SDA);
} else {
I2C_DDR |= 1 << SDA;
}
} while (i2c_get_sda() != value);
}
void
i2c_start()
{
/* pull down SDA while SCL is up */
i2c_set_sda(1);
i2c_set_scl(1);
i2c_set_sda(0);
}
void
i2c_stop()
{
/* release SDA while SCL is up */
i2c_set_sda(0);
i2c_set_scl(1);
i2c_set_sda(1);
}
/* returns ACK bit */
uint8_t
i2c_write(uint8_t byte)
{
int8_t bit_no;
for (bit_no = 7; bit_no >= 0; bit_no--) {
i2c_set_scl(0);
/* put next bit on SDA */
i2c_set_sda((byte >> bit_no) & 0x01);
i2c_set_scl(1);
}
/* release SDA; let slave to be able to change it */
i2c_set_sda(1);
i2c_set_scl(0);
i2c_set_scl(1);
/* get slave ACK bit */
return i2c_get_sda();
}
uint8_t
i2c_read(uint8_t ack)
{
/* release SDA; let slave to be able to change it */
i2c_set_sda(1);
uint8_t byte = 0;
int8_t bit_no;
for (bit_no = 7; bit_no >= 0; bit_no--) {
i2c_set_scl(0);
i2c_set_scl(1);
/* get next bit */
byte |= i2c_get_sda() << bit_no;
}
i2c_set_scl(0);
/* set ACK bit */
i2c_set_sda(ack);
i2c_set_scl(1);
return byte;
}
int
main()
{
I2C_PORT &= ~((1 << SDA) | (1 << SCL));
//const uint8_t eeprom_i2c_addr = 0b10100000;
const uint8_t eeprom_i2c_addr = 0xa0;
const uint16_t eeprom_memory_addr = 0x0000;
const uint8_t eeprom_memory_value = 0x42;
uint8_t ack = 0;
i2c_start();
ack |= i2c_write(eeprom_i2c_addr);
ack |= i2c_write((uint8_t) (eeprom_memory_addr >> 8)) << 1;
ack |= i2c_write((uint8_t) eeprom_memory_addr) << 2;
ack |= i2c_write(eeprom_memory_value) << 3;
i2c_stop();
while(1) {
set_led_digit(0, ack);
_delay_ms(1);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment