Peter Cooper
/
Dome
Geodesic Light Dome Controller Program
i2c.c@1:dc58f0b0eeec, 2010-03-24 (annotated)
- Committer:
- lolpcc
- Date:
- Wed Mar 24 09:06:23 2010 +0000
- Revision:
- 1:dc58f0b0eeec
- Parent:
- 0:a7af7ec8b12f
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
lolpcc | 0:a7af7ec8b12f | 1 | #include "mbed.h" |
lolpcc | 0:a7af7ec8b12f | 2 | |
lolpcc | 0:a7af7ec8b12f | 3 | #include "main.h" |
lolpcc | 0:a7af7ec8b12f | 4 | #include "useful.h" |
lolpcc | 0:a7af7ec8b12f | 5 | #include "i2c.h" |
lolpcc | 0:a7af7ec8b12f | 6 | #include "pca9685_reg.h" /* Light Driver Chip */ |
lolpcc | 0:a7af7ec8b12f | 7 | |
lolpcc | 0:a7af7ec8b12f | 8 | I2C i2c(p9, p10); // sda, scl |
lolpcc | 0:a7af7ec8b12f | 9 | I2C i2c_1(p28, p27); // sda, scl |
lolpcc | 0:a7af7ec8b12f | 10 | |
lolpcc | 0:a7af7ec8b12f | 11 | |
lolpcc | 0:a7af7ec8b12f | 12 | #define PIO 0x40 |
lolpcc | 0:a7af7ec8b12f | 13 | #define RELAYS 0x40 |
lolpcc | 0:a7af7ec8b12f | 14 | |
lolpcc | 0:a7af7ec8b12f | 15 | |
lolpcc | 0:a7af7ec8b12f | 16 | |
lolpcc | 0:a7af7ec8b12f | 17 | /******************************************/ |
lolpcc | 0:a7af7ec8b12f | 18 | /* */ |
lolpcc | 0:a7af7ec8b12f | 19 | /* Probe the I2C bus, and show the */ |
lolpcc | 0:a7af7ec8b12f | 20 | /* user what we have found */ |
lolpcc | 0:a7af7ec8b12f | 21 | /* */ |
lolpcc | 0:a7af7ec8b12f | 22 | /* */ |
lolpcc | 0:a7af7ec8b12f | 23 | /* */ |
lolpcc | 0:a7af7ec8b12f | 24 | /******************************************/ |
lolpcc | 0:a7af7ec8b12f | 25 | void i2c_probe(void) |
lolpcc | 0:a7af7ec8b12f | 26 | { |
lolpcc | 0:a7af7ec8b12f | 27 | lprintf("Searching for I2C devices...\n"); |
lolpcc | 0:a7af7ec8b12f | 28 | |
lolpcc | 0:a7af7ec8b12f | 29 | int count = 0; |
lolpcc | 0:a7af7ec8b12f | 30 | for (int address=4; address<256; address+=2) { |
lolpcc | 0:a7af7ec8b12f | 31 | if (!i2c.write(address, NULL, 0)) { // 0 returned is ok |
lolpcc | 0:a7af7ec8b12f | 32 | lprintf(" - I2C device found at address 0x%02X\n", address); |
lolpcc | 0:a7af7ec8b12f | 33 | count++; |
lolpcc | 0:a7af7ec8b12f | 34 | } |
lolpcc | 0:a7af7ec8b12f | 35 | } |
lolpcc | 0:a7af7ec8b12f | 36 | lprintf("%d devices found\n", count); |
lolpcc | 0:a7af7ec8b12f | 37 | } |
lolpcc | 0:a7af7ec8b12f | 38 | void i2c_probe2(void) |
lolpcc | 0:a7af7ec8b12f | 39 | { |
lolpcc | 0:a7af7ec8b12f | 40 | lprintf("Searching for I2C devices... (seconday bus)\n"); |
lolpcc | 0:a7af7ec8b12f | 41 | |
lolpcc | 0:a7af7ec8b12f | 42 | int count = 0; |
lolpcc | 0:a7af7ec8b12f | 43 | for (int address=4; address<256; address+=2) { |
lolpcc | 0:a7af7ec8b12f | 44 | if (!i2c_1.write(address, NULL, 0)) { // 0 returned is ok |
lolpcc | 0:a7af7ec8b12f | 45 | lprintf(" - I2C device found at address 0x%02X\n", address); |
lolpcc | 0:a7af7ec8b12f | 46 | count++; |
lolpcc | 0:a7af7ec8b12f | 47 | } |
lolpcc | 0:a7af7ec8b12f | 48 | } |
lolpcc | 0:a7af7ec8b12f | 49 | lprintf("%d devices found\n", count); |
lolpcc | 0:a7af7ec8b12f | 50 | } |
lolpcc | 0:a7af7ec8b12f | 51 | |
lolpcc | 0:a7af7ec8b12f | 52 | |
lolpcc | 0:a7af7ec8b12f | 53 | |
lolpcc | 0:a7af7ec8b12f | 54 | /******************************************/ |
lolpcc | 0:a7af7ec8b12f | 55 | /* */ |
lolpcc | 0:a7af7ec8b12f | 56 | /* 1 - 8, Relays On, */ |
lolpcc | 0:a7af7ec8b12f | 57 | /* */ |
lolpcc | 0:a7af7ec8b12f | 58 | /******************************************/ |
lolpcc | 0:a7af7ec8b12f | 59 | void relay_operate(char r) |
lolpcc | 0:a7af7ec8b12f | 60 | { |
lolpcc | 0:a7af7ec8b12f | 61 | char buf[0x60]; |
lolpcc | 0:a7af7ec8b12f | 62 | |
lolpcc | 0:a7af7ec8b12f | 63 | switch(r){ |
lolpcc | 0:a7af7ec8b12f | 64 | case 0 : /* Turn off the relays */ |
lolpcc | 0:a7af7ec8b12f | 65 | buf[0]=0x00; |
lolpcc | 0:a7af7ec8b12f | 66 | break; |
lolpcc | 0:a7af7ec8b12f | 67 | case 1 : |
lolpcc | 0:a7af7ec8b12f | 68 | buf[0]=0x01; |
lolpcc | 0:a7af7ec8b12f | 69 | break; |
lolpcc | 0:a7af7ec8b12f | 70 | case 2 : |
lolpcc | 0:a7af7ec8b12f | 71 | buf[0]=0x02; |
lolpcc | 0:a7af7ec8b12f | 72 | break; |
lolpcc | 0:a7af7ec8b12f | 73 | case 3 : |
lolpcc | 0:a7af7ec8b12f | 74 | buf[0]=0x04; |
lolpcc | 0:a7af7ec8b12f | 75 | break; |
lolpcc | 0:a7af7ec8b12f | 76 | case 4 : |
lolpcc | 0:a7af7ec8b12f | 77 | buf[0]=0x08; |
lolpcc | 0:a7af7ec8b12f | 78 | break; |
lolpcc | 0:a7af7ec8b12f | 79 | case 5 : |
lolpcc | 0:a7af7ec8b12f | 80 | buf[0]=0x10; |
lolpcc | 0:a7af7ec8b12f | 81 | break; |
lolpcc | 0:a7af7ec8b12f | 82 | case 6 : |
lolpcc | 0:a7af7ec8b12f | 83 | buf[0]=0x20; |
lolpcc | 0:a7af7ec8b12f | 84 | break; |
lolpcc | 0:a7af7ec8b12f | 85 | case 7 : |
lolpcc | 0:a7af7ec8b12f | 86 | buf[0]=0x40; |
lolpcc | 0:a7af7ec8b12f | 87 | break; |
lolpcc | 0:a7af7ec8b12f | 88 | case 8 : |
lolpcc | 0:a7af7ec8b12f | 89 | buf[0]=0x80; |
lolpcc | 0:a7af7ec8b12f | 90 | break; |
lolpcc | 0:a7af7ec8b12f | 91 | default : |
lolpcc | 0:a7af7ec8b12f | 92 | lprintf("Unknown Relay %d\n\r",r); |
lolpcc | 0:a7af7ec8b12f | 93 | return; |
lolpcc | 0:a7af7ec8b12f | 94 | } |
lolpcc | 0:a7af7ec8b12f | 95 | i2c.write(RELAYS,buf,1); |
lolpcc | 0:a7af7ec8b12f | 96 | } |
lolpcc | 0:a7af7ec8b12f | 97 | |
lolpcc | 0:a7af7ec8b12f | 98 | /******************************************/ |
lolpcc | 0:a7af7ec8b12f | 99 | /* */ |
lolpcc | 0:a7af7ec8b12f | 100 | /* Read and Write the PIO latch */ |
lolpcc | 0:a7af7ec8b12f | 101 | /* */ |
lolpcc | 0:a7af7ec8b12f | 102 | /******************************************/ |
lolpcc | 0:a7af7ec8b12f | 103 | void pio_write(unsigned char r, unsigned char d) |
lolpcc | 0:a7af7ec8b12f | 104 | { |
lolpcc | 0:a7af7ec8b12f | 105 | unsigned char buf[0x60]; |
lolpcc | 0:a7af7ec8b12f | 106 | |
lolpcc | 0:a7af7ec8b12f | 107 | buf[0]=d; |
lolpcc | 0:a7af7ec8b12f | 108 | i2c.write(r,(char *)buf,1); |
lolpcc | 0:a7af7ec8b12f | 109 | } |
lolpcc | 0:a7af7ec8b12f | 110 | void pio_read(unsigned char d) |
lolpcc | 0:a7af7ec8b12f | 111 | { |
lolpcc | 0:a7af7ec8b12f | 112 | unsigned char r; |
lolpcc | 0:a7af7ec8b12f | 113 | unsigned char buf[0x60]; |
lolpcc | 0:a7af7ec8b12f | 114 | |
lolpcc | 0:a7af7ec8b12f | 115 | i2c.read(d,(char *)buf,1); |
lolpcc | 0:a7af7ec8b12f | 116 | r = buf[0]; |
lolpcc | 0:a7af7ec8b12f | 117 | |
lolpcc | 0:a7af7ec8b12f | 118 | lprintf("Returned value from the PIO was 0x%02x\n\r",r); |
lolpcc | 0:a7af7ec8b12f | 119 | } |
lolpcc | 0:a7af7ec8b12f | 120 | |
lolpcc | 0:a7af7ec8b12f | 121 | /******************************************/ |
lolpcc | 0:a7af7ec8b12f | 122 | /* */ |
lolpcc | 0:a7af7ec8b12f | 123 | /* Philips PCA9685 I2C Driver, 16 channel */ |
lolpcc | 0:a7af7ec8b12f | 124 | /* Lighting controler chip, we have 4 */ |
lolpcc | 0:a7af7ec8b12f | 125 | /* running in this system, so we need to */ |
lolpcc | 0:a7af7ec8b12f | 126 | /* think how the channels map ?? */ |
lolpcc | 0:a7af7ec8b12f | 127 | /* */ |
lolpcc | 0:a7af7ec8b12f | 128 | /******************************************/ |
lolpcc | 0:a7af7ec8b12f | 129 | |
lolpcc | 0:a7af7ec8b12f | 130 | /******************************************/ |
lolpcc | 0:a7af7ec8b12f | 131 | /* */ |
lolpcc | 0:a7af7ec8b12f | 132 | /* Init code for the PCA9685 */ |
lolpcc | 0:a7af7ec8b12f | 133 | /* */ |
lolpcc | 0:a7af7ec8b12f | 134 | /******************************************/ |
lolpcc | 0:a7af7ec8b12f | 135 | |
lolpcc | 0:a7af7ec8b12f | 136 | void init_pca9685(unsigned char address) |
lolpcc | 0:a7af7ec8b12f | 137 | { |
lolpcc | 0:a7af7ec8b12f | 138 | unsigned char buf[30]; |
lolpcc | 0:a7af7ec8b12f | 139 | |
lolpcc | 0:a7af7ec8b12f | 140 | lprintf("Setting up channel %d\n\r",address); |
lolpcc | 0:a7af7ec8b12f | 141 | |
lolpcc | 0:a7af7ec8b12f | 142 | buf[0] = PCA9685_MODE1; |
lolpcc | 0:a7af7ec8b12f | 143 | buf[1] = PCA9685_AI; |
lolpcc | 0:a7af7ec8b12f | 144 | buf[2] = PCA9685_OUTDRV; |
lolpcc | 0:a7af7ec8b12f | 145 | i2c.write(address,(char *) buf, 3); |
lolpcc | 0:a7af7ec8b12f | 146 | } |
lolpcc | 0:a7af7ec8b12f | 147 | |
lolpcc | 0:a7af7ec8b12f | 148 | /******************************************/ |
lolpcc | 0:a7af7ec8b12f | 149 | /* */ |
lolpcc | 0:a7af7ec8b12f | 150 | /* Send data to a given channle of a */ |
lolpcc | 0:a7af7ec8b12f | 151 | /* given PCA9685 chip */ |
lolpcc | 0:a7af7ec8b12f | 152 | /* */ |
lolpcc | 0:a7af7ec8b12f | 153 | /******************************************/ |
lolpcc | 0:a7af7ec8b12f | 154 | |
lolpcc | 0:a7af7ec8b12f | 155 | void pca9685_led(unsigned char addr, int led, unsigned char *values) |
lolpcc | 0:a7af7ec8b12f | 156 | { |
lolpcc | 0:a7af7ec8b12f | 157 | unsigned char buf[5]; |
lolpcc | 0:a7af7ec8b12f | 158 | |
lolpcc | 0:a7af7ec8b12f | 159 | if (led == PCA9685_ALL_LEDS) { |
lolpcc | 0:a7af7ec8b12f | 160 | buf[0] = PCA9685_ALL_LED_ON_L; |
lolpcc | 0:a7af7ec8b12f | 161 | } else { |
lolpcc | 0:a7af7ec8b12f | 162 | buf[0] = PCA9685_BASE(led); |
lolpcc | 0:a7af7ec8b12f | 163 | } |
lolpcc | 0:a7af7ec8b12f | 164 | |
lolpcc | 0:a7af7ec8b12f | 165 | buf[1] = values[0]; |
lolpcc | 0:a7af7ec8b12f | 166 | buf[2] = values[1]; |
lolpcc | 0:a7af7ec8b12f | 167 | buf[3] = values[2]; |
lolpcc | 0:a7af7ec8b12f | 168 | buf[4] = values[3]; |
lolpcc | 0:a7af7ec8b12f | 169 | i2c.write(addr, (char *)buf, 5); |
lolpcc | 0:a7af7ec8b12f | 170 | } |
lolpcc | 0:a7af7ec8b12f | 171 | |
lolpcc | 0:a7af7ec8b12f | 172 | /******************************************/ |
lolpcc | 0:a7af7ec8b12f | 173 | /* */ |
lolpcc | 0:a7af7ec8b12f | 174 | /* Calculate the register values for a */ |
lolpcc | 0:a7af7ec8b12f | 175 | /* givern brightness percentage */ |
lolpcc | 0:a7af7ec8b12f | 176 | /* */ |
lolpcc | 0:a7af7ec8b12f | 177 | /******************************************/ |
lolpcc | 0:a7af7ec8b12f | 178 | |
lolpcc | 0:a7af7ec8b12f | 179 | void pca9685_brightness(int percent, unsigned char *values) |
lolpcc | 0:a7af7ec8b12f | 180 | { |
lolpcc | 0:a7af7ec8b12f | 181 | unsigned int on, off; |
lolpcc | 0:a7af7ec8b12f | 182 | |
lolpcc | 0:a7af7ec8b12f | 183 | if (percent == 0) { |
lolpcc | 0:a7af7ec8b12f | 184 | values[PCA9685_LED_ON_H] = 0; |
lolpcc | 0:a7af7ec8b12f | 185 | values[PCA9685_LED_OFF_H] = PCA9685_LED_OFF; |
lolpcc | 0:a7af7ec8b12f | 186 | return; |
lolpcc | 0:a7af7ec8b12f | 187 | } |
lolpcc | 0:a7af7ec8b12f | 188 | if (percent == 100) { |
lolpcc | 0:a7af7ec8b12f | 189 | values[PCA9685_LED_ON_H] = PCA9685_LED_ON; |
lolpcc | 0:a7af7ec8b12f | 190 | values[PCA9685_LED_OFF_H] = 0; |
lolpcc | 0:a7af7ec8b12f | 191 | return; |
lolpcc | 0:a7af7ec8b12f | 192 | } |
lolpcc | 0:a7af7ec8b12f | 193 | on = 0; |
lolpcc | 0:a7af7ec8b12f | 194 | off = (4096 * percent) / 100; |
lolpcc | 0:a7af7ec8b12f | 195 | values[PCA9685_LED_ON_L] = on & 0xff; |
lolpcc | 0:a7af7ec8b12f | 196 | values[PCA9685_LED_ON_H] = (on >> 8) & 0xf; |
lolpcc | 0:a7af7ec8b12f | 197 | values[PCA9685_LED_OFF_L] = off & 0xff; |
lolpcc | 0:a7af7ec8b12f | 198 | values[PCA9685_LED_OFF_H] = (off >> 8) & 0xf; |
lolpcc | 0:a7af7ec8b12f | 199 | } |
lolpcc | 0:a7af7ec8b12f | 200 | |
lolpcc | 0:a7af7ec8b12f | 201 | /******************************************/ |
lolpcc | 0:a7af7ec8b12f | 202 | /* */ |
lolpcc | 0:a7af7ec8b12f | 203 | /* Set a given channel to a given level */ |
lolpcc | 0:a7af7ec8b12f | 204 | /* */ |
lolpcc | 0:a7af7ec8b12f | 205 | /******************************************/ |
lolpcc | 0:a7af7ec8b12f | 206 | void channel_light(unsigned char ch, unsigned char lev) |
lolpcc | 0:a7af7ec8b12f | 207 | { |
lolpcc | 0:a7af7ec8b12f | 208 | char chip,led; /* Chip Number, channel number */ |
lolpcc | 0:a7af7ec8b12f | 209 | unsigned char v[4]; /* register data for givern level */ |
lolpcc | 0:a7af7ec8b12f | 210 | |
lolpcc | 0:a7af7ec8b12f | 211 | led = ch%16; |
lolpcc | 0:a7af7ec8b12f | 212 | v[0]=0; |
lolpcc | 0:a7af7ec8b12f | 213 | v[1]=0; |
lolpcc | 0:a7af7ec8b12f | 214 | v[2]=0; |
lolpcc | 0:a7af7ec8b12f | 215 | v[3]=0; |
lolpcc | 0:a7af7ec8b12f | 216 | |
lolpcc | 0:a7af7ec8b12f | 217 | if(lev > 100){ |
lolpcc | 0:a7af7ec8b12f | 218 | lprintf("Level percentage range 0 - 100 (Trying for %d)\n\r",lev); |
lolpcc | 0:a7af7ec8b12f | 219 | return; |
lolpcc | 0:a7af7ec8b12f | 220 | } |
lolpcc | 0:a7af7ec8b12f | 221 | |
lolpcc | 0:a7af7ec8b12f | 222 | switch(ch/16){ |
lolpcc | 0:a7af7ec8b12f | 223 | case 0 : |
lolpcc | 0:a7af7ec8b12f | 224 | chip=LEDDRV1; |
lolpcc | 0:a7af7ec8b12f | 225 | break; |
lolpcc | 0:a7af7ec8b12f | 226 | case 1 : |
lolpcc | 0:a7af7ec8b12f | 227 | chip=LEDDRV2; |
lolpcc | 0:a7af7ec8b12f | 228 | break; |
lolpcc | 0:a7af7ec8b12f | 229 | case 2 : |
lolpcc | 0:a7af7ec8b12f | 230 | chip=LEDDRV3; |
lolpcc | 0:a7af7ec8b12f | 231 | break; |
lolpcc | 0:a7af7ec8b12f | 232 | case 3 : |
lolpcc | 0:a7af7ec8b12f | 233 | chip=LEDDRV4; |
lolpcc | 0:a7af7ec8b12f | 234 | break; |
lolpcc | 0:a7af7ec8b12f | 235 | case 4 : |
lolpcc | 0:a7af7ec8b12f | 236 | chip=LEDDRV5; |
lolpcc | 0:a7af7ec8b12f | 237 | break; |
lolpcc | 0:a7af7ec8b12f | 238 | case 5 : |
lolpcc | 0:a7af7ec8b12f | 239 | chip=LEDDRV6; |
lolpcc | 0:a7af7ec8b12f | 240 | break; |
lolpcc | 0:a7af7ec8b12f | 241 | default : |
lolpcc | 0:a7af7ec8b12f | 242 | lprintf("Error unknown chip %d\n\r",ch/16); |
lolpcc | 0:a7af7ec8b12f | 243 | return; |
lolpcc | 0:a7af7ec8b12f | 244 | } |
lolpcc | 0:a7af7ec8b12f | 245 | |
lolpcc | 0:a7af7ec8b12f | 246 | lprintf("Setting channel %d to brightness leven %d chip = %d(%d),%d\n\r", |
lolpcc | 0:a7af7ec8b12f | 247 | ch,lev,chip,ch/16,led); |
lolpcc | 0:a7af7ec8b12f | 248 | pca9685_brightness(lev,v); /* Calculate the brightness level */ |
lolpcc | 0:a7af7ec8b12f | 249 | lprintf("Brightness level is %02x,%02x,%02x,%02x\n\r",v[0],v[1],v[2],v[3]); |
lolpcc | 0:a7af7ec8b12f | 250 | pca9685_led(chip,led,v); /* Send to chip */ |
lolpcc | 0:a7af7ec8b12f | 251 | } |
lolpcc | 0:a7af7ec8b12f | 252 |