Libraries and Example of mbed parallel bus using I2C port expanders

Dependencies:   HDSP253X mbed PCF8574_Bus

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed bus - Main
00002  * Copyright (c) 2011 Wim Huiskamp
00003  *
00004  * Released under the MIT License: http://mbed.org/license/mit
00005  *
00006  * version 0.2 Initial Release
00007 */
00008 #include "mbed.h"
00009 #include "BusDefines.h"
00010 #include "PCF8574_DataBus.h"
00011 #include "PCF8574_AddressBus.h"
00012 #include "PCF8574_EnableBus.h"
00013 #include "MBED_ControlBus.h"
00014 #include "HDSP253X.h"
00015   
00016 // Debug stuff
00017 #define __DEBUG  
00018 #include "Dbg.h"
00019 
00020 // mbed Interface Hardware definitions
00021 DigitalOut myled1(LED1);
00022 DigitalOut myled2(LED2);
00023 DigitalOut myled3(LED3);
00024 DigitalOut heartbeatLED(LED4);
00025 
00026 // Host PC Communication channels
00027 Serial pc(USBTX, USBRX);
00028 
00029 //I2C Bus
00030 I2C i2c(D_SDA, D_SCL);
00031 
00032 // Bus Interface Hardware definitions
00033 PCF8574_DataBus    databus = PCF8574_DataBus(i2c, D_I2C_DATA_BUS);  //Copy constructors..
00034 PCF8574_AddressBus addressbus = PCF8574_AddressBus(i2c, D_I2C_ADDR_BUS);
00035 PCF8574_EnableBus  enablebus = PCF8574_EnableBus(i2c, D_I2C_ENA_BUS);
00036 MBED_ControlBus  controlbus = MBED_ControlBus(D_WR, D_RD, D_DTR, D_CDBUF, D_CDINT);
00037 
00038 // Display Hardware definitions
00039 HDSP253X_Display LED_display = HDSP253X_Display(databus, addressbus, enablebus, controlbus);
00040 
00041 // Dummy delay
00042 #define DEVICE_WAIT_MS   0
00043 
00044 
00045 // Variables for Heartbeat and Status monitoring
00046 Ticker heartbeat;
00047 bool heartbeatflag=false;
00048 
00049 // Cycle Timer
00050 Timer cycletimer;
00051 int cyclecount = 0;
00052 const int maxcount = 10;
00053 
00054 // Local functions
00055 void clear_screen() {
00056 //ANSI Terminal Commands
00057     pc.printf("\x1B[2J");
00058     pc.printf("\x1B[H");
00059 }
00060 
00061 
00062 void init_interfaces() {
00063 // Init Host PC communication, default is 9600
00064     pc.baud(D_BAUDRATE);
00065       
00066 // Init I/F hardware
00067     i2c.frequency(100000);  
00068   
00069     //Done, Tell me about it
00070     myled1 = 1;
00071 //    DBG("Init Interfaces Done\r");    
00072 }
00073       
00074 
00075 // Heartbeat monitor
00076 void pulse() {
00077   heartbeatLED = !heartbeatLED;
00078 }
00079 
00080 void heartbeat_start() {
00081   heartbeat.attach(&pulse, 0.5);
00082   heartbeatflag = true;
00083 }
00084 
00085 void heartbeat_stop() {
00086   heartbeat.detach();
00087   heartbeatflag = false;
00088 }
00089 
00090 void show_LEDS () {
00091   static int state = 0;
00092  
00093   switch (state) {
00094    case 0: 
00095         myled1 = 1;
00096         myled2 = 0;
00097         myled3 = 0;
00098         state = 1;
00099         break;
00100    case 1: 
00101         myled1 = 0;
00102         myled2 = 1;
00103         myled3 = 0;
00104         state = 2;
00105         break;
00106    case 2:     
00107         myled1 = 0;
00108         myled2 = 0;
00109         myled3 = 1;
00110         state = 0;
00111         break;
00112    }
00113 }
00114 
00115 
00116 // The next two functions are examples of low-level reading and writing to a device that is connected on the mbed bus.
00117 // In your own application you can develop a Class for each specific slave device and include modified versions of the 
00118 // functions below as 'private' functions. This allows you to hardcode the device CS_pin signals, define specific delays
00119 // 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.
00120 //
00121 
00122 /*---------------------------------------------------------------------------*\
00123  |
00124  |  Function:       write
00125  |
00126  |  Description:    Low level data write routine for device. Takes in data
00127  |                  and address and CS pin to identify the device and writes
00128  |                  data to the display. For simplicity, entire address byte
00129  |                  is written, even though top two bits are unused inputs.
00130  |                  After performing the operation, address lines are set
00131  |                  all high, in order to eliminate current drain through
00132  |                  pullup resistors (0.5mA per pin with 10K pullups)
00133  |
00134  |  Parameters:     address - full address in bits 0-5
00135  |                  device  - enum CS_Pin for Chip Select pin
00136  |                  data - data byte to write out
00137  |
00138  |  Returns:        Nothing.
00139  |
00140 \*---------------------------------------------------------------------------*/
00141 
00142 void write(uint8_t address, CS_Pin device, uint8_t data)
00143 {
00144 //    // Switch databus buffer to outputs (note: this is the default state)
00145 //    controlbus.busdir(WRITE);        
00146 //    // Switch databus to outputs
00147 //    databus.busdir(WRITE);   
00148 
00149     
00150     // Write out the address on to the addressbus and wait
00151     addressbus.write(address);
00152     wait_ms(DEVICE_WAIT_MS);
00153 
00154     // Set CE low and wait
00155     enablebus.chipselect(device, LOW);  
00156     wait_ms(DEVICE_WAIT_MS);
00157 
00158     // Write data to the databus
00159     databus.write(data);        
00160     wait_ms(DEVICE_WAIT_MS);
00161      
00162     // Set WR low, wait, then set high and wait
00163     controlbus.WR(LOW);
00164     wait_ms(DEVICE_WAIT_MS);
00165     controlbus.WR(HIGH);
00166     wait_ms(DEVICE_WAIT_MS);
00167 
00168     // Set CE high and wait
00169     enablebus.chipselect(device, HIGH);  
00170     wait_ms(DEVICE_WAIT_MS);
00171     
00172 //    // Switch databus back to inputs
00173 //    databus.busdir(READ);        
00174 //    // Switch databus buffer back to inputs
00175 //    controlbus.busdir(READ);  
00176 
00177 //    // Set address lines all high to minimise power through pullups
00178 //    addressbus.write(0xFF);
00179 }
00180 
00181 /*---------------------------------------------------------------------------*\
00182  |
00183  |  Function:       read
00184  |
00185  |  Description:    Low level data read routine for a Device. Takes in 
00186  |                  address and CS pin to identify the device and then 
00187  |                  reads data from the device.
00188  |                  After performing the operation, address lines are set
00189  |                  all high, in order to eliminate current drain through
00190  |                  pullup resistors (0.5mA per pin with 10K pullups)
00191  |
00192  |  Parameters:     address - 8 bit address
00193  |                  device  - enum CS_Pin for Chip Select pin
00194  |  Returns:        data - data byte read
00195  |
00196 \*---------------------------------------------------------------------------*/
00197 
00198 uint8_t read(uint8_t address, CS_Pin device)
00199 {
00200     uint8_t data = 0;
00201 
00202     // Switch databus to inputs (default state is output)
00203     databus.busdir(READ);        
00204     // Switch databus buffer to inputs
00205     controlbus.busdir(READ);      
00206        
00207     // Write out the address on to the addressbus and wait
00208     addressbus.write(address);
00209     wait_ms(DEVICE_WAIT_MS);
00210 
00211     // Set CE low and wait
00212     enablebus.chipselect(device, LOW);
00213     wait_ms(DEVICE_WAIT_MS);
00214 
00215     // Set RD low and wait
00216     controlbus.RD(LOW);
00217     wait_ms(DEVICE_WAIT_MS);
00218     
00219     // Read the data byte from databus
00220     data = databus.read();
00221 
00222     // set RD high and wait
00223     controlbus.RD(HIGH);
00224     wait_ms(DEVICE_WAIT_MS);
00225 
00226     // Set CE high and wait
00227     enablebus.chipselect(device, HIGH);
00228     wait_ms(DEVICE_WAIT_MS);
00229 
00230 //    // Set address lines all high to minimise power through pullups
00231 //    addressbus.write(0xFF);
00232 
00233     // Switch databus buffer back to outputs
00234     controlbus.busdir(WRITE);        
00235     // Switch databus to outputs
00236     databus.busdir(WRITE);   
00237     
00238     // Return read data to caller
00239     return data;
00240 }
00241 
00242 
00243 void HDSP_BITE() {
00244   int count;
00245     
00246     for (count=0; count<5; count++) {
00247       LED_display.locate(0);
00248       LED_display.printf("BITE  - ");
00249       wait(0.05);                    
00250       LED_display.locate(0);         
00251       LED_display.printf("BITE  \\ ");
00252       wait(0.05);                              
00253       LED_display.locate(0);        
00254       LED_display.printf("BITE  | ");
00255       wait(0.05);              
00256       LED_display.locate(0);    
00257       LED_display.printf("BITE  / ");    
00258       wait(0.05);      
00259       LED_display.locate(0);    
00260       LED_display.printf("BITE  - ");                
00261       wait(0.05);      
00262     };
00263 
00264     LED_display.locate(0);    
00265     LED_display.printf("BITE  OK"); 
00266 
00267     LED_display.set_blink_mode(true);            
00268     wait(2.0);          
00269     LED_display.set_blink_mode(false);
00270                     
00271     LED_display.cls();  
00272 
00273     //Done, Tell me about it                        
00274 //    DBG("BITE Done, Main, Step = %d\r", 30);    
00275 }
00276 
00277 void HDSP_Init_UDC() {
00278 
00279 // batt empty
00280   LED_display.define_user_char(0, 0x0E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1F);
00281 // batt full  
00282   LED_display.define_user_char(1, 0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F);  
00283 }  
00284   
00285 
00286 void HDSP_Show_UDC() {
00287  
00288   LED_display.locate(0);    
00289   LED_display.printf("Batt "); 
00290 //  LED_display.putc(HDSP253X_ASCII_UDC_CHARS + 0); 
00291 //  LED_display.putc(HDSP253X_ASCII_UDC_CHARS + 1); 
00292   LED_display.putudc(0); 
00293   LED_display.putudc(1); 
00294     
00295   wait(2.0);          
00296 }
00297 
00298 int main() {
00299     int address;
00300     uint8_t dummy;
00301 
00302     init_interfaces();
00303     
00304     heartbeat_start();
00305           
00306     clear_screen(); 
00307     
00308     HDSP_Init_UDC();
00309             
00310 //    DBG("Start Main Loop\r");    
00311 
00312 //Testing stuff
00313         
00314     //Test cycletime
00315     cycletimer.start();      
00316     cycletimer.reset();
00317 
00318 
00319 #if (1)
00320 // Bus test
00321     while (1) {
00322       for (address=0; address<256; address++) {
00323         //data = read(address, CS_SWITCH);
00324         
00325         dummy = ~address;
00326         write(address, LATCHEN_1, dummy); 
00327 //        wait(0.05);       
00328       }    
00329     
00330       // Just for Info, lets see how fast this cycle is...
00331       cyclecount++;
00332       if (cyclecount == maxcount) {
00333         pc.printf("Freq = %d Hz\r", (cyclecount * 256 * 1000) / cycletimer.read_ms());
00334         cyclecount = 0;          
00335         cycletimer.reset();      
00336       }
00337       
00338       show_LEDS ();      
00339     }
00340 #else
00341 // LED Display test
00342     while (1) {
00343       HDSP_BITE();   
00344 
00345       cyclecount++;
00346       if (cyclecount == 10) {
00347         cyclecount = 0;
00348 //        LED_display.printf ("Restart ");
00349         HDSP_Show_UDC();         
00350       }       
00351       else {
00352         LED_display.printf ("Cnt=  %2d", cyclecount);      
00353       }
00354       wait(2.0);
00355       pc.printf ("."); 
00356                      
00357       show_LEDS ();      
00358     }
00359 
00360 #endif
00361       
00362     //DBG("I'll be back...\r\r");
00363 }