From b93a5588a9241099df632a6dc476ab4f814247ee Mon Sep 17 00:00:00 2001 From: "Xie,Qi" Date: Mon, 12 Sep 2016 09:39:57 +0800 Subject: [PATCH] Added ARC I2C interfae library Support I2C controller ACI_I2C0 and ARC_I2C1 of the ARC Core. --- .../examples/master_reader/master_reader.ino | 67 ++++++ .../examples/master_writer/master_writer.ino | 71 ++++++ ARC_I2C/keywords.txt | 32 +++ ARC_I2C/library.properties | 11 + ARC_I2C/src/ARC_I2C.cpp | 203 ++++++++++++++++++ ARC_I2C/src/ARC_I2C.h | 83 +++++++ 6 files changed, 467 insertions(+) create mode 100644 ARC_I2C/examples/master_reader/master_reader.ino create mode 100644 ARC_I2C/examples/master_writer/master_writer.ino create mode 100644 ARC_I2C/keywords.txt create mode 100644 ARC_I2C/library.properties create mode 100644 ARC_I2C/src/ARC_I2C.cpp create mode 100644 ARC_I2C/src/ARC_I2C.h diff --git a/ARC_I2C/examples/master_reader/master_reader.ino b/ARC_I2C/examples/master_reader/master_reader.ino new file mode 100644 index 0000000..cd8e40e --- /dev/null +++ b/ARC_I2C/examples/master_reader/master_reader.ino @@ -0,0 +1,67 @@ +// Copyright (c) 2016 Intel Corporation. All rights reserved. +// See the bottom of this file for the license terms. + +/* + * This sketch is to demonstrate I2C reading from a device, as a bus master. It first makes a request to + * read from the device. Then proceed with reading out one byte at a time and dump in onto the serial term + * for display, in hex. The sketch continue doing the above steps. If the read operation fails, please check + * the connection to the external device: verify the signals, make sure the board and the device share a + * common ground connection. + * + * Please note: + * 1. This sketch makes use of ARC_I2C0. One of the two I2C connections from the ARC core. For the QUARK core I2C + * connection, please refer to the quarkI2C library. + * 2. This sketch can easily be changed to make use of ARC_I2C1 - just change to the ARC_I2C1 object instead of ARC_I2C0. + * 3. The ARC_I2C1 connections are not available in the Arduino 101 hardware platform. + * 4. The sketch is accessing an external I2C device with an device number (address) of 8. This address can be + * changed to fit your setup. + */ + +#include + +void setup() +{ + Serial.begin(9600); // start serial for output + while(!Serial); // Wait here till serial terminal is ready/opened + + ARC_I2C0.begin(); // join i2c bus +} + +void loop() +{ + + int ret = ARC_I2C0.requestFrom(8, 20); // request 20 bytes from slave device #8 + if (ret == 0) + { + Serial.println("read from slave device failed"); + } + + while (ARC_I2C0.available()) // slave may send less than requested + { + char c = ARC_I2C0.read(); // receive a byte as character + Serial.println(c, HEX); + } + delay(1000); +} + + +/* + Copyright (c) 2016 Intel Corporation. All rights 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 Street, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + diff --git a/ARC_I2C/examples/master_writer/master_writer.ino b/ARC_I2C/examples/master_writer/master_writer.ino new file mode 100644 index 0000000..6ab2239 --- /dev/null +++ b/ARC_I2C/examples/master_writer/master_writer.ino @@ -0,0 +1,71 @@ +// Copyright (c) 2016 Intel Corporation. All rights reserved. +// See the bottom of this file for the license terms. + +/* + * This sketch is to demonstrate I2C writing to a device, as a bus master. It first makes a request to + * write to the device. Then proceed with write out one byte annd completed the transmission. The sketch + * continues with these steps and increament the byte value each lap. If the write operation fails, please check + * the connection to the external device: verify the signals, make sure the board and the device share a + * common ground connection. + * + * Please note: + * 1. This sketch makes use of ARC_I2C0. One of the two I2C connections from the ARC core. For the QUARK core I2C + * connection, please refer to the quarkI2C library. + * 2. This sketch can easily be changed to make use of ARC_I2C1 - just change to the ARC_I2C1 object instead of ARC_I2C0. + * 3. The ARC_I2C1 connections are not available in the Arduino 101 hardware platform. + * 4. The sketch is accessing an external I2C device with an device number (address) of 8. This address can be + * changed to fit your setup. + */ + + +#include + +void setup() +{ + Serial.begin(9600); // start serial for output + while(!Serial); // Wait here till serial terminal is ready/opened + + ARC_I2C0.begin(); // join i2c bus +} + +byte x = 1; +byte rdata; +void loop() +{ + ARC_I2C0.beginTransmission(8); // transmit to device #8 + ARC_I2C0.write(x); // sends one byte + int result = ARC_I2C0.endTransmission(); // stop transmitting + if (result == 0) + { + Serial.print("x = "); + Serial.println(x); + } + else + { + Serial.print("transmit failed with error code "); + Serial.println(result); + } + x++; + delay(500); +} + + +/* + Copyright (c) 2016 Intel Corporation. All rights 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 Street, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + diff --git a/ARC_I2C/keywords.txt b/ARC_I2C/keywords.txt new file mode 100644 index 0000000..96ff91a --- /dev/null +++ b/ARC_I2C/keywords.txt @@ -0,0 +1,32 @@ +######################################################## +# Syntax Coloring Map For tinyTILEExtendedSupportLibrary +######################################################## + +####################################### +# Datatypes (KEYWORD1) +####################################### +ARC_I2C KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +begin KEYWORD2 +end KEYWORD2 +setSpeed KEYWORD2 +setAddressMode KEYWORD2 +beginTransmission KEYWORD2 +endTransmission KEYWORD2 +requestFrom KEYWORD2 +write KEYWORD2 +available KEYWORD2 +read KEYWORD2 +peek KEYWORD2 +flush KEYWORD2 +onReceive KEYWORD2 +onRequest KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### +ARC_I2C0 KEYWORD2 +ARC_I2C1 KEYWORD2 diff --git a/ARC_I2C/library.properties b/ARC_I2C/library.properties new file mode 100644 index 0000000..84da47c --- /dev/null +++ b/ARC_I2C/library.properties @@ -0,0 +1,11 @@ +name=ARC_I2C +version=1.0 +author=Intel +maintainer=Intel +email=dave@emutex.com +sentence=This is a I2C libraries from the Arc core that are specific to the Randon+ hardware platform. +paragraph=Collection contains, ArcI2C library which is developed for the two I2C connections originated from the Arc core. +url=http://makers.intel.com +architectures=arc32 +category=Communication +core-dependencies=arduino (>=1.6.3) diff --git a/ARC_I2C/src/ARC_I2C.cpp b/ARC_I2C/src/ARC_I2C.cpp new file mode 100644 index 0000000..44b1279 --- /dev/null +++ b/ARC_I2C/src/ARC_I2C.cpp @@ -0,0 +1,203 @@ +/* + * ARC_I2C.cpp is developed based upon the Wire.cpp module. + * + * TwoWire.h - TWI/I2C library for Linux Userspace + * Copyright (c) 2013 Parav https://github.com/meanbot. + * All rights 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 + * + * Modifications to support Intel Arduino 101 + * Copyright (C) 2015 Intel Corporation + * + * Modifications made to support the two I2C connections of the ARC core + * Copyright (C) 2016 Intel Corporation + */ + +extern "C" { +#include +#include +} + +#include "ARC_I2C.h" +#include "variant.h" + +ARC_I2C::ARC_I2C(I2C_CONTROLLER _controller_id) + : rxBufferIndex(0), rxBufferLength(0), txBufferLength(0), init_status(-1), controller_id(_controller_id) +{ + // Empty +} + +void ARC_I2C::begin(void) +{ + init_status = i2c_openadapter(controller_id); +} + +void ARC_I2C::begin(int i2c_speed) +{ + init_status = i2c_openadapter_speed(controller_id, i2c_speed); +} + +void ARC_I2C::setClock(long speed) +{ + if (speed == 400000L) { + init_status = i2c_openadapter_speed(controller_id, I2C_SPEED_FAST); + } else if (speed == 100000L) { + init_status = i2c_openadapter_speed(controller_id, I2C_SPEED_SLOW); + } else if (speed == I2C_SPEED_FAST) { + init_status = i2c_openadapter_speed(controller_id, I2C_SPEED_FAST); + } else { + init_status = i2c_openadapter(controller_id); + } +} + +uint8_t ARC_I2C::requestFrom(uint8_t address, uint8_t quantity, + uint8_t sendStop) +{ + int ret; + if (quantity > BUFFER_LENGTH) + quantity = BUFFER_LENGTH; + + /* Set slave address via ioctl */ + i2c_setslave(controller_id, address); + ret = i2c_readbytes(controller_id, rxBuffer, quantity, !sendStop); + if (ret < 0) { + return 0; + } + // set rx buffer iterator vars + rxBufferIndex = 0; + rxBufferLength = quantity; + + return quantity; +} + +uint8_t ARC_I2C::requestFrom(uint8_t address, uint8_t quantity) +{ + return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t) true); +} + +uint8_t ARC_I2C::requestFrom(int address, int quantity) +{ + return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t) true); +} + +uint8_t ARC_I2C::requestFrom(int address, int quantity, int sendStop) +{ + return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop); +} + +void ARC_I2C::beginTransmission(uint8_t address) +{ + if (init_status < 0) + return; + // set slave address + i2c_setslave(controller_id, address); + // reset transmit buffer + txBufferLength = 0; +} + +void ARC_I2C::beginTransmission(int address) +{ + beginTransmission((uint8_t)address); +} + +// +// Originally, 'endTransmission' was an f(void) function. +// It has been modified to take one parameter indicating +// whether or not a STOP should be performed on the bus. +// Calling endTransmission(false) allows a sketch to +// perform a repeated start. +// +// WARNING: Nothing in the library keeps track of whether +// the bus tenure has been properly ended with a STOP. It +// is very possible to leave the bus in a hung state if +// no call to endTransmission(true) is made. Some I2C +// devices will behave oddly if they do not see a STOP. +// +uint8_t ARC_I2C::endTransmission(uint8_t sendStop) +{ + int err; + // transmit buffer (blocking) + if (txBufferLength >= 1) { + err = + i2c_writebytes(controller_id, txBuffer, txBufferLength, !sendStop); + } else { + uint8_t temp = 0; + // Workaround: I2C bus scan is currently implemented by reading, + // so set the read length to 0 to inform the lower I2C driver that we are doing bus scan + err = i2c_readbytes(controller_id, &temp, 0, 0); + } + // empty buffer + txBufferLength = 0; + if (err < 0) { + return -err; + } + return 0; // success +} + +// This provides backwards compatibility with the original +// definition, and expected behaviour, of endTransmission +// +uint8_t ARC_I2C::endTransmission(void) +{ + return endTransmission(true); +} + +size_t ARC_I2C::write(uint8_t data) +{ + if (txBufferLength >= BUFFER_LENGTH) + return 0; + txBuffer[txBufferLength++] = data; + return 1; +} + +size_t ARC_I2C::write(const uint8_t *data, size_t quantity) +{ + for (size_t i = 0; i < quantity; ++i) { + if (txBufferLength >= BUFFER_LENGTH) + return i; + txBuffer[txBufferLength++] = data[i]; + } + return quantity; +} + +int ARC_I2C::available(void) +{ + return rxBufferLength - rxBufferIndex; +} + +int ARC_I2C::read(void) +{ + if (rxBufferIndex < rxBufferLength) + return rxBuffer[rxBufferIndex++]; + return -1; +} + +int ARC_I2C::peek(void) +{ + if (rxBufferIndex < rxBufferLength) + return rxBuffer[rxBufferIndex]; + return -1; +} + +void ARC_I2C::flush(void) +{ + // Do nothing, use endTransmission(..) to force + // data transfer. +} + +ARC_I2C ARC_I2C0 = ARC_I2C(I2C_SENSING_0); +ARC_I2C ARC_I2C1 = ARC_I2C(I2C_SENSING_1); + diff --git a/ARC_I2C/src/ARC_I2C.h b/ARC_I2C/src/ARC_I2C.h new file mode 100644 index 0000000..e105cb7 --- /dev/null +++ b/ARC_I2C/src/ARC_I2C.h @@ -0,0 +1,83 @@ +/* + * arcI2C.h is developed based upon the TwoWire.h module. + * + * TwoWire.h - TWI/I2C library for Linux Userspace + * Copyright (c) 2013 Parav https://github.com/meanbot. + * All rights 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 + * + * Modifications made to support the two I2C connections of the Quark core + * Copyright (C) 2016 Intel Corporation + */ + +#ifndef _ARC_I2C_H_ +#define _ARC_I2C_H_ + +#include "Stream.h" +#include "variant.h" +#include "ss_i2c_iface.h" + +#define BUFFER_LENGTH 32 +#define I2C_SPEED_SLOW 1 +#define I2C_SPEED_FAST 2 + +class ARC_I2C : public Stream { +public: + ARC_I2C(I2C_CONTROLLER _controller_id); + void begin(void); + void begin(int speed); + void setClock(long speed); + void beginTransmission(uint8_t); + void beginTransmission(int); + uint8_t endTransmission(void); + uint8_t endTransmission(uint8_t); + uint8_t requestFrom(uint8_t, uint8_t); + uint8_t requestFrom(uint8_t, uint8_t, uint8_t); + uint8_t requestFrom(int, int); + uint8_t requestFrom(int, int, int); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *, size_t); + virtual int available(void); + virtual int read(void); + virtual int peek(void); + virtual void flush(void); + + inline size_t write(unsigned long n) { return write((uint8_t)n); } + inline size_t write(long n) { return write((uint8_t)n); } + inline size_t write(unsigned int n) { return write((uint8_t)n); } + inline size_t write(int n) { return write((uint8_t)n); } + using Print::write; + +private: + // RX Buffer + uint8_t rxBuffer[BUFFER_LENGTH]; + uint8_t rxBufferIndex; + uint8_t rxBufferLength; + + // TX Buffer + uint8_t txAddress; + uint8_t txBuffer[BUFFER_LENGTH]; + uint8_t txBufferLength; + + int init_status; + + I2C_CONTROLLER controller_id; +}; + +extern ARC_I2C ARC_I2C0; +extern ARC_I2C ARC_I2C1; + +#endif