Libraries and Example of mbed parallel bus using I2C port expanders

Dependencies:   HDSP253X mbed PCF8574_Bus

Committer:
wim
Date:
Sun Jan 25 17:52:55 2015 +0000
Revision:
7:8680b8b718c8
Test of PCF8574 Bus interface to control HDSP253X Smart Alphanumeric LED matrix display.

Who changed what in which revision?

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