Skip to content

Abstraction of I2C interface for discussion - STM32 #76

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions src/ArduinoInterface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright (C) 2020 Bruce MacKinnon KC1FSZ
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ArduinoInterface_h
#define _ArduinoInterface_h

#include "Arduino.h"
#include "Wire.h"
#include "I2CInterface.h"

/**
* The standard Ardiuno way of talking to I2C
* via the Wire.h library.
*/
class ArduinoInterface : public I2CInterface {
public:

ArduinoInterface() {
Wire.begin();
}

uint8_t check_address(uint8_t i2c_bus_addr) {
Wire.beginTransmission(i2c_bus_addr);
return Wire.endTransmission();
}

uint8_t read(uint8_t i2c_bus_addr, uint8_t addr) {

uint8_t reg_val = 0;

Wire.beginTransmission(i2c_bus_addr);
Wire.write(addr);
Wire.endTransmission();

Wire.requestFrom(i2c_bus_addr, (uint8_t)1, (uint8_t)false);

while(Wire.available())
{
reg_val = Wire.read();
}

return reg_val;
}

uint8_t write(uint8_t i2c_bus_addr, uint8_t addr, uint8_t data) {
Wire.beginTransmission(i2c_bus_addr);
Wire.write(addr);
Wire.write(data);
return Wire.endTransmission();
}

uint8_t write_bulk(uint8_t i2c_bus_addr, uint8_t addr, uint8_t bytes, uint8_t *data) {
Wire.beginTransmission(i2c_bus_addr);
Wire.write(addr);
for(int i = 0; i < bytes; i++)
{
Wire.write(data[i]);
}
return Wire.endTransmission();
}
};

#endif
53 changes: 53 additions & 0 deletions src/I2CInterface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright (C) 2020 Bruce MacKinnon KC1FSZ
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _I2CInterface_h
#define _I2CInterface_h

#include <stdint.h>

/**
* A generic interface for interacting with an I2C bus
*/
class I2CInterface {
public:

/**
* Determmines whether a device is connected at the specified address.
* @return 0 if things are good, -1 if there is a problem.
*/
virtual uint8_t check_address(uint8_t i2c_bus_addr) = 0;

/**
* Standard read operation.
* @return The received byte
*/
virtual uint8_t read(uint8_t i2c_bus_addr, uint8_t addr) = 0;

/**
* Standard write operation.
* @return Then number of bytes written
*/
virtual uint8_t write(uint8_t i2c_bus_addr, uint8_t addr, uint8_t data) = 0;

/**
* Multi-byte write operation
* @return The number of bytes written
*/
virtual uint8_t write_bulk(uint8_t i2c_bus_addr, uint8_t addr, uint8_t bytes, uint8_t *data) = 0;
};

#endif
86 changes: 86 additions & 0 deletions src/STM32_HAL_Interface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright (C) 2020 Bruce MacKinnon KC1FSZ
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _STM32_HAL_Interface_h
#define _STM32_HAL_Interface_h

#include <stdint.h>
// NOTE: Add the appropriate HAL include here:
#include "stm32f4xx_hal.h"

#include "I2CInterface.h"

// An STM32/HAL based implementation of the I2CInterface.
//
// NOT IMPLEMENTED YET!!
//
class STM32_HAL_Interface : public I2CInterface {
public:

STM32_HAL_Interface(I2C_HandleTypeDef* hi2c)
: _hi2c(hi2c),
_errorCount(0),
_timeoutMs(10) {
}

uint8_t check_address(uint8_t i2c_bus_addr) {
HAL_StatusTypeDef status = HAL_I2C_IsDeviceReady(_hi2c, (uint16_t)(i2c_bus_addr << 1), 1, _timeoutMs);
if (status == HAL_OK) {
return 0;
} else {
return -1;
}
}

uint8_t read(uint8_t i2c_bus_addr, uint8_t addr) {
uint8_t reg_val = 0;
// NOTE: PER HAL DOCUMENTATION, ADDRESS NEEDS TO BE SHIFTED LEFT
HAL_StatusTypeDef status = HAL_I2C_Mem_Read(_hi2c, (uint16_t)(i2c_bus_addr << 1), (uint16_t)(addr), 1,
&reg_val, 1, _timeoutMs);
if (status != HAL_OK) {
_errorCount++;
}
return reg_val;
}

uint8_t write(uint8_t i2c_bus_addr, uint8_t addr, uint8_t data) {
// NOTE: PER HAL DOCUMENTATION, ADDRESS NEEDS TO BE SHIFTED LEFT
HAL_StatusTypeDef status = HAL_I2C_Mem_Write(_hi2c, (uint16_t)(i2c_bus_addr << 1), addr, 1,
&data, 1, _timeoutMs);
if (status != HAL_OK) {
_errorCount++;
}
return 1;
}

uint8_t write_bulk(uint8_t i2c_bus_addr, uint8_t addr, uint8_t bytes, uint8_t *data) {
// NOTE: PER HAL DOCUMENTATION, ADDRESS NEEDS TO BE SHIFTED LEFT
HAL_StatusTypeDef status = HAL_I2C_Mem_Write(_hi2c, (uint16_t)(i2c_bus_addr << 1), addr, 1,
data, bytes, _timeoutMs);
if (status != HAL_OK) {
_errorCount++;
}
return bytes;
}

private:

I2C_HandleTypeDef* _hi2c;
int _errorCount;
uint32_t _timeoutMs;
};

#endif
53 changes: 53 additions & 0 deletions src/TestInterface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright (C) 2020 Bruce MacKinnon KC1FSZ
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _Test_Interface_h
#define _Test_Interface_h

#include <stdint.h>
#include <stdio.h>
#include "I2CInterface.h"

// A dummy interface for testing.
//
class TestInterface : public I2CInterface {
public:
TestInterface() {
printf("TestInterface initialized\n");
}
uint8_t check_address(uint8_t i2c_bus_addr) {
printf("check_address\n");
return 0;
}
uint8_t read(uint8_t i2c_bus_addr, uint8_t addr) {
printf("read(%x,%x)\n", i2c_bus_addr, addr);
return 0;
}
uint8_t write(uint8_t i2c_bus_addr, uint8_t addr, uint8_t data) {
printf("write(%x, %x, %x)\n", i2c_bus_addr, addr, data);
return 0;
}
uint8_t write_bulk(uint8_t i2c_bus_addr, uint8_t addr, uint8_t bytes, uint8_t *data) {
printf("write_bulk(%x, %x, ", i2c_bus_addr, addr);
for (int i = 0; i < bytes; i++) {
printf("%x ", data[i]);
}
printf(")\n");
return 0;
}
};

#endif
Loading