Subversion Repositories group.electronics

Rev

Blame | Last modification | View Log | RSS feed

#include <avr/io.h>
#include "wire.h"
#include "twi.h"

void i2c_master(void) {
        wire.rxBufferIndex = 0;
        wire.rxBufferLength = 0;

        wire.txBufferIndex = 0;
        wire.txBufferLength = 0;
        
        twi_init();
}

void i2c_slave(uint8_t address) {
        twi_setAddress(address);
        twi_attachSlaveTxEvent(&i2c_onRequestService);
        twi_attachSlaveRxEvent(&i2c_onReceiveService);
        i2c_master();
}

uint8_t i2c_requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) {
        if (quantity > MAX_BUFFER) {
                quantity = MAX_BUFFER;
        }

        uint8_t read = twi_readFrom(address, wire.rxBuffer, quantity, sendStop);
        wire.rxBufferIndex = 0;
        wire.rxBufferLength = read;

        return read;
}

void i2c_beginTransmission(uint8_t address) {
        wire.transmitting = 1;
        wire.txAddress = address;
        wire.txBufferIndex = 0;
        wire.txBufferLength = 0;
}

uint8_t i2c_endTransmission(uint8_t sendStop) {
        int8_t ret = twi_writeTo(wire.txAddress, 
                                        wire.txBuffer, 
                                        wire.txBufferLength, 
                                        1, sendStop);
        wire.txBufferIndex = 0;
        wire.txBufferLength = 0;
        wire.transmitting = 0;
        return ret;
}

uint8_t i2c_writeByte(uint8_t data) {
        if (wire.transmitting) {
                if (wire.txBufferLength >= MAX_BUFFER) {
                        return 0;
                }

                wire.txBuffer[wire.txBufferIndex] = data;
                ++wire.txBufferIndex;
                wire.txBufferLength = wire.txBufferIndex;
        } else {
                twi_transmit(&data, 1);
        }
        return 1;
}

uint8_t i2c_writeBytes(uint8_t *data, uint8_t bytes) {
        if (wire.transmitting) {
                uint8_t i = 0;
                for (i = 0; i < bytes; i++) {
                        i2c_writeByte(data[i]);
                }
        } else {
                twi_transmit(data, bytes);
        }
        return bytes;
}

        
int i2c_available(void) {
        return wire.rxBufferLength - wire.rxBufferIndex;
}

uint8_t i2c_read(void) {
        int value = 0;
        if (wire.rxBufferIndex < wire.rxBufferLength) {
                value = wire.rxBuffer[wire.rxBufferIndex];
                ++wire.rxBufferIndex;
        }
        return value;
}

void i2c_onReceiveService(uint8_t* inBytes, int numBytes) {
        if(!wire.user_onReceive) {
                return;
        }

        if(wire.rxBufferIndex < wire.rxBufferLength) {
                return;
        }

        uint8_t i = 0;
        for(i = 0; i < numBytes; ++i) {
                wire.rxBuffer[i] = inBytes[i];
        }

        wire.rxBufferIndex = 0;
        wire.rxBufferLength = numBytes;
        wire.user_onReceive(numBytes);
}

void i2c_onRequestService(void) {
        if(!wire.user_onRequest) {
                return;
        }

        wire.txBufferIndex = 0;
        wire.txBufferLength = 0;
        wire.user_onRequest();
}

void i2c_onReceive( void(*function)(uint8_t)) {
        wire.user_onReceive = function;
}

void i2c_onRequest( void(*function)(void)) {
        wire.user_onRequest = function;
}