Libraries and Example of mbed parallel bus using I2C port expanders

Dependencies:   HDSP253X mbed PCF8574_Bus

main.cpp

Committer:
wim
Date:
2015-01-25
Revision:
7:8680b8b718c8
Parent:
6:aaefa04f06be

File content as of revision 7:8680b8b718c8:

/* mbed bus - Main
 * Copyright (c) 2011 Wim Huiskamp
 *
 * Released under the MIT License: http://mbed.org/license/mit
 *
 * version 0.2 Initial Release
*/
#include "mbed.h"
#include "BusDefines.h"
#include "PCF8574_DataBus.h"
#include "PCF8574_AddressBus.h"
#include "PCF8574_EnableBus.h"
#include "MBED_ControlBus.h"
#include "HDSP253X.h"
  
// Debug stuff
#define __DEBUG  
#include "Dbg.h"

// mbed Interface Hardware definitions
DigitalOut myled1(LED1);
DigitalOut myled2(LED2);
DigitalOut myled3(LED3);
DigitalOut heartbeatLED(LED4);

// Host PC Communication channels
Serial pc(USBTX, USBRX);

//I2C Bus
I2C i2c(D_SDA, D_SCL);

// Bus Interface Hardware definitions
PCF8574_DataBus    databus = PCF8574_DataBus(i2c, D_I2C_DATA_BUS);  //Copy constructors..
PCF8574_AddressBus addressbus = PCF8574_AddressBus(i2c, D_I2C_ADDR_BUS);
PCF8574_EnableBus  enablebus = PCF8574_EnableBus(i2c, D_I2C_ENA_BUS);
MBED_ControlBus  controlbus = MBED_ControlBus(D_WR, D_RD, D_DTR, D_CDBUF, D_CDINT);

// Display Hardware definitions
HDSP253X_Display LED_display = HDSP253X_Display(databus, addressbus, enablebus, controlbus);

// Dummy delay
#define DEVICE_WAIT_MS   0


// Variables for Heartbeat and Status monitoring
Ticker heartbeat;
bool heartbeatflag=false;

// Cycle Timer
Timer cycletimer;
int cyclecount = 0;
const int maxcount = 10;

// Local functions
void clear_screen() {
//ANSI Terminal Commands
    pc.printf("\x1B[2J");
    pc.printf("\x1B[H");
}


void init_interfaces() {
// Init Host PC communication, default is 9600
    pc.baud(D_BAUDRATE);
      
// Init I/F hardware
    i2c.frequency(100000);  
  
    //Done, Tell me about it
    myled1 = 1;
//    DBG("Init Interfaces Done\r");    
}
      

// Heartbeat monitor
void pulse() {
  heartbeatLED = !heartbeatLED;
}

void heartbeat_start() {
  heartbeat.attach(&pulse, 0.5);
  heartbeatflag = true;
}

void heartbeat_stop() {
  heartbeat.detach();
  heartbeatflag = false;
}

void show_LEDS () {
  static int state = 0;
 
  switch (state) {
   case 0: 
        myled1 = 1;
        myled2 = 0;
        myled3 = 0;
        state = 1;
        break;
   case 1: 
        myled1 = 0;
        myled2 = 1;
        myled3 = 0;
        state = 2;
        break;
   case 2:     
        myled1 = 0;
        myled2 = 0;
        myled3 = 1;
        state = 0;
        break;
   }
}


// The next two functions are examples of low-level reading and writing to a device that is connected on the mbed bus.
// In your own application you can develop a Class for each specific slave device and include modified versions of the 
// functions below as 'private' functions. This allows you to hardcode the device CS_pin signals, define specific delays
// 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.
//

/*---------------------------------------------------------------------------*\
 |
 |  Function:       write
 |
 |  Description:    Low level data write routine for device. Takes in data
 |                  and address and CS pin to identify the device and writes
 |                  data to the display. For simplicity, entire address byte
 |                  is written, even though top two bits are unused inputs.
 |                  After performing the operation, address lines are set
 |                  all high, in order to eliminate current drain through
 |                  pullup resistors (0.5mA per pin with 10K pullups)
 |
 |  Parameters:     address - full address in bits 0-5
 |                  device  - enum CS_Pin for Chip Select pin
 |                  data - data byte to write out
 |
 |  Returns:        Nothing.
 |
\*---------------------------------------------------------------------------*/

void write(uint8_t address, CS_Pin device, uint8_t data)
{
//    // Switch databus buffer to outputs (note: this is the default state)
//    controlbus.busdir(WRITE);        
//    // Switch databus to outputs
//    databus.busdir(WRITE);   

    
    // Write out the address on to the addressbus and wait
    addressbus.write(address);
    wait_ms(DEVICE_WAIT_MS);

    // Set CE low and wait
    enablebus.chipselect(device, LOW);  
    wait_ms(DEVICE_WAIT_MS);

    // Write data to the databus
    databus.write(data);        
    wait_ms(DEVICE_WAIT_MS);
     
    // Set WR low, wait, then set high and wait
    controlbus.WR(LOW);
    wait_ms(DEVICE_WAIT_MS);
    controlbus.WR(HIGH);
    wait_ms(DEVICE_WAIT_MS);

    // Set CE high and wait
    enablebus.chipselect(device, HIGH);  
    wait_ms(DEVICE_WAIT_MS);
    
//    // Switch databus back to inputs
//    databus.busdir(READ);        
//    // Switch databus buffer back to inputs
//    controlbus.busdir(READ);  

//    // Set address lines all high to minimise power through pullups
//    addressbus.write(0xFF);
}

