Libraries and Example of mbed parallel bus using I2C port expanders
Dependencies: HDSP253X mbed PCF8574_Bus
main.cpp@0:2467aed99127, 2011-08-31 (annotated)
- 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?
User | Revision | Line number | New 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 | } |