Skip to content

Commit

Permalink
Initial commit v0.9.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Richard-Gemmell committed Nov 7, 2019
1 parent 05b0d9e commit ae42b5e
Show file tree
Hide file tree
Showing 33 changed files with 3,913 additions and 23 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.idea
.pio
cmake-build-teensy40
CMakeListsPrivate.txt
67 changes: 67 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Continuous Integration (CI) is the practice, in software
# engineering, of merging all developer working copies with a shared mainline
# several times a day < https://docs.platformio.org/page/ci/index.html >
#
# Documentation:
#
# * Travis CI Embedded Builds with PlatformIO
# < https://docs.travis-ci.com/user/integration/platformio/ >
#
# * PlatformIO integration with Travis CI
# < https://docs.platformio.org/page/ci/travis.html >
#
# * User Guide for `platformio ci` command
# < https://docs.platformio.org/page/userguide/cmd_ci.html >
#
#
# Please choose one of the following templates (proposed below) and uncomment
# it (remove "# " before each line) or use own configuration according to the
# Travis CI documentation (see above).
#


#
# Template #1: General project. Test it using existing `platformio.ini`.
#

# language: python
# python:
# - "2.7"
#
# sudo: false
# cache:
# directories:
# - "~/.platformio"
#
# install:
# - pip install -U platformio
# - platformio update
#
# script:
# - platformio run


#
# Template #2: The project is intended to be used as a library with examples.
#

# language: python
# python:
# - "2.7"
#
# sudo: false
# cache:
# directories:
# - "~/.platformio"
#
# env:
# - PLATFORMIO_CI_SRC=path/to/test/file.c
# - PLATFORMIO_CI_SRC=examples/file.ino
# - PLATFORMIO_CI_SRC=path/to/test/directory
#
# install:
# - pip install -U platformio
# - platformio update
#
# script:
# - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
83 changes: 83 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# !!! WARNING !!! AUTO-GENERATED FILE, PLEASE DO NOT MODIFY IT AND USE
# https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags
#
# If you need to override existing CMake configuration or add extra,
# please create `CMakeListsUser.txt` in the root of project.
# The `CMakeListsUser.txt` will not be overwritten by PlatformIO.

cmake_minimum_required(VERSION 3.2)
project(teensy4_i2c)

include(CMakeListsPrivate.txt)

if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/CMakeListsUser.txt)
include(CMakeListsUser.txt)
endif()

add_custom_target(
PLATFORMIO_BUILD ALL
COMMAND ${PLATFORMIO_CMD} -f -c clion run "$<$<NOT:$<CONFIG:All>>:-e${CMAKE_BUILD_TYPE}>"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_custom_target(
PLATFORMIO_BUILD_VERBOSE ALL
COMMAND ${PLATFORMIO_CMD} -f -c clion run --verbose "$<$<NOT:$<CONFIG:All>>:-e${CMAKE_BUILD_TYPE}>"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_custom_target(
PLATFORMIO_UPLOAD ALL
COMMAND ${PLATFORMIO_CMD} -f -c clion run --target upload "$<$<NOT:$<CONFIG:All>>:-e${CMAKE_BUILD_TYPE}>"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_custom_target(
PLATFORMIO_CLEAN ALL
COMMAND ${PLATFORMIO_CMD} -f -c clion run --target clean "$<$<NOT:$<CONFIG:All>>:-e${CMAKE_BUILD_TYPE}>"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_custom_target(
PLATFORMIO_MONITOR ALL
COMMAND ${PLATFORMIO_CMD} -f -c clion device monitor "$<$<NOT:$<CONFIG:All>>:-e${CMAKE_BUILD_TYPE}>"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_custom_target(
PLATFORMIO_TEST ALL
COMMAND ${PLATFORMIO_CMD} -f -c clion test "$<$<NOT:$<CONFIG:All>>:-e${CMAKE_BUILD_TYPE}>"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_custom_target(
PLATFORMIO_PROGRAM ALL
COMMAND ${PLATFORMIO_CMD} -f -c clion run --target program "$<$<NOT:$<CONFIG:All>>:-e${CMAKE_BUILD_TYPE}>"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_custom_target(
PLATFORMIO_UPLOADFS ALL
COMMAND ${PLATFORMIO_CMD} -f -c clion run --target uploadfs "$<$<NOT:$<CONFIG:All>>:-e${CMAKE_BUILD_TYPE}>"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_custom_target(
PLATFORMIO_UPDATE_ALL ALL
COMMAND ${PLATFORMIO_CMD} -f -c clion update
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_custom_target(
PLATFORMIO_REBUILD_PROJECT_INDEX ALL
COMMAND ${PLATFORMIO_CMD} -f -c clion init --ide clion
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_custom_target(
PLATFORMIO_DEVICE_LIST ALL
COMMAND ${PLATFORMIO_CMD} -f -c clion device list
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_executable(${PROJECT_NAME} ${SRC_LIST})
3 changes: 3 additions & 0 deletions CMakeListsUser.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Make tests visible to CLion.
# Use CLion's "Mark directory as" option to mark the "test" directory as a source folder.
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/test/test_register_i2c)
21 changes: 0 additions & 21 deletions LICENSE

This file was deleted.

92 changes: 90 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,90 @@
# teensy4_i2c
An I2C library for the Teensy 4. Provides slave and master mode.
#teensy4_i2c
An I2C library for the [Teensy 4](https://www.pjrc.com/store/teensy40.html)
microcontroller.

The Teensy 4.0 uses the [NXP i.MXRT 1062](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/i.mx-rt-series/i.mx-rt1060-crossover-processor-with-arm-cortex-m7-core:i.MX-RT1060)
microcontroller with n ARM Corex-M7 core.

This library is intended to be used as a drop in replacement for the
Wire library in [Teensyduino](https://www.pjrc.com/teensy/td_download.html).
The primary reason for writing it was to add support for Slave mode.

The driver implementations IMX_RT1060_I2CMaster and IMX_RT1060_I2CSlave have
no dependencies on Arduino itself and relatively few dependencies on the
Teensy code. This means that is should be possible to use the drivers with
other tool sets without having to change too much.

##Usage
### Use I2C Register Wrappers
I2CDevice and I2CRegisterSlave classes make it very simple to follow
the standard I2C pattern of reading or writing to "registers".
I recommend that you use this interface if it's suitable.

1. Download the code and put it in your include path.
1. &#35;include "i2c_device.h" if you have a master and wish
to read from a slave device.
1. &#35;include "i2c_register_slave.h" if you want to implement
a slave device to be read by a master.
1. See the examples in the examples/simple directory

### Use the Driver Directly
The driver interfaces are defined in i2c_driver.h. These provide
everything you need to use I2C without the limitations of the Wire
library. The key classes are I2CMaster and I2CSlave.

1. Download the code and put it in your include path.
1. &#35;include "imx_rt1060_i2c_driver.h"
1. See the examples in the examples/raw directory

###Replacing Wire.h
Follow these instructions if you have already written code to
use Wire.h and don't want to change it. I don't recommend using
the Wire API unless you have to. See below for alternatives.
1. Download the code and put it in your include path.
1. Change all #includes from Wire.h to i2c_driver_wire.h.
1. If any of your dependencies use Wire.h you'll have to
modify them to use i2c_driver_wire.h instead.
1. See the examples in the examples/wire directory

##Features
* Supports all features that are required by the I2C specification
for master, multi-master and slave devices.
* Drop in replacement for the Wire library
* Master Mode
* Slave Mode
* Standard Mode (100 kbps)
* Fast Mode (400 kbps)
* Fast Mode Plus (1 Mbps)
* Multi-master support
* Clock stretching in Slave Mode
* Non-blocking API for Master Mode and Slave Mode
* Comprehensive error handling

## Not Tested
I haven't been able to test some features because of hardware and time
restrictions. These features *should* work but don't be surprised if
they don't. Please contact me if you encounter any problems.
* Multi-master configurations
* Noisy environments
* Cortex i.MX RT1050

## Not Implemented
The following features are supported by the NXP i.MXRT 1062 processor but
I haven't implemented them in this driver.
Please contact me if you need any of these features.
* Alternative pins for port 1
* Direct Memory Access (DMA)
* High Speed Mode (3.4 Mbps)
* Ultra Fast Mode (5 Mbps)
* Multiple addresses for a single slave
* 10 bit slave addresses
* Glitch filter (for slave mode)
* SMBus Alert
* General Call
* 4 pin I2C in Master mode
* Master reading more than 256 bytes in a single transfer

## Version History
| Version | Release Date | Comment |
| ------- |-------------------| ----------------|
| v0.9.0 | 7th November 2019 | Initial Version |
119 changes: 119 additions & 0 deletions examples/raw/raw_master_reader/raw_master_reader.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// Copyright © 2019 Richard Gemmell
// Released under the MIT License. See license.txt. (https://opensource.org/licenses/MIT)

// This example WILL NOT work unless you have an INA260
// current sensor connected to pins 16 and 17.
//
// Demonstrates use of the raw I2C driver.
// Creates an I2C master and reads a device with it.
//
// This is an advanced example. Use the "simple" examples
// instead if you want to follow the typical usage pattern
// for I2C.

#include <Arduino.h>
#include <i2c_driver.h>
#include "imx_rt1060/imx_rt1060_i2c_driver.h"

// Blink the LED to make sure the Teensy hasn't hung
IntervalTimer blink_timer;
volatile bool led_high = false;
void blink_isr();

// The slave is an INA 260 current sensor
const uint16_t slave_address = 0x40;
const uint8_t manufacturer_id_register = 0xFE;
const uint8_t die_id_register = 0xFF;
I2CMaster& master = Master1;

// Create a buffer to receive data from the slave.
uint8_t rx_buffer[2] = {};

void finish();
bool ok(const char* message);
uint16_t get_int_from_buffer();

void setup() {
// Turn the LED on
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, true);

// Create a timer to blink the LED
blink_timer.begin(blink_isr, 500000);

// Initialise the master
master.begin(100 * 1000U);

// Enable the serial port for debugging
Serial.begin(9600);
Serial.println("Started");
}

void loop() {
Serial.println("");
// Request the Manufacturer ID
master.write_async(slave_address, (uint8_t*)&manufacturer_id_register, sizeof(manufacturer_id_register), false);
finish();
if(ok("Failed to send manufacture id register value")) {
master.read_async(slave_address, rx_buffer, sizeof(rx_buffer), true);
finish();
if (ok("Failed to read manufacture ID.")) {
uint16_t manufacturerID = get_int_from_buffer();
const uint16_t expected = 0x5449;
if (manufacturerID == expected) {
Serial.println("Got correct Manufacturer ID.");
} else {
Serial.printf("Manufacturer ID is 0x%X. Expected 0x%X.\n", manufacturerID, expected);
}
}
}

// Request the Die ID
master.write_async(slave_address, (uint8_t*)&die_id_register, sizeof(die_id_register), false);
finish();
if(ok("Failed to send die id register value")) {
master.read_async(slave_address, rx_buffer, sizeof(rx_buffer), true);
finish();
if (ok("Failed to read die ID.")) {
uint16_t dieId = get_int_from_buffer();
const uint16_t expected = 0x2270;
if (dieId == expected) {
Serial.println("Got correct Die ID.");
} else {
Serial.printf("Die ID is 0x%X. Expected 0x%X.\n", dieId, expected);
}
}
}

delay(1000);
}

uint16_t get_int_from_buffer() {
uint16_t result = ((uint16_t)rx_buffer[0] << 8U) + ((uint16_t)rx_buffer[1]);
return result;
}

bool ok(const char* message) {
if (master.has_error()) {
Serial.print(message);
Serial.print(" Error: ");
Serial.println((int)master.error());
return false;
}
return true;
}

void finish() {
elapsedMillis timeout;
while (timeout < 200) {
if (master.finished()){
return;
}
}
Serial.println("Master: ERROR timed out waiting for transfer to finish.");
}

void blink_isr() {
led_high = !led_high;
digitalWrite(LED_BUILTIN, led_high);
}
Loading

0 comments on commit ae42b5e

Please sign in to comment.