/*---------------------------------------------------------------------------*\
 |
 |  Function:       read
 |
 |  Description:    Low level data read routine for a Device. Takes in 
 |                  address and CS pin to identify the device and then 
 |                  reads data from the device.
 |                  After performing the operation, address lines are set
 |                  all high, in order to eliminate current drain through
 |                  pullup resistors (0.5mA per pin with 10K pullups)
 |
 |  Parameters:     address - 8 bit address
 |                  device  - enum CS_Pin for Chip Select pin
 |  Returns:        data - data byte read
 |
\*---------------------------------------------------------------------------*/

uint8_t read(uint8_t address, CS_Pin device)
{
    uint8_t data = 0;

    // Switch databus to inputs (default state is output)
    databus.busdir(READ);        
    // Switch databus buffer to inputs
    controlbus.busdir(READ);      
       
    // Write out the address on to the addressbus and wait
    addressbus.write(address);
    wait_ms(DEVICE_WAIT_MS);

    // Set CE low and wait
    enablebus.chipselect(device, LOW);
    wait_ms(DEVICE_WAIT_MS);

    // Set RD low and wait
    controlbus.RD(LOW);
    wait_ms(DEVICE_WAIT_MS);
    
    // Read the data byte from databus
    data = databus.read();

    // set RD high and wait
    controlbus.RD(HIGH);
    wait_ms(DEVICE_WAIT_MS);

    // Set CE high and wait
    enablebus.chipselect(device, HIGH);
    wait_ms(DEVICE_WAIT_MS);

//    // Set address lines all high to minimise power through pullups
//    addressbus.write(0xFF);

    // Switch databus buffer back to outputs
    controlbus.busdir(WRITE);        
    // Switch databus to outputs
    databus.busdir(WRITE);   
    
    // Return read data to caller
    return data;
}


void HDSP_BITE() {
  int count;
    
    for (count=0; count<5; count++) {
      LED_display.locate(0);
      LED_display.printf("BITE  - ");
      wait(0.05);                    
      LED_display.locate(0);         
      LED_display.printf("BITE  \\ ");
      wait(0.05);                              
      LED_display.locate(0);        
      LED_display.printf("BITE  | ");
      wait(0.05);              
      LED_display.locate(0);    
      LED_display.printf("BITE  / ");    
      wait(0.05);      
      LED_display.locate(0);    
      LED_display.printf("BITE  - ");                
      wait(0.05);      
    };

    LED_display.locate(0);    
    LED_display.printf("BITE  OK"); 

    LED_display.set_blink_mode(true);            
    wait(2.0);          
    LED_display.set_blink_mode(false);
                    
    LED_display.cls();  

    //Done, Tell me about it                        
//    DBG("BITE Done, Main, Step = %d\r", 30);    
}

void HDSP_Init_UDC() {

// batt empty
  LED_display.define_user_char(0, 0x0E, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1F);
// batt full  
  LED_display.define_user_char(1, 0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F);  
}  
  

void HDSP_Show_UDC() {
 
  LED_display.locate(0);    
  LED_display.printf("Batt "); 
//  LED_display.putc(HDSP253X_ASCII_UDC_CHARS + 0); 
//  LED_display.putc(HDSP253X_ASCII_UDC_CHARS + 1); 
  LED_display.putudc(0); 
  LED_display.putudc(1); 
    
  wait(2.0);          
}

int main() {
    int address;
    uint8_t dummy;

    init_interfaces();
    
    heartbeat_start();
          
    clear_screen(); 
    
    HDSP_Init_UDC();
            
//    DBG("Start Main Loop\r");    

//Testing stuff
        
    //Test cycletime
    cycletimer.start();      
    cycletimer.reset();


#if (1)
// Bus test
    while (1) {
      for (address=0; address<256; address++) {
        //data = read(address, CS_SWITCH);
        
        dummy = ~address;
        write(address, LATCHEN_1, dummy); 
//        wait(0.05);       
      }    
    
      // Just for Info, lets see how fast this cycle is...
      cyclecount++;
      if (cyclecount == maxcount) {
        pc.printf("Freq = %d Hz\r", (cyclecount * 256 * 1000) / cycletimer.read_ms());
        cyclecount = 0;          
        cycletimer.reset();      
      }
      
      show_LEDS ();      
    }
#else
// LED Display test
    while (1) {
      HDSP_BITE();   

      cyclecount++;
      if (cyclecount == 10) {
        cyclecount = 0;
//        LED_display.printf ("Restart ");
        HDSP_Show_UDC();         
      }       
      else {
        LED_display.printf ("Cnt=  %2d", cyclecount);      
      }
      wait(2.0);
      pc.printf ("."); 
                     
      show_LEDS ();      
    }

#endif
      
    //DBG("I'll be back...\r\r");
}