Libraries and Example of mbed parallel bus using I2C port expanders

Dependencies:   HDSP253X mbed PCF8574_Bus

Committer:
wim
Date:
Wed Aug 31 19:45:31 2011 +0000
Revision:
0:2467aed99127
Child:
1:e180256ba6fb
First Version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wim 0:2467aed99127 1 /* mbed bus - Main
wim 0:2467aed99127 2 * Copyright (c) 2011 Wim Huiskamp
wim 0:2467aed99127 3 *
wim 0:2467aed99127 4 * Released under the MIT License: http://mbed.org/license/mit
wim 0:2467aed99127 5 *
wim 0:2467aed99127 6 * version 0.2 Initial Release
wim 0:2467aed99127 7 */
wim 0:2467aed99127 8 #include "mbed.h"
wim 0:2467aed99127 9 #include "BusDefines.h"
wim 0:2467aed99127 10 #include "PCF8574_DataBus.h"
wim 0:2467aed99127 11 #include "PCF8574_AddressBus.h"
wim 0:2467aed99127 12 #include "PCF8574_EnableBus.h"
wim 0:2467aed99127 13 #include "MBED_ControlBus.h"
wim 0:2467aed99127 14
wim 0:2467aed99127 15 // Debug stuff
wim 0:2467aed99127 16 #define __DEBUG
wim 0:2467aed99127 17 #include "Dbg.h"
wim 0:2467aed99127 18
wim 0:2467aed99127 19 // mbed Interface Hardware definitions
wim 0:2467aed99127 20 DigitalOut myled1(LED1);
wim 0:2467aed99127 21 DigitalOut myled2(LED2);
wim 0:2467aed99127 22 DigitalOut myled3(LED3);
wim 0:2467aed99127 23 DigitalOut heartbeatLED(LED4);
wim 0:2467aed99127 24
wim 0:2467aed99127 25 // Host PC Communication channels
wim 0:2467aed99127 26 Serial pc(USBTX, USBRX);
wim 0:2467aed99127 27
wim 0:2467aed99127 28 //I2C Bus
wim 0:2467aed99127 29 I2C i2c(D_SDA, D_SCL);
wim 0:2467aed99127 30
wim 0:2467aed99127 31 // Bus Interface Hardware definitions
wim 0:2467aed99127 32 PCF8574_DataBus databus = PCF8574_DataBus(i2c, D_I2C_DATA_BUS); //Copy constructors..
wim 0:2467aed99127 33 PCF8574_AddressBus addressbus = PCF8574_AddressBus(i2c, D_I2C_ADDR_BUS);
wim 0:2467aed99127 34 PCF8574_EnableBus enablebus = PCF8574_EnableBus(i2c, D_I2C_ENA_BUS);
wim 0:2467aed99127 35 MBED_ControlBus controlbus = MBED_ControlBus(D_WR, D_RD, D_DTR, D_CDBUF, D_CDINT);
wim 0:2467aed99127 36
wim 0:2467aed99127 37 // Dummy delay
wim 0:2467aed99127 38 #define DEVICE_WAIT_MS 0
wim 0:2467aed99127 39
wim 0:2467aed99127 40
wim 0:2467aed99127 41 // Variables for Heartbeat and Status monitoring
wim 0:2467aed99127 42 Ticker heartbeat;
wim 0:2467aed99127 43 bool heartbeatflag=false;
wim 0:2467aed99127 44
wim 0:2467aed99127 45 // Cycle Timer
wim 0:2467aed99127 46 Timer cycletimer;
wim 0:2467aed99127 47 int cyclecount = 0;
wim 0:2467aed99127 48 const int maxcount = 10;
wim 0:2467aed99127 49
wim 0:2467aed99127 50 // Local functions
wim 0:2467aed99127 51 void clear_screen() {
wim 0:2467aed99127 52 //ANSI Terminal Commands
wim 0:2467aed99127 53 pc.printf("\x1B[2J");
wim 0:2467aed99127 54 pc.printf("\x1B[H");
wim 0:2467aed99127 55 }
wim 0:2467aed99127 56
wim 0:2467aed99127 57
wim 0:2467aed99127 58 void init_interfaces() {
wim 0:2467aed99127 59 // Init Host PC communication, default is 9600
wim 0:2467aed99127 60 pc.baud(D_BAUDRATE);
wim 0:2467aed99127 61
wim 0:2467aed99127 62 // Init I/F hardware
wim 0:2467aed99127 63 i2c.frequency(100000);
wim 0:2467aed99127 64
wim 0:2467aed99127 65 //Done, Tell me about it
wim 0:2467aed99127 66 myled1 = 1;
wim 0:2467aed99127 67 DBG("Init Interfaces Done\r");
wim 0:2467aed99127 68 }
wim 0:2467aed99127 69
wim 0:2467aed99127 70
wim 0:2467aed99127 71 // Heartbeat monitor
wim 0:2467aed99127 72 void pulse() {
wim 0:2467aed99127 73 heartbeatLED = !heartbeatLED;
wim 0:2467aed99127 74 }
wim 0:2467aed99127 75
wim 0:2467aed99127 76 void heartbeat_start() {
wim 0:2467aed99127 77 heartbeat.attach(&pulse, 0.5);
wim 0:2467aed99127 78 heartbeatflag = true;
wim 0:2467aed99127 79 }
wim 0:2467aed99127 80
wim 0:2467aed99127 81 void heartbeat_stop() {
wim 0:2467aed99127 82 heartbeat.detach();
wim 0:2467aed99127 83 heartbeatflag = false;
wim 0:2467aed99127 84 }
wim 0:2467aed99127 85
wim 0:2467aed99127 86 void show_LEDS () {
wim 0:2467aed99127 87 static int state = 0;
wim 0:2467aed99127 88
wim 0:2467aed99127 89 switch (state) {
wim 0:2467aed99127 90 case 0:
wim 0:2467aed99127 91 myled1 = 1;
wim 0:2467aed99127 92 myled2 = 0;
wim 0:2467aed99127 93 myled3 = 0;
wim 0:2467aed99127 94 state = 1;
wim 0:2467aed99127 95 break;
wim 0:2467aed99127 96 case 1:
wim 0:2467aed99127 97 myled1 = 0;
wim 0:2467aed99127 98 myled2 = 1;
wim 0:2467aed99127 99 myled3 = 0;
wim 0:2467aed99127 100 state = 2;
wim 0:2467aed99127 101 break;
wim 0:2467aed99127 102 case 2:
wim 0:2467aed99127 103 myled1 = 0;
wim 0:2467aed99127 104 myled2 = 0;
wim 0:2467aed99127 105 myled3 = 1;
wim 0:2467aed99127 106 state = 0;
wim 0:2467aed99127 107 break;
wim 0:2467aed99127 108 }
wim 0:2467aed99127 109 }
wim 0:2467aed99127 110
wim 0:2467aed99127 111
wim 0:2467aed99127 112 // The next two functions are examples of low-level reading and writing to a device that is connected on the mbed bus.
wim 0:2467aed99127 113 // In your own application you can develop a Class for each specific slave device and include modified versions of the
wim 0:2467aed99127 114 // functions below as 'private' functions. This allows you to hardcode the device CS_pin signals, define specific delays
wim 0:2467aed99127 115 // when needed, change the sequence of CS, WR etc or mask out certain address or databits when they are not used in a certain case.
wim 0:2467aed99127 116 //
wim 0:2467aed99127 117
wim 0:2467aed99127 118 /*---------------------------------------------------------------------------*\
wim 0:2467aed99127 119 |
wim 0:2467aed99127 120 | Function: write
wim 0:2467aed99127 121 |
wim 0:2467aed99127 122 | Description: Low level data write routine for device. Takes in data
wim 0:2467aed99127 123 | and address and CS pin to identify the device and writes
wim 0:2467aed99127 124 | data to the display. For simplicity, entire address byte
wim 0:2467aed99127 125 | is written, even though top two bits are unused inputs.
wim 0:2467aed99127 126 | After performing the operation, address lines are set
wim 0:2467aed99127 127 | all high, in order to eliminate current drain through
wim 0:2467aed99127 128 | pullup resistors (0.5mA per pin with 10K pullups)
wim 0:2467aed99127 129 |
wim 0:2467aed99127 130 | Parameters: address - full address in bits 0-5
wim 0:2467aed99127 131 | device - enum CS_Pin for Chip Select pin
wim 0:2467aed99127 132 | data - data byte to write out
wim 0:2467aed99127 133 |
wim 0:2467aed99127 134 | Returns: Nothing.
wim 0:2467aed99127 135 |
wim 0:2467aed99127 136 \*---------------------------------------------------------------------------*/
wim 0:2467aed99127 137
wim 0:2467aed99127 138 void write(uint8_t address, CS_Pin device, uint8_t data)
wim 0:2467aed99127 139 {
wim 0:2467aed99127 140 // // Switch databus buffer to outputs (note: this is the default state)
wim 0:2467aed99127 141 // controlbus.busdir(WRITE);
wim 0:2467aed99127 142 // // Switch databus to outputs
wim 0:2467aed99127 143 // databus.busdir(WRITE);
wim 0:2467aed99127 144
wim 0:2467aed99127 145
wim 0:2467aed99127 146 // Write out the address on to the addressbus and wait
wim 0:2467aed99127 147 addressbus.write(address);
wim 0:2467aed99127 148 wait_ms(DEVICE_WAIT_MS);
wim 0:2467aed99127 149
wim 0:2467aed99127 150 // Set CE low and wait
wim 0:2467aed99127 151 enablebus.chipselect(device, LOW);
wim 0:2467aed99127 152 wait_ms(DEVICE_WAIT_MS);
wim 0:2467aed99127 153
wim 0:2467aed99127 154 // Write data to the databus
wim 0:2467aed99127 155 databus.write(data);
wim 0:2467aed99127 156 wait_ms(DEVICE_WAIT_MS);
wim 0:2467aed99127 157
wim 0:2467aed99127 158 // Set WR low, wait, then set high and wait
wim 0:2467aed99127 159 controlbus.WR(LOW);
wim 0:2467aed99127 160 wait_ms(DEVICE_WAIT_MS);
wim 0:2467aed99127 161 controlbus.WR(HIGH);
wim 0:2467aed99127 162 wait_ms(DEVICE_WAIT_MS);
wim 0:2467aed99127 163
wim 0:2467aed99127 164 // Set CE high and wait
wim 0:2467aed99127 165 enablebus.chipselect(device, HIGH);
wim 0:2467aed99127 166 wait_ms(DEVICE_WAIT_MS);
wim 0:2467aed99127 167
wim 0:2467aed99127 168 // // Switch databus back to inputs
wim 0:2467aed99127 169 // databus.busdir(READ);
wim 0:2467aed99127 170 // // Switch databus buffer back to inputs
wim 0:2467aed99127 171 // controlbus.busdir(READ);
wim 0:2467aed99127 172
wim 0:2467aed99127 173 // // Set address lines all high to minimise power through pullups
wim 0:2467aed99127 174 // addressbus.write(0xFF);
wim 0:2467aed99127 175 }
wim 0:2467aed99127 176
wim 0:2467aed99127 177 /*---------------------------------------------------------------------------*\
wim 0:2467aed99127 178 |
wim 0:2467aed99127 179 | Function: read
wim 0:2467aed99127 180 |
wim 0:2467aed99127 181 | Description: Low level data read routine for a Device. Takes in
wim 0:2467aed99127 182 | address and CS pin to identify the device and then
wim 0:2467aed99127 183 | reads data from the device.
wim 0:2467aed99127 184 | After performing the operation, address lines are set
wim 0:2467aed99127 185 | all high, in order to eliminate current drain through
wim 0:2467aed99127 186 | pullup resistors (0.5mA per pin with 10K pullups)
wim 0:2467aed99127 187 |
wim 0:2467aed99127 188 | Parameters: address - 8 bit address
wim 0:2467aed99127 189 | device - enum CS_Pin for Chip Select pin
wim 0:2467aed99127 190 | Returns: data - data byte read
wim 0:2467aed99127 191 |
wim 0:2467aed99127 192 \*---------------------------------------------------------------------------*/
wim 0:2467aed99127 193
wim 0:2467aed99127 194 uint8_t read(uint8_t address, CS_Pin device)
wim 0:2467aed99127 195 {
wim 0:2467aed99127 196 uint8_t data = 0;
wim 0:2467aed99127 197
wim 0:2467aed99127 198 // Switch databus to inputs (default state is output)
wim 0:2467aed99127 199 databus.busdir(READ);
wim 0:2467aed99127 200 // Switch databus buffer to inputs
wim 0:2467aed99127 201 controlbus.busdir(READ);
wim 0:2467aed99127 202
wim 0:2467aed99127 203 // Write out the address on to the addressbus and wait
wim 0:2467aed99127 204 addressbus.write(address);
wim 0:2467aed99127 205 wait_ms(DEVICE_WAIT_MS);
wim 0:2467aed99127 206
wim 0:2467aed99127 207 // Set CE low and wait
wim 0:2467aed99127 208 enablebus.chipselect(device, LOW);
wim 0:2467aed99127 209 wait_ms(DEVICE_WAIT_MS);
wim 0:2467aed99127 210
wim 0:2467aed99127 211 // Set RD low and wait
wim 0:2467aed99127 212 controlbus.RD(LOW);
wim 0:2467aed99127 213 wait_ms(DEVICE_WAIT_MS);
wim 0:2467aed99127 214
wim 0:2467aed99127 215 // Read the data byte from databus
wim 0:2467aed99127 216 data = databus.read();
wim 0:2467aed99127 217
wim 0:2467aed99127 218 // set RD high and wait
wim 0:2467aed99127 219 controlbus.RD(HIGH);
wim 0:2467aed99127 220 wait_ms(DEVICE_WAIT_MS);
wim 0:2467aed99127 221
wim 0:2467aed99127 222 // Set CE high and wait
wim 0:2467aed99127 223 enablebus.chipselect(device, HIGH);
wim 0:2467aed99127 224 wait_ms(DEVICE_WAIT_MS);
wim 0:2467aed99127 225
wim 0:2467aed99127 226 // // Set address lines all high to minimise power through pullups
wim 0:2467aed99127 227 // addressbus.write(0xFF);
wim 0:2467aed99127 228
wim 0:2467aed99127 229 // Switch databus buffer back to outputs
wim 0:2467aed99127 230 controlbus.busdir(WRITE);
wim 0:2467aed99127 231 // Switch databus to outputs
wim 0:2467aed99127 232 databus.busdir(WRITE);
wim 0:2467aed99127 233
wim 0:2467aed99127 234 // Return read data to caller
wim 0:2467aed99127 235 return data;
wim 0:2467aed99127 236 }
wim 0:2467aed99127 237
wim 0:2467aed99127 238 int main() {
wim 0:2467aed99127 239 int address, result;
wim 0:2467aed99127 240 uint8_t data, dummy;
wim 0:2467aed99127 241
wim 0:2467aed99127 242 init_interfaces();
wim 0:2467aed99127 243
wim 0:2467aed99127 244 heartbeat_start();
wim 0:2467aed99127 245
wim 0:2467aed99127 246 clear_screen();
wim 0:2467aed99127 247
wim 0:2467aed99127 248 DBG("Start Main Loop\r");
wim 0:2467aed99127 249
wim 0:2467aed99127 250 //Testing stuff
wim 0:2467aed99127 251
wim 0:2467aed99127 252 //Test cycletime
wim 0:2467aed99127 253 cycletimer.start();
wim 0:2467aed99127 254 cycletimer.reset();
wim 0:2467aed99127 255
wim 0:2467aed99127 256 while (1) {
wim 0:2467aed99127 257 for (address=0; address<256; address++) {
wim 0:2467aed99127 258 //data = read(address, CS_SWITCH);
wim 0:2467aed99127 259
wim 0:2467aed99127 260 dummy = ~address;
wim 0:2467aed99127 261 write(address, LATCHEN_1, dummy);
wim 0:2467aed99127 262 // wait(0.05);
wim 0:2467aed99127 263 }
wim 0:2467aed99127 264
wim 0:2467aed99127 265 // Just for Info, lets see how fast this cycle is...
wim 0:2467aed99127 266 cyclecount++;
wim 0:2467aed99127 267 if (cyclecount == maxcount) {
wim 0:2467aed99127 268 pc.printf("Freq = %d Hz\r", (cyclecount * 256 * 1000) / cycletimer.read_ms());
wim 0:2467aed99127 269 cyclecount = 0;
wim 0:2467aed99127 270 cycletimer.reset();
wim 0:2467aed99127 271 }
wim 0:2467aed99127 272
wim 0:2467aed99127 273 show_LEDS ();
wim 0:2467aed99127 274 }
wim 0:2467aed99127 275
wim 0:2467aed99127 276
wim 0:2467aed99127 277 DBG("I'll be back...\r\r");
wim 0:2467aed99127 278 }