Changes for page Front I/O
Last modified by Kevin Wiki on 2024/07/07 22:48
From version
7.2
edited by Kevin Wiki
on 2024/07/05 09:26
on 2024/07/05 09:26
Change comment:
There is no comment for this version
To version
9.1
edited by Kevin Wiki
on 2024/07/07 22:44
on 2024/07/07 22:44
Change comment:
There is no comment for this version
Summary
Details
- Page properties
-
- Content
-
... ... @@ -2,6 +2,10 @@ 2 2 ((( 3 3 (% class="col-xs-12 col-sm-8" %) 4 4 ((( 5 += Code = 6 + 7 +Arduino project with utils and script for driving all LEDs, buttons and MLB front I/O headers for driving Xserve front I/O devices: [[https:~~/~~/github.com/KevinMidboe/xserve-io>>https://github.com/KevinMidboe/xserve-io/]]. 8 + 5 5 = Pinout = 6 6 7 7 There is a single cable that controls four parts, each half side of I/O LED and center column of blue LEDs. ... ... @@ -148,7 +148,7 @@ 148 148 149 149 == SAA1064T data for driving center IO LED stack == 150 150 151 -Center IO stack is a stack of 2 3LED's, 22blue and 1 green for ethernet activity. These are duplicated next to each other and driven by each their SAA1064T chips. Earlier we found the i2c address and just by playing around figured out that 4 segments of 1 byte binary values are used to set ship register.155 +Center IO stack is a stack of 24 LED's, 23 blue and 1 green for ethernet activity. These are duplicated next to each other and driven by each their SAA1064T chips. Earlier we found the i2c address and just by playing around figured out that 4 segments of 1 byte binary values are used to set ship register. 152 152 153 153 {{code language="C++"}} 154 154 void fillColumns() { ... ... @@ -166,7 +166,7 @@ 166 166 {{/code}} 167 167 168 168 (% class="wikigeneratedid" %) 169 -Here the last byte we send only is 5 bits since we only have 5 LEDs instead of 6 to address (total of 2 3). Also note that we start the transmission with a single bit.173 +~-~- Here the last byte we send only is 5 bits since we only have 5 LEDs instead of 6 to address (total of 24). Also note that we start the transmission with a single bit. ~-~- 170 170 171 171 == Pinouts voltages from MLB == 172 172 ... ... @@ -194,7 +194,294 @@ 194 194 * Power LED P3V3 - 3.30V 195 195 * Power LED - 0.87 V 196 196 201 += Controlling top I/O LED = 202 + 203 +On the top row we have the following input/output devices in order from left to right; 204 + 205 +Left side: 206 + 207 +* physical lock 208 +* lock LED 209 +* warning/service button 210 +* warning/service LED 211 +* locate button 212 +* power LED (red & green) 213 +* fan LED (red & green) 214 +* temperature LED (red & green) 215 +* compute LED (unknown) 216 + 217 +Right side: 218 + 219 +* power LED (red & green) 220 +* fan LED (red & green) 221 +* temperature LED (red & green) 222 +* compute LED (unknown) 223 +* lock switch 224 + 225 +Each sides bank of LEDs are driven by each their PCA9554 shift register. The registers represent the following LEDs: (Note that Lock LED is only present for the LEFT side) 226 + 227 +(% border="1" %) 228 +|=(% scope="row" %)Register|1|2|3|4|5|6|7 229 +|=Device|Power LED Green|Power LED Red|Fan LED Green|Fan LED Red|Temperature LED Green|Temperature LED Red|Lock LED 230 + 231 +To control each LED we shift either a 0 to turn off or 1 to turn on. Since each device shares a single red/green LED (power LED green & power LED red) setting both to 1 at the same time will always leave it red. That is when power LED green and power LED red are both enabled, red always takes precedence. 232 + 233 +Use following script to power LEDs one at a time: 234 + 235 +{{code language="c++"}} 236 +#include <PCA9554.h> // Load the PCA9554 Library 237 + 238 +PCA9554 ioCon1(0x24); // Create an object at this address 239 + 240 +uint8_t mapIO = 0b10000000; 241 + 242 +void shiftL() { 243 + mapIO = (mapIO << 1) | ((mapIO & 0x80) >> 7); 244 +} 245 + 246 +void write() { 247 + Serial.println("writing to PCA9554 device"); 248 + 249 + for (int i = 0; i < 8; ++i) { 250 + ioCon1.digitalWrite(i, (mapIO & (1 << i)) ? 0 : 1); 251 + } 252 +} 253 + 254 +void setup() 255 +{ 256 + Serial.begin(9600); 257 + Serial.println("Setup"); 258 + 259 + ioCon1.portMode(ALLOUTPUT); 260 +} 261 + 262 +void loop() 263 +{ 264 + write(); 265 + shiftL(); 266 + 267 + delay(500); 268 +} 269 +{{/code}} 270 + 271 + 272 +Controlling middle IO strip 273 + 274 +0 = 0000 275 +1 (green) = 0001 276 +2 = 0010 277 +1 + 2 = 0011 278 +3 = 0100 279 + 280 + 281 +There are 4 words, each containing 7 data bits. They do not 282 + 283 + 284 += Controlling center LED columns = 285 + 286 +There are a total of 4 banks of addressable LED's 12 each of the total 48. 287 + 288 + 289 +|**Address Range (Binary)**|**Address Range (hex)**|**Size**|**Description** 290 +|0-7|00-07|1 byte|Ethernet indicator and LEDs bank-1 291 +|8-15|08-0F|1 byte|LEDs bank-2 292 +|16-23|10-17|1 byte|LEDs bank-3 293 +|24-31|18-1F|1 byte|LEDs bank-4 294 + 295 +[[attach:Address Ranges-Table 1.csv||target="_blank"]] 296 + 297 +|=**Address Banks**|=**LEDs Controlled**|=**Count**|=**Address Range (hex)**|=**Description** 298 +|=**Bank-1**|1 2 4 6 8 10 12|7|00-07|LED 1 ethernet indicator, even bottom half 299 +|=**Bank-2**|3 5 7 9 11 13|6|08-0F|Odd LED top half 300 +|=**Bank-3**|14 16 18 20 22 23 24|7|10-17|Even LED bottom half 301 +|=**Bank-4**|15 17 19 21|4|18-1F|Odd LED top half 302 + 303 +[[attach:LEDs per bank-Table 1.csv||target="_blank"]] 304 + 305 + 306 +| | |(% colspan="8" %)**bits (1 byte per register)** 307 +|**Controls device**|**Register**|**7**|**6**|**5**|**4**|**3**|**2**|**1**|**0** 308 +|**Ethernet LED**|Register 1|0|0|0|0|0|0|0|1 309 +|**LED 1**|Register 1|0|0|0|0|0|0|1|0 310 +|**LED 2**|Register 2|0|0|0|0|0|0|1|0 311 +|**LED 3**|Register 1|0|0|0|0|0|1|0|0 312 +|**LED 4**|Register 2|0|0|0|0|0|1|0|0 313 +|**LED 5**|Register 1|0|0|0|0|1|0|0|0 314 +|**LED 6**|Register 2|0|0|0|0|1|0|0|0 315 +|**LED 7**|Register 1|0|0|0|1|0|0|0|0 316 +|**LED 8**|Register 2|0|0|0|1|0|0|0|0 317 +|**LED 9**|Register 1|0|0|1|0|0|0|0|0 318 +|**LED 10**|Register 2|0|0|1|0|0|0|0|0 319 +|**LED 11**|Register 1|0|1|0|0|0|0|0|0 320 +|**LED 12**|Register 2|0|1|0|0|0|0|0|0 321 +|**LED 13**|Register 3|0|0|0|0|0|0|0|1 322 +|**LED 14**|Register 4|0|0|0|0|0|0|0|1 323 +|**LED 15**|Register 3|0|0|0|0|0|0|1|0 324 +|**LED 16**|Register 4|0|0|0|0|0|0|1|0 325 +|**LED 17**|Register 3|0|0|0|0|0|1|0|0 326 +|**LED 18**|Register 4|0|0|0|0|0|1|0|0 327 +|**LED 19**|Register 3|0|0|0|0|1|0|0|0 328 +|**LED 20**|Register 4|0|0|0|0|1|0|0|0 329 +|**LED 21**|Register 3|0|0|0|1|0|0|0|0 330 +|**LED 22**|Register 3|0|0|1|0|0|0|0|0 331 +|**LED 23**|Register 3|0|1|0|0|0|0|0|0 332 + 333 + 334 + 335 +Script for writing all permutations to display: 336 + 337 +{{code language="c++"}} 338 +#include "Wire.h" // enable I2C bus 339 + 340 +byte saa1064 = 0x3B; // define the I2C bus address for our SAA1064 (pin 1 to GND) **** 341 + 342 +void setup() 343 +{ 344 + Wire.begin(); // start up I2C bus 345 +} 346 + 347 +void write(int value) { 348 + Wire.beginTransmission(saa1064); 349 + Wire.write(1); 350 + 351 + Wire.write(value); 352 + Wire.write(value); 353 + Wire.write(value); 354 + Wire.write(value); 355 + 356 + Wire.endTransmission(); 357 +} 358 + 359 +void loop() { 360 + for (int value = 0; value < 127; value++) { 361 + write(value); 362 + delay(300); 363 + } 364 +} 365 +{{/code}} 366 + 367 +Since LED positions don't map sequentially with LED number we can't address them in 10-base form, but we can define each LED in binary and use OR operator to display LEDs we want. 368 + 369 +{{code language="c++"}} 370 +#include "Wire.h" // enable I2C bus 371 + 372 +#define TCAADDR 0x70 373 +byte saa1064 = 0x3B; // define the I2C bus address for our SAA1064 374 + 375 +byte bank1; 376 +byte bank2; 377 +byte bank3; 378 +byte bank4; 379 + 380 +byte activityLED = 0b00000001; 381 +byte leds[23][4] = { 382 + {0b00000010, 0b00000000, 0b00000000, 0b00000000}, // 1 383 + {0b00000000, 0b00000010, 0b00000000, 0b00000000}, // 2 384 + {0b00000100, 0b00000000, 0b00000000, 0b00000000}, // 3 385 + {0b00000000, 0b00000100, 0b00000000, 0b00000000}, // 4 386 + {0b00001000, 0b00000000, 0b00000000, 0b00000000}, // 5 387 + {0b00000000, 0b00001000, 0b00000000, 0b00000000}, // 6 388 + {0b00010000, 0b00000000, 0b00000000, 0b00000000}, // 7 389 + {0b00000000, 0b00010000, 0b00000000, 0b00000000}, // 8 390 + {0b00100000, 0b00000000, 0b00000000, 0b00000000}, // 9 391 + {0b00000000, 0b00100000, 0b00000000, 0b00000000}, // 10 392 + {0b01000000, 0b00000000, 0b00000000, 0b00000000}, // 11 393 + {0b00000000, 0b01000000, 0b00000000, 0b00000000}, // 12 394 + {0b00000000, 0b00000000, 0b00000001, 0b00000000}, // 13 395 + {0b00000000, 0b00000000, 0b00000000, 0b00000001}, // 14 396 + {0b00000000, 0b00000000, 0b00000010, 0b00000000}, // 15 397 + {0b00000000, 0b00000000, 0b00000000, 0b00000010}, // 16 398 + {0b00000000, 0b00000000, 0b00000100, 0b00000000}, // 17 399 + {0b00000000, 0b00000000, 0b00000000, 0b00000100}, // 18 400 + {0b00000000, 0b00000000, 0b00001000, 0b00000000}, // 19 401 + {0b00000000, 0b00000000, 0b00000000, 0b00001000}, // 20 402 + {0b00000000, 0b00000000, 0b00010000, 0b00000000}, // 21 403 + {0b00000000, 0b00000000, 0b00100000, 0b00000000}, // 22 404 + {0b00000000, 0b00000000, 0b01000000, 0b00000000} // 23 405 +}; 406 + 407 +void setup() 408 +{ 409 + Serial.begin(9600); 410 + Wire.begin(); // start up I2C bus 411 + 412 + Serial.println("setting up ports"); 413 +} 414 + 415 +void tcaselect(uint8_t i) { 416 + if (i > 7) return; 197 197 418 + Wire.beginTransmission(TCAADDR); 419 + Wire.write(1 << i); 420 + Wire.endTransmission(); 421 +} 422 + 423 +void selectLeft() { tcaselect(2); } 424 +void selectRight() { tcaselect(1); } 425 + 426 +void write() { 427 + Wire.beginTransmission(saa1064); 428 + Wire.write(1); 429 + 430 + Wire.write(bank1); 431 + Wire.write(bank2); 432 + Wire.write(bank3); 433 + Wire.write(bank4); 434 + 435 + Wire.endTransmission(); 436 +} 437 + 438 +void resetBanks() { 439 + bank1 = 0; 440 + bank2 = 0; 441 + bank3 = 0; 442 + bank4 = 0; 443 +} 444 + 445 +void displayNumber(int number) { 446 + bank1 = leds[number - 1][0]; 447 + bank2 = leds[number - 1][1]; 448 + bank3 = leds[number - 1][2]; 449 + bank4 = leds[number - 1][3]; 450 +} 451 + 452 +void displayUpToNumber(int number) { 453 + for (int i = 0; i < number; i++) { 454 + bank1 = bank1 | leds[i][0]; 455 + bank2 = bank2 | leds[i][1]; 456 + bank3 = bank3 | leds[i][2]; 457 + bank4 = bank4 | leds[i][3]; 458 + } 459 +} 460 + 461 +void computeEthernetActivity() { 462 + bank1 = bank1 | activityLED; 463 +} 464 + 465 +void loop() { 466 + resetBanks(); 467 + delay(10); 468 + 469 + displayUpToNumber(15); 470 + computeEthernetActivity(); 471 + 472 + selectLeft(); 473 + write(); 474 + delay(2); 475 + 476 + selectRight(); 477 + write(); 478 + delay(1000); 479 +} 480 +{{/code}} 481 + 482 + 483 += Missing pieces, TODO = 484 + 485 +* how to control compute LED in top IO row 486 +* control warning button LED 487 + 488 + 198 198 ))) 199 199 200 200
- Address Ranges-Table 1.csv
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.kevin - Size
-
... ... @@ -1,0 +1,1 @@ 1 +209 bytes - Content
-
... ... @@ -1,0 +1,6 @@ 1 +Address Range (Binary);Address Range (hex);Size;Description 2 +0-7;00-07;1 byte;Ethernet indicator and LEDs bank-1 3 +8-15;08-0F;1 byte;LEDs bank-2 4 +16-23;10-17;1 byte;LEDs bank-3 5 +24-31;18-1F;1 byte;LEDs bank-4 6 +
- LEDs per bank-Table 1.csv
-
- Author
-
... ... @@ -1,0 +1,1 @@ 1 +XWiki.kevin - Size
-
... ... @@ -1,0 +1,1 @@ 1 +294 bytes - Content
-
... ... @@ -1,0 +1,6 @@ 1 +Address Banks;LEDs Controlled;Count;Address Range (hex);Description 2 +Bank-1;1 2 4 6 8 10 12;7;00-07;LED 1 ethernet indicator, even bottom half 3 +Bank-2;3 5 7 9 11 13;6;08-0F;Odd LED top half 4 +Bank-3;14 16 18 20 22 23 24;7;10-17;Even LED bottom half 5 +Bank-4;15 17 19 21;4;18-1F;Odd LED top half 6 +