2024-08-31 01:53:25 +10:00
|
|
|
|
|
|
|
#include <Arduino.h>
|
2024-10-01 16:19:43 +10:00
|
|
|
#include "soft_twi.hpp"
|
|
|
|
#include "port.hpp"
|
2024-08-31 01:53:25 +10:00
|
|
|
|
|
|
|
uint8_t SoftTWI::read(bool ack) {
|
2024-10-01 16:19:43 +10:00
|
|
|
port::Drain sda(_sda);
|
|
|
|
port::Drain scl(_scl);
|
|
|
|
|
2024-08-31 01:53:25 +10:00
|
|
|
uint8_t v = 0;
|
|
|
|
for(unsigned m = 0x80; m; m >>= 1) {
|
2024-10-01 16:19:43 +10:00
|
|
|
sda.set(1);
|
|
|
|
scl.set(1);
|
|
|
|
while(!scl.get()) {}
|
|
|
|
if(sda.get()) {
|
2024-08-31 01:53:25 +10:00
|
|
|
v |= m;
|
|
|
|
}
|
2024-10-01 16:19:43 +10:00
|
|
|
scl.set(0);
|
2024-08-31 01:53:25 +10:00
|
|
|
}
|
2024-10-01 16:19:43 +10:00
|
|
|
|
|
|
|
// send ACK
|
|
|
|
if(ack) {
|
|
|
|
sda.set(!ack);
|
|
|
|
scl.set(1);
|
|
|
|
while(!scl.get()) {}
|
|
|
|
scl.set(0);
|
|
|
|
}
|
|
|
|
|
2024-08-31 01:53:25 +10:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SoftTWI::write(uint8_t v) {
|
2024-10-01 16:19:43 +10:00
|
|
|
port::Drain sda(_sda);
|
|
|
|
port::Drain scl(_scl);
|
|
|
|
|
2024-08-31 01:53:25 +10:00
|
|
|
for(unsigned m = 0x80; m; m >>= 1) {
|
2024-10-01 16:19:43 +10:00
|
|
|
sda.set(v & m);
|
|
|
|
scl.set(1);
|
|
|
|
while(!scl.get()) {}
|
|
|
|
scl.set(0);
|
2024-08-31 01:53:25 +10:00
|
|
|
}
|
2024-10-01 16:19:43 +10:00
|
|
|
|
|
|
|
// get ACK
|
|
|
|
sda.set(1);
|
|
|
|
scl.set(1);
|
|
|
|
while(!scl.get()) {}
|
|
|
|
uint8_t s = sda.get();
|
|
|
|
scl.set(0);
|
|
|
|
|
|
|
|
return !s;
|
2024-08-31 01:53:25 +10:00
|
|
|
}
|
|
|
|
|
2024-08-31 16:31:19 +10:00
|
|
|
void SoftTWI::read(uint8_t* data, unsigned data_len, bool nack_at_end) {
|
|
|
|
for(unsigned i = 0; i < data_len; i++) {
|
|
|
|
data[i] = read(nack_at_end ? (i < data_len - 1) : true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-31 01:53:25 +10:00
|
|
|
unsigned SoftTWI::write(const uint8_t* data, unsigned data_len) {
|
|
|
|
for(unsigned i = 0; i < data_len; i++) {
|
|
|
|
if(!write(data[i])) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return data_len;
|
|
|
|
}
|
|
|
|
|
2024-10-01 16:19:43 +10:00
|
|
|
bool SoftTWI::start(uint8_t addr) {
|
|
|
|
port::Drain sda(_sda);
|
|
|
|
port::Drain scl(_scl);
|
|
|
|
sda.set(1);
|
|
|
|
scl.set(1);
|
|
|
|
sda.set(0);
|
|
|
|
scl.set(0);
|
|
|
|
write(addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SoftTWI::end() {
|
|
|
|
port::Drain sda(_sda);
|
|
|
|
port::Drain scl(_scl);
|
|
|
|
sda.set(0);
|
|
|
|
scl.set(1);
|
|
|
|
sda.set(1);
|
|
|
|
}
|
|
|
|
|