Skip to content
Snippets Groups Projects
Commit 7b8c37d2 authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

Add Software I2C implementation

parent c374e913
No related branches found
No related tags found
No related merge requests found
......@@ -27,6 +27,11 @@ ifneq ($(findstring sharp96,${drivers}), )
COMMON_FLAGS += -DSHARP96_CS_PIN=GPIO::${sharp96_cs_pin}
endif
ifneq ($(findstring softi2c,${drivers}), )
TARGETS += src/driver/soft_i2c.cc
COMMON_FLAGS += -DDRIVER_SOFTI2C
endif
ifeq (${timer_cycles}, 1)
COMMON_FLAGS += -DTIMER_CYCLES
endif
......
#ifndef SOFTI2C_H
#define SOFTI2C_H
class SoftI2C {
private:
SoftI2C(const SoftI2C &copy);
unsigned char sda, scl;
void start();
void stop();
bool tx(unsigned char byte);
unsigned char rx(bool send_ack);
public:
SoftI2C(unsigned char sda, unsigned char scl) : sda(sda), scl(scl) {}
signed char setup();
void scan(unsigned int *results);
signed char xmit(unsigned char address,
unsigned char tx_len, unsigned char *tx_buf,
unsigned char rx_len, unsigned char *rx_buf);
};
extern SoftI2C i2c;
#endif
#include "driver/soft_i2c.h"
#include "driver/gpio.h"
signed char SoftI2C::setup()
{
gpio.write(sda, 0);
gpio.write(scl, 0);
return 0;
}
void SoftI2C::start()
{
gpio.input(sda);
gpio.input(scl);
//
gpio.output(sda);
//
gpio.output(scl);
}
void SoftI2C::stop()
{
gpio.output(sda);
//
gpio.input(scl);
//
gpio.input(sda);
}
bool SoftI2C::tx(unsigned char byte)
{
unsigned char got_ack = 0;
for (unsigned char i = 0; i <= 8; i++) {
if ((byte & 0x80) || (i == 8)) {
gpio.input(sda);
} else {
gpio.output(sda);
}
byte <<= 1;
//
gpio.input(scl);
//
if (i == 8) {
if (!gpio.read(sda)) {
got_ack = 1;
}
}
gpio.output(scl);
//
}
return got_ack;
}
unsigned char SoftI2C::rx(bool send_ack)
{
unsigned char byte = 0;
gpio.input(sda);
for (unsigned char i = 0; i <= 8; i++) {
//
gpio.input(scl);
//
if ((i < 8) && gpio.read(sda)) {
byte |= 1 << (7 - i);
}
//
gpio.output(scl);
//
if ((i == 7) && send_ack) {
gpio.output(sda);
} else if ((i == 8) && send_ack) {
gpio.input(sda);
}
}
return byte;
}
void SoftI2C::scan(unsigned int *results)
{
unsigned char i2caddr;
for (unsigned char address = 0; address < 128; address++) {
i2caddr = (address << 1) | 1;
start();
if (tx(i2caddr)) {
results[address / (8 * sizeof(unsigned int))] |= 1 << (address % (8 * sizeof(unsigned int)));
}
}
stop();
}
signed char SoftI2C::xmit(unsigned char address,
unsigned char tx_len, unsigned char *tx_buf,
unsigned char rx_len, unsigned char *rx_buf)
{
unsigned char i;
if (tx_len) {
start();
tx((address << 1) | 0);
for (i = 0; i < tx_len; i++) {
tx(tx_buf[i]);
}
}
if (rx_len) {
start();
tx((address << 1) | 1);
for (i = 1; i <= rx_len; i++) {
rx_buf[i] = rx((i < rx_len) * 1);
}
}
stop();
return 0;
}
SoftI2C i2c(GPIO::p1_6, GPIO::p1_7);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment