This project implements an extensible command parser that you can communicate with using the LPC845's I2C0 peripheral block in slave mode. It causes the LPC845 to behave similar to most I2C sensors, in that you interact with the coprocessor via a series of register reads and writes from any standard I2C master.
It is based on the minimalistic, super low cost LPC845-BRK from NXP (available for not much more than a decent drink), but is easily adaptable to any LPC84x board, and likely any LPC800 without too much extra effort.Design Goals
The main purpose of this demo is to enable the use of the low-cost but relatively high-performance ARM Cortex M0+ LPC845 from NXP as an affordable real-time co-processor on systems that have no or limited real time control, such as the Raspberry Pi or other Linux-based embedded systems.
It can also be used in situations where the main MCU may not have enough pins, SRAM or peripherals, such as requiring an additional HW UART block with flow control, or driving a large number of timing-specific peripherals like NeoPixels.
Since the coprocessor communicates over I2C, multiple devices can be used in the same system by changing the I2C address accepted by the LPC845.
It's also just an excuse for me to keep up to date on what's new in the LPC device family, since I have a long, happy experience with them (my first ARM chip was the ARM7 LPC2148), and I'm always curious what's new peripherals and devices have been added.Architecture
There are two key parts of the LPC845 I2C coprocessor project:
- The I2C Slave Engine
- The Command Registry/Parser
The I2C0 peripheral is configured as a slave device responding to the address set in
#define I2C_CFG_ADDR_7BIT (0x7EU)
The I2C engine has the following logic:
- Continuously Wait for a START or REPEATED START event to occur.
- Once a START or REPEATED START even is detected:
- If this is a WRITE request, send the incoming payload to the write command handler associated with that register/opcode.
- Track the last register/opcode written to correlate it with subsequent read attempts.
- If this is a READ request, the read command handler associated with the specified register/opcode will be fired in the I2C0 slave callback.
I2C commands are distinguished by a unique 8-bit opcode (or 'register'), and a registry of all of these commands is maintained as a singly-linked-list.
To add commands to the registry, you need to define a unique opcode for the command, and register the command information via
cmd_register(struct cmd_record *rec), passing in an appropriate
NOTE: Because the command registry is implemented as a singly-linked-list, commands can be dynamically added or removed at run-time if you need to have the flexibility of only making specific commands available in certain situations.
For details on adding commands and implementing command handlers, see the README.md file on Github to make sure that you are looking at the latest updates.Hardware Setup (LPC845-BRK)
This project makes use of the low cost LPC845-BRK from NXP, which includes an on-board debugger, and has minimal on board components which is always preferable (to me anyway!) on a dev board.
We makes use of two pins for the I2C bus, plus the common GND pin.
You MAY also need two 4.7K pullup resistors, which are required on the I2C bus to pull the SCL and SDA pins to logic high (connect the resistor between SCL and VDD, and SD and VDD). The I2C master (the device you are connecting the LPC845 to) may or may not have these available. If no pullups are present, the I2C bus won't work, but you will need to verify this on the platform you are using as the I2C Master.ADC Input (Optional)
The examples later in this readme use the ADC registers on the I2C co-processor, so you may want to connect the
ADC CH0 to an appropriate load using the following pin:
doc/examples folder contains a number of examples of how to communicate with the LPC845 coprocessor over I2C using a variety of common platforms.
You can easily connect the LPC845 I2C Co-processor to the Arduino using the standard I2C pins (SCL and SDA).Hardware Setup
You will need to connect SCL on the Arduino to SCL on the LPC845, and SDA on the Arduino to SDA on the LPC845:
Func.ArduinoLPC845 BreakoutSCLSCLP0_10 (Pin 23)SDASDAP0_11 (Pin 24)GNDGNDGND (Pin 20)
There are no 4.7K pullups on the Arduino by default, so you will also need to add two 4.7K (or similar) pullup resistors between the following pins:
- SCL and 3.3V (
o SCL ---[ 4.7K ]--- 3.3V o)
- SDA and 3.3V (
o SDA ---[ 4.7K ]--- 3.3V o)
Run the LPC845_coproc_arduino.ino sketch on your Arduino once you have connected the two boards are described above.2. Raspbery Pi (Python)
The Raspberry Pi contains HW I2C pins and support, meaning that you can communicate with the LPC845 I2C co-processor by connecting the LPC845 to the RPi using the SCL and SDA pins, and send and receive data in C or Python (or most other languages).Hardware Setup
The following pins should be connected:
SCL (3) and SDA (2) ALREADY HAVE 1.8K pullups to 3.3V, so no additional connections or components are required here! The I2C pins can be connected directly together between the RPi and the LPC845, and the I2C bus will be automatically pulled high by default.
If you've setup a new Raspberry Pi using Raspbian, and you don't have it hooked up to a display or keyboard, you can use a USB serial adapter (FTDI, etc.) and connect to the TTY UART pins on the RPi:
- BCM14 (TXD)
- BCM15 (RXD)
With the cable connected between your desktop and the RPi, you can run a terminal emulator on your desktop at
115200 baud. For OS X or Linux, for example, you could use
minicom (OPT+X to exit!):
$ minicom -D /dev/tty.usbserial -b 115200
When prompted for a login, the default username and password are
You will require network access for the
apt-get install commands below.
If you need help setting WiFi up, see Setting WiFi up via the command line.
Once network access has been established, the following commands should be run on the RPi to enable I2C support if it hasn't previously been enabled:RPi I2C Prerequisites (Raspbian)1. Enable I2C on the RPi
Before you can use I2C, you will need to enable it on the device. Run:
$ sudo raspi-config
I2C, and select
Yes when asked
Would you like the ARM I2C interface to be enabled?.
3. Install python-smbus
$ sudo apt-get install i2c-tools
Finally, you should install the
smbus library for Python if you wish to access I2C using Python:
Example Code (Python)
$ sudo apt-get install python-smbus
You can now copy and run lpc845_i2c.py on your RPi, which will attemptn to connect to the LPC845 I2C co-processor and perform a few basic read and write requests.