This project demonstrates how to take advantage of the male and female extension contacts on the LPCXpresso Base Board. With a logic analyzer we will illustrate the I2C and SPI communication between the LPC1343 board and eeprom devices placed on the LPCXpresso Base Board and on a separate breadboard.

The LPCXpresso Base Board comes with a lot of diverse components such as accelerometer, joystick and flash memory. It is also fitted with two extension connectors, one female and one male, which makes it ideal for connecting other components to your LPCXpresso Base Board. Both the connectors have 50 pin expansion dual row header with 100 mil pitch. The female contact could be used for connection to external designs (see previous projects) or a breadboard (figure 3a) while the male contact could be used for connection with flat cable (figure 3b) or to a logic analyzer (figure 3c). While using the extension contacts beware that some of the signals from the LPC1343 board are connected to devices on the LPCXpresso base board and that these might need to be disabled using the jumpers on the board. The correct pin configuration is described in the schematics and the user's manual for the LPCXpresso Base Board (download it from Embedded Artists support pages).


When debugging software and hardware it is often helpful to see the signal on the pins that you want to manipulate. Whether this is just setting a specific pin high or low or inspecting what bits flow over a communication bus the logic analyzer will help to illustrate the behavior of any exposed signal. The logic analyzers come in various shapes and setups, from full mainframe systems to simple USB-connected devices.
The logic analyzer shows relative timing and states, high or low, of the different signals acquired. Note that the logic analyzer does not show an analogue signal so rise time and fringes on the wire will not be visible. It simply indicates whether the signal is high or low, given by a threshold value, and at what relative time it got there. This makes it suitable for analyzing digital signals in a circuit.
A key feature of a logic analyzer is to trigger signal acquisition on a given state. This might be the change on a single wire or on a combination of wires. Performance of a logic analyzer is often measured in speed, resolution, number of channels and memory. Apart from being capable of measuring the signals many logic analyzers can also interpret signals from known communication protocols such as I2C and SPI.
There are several logic analyzers on the market but the one we at Embedded Artists have found to work for us is the Intronix Logicport ( www.pcTestInstruments.com). The software for the PC is downloaded of the Internet and once installed it is just to plug the Logic Analyzer into the USB-contact of your computer and start measuring.
In this demonstration we will use the logic analyzer to view the I2C signal between the LPC1343 placed on the LPCXpresso Base Board and an internal I2C eeprom mounted on the LPCXpresso Base Board. The I2C protocol requires two signal lines; serial data (SDA) and serial clock (SCL). These are the signals that we will monitor.
Connect the logic analyzer to the corresponding pins on the male extension connector on the baseboard (see picture for correct setup):

Add the wires D0 and D1 to the signal view. Trigger the signal on the SDA going from high to low (corresponds to a start bit). Insert an I2C interpreter to the signals (Use "Setup -> Interpreter...-> Create..." or "Right Click" in the wire view). In the interpreter settings use the SDA as the signal and the settings as seen below.

The eeprom is organized as four blocks of 256 x 8-bit memory. When writing to the device it is necessary to first specify which block to write to and then specify which of the 256 memory positions to address. Our program will write to the 240th memory location in the first block and then read back the value from the same memory location. Below is the source code for this:
#include "type.h"
#include "timer32.h"
#include "i2c.h"
#include "gpio.h"
#include "eeprom.h"
#define E_WRITE_LEN 1
int main (void)
{
uint16_t offset = 240;
uint8_t b[E_WRITE_LEN];
uint8_t a[E_WRITE_LEN];
int16_t len = 0;
uint16_t addr;
GPIOInit();
init_timer32(0, 10);
I2CInit( (uint32_t)I2CMASTER, 0 );
// Set the value to write to the eeprom
b[0]= 0x5A;
// Set the address position
addr=offset;
// Write to the value b to eeprom addr
len = eeprom_write(b, addr, E_WRITE_LEN);
// Wait for eeprom to finish writing
delay32Ms(0, 6);
// Read the value from eeprom addr
len = eeprom_read(a, addr, E_WRITE_LEN);
}
The write and read commands for the eeprom are located in the eeprom.c file:
int16_t eeprom_read(uint8_t* buf, uint16_t offset, uint16_t len)
{
uint8_t addr = 0;
int i = 0;
uint16_t off = offset;
if (len > EEPROM_TOTAL_SIZE || offset+len > EEPROM_TOTAL_SIZE) {
return -1;
}
addr = EEPROM_I2C_ADDR1 + (offset/EEPROM_BLOCK_SIZE);
off = offset % EEPROM_BLOCK_SIZE;
I2CWrite((addr << 1), (uint8_t*)&off, 1);
for ( i = 0; i < 0x2000; i++);
I2CRead((addr << 1), buf, len);
return len;
}
int16_t eeprom_write(uint8_t* buf, uint16_t offset, uint16_t len)
{
uint8_t addr = 0;
int16_t written = 0;
uint16_t wLen = 0;
uint16_t off = offset;
uint8_t tmp[17];
if (len > EEPROM_TOTAL_SIZE || offset+len > EEPROM_TOTAL_SIZE) {
return -1;
}
addr = EEPROM_I2C_ADDR1 + (offset/EEPROM_BLOCK_SIZE);
off = offset % EEPROM_BLOCK_SIZE;
wLen = ((((off >> 4) + 1) << 4) - off);
wLen = MIN(wLen, len);
while (len) {
tmp[0] = off;
memcpy(&tmp[1], (void*)&buf[written], wLen);
I2CWrite((addr << 1), tmp, wLen+1);
/* delay to wait for a write cycle */
eepromDelay();
len -= wLen;
written += wLen;
off += wLen;
wLen = MIN(EEPROM_PAGE_SIZE, len);
addr += off / EEPROM_BLOCK_SIZE;
off = off % EEPROM_BLOCK_SIZE;
}
return written;
}
Start acquiring signals from the logic analyzer. What you will see is a string of bits sent over the wires. If you’re having trouble finding your signal use the view -> Scroll to trigger and Zoom in /out.

