Geodesic Light Dome Controller Program

Dependencies:   mbed

i2c.c

Committer:
lolpcc
Date:
2010-03-24
Revision:
1:dc58f0b0eeec
Parent:
0:a7af7ec8b12f

File content as of revision 1:dc58f0b0eeec:

#include "mbed.h"

#include "main.h"
#include "useful.h"
#include "i2c.h"
#include "pca9685_reg.h"    /* Light Driver Chip */

I2C i2c(p9, p10); // sda, scl
I2C i2c_1(p28, p27); // sda, scl


#define PIO          0x40
#define RELAYS       0x40



/******************************************/
/*                                        */
/*   Probe the I2C bus, and show the      */
/*   user what we have found              */
/*                                        */
/*                                        */
/*                                        */
/******************************************/
void i2c_probe(void) 
{
    lprintf("Searching for I2C devices...\n");
    
    int count = 0;
    for (int address=4; address<256; address+=2) {
        if (!i2c.write(address, NULL, 0)) { // 0 returned is ok
            lprintf(" - I2C device found at address 0x%02X\n", address);
            count++;
        }
    }
    lprintf("%d devices found\n", count);
}
void i2c_probe2(void) 
{
    lprintf("Searching for I2C devices... (seconday bus)\n");
    
    int count = 0;
    for (int address=4; address<256; address+=2) {
        if (!i2c_1.write(address, NULL, 0)) { // 0 returned is ok
            lprintf(" - I2C device found at address 0x%02X\n", address);
            count++;
        }
    }
    lprintf("%d devices found\n", count);
}



/******************************************/
/*                                        */
/* 1 - 8, Relays On,                      */
/*                                        */
/******************************************/
void relay_operate(char r)
{
    char buf[0x60];
        
    switch(r){
        case    0    :    /* Turn off the relays */
            buf[0]=0x00; 
            break;
        case    1    :
            buf[0]=0x01; 
            break;
        case    2    :
            buf[0]=0x02; 
            break;
        case    3    :
            buf[0]=0x04; 
            break;
        case    4    :
            buf[0]=0x08; 
            break;
        case    5    :
            buf[0]=0x10; 
            break;
        case    6    :
            buf[0]=0x20; 
            break;
        case    7    :
            buf[0]=0x40; 
            break;
        case    8    :
            buf[0]=0x80; 
            break;
        default      :
            lprintf("Unknown Relay %d\n\r",r);
            return;
    }
    i2c.write(RELAYS,buf,1);
}

/******************************************/
/*                                        */
/* Read and Write the PIO latch           */
/*                                        */
/******************************************/
void pio_write(unsigned char r, unsigned char d)
{
    unsigned char buf[0x60];
    
    buf[0]=d;
    i2c.write(r,(char *)buf,1);
}
void pio_read(unsigned char d)
{
   unsigned char r;
   unsigned char buf[0x60];
    
   i2c.read(d,(char *)buf,1);
   r = buf[0];
   
   lprintf("Returned value from the PIO was 0x%02x\n\r",r);
}

/******************************************/
/*                                        */
/* Philips PCA9685 I2C Driver, 16 channel */
/* Lighting controler chip, we have 4     */
/* running in this system, so we need to  */
/* think how the channels map ??          */
/*                                        */
/******************************************/

/******************************************/
/*                                        */
/* Init code for the PCA9685              */
/*                                        */
/******************************************/

void init_pca9685(unsigned char address)
{
    unsigned char buf[30];
    
    lprintf("Setting up channel %d\n\r",address);
    
    buf[0] = PCA9685_MODE1;
    buf[1] = PCA9685_AI;
    buf[2] = PCA9685_OUTDRV;
    i2c.write(address,(char *) buf, 3);
}

/******************************************/
/*                                        */
/* Send data to a given channle of a      */
/* given PCA9685 chip                     */
/*                                        */
/******************************************/

void pca9685_led(unsigned char addr, int led, unsigned char *values) 
{
    unsigned char buf[5];
   
    if (led == PCA9685_ALL_LEDS) {
        buf[0] = PCA9685_ALL_LED_ON_L;
    } else {
        buf[0] = PCA9685_BASE(led);
    }

    buf[1] = values[0];
    buf[2] = values[1];
    buf[3] = values[2];
    buf[4] = values[3];
    i2c.write(addr, (char *)buf, 5);
}

/******************************************/
/*                                        */
/* Calculate the register values for a    */
/* givern brightness percentage           */
/*                                        */
/******************************************/

void pca9685_brightness(int percent, unsigned char *values) 
{
    unsigned int on, off;

    if (percent == 0) {
    values[PCA9685_LED_ON_H] = 0;
    values[PCA9685_LED_OFF_H] = PCA9685_LED_OFF;
    return;
    }
    if (percent == 100) {
    values[PCA9685_LED_ON_H] = PCA9685_LED_ON;
    values[PCA9685_LED_OFF_H] = 0;
    return;
    }
    on = 0;
    off = (4096 * percent) / 100;
    values[PCA9685_LED_ON_L] = on & 0xff;
    values[PCA9685_LED_ON_H] = (on >> 8) & 0xf;
    values[PCA9685_LED_OFF_L] = off & 0xff;
    values[PCA9685_LED_OFF_H] = (off >> 8) & 0xf;
}

/******************************************/
/*                                        */
/* Set a given channel to a given level   */
/*                                        */
/******************************************/
void channel_light(unsigned char ch, unsigned char lev)
{
    char            chip,led;     /* Chip Number, channel number */
    unsigned char   v[4];         /* register data for givern level */
    
    led = ch%16;
    v[0]=0;
    v[1]=0;
    v[2]=0;
    v[3]=0;
    
    if(lev > 100){
        lprintf("Level percentage range 0 - 100 (Trying for %d)\n\r",lev);
        return;
    }
    
    switch(ch/16){
        case    0    :
            chip=LEDDRV1;
            break;
        case    1    :
            chip=LEDDRV2;
            break;
        case    2    :
            chip=LEDDRV3;
            break;
        case    3    :
            chip=LEDDRV4;
            break;
        case    4    :
            chip=LEDDRV5;
            break;
        case    5    :
            chip=LEDDRV6;
            break;
        default      :
            lprintf("Error unknown chip %d\n\r",ch/16);
            return;
    }
    
    lprintf("Setting channel %d to brightness leven %d chip = %d(%d),%d\n\r",
        ch,lev,chip,ch/16,led);
    pca9685_brightness(lev,v);    /* Calculate the brightness level */
    lprintf("Brightness level is %02x,%02x,%02x,%02x\n\r",v[0],v[1],v[2],v[3]);
    pca9685_led(chip,led,v);      /* Send to chip */
}