Skip to content

Commit

Permalink
Merge pull request #10592 from gschorcht/sys_arduino_ext
Browse files Browse the repository at this point in the history
sys/arduino: Added Wire (I2C) interface
  • Loading branch information
maribu authored Oct 24, 2019
2 parents 20e1e16 + 3fc2c60 commit 1c624e4
Show file tree
Hide file tree
Showing 6 changed files with 632 additions and 3 deletions.
4 changes: 4 additions & 0 deletions sys/Makefile.dep
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
ifneq (,$(filter arduino,$(USEMODULE)))
FEATURES_OPTIONAL += periph_i2c
endif

ifneq (,$(filter eepreg,$(USEMODULE)))
FEATURES_REQUIRED += periph_eeprom
endif
Expand Down
33 changes: 33 additions & 0 deletions sys/arduino/include/Arduino.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2018 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @ingroup sys_arduino
* @brief Wrapper to keep source code compatibility for Arduino.h
* @author Gunar Schorcht <[email protected]>
* @file
* @{
*/

#ifndef ARDUINO_H
#define ARDUINO_H

#ifdef __cplusplus
#include "arduino.hpp"
#endif

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

#endif /* ARDUINO_H */
/** @} */
37 changes: 37 additions & 0 deletions sys/arduino/include/Wire.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (C) 2018 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @ingroup sys_arduino
* @brief Wrapper to keep source code compatibility for Wire.h
* @author Gunar Schorcht <[email protected]>
* @file
* @{
*/

#ifndef WIRE_H
#define WIRE_H

#ifndef MODULE_PERIPH_I2C
#error "No I2C support on your board"
#endif

#ifdef __cplusplus
#include "wireport.hpp"
#endif

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

#endif /* WIRE_H */
/** @} */
6 changes: 3 additions & 3 deletions sys/arduino/include/arduino.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
* @author Hauke Petersen <[email protected]>
*/

#ifndef ARDUINO_H
#define ARDUINO_H
#ifndef ARDUINO_HPP
#define ARDUINO_HPP

extern "C" {
#include "periph/gpio.h"
Expand Down Expand Up @@ -122,5 +122,5 @@ unsigned long millis();
int analogRead(int pin);
#endif

#endif /* ARDUINO_H */
#endif /* ARDUINO_HPP */
/** @} */
297 changes: 297 additions & 0 deletions sys/arduino/include/wireport.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
/*
* Copyright (C) 2018 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @ingroup sys_arduino_api
* @{
*
* @author Gunar Schorcht <[email protected]>
* @file
*
* @brief Definition of the Arduino 'Wire Library' for TwoWire interfaces
*
* This library is the implementation of the [Arduino Wire Library]
* (https://www.arduino.cc/en/Reference/Wire) for the I2C peripheral
* interfaces in RIOT. It supports only I2C master mode and the functions
* that are documented in the official [Arduino Reference]
* (https://www.arduino.cc/en/Reference/Wire) of this library.
*
* The implementation is an adaptation of the original Arduino Wire Library
* which is published under the following copyright:
*
* ```
* TwoWire.h - TWI/I2C library for Arduino & Wiring
* Copyright (c) 2006 Nicholas Zambetti. All right reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Modified 2012 by Todd Krein ([email protected]) to implement repeated starts
* ```
*
* The documentation in this file is partially extracted from the original
* [Arduino Reference](https://www.arduino.cc/en/Reference/Wire) of this
* library which is published under the
* [Creative Commons Attribution-ShareAlike 3.0 License]
* (https://creativecommons.org/licenses/by-sa/3.0/).
*/

#ifndef WIREPORT_HPP
#define WIREPORT_HPP

#include <inttypes.h>
#include <stddef.h>

/** Default Arduino I2C interface */
#ifndef ARDUINO_I2C_DEV
#define ARDUINO_I2C_DEV (I2C_DEV(0))
#endif

/** Buffer length used by the Arduino Wire library implementation */
#define WIREPORT_BUFFER_LENGTH 32

/** Class definition for the Arduino Wire library implementation */
class TwoWire
{
private:

static uint8_t rxBuffer[]; /**< RX buffer */
static uint8_t rxBufferIndex; /**< index for RX buffer read */
static uint8_t rxBufferLength; /**< number of bytes in RX buffer */

static uint8_t txAddress; /**< adress for transfer */
static uint8_t txBuffer[]; /**< TX buffer */
static uint8_t txBufferIndex; /**< index for TX buffer write */
static uint8_t txBufferLength; /**< number of bytes in TX buffer */
static uint8_t txError; /**< error code in write operations */

static uint8_t transmitting; /**< set by #beginTransmission and reset
by #endTransmission to indicate an
ongoing transmission */
public:

/**
* @brief Constructor
*/
TwoWire(void);

/**
* @brief Initializes the I2C device defined by #ARDUINO_I2C_DEV as master
*/
void begin(void);

/**
* @brief Initializes the I2C device defined by #ARDUINO_I2C_DEV as slave
*
* @note Since slave mode is not yet supported by the RIOT port of the
* Arduino Wire library, calling this method leads to a core panic.
*
* @param[in] addr Address of the device initialized as slave
*/
void begin(uint8_t addr);

/**
* @brief Set the clock speed of the I2C device defined by
* #ARDUINO_I2C_DEV.
*
* @note In RIOT, the I2C bus clock speed is determined by the board
* definition. This method does therefore nothing. It is just realized
* for compatibility reasons.
*
* @param[in] clk I2C clock speed in Hz
*/
void setClock(uint32_t clk);

/**
* @brief Begin a transmission to a I2C slave device
*
* This method begins a transmission to the I2C slave device with the
* given address. Subsequently, queue bytes for transmission with the
* #write method and transmit them by calling #endTransmission.
*
* Copied from https://www.arduino.cc/en/Reference/WireBeginTransmission
*
* @param[in] addr Address of the slave device
*/
void beginTransmission(uint8_t addr);

/**
* @brief End a transmission to a I2C slave device
*
* Ends a transmission to a slave device that was begun by
* #beginTransmission() and transmits the bytes that were queued by #write.
* Sends always a STOP condition after the request.
*
* Copied from https://www.arduino.cc/en/Reference/WireEndTransmission
*
* @retval 0 success
* @retval 1 data too long to fit in transmit buffer
* @retval 2 received NACK on transmit of address
* @retval 3 received NACK on transmit of data
* @retval 4 other error
*/
uint8_t endTransmission(void);

/**
* @brief End a transmission to a I2C slave device
*
* Ends a transmission to a slave device that was begun by
* #beginTransmission() and transmits the bytes that were queued by #write.
*
* Copied from https://www.arduino.cc/en/Reference/WireEndTransmission
*
* @param stop Send STOP condition after transmission if true or
* nothing if false.
*
* @retval 0 success
* @retval 1 data too long to fit in transmit buffer
* @retval 2 received NACK on transmit of address
* @retval 3 received NACK on transmit of data
* @retval 4 other error
*/
uint8_t endTransmission(uint8_t stop);

/**
* @brief Request bytes from a I2C slave device
*
* Used by the master to request bytes from a slave device. The bytes may
* then be retrieved with the #available and #read methods. Sends always
* a STOP condition after the request.
*
* Copied from https://www.arduino.cc/en/Reference/WireRequestFrom
*
* @param[in] addr 7-bit address of the device to request bytes from
* @param[in] size Number of bytes to request
*
* @return number of bytes returned from the slave device
*/
uint8_t requestFrom(uint8_t addr, uint8_t size);

/**
* @brief Request bytes from a I2C slave device
*
* Used by the master to request bytes from a slave device. The bytes may
* then be retrieved with the #available and #read methods.
*
* @param[in] addr 7-bit address of the device to request bytes from
* @param[in] size Number of bytes to request
* @param[in] stop Send STOP condition after the request if true or
* nothing if false.
*
* Copied from https://www.arduino.cc/en/Reference/WireRequestFrom
*
* @return number of bytes returned from the slave device
*/
uint8_t requestFrom(uint8_t addr, uint8_t size, uint8_t stop);

/**
* @brief Queue a byte for transmission from a master to slave device
*
* The method queues a byte for transmission from a master to slave device
* in-between calls to #beginTransmission and #endTransmission.
*
* @param[in] data Data byte
*
* Copied from https://www.arduino.cc/en/Reference/WireWrite
*
* @return number of bytes queued
*/
virtual size_t write(uint8_t data);

/**
* @brief Queue bytes for transmission from a master to slave device
*
* The method queues bytes for transmission from a master to slave device
* in-between calls to #beginTransmission and #endTransmission.
*
* @param[in] data Array of data to send as bytes
* @param[in] size Number of bytes to transmit
*
* Copied from https://www.arduino.cc/en/Reference/WireWrite
*
* @return number of bytes queued
*/
virtual size_t write(const uint8_t *data, size_t size);

/**
* @brief Return the number of bytes available for retrieval
*
* Returns the number of bytes available for retrieval with #read. This
* should be called on a master device after a call to #requestFrom.
*
* Copied from https://www.arduino.cc/en/Reference/WireAvailable
*
* @return number of bytes available for retrieval
*/
virtual int available(void);

/**
* @brief Reads one byte transmitted from slave device to the master
*
* Reads a byte that was transmitted from a slave device to the master after
* a call to #requestFrom and removes it from receive buffer.
*
* Copied from https://www.arduino.cc/en/Reference/WireRead
*
* @return next byte received, or -1 if none is available.
*/
virtual int read(void);

/**
* @brief Read bytes transmitted from slave device to the master
*
* Reads a number of bytes that were transmitted from a slave device to the
* master after a call to #requestFrom and removes them from receive buffer.
*
* @param[out] buffer buffer to store the bytes
* @param[in] length number of bytes to read
*
* @return number of bytes placed in the buffer
*/
virtual size_t readBytes(uint8_t *buffer, size_t length);
/**
* @brief Peeks one byte transmitted from slave device to the master
*
* Reads a byte that was transmitted from a slave device to the master after
* a call to #requestFrom without advancing to the next one. That is,
* successive calls to #peek will return the same value, as will the
* next call to read.
*
* Copied from https://www.arduino.cc/en/Reference/WireRead and
* https://www.arduino.cc/en/Reference/StreamPeek
*
* @return next byte received, or -1 if none is available.
*/
virtual int peek(void);

/**
* @brief Flush the RX and TX buffer
*
* This method clears the RX as well as the TX buffer. It is not necessary
* to call this method explicitly. RX buffer is flushed implicitly when
* method #requestFrom is called. Tx buffer is flushed implicitly when
* method #beginTransmission is called.
*/
virtual void flush(void);
};

extern TwoWire Wire;

#endif /* WIREPORT_HPP */
/** @} */
Loading

0 comments on commit 1c624e4

Please sign in to comment.