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