The write command consists of three parts:

The read command consists of three parts:
In this demonstration we will use the logic analyzer to view the SPI signal between the LPC1343 placed on the LPCXpresso Base Board and an external SPI eeprom placed on a breadboard. The SPI protocol requires four signal lines; chip select, clock, line out and line in. These are the signals that we will monitor.
Connect the eeprom to the female extension connectors on the base board (see picture for correct setup):
Connect the logic analyzer to the corresponding pins on the male extension connectors on the baseboard (see picture for correct setup):


Add the wires D0, D1, D2 and D3 to the signal view. Make sure that the trigger is on the chip select (CS) edge up. Insert two SPI interpreters to the signals (Use “Setup -> Interpreter…-> Create…” or "Right-Click" in the wire view). For the first interpreter use the MOSI signal as the data signal and use active high as trigger. For the second interpreter use the MISO signal as the data signal.

Our program will set a memory position, write a value to that memory position and then read back the value from the same memory position. Below is the source code for this
#include "type.h"
#include "timer32.h"
#include "ssp.h"
#include "gpio.h"
#define CS_ON() GPIOSetValue(PORT1, 11, 1 )
#define CS_OFF() GPIOSetValue(PORT1, 11, 0 )
#define SB (0x01)
#define WRITE (0x40)
#define READ (0x80)
static void writeEnable(void)
{
uint8_t data[2];
data[0]= 0x01;
data[1]= 0x30;
CS_ON();
SSPSend(&data, 2);
CS_OFF();
}
static void writeDisable(void)
{
uint8_t data[2];
data[0]= 0x01;
data[1]= 0x00;
CS_ON();
SSPSend(&data, 2);
CS_OFF();
}
int main (void){
GPIOInit();
init_timer32(0, 10);
SSPInit();
GPIOSetDir( PORT1, 11, 1 );
CS_OFF();
uint8_t send[4], data[2];
uint8_t addr =0x26;
send[0] = SB; // give the send vector the start bit
send[1] = WRITE; // give the send vector the write command
send[1] |= addr; // give the send vector the address
// to write to
send[2] = 0xAA;
send[3] = 0xAA;
writeEnable(); // enable write to the eeprom
CS_ON(); // turn on chip select
SSPSend(send,4); // send the command for writing
CS_OFF(); // turn off chip select
writeDisable(); // disable write to the eeprom
delay32Ms(0, 10); // 10ms delay for eeprom to erase and
// write
send[1]=0x00; // set the send vector to 0x0100xxxx
send[2]=0x00; // set the send vector to 0x010000xx
send[3]=0x00; // set the send vector to 0x01000000
send[1]|=READ; // give send vector read command
send[1]|=addr; // give send vector addr to read from
CS_ON(); // turn on chip select
SSPSend(send, 2); // send command for reading from
// the eeeprom
SSPReceive(data, 2); // read the 16 bit value that the
// eeprom sends
CS_OFF(); // turn off chip select
return 0;
}
Settings for the SSP port on the LPC1343 are controlled in the function SSPInit() created in the ssp.c (seen below). There are a few things to take note of. The frequency of the SPI communication is controlled through a number of dividers. First the system clock is divided to the SSP peripheral clock (SSP_PCLK). The second division is the Prescale Clock Divider (CPSDVSR) that reduces the SSP peripheral clock. Third is the Serial Clock Rate (SCR) that sets the number of prescaled clocks per bit on the bus. The final clock rate of the SSP communication is (System Clock)/((SSP_PCLK divider)*(Prescale Clock Divider)*(Serial Clock Rate +1)). Please see LPC1343 user's manual (page 236) for details of the SSP clock setup. The values we have used are:
From the data sheet we can see that the max frequency of the eeprom is 2MHz. With current setup, the SPI clock frequency is 72 MHz/(4*2*(15+1))= 562 KHz and well below the maximum value.
void SSPInit( void )
{
uint8_t i, Dummy=Dummy;
LPC_SYSCON->PRESETCTRL |= (0x1<<0);
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<11);
LPC_SYSCON->SSPCLKDIV = 0x04; /* Divided by 4 */
LPC_IOCON->PIO0_8 &= ~0x07; /* SSP I/O config */
LPC_IOCON->PIO0_8 |= 0x01; /* SSP MISO */
LPC_IOCON->PIO0_9 &= ~0x07;
LPC_IOCON->PIO0_9 |= 0x01; /* SSP MOSI */
#ifdef __JTAG_DISABLED
LPC_IOCON->SCKLOC = 0x00;
LPC_IOCON->JTAG_TCK_PIO0_10 &= ~0x07;
LPC_IOCON->JTAG_TCK_PIO0_10 |= 0x02; /* SSP CLK */
#endif
#if 1
/* On HummingBird 1(HB1), SSP CLK can be routed to different pins,
other than JTAG TCK, it's either P2.11 func. 1 or P0.6 func. 2. */
LPC_IOCON->SCKLOC = 0x01;
/* P2.11 function 1 is SSP clock, need to combined
with IOCONSCKLOC register setting */
LPC_IOCON->PIO2_11 = 0x01;
#else
LPC_IOCON->SCKLOC = 0x02;
/* P0.6 function 2 is SSP clock, need to combined
with IOCONSCKLOC register setting */
LPC_IOCON->PIO0_6 = 0x02;
#endif
#if USE_CS
LPC_IOCON->PIO0_2 &= ~0x07;
LPC_IOCON->PIO0_2 |= 0x01; /* SSP SSEL */
#else
LPC_IOCON->PIO0_2 &= ~0x07; /* SSP SSEL is a GPIO pin */
/* port0, bit 2 is set to GPIO output and high */
GPIOSetDir( PORT0, 2, 1 );
GPIOSetValue( PORT0, 2, 1 );
#endif
/* Set DSS data to 8-bit, Frame format SPI, CPOL = 0,
CPHA = 0, and SCR is 15 */
LPC_SSP->CR0 = 0x0F07;
/* SSPCPSR clock prescale register, master mode,
minimum divisor is 0x02 */
LPC_SSP->CPSR = 0x2;
for ( i = 0; i < FIFOSIZE; i++ )
{
Dummy = LPC_SSP->DR; /* clear the RxFIFO */
}
/* Enable the SSP Interrupt */
NVIC_EnableIRQ(SSP_IRQn);
/* Device select as master, SSP Enabled */
#if LOOPBACK_MODE
LPC_SSP->CR1 = SSPCR1_LBM | SSPCR1_SSE;
#else
#if SSP_SLAVE
/* Slave mode */
if ( LPC_SSP->CR1 & SSPCR1_SSE )
{
/* The slave bit can't be set until SSE bit is zero. */
LPC_SSP->CR1 &= ~SSPCR1_SSE;
}
LPC_SSP->CR1 = SSPCR1_MS; /* Enable slave bit first */
LPC_SSP->CR1 |= SSPCR1_SSE; /* Enable SSP */
#else
/* Master mode */
LPC_SSP->CR1 = SSPCR1_SSE;
#endif
#endif
/* Set SSPINMS registers to enable interrupts */
/* enable all error related interrupts */
LPC_SSP->IMSC = SSPIMSC_RORIM | SSPIMSC_RTIM;
return;
}
Start acquiring signals from the logic analyzer. What you will see is a string of bits being sent over the wires. (If you're having trouble finding your signal use the view -> Scroll to trigger and Zoom in /out). There should be two sets of signals, one at the beginning of acquisition containing the write command and one 10 ms after containing the read command. The LPC1343 sends the information one byte at the time and therefore the start bit (SB) will be sent in a first byte and the following byte will contain the rest of the instructions (see table below for instruction set for the 93LC46C).


The write command consists of three parts:

The read command consists of two parts: