Published

Dependents:   DuckLights

Fork of TLC5940 by Spencer Davis

Committer:
roysandberg
Date:
Sat Jun 09 23:22:13 2018 +0000
Revision:
4:ab6b451bbf40
Published

Who changed what in which revision?

UserRevisionLine numberNew contents of line
roysandberg 4:ab6b451bbf40 1 #include "TLC5955.h"
roysandberg 4:ab6b451bbf40 2 #include "math.h"
roysandberg 4:ab6b451bbf40 3
roysandberg 4:ab6b451bbf40 4 extern void init_clock(PinName clkPin);
roysandberg 4:ab6b451bbf40 5
roysandberg 4:ab6b451bbf40 6 DigitalOut led2(LED2);
roysandberg 4:ab6b451bbf40 7
roysandberg 4:ab6b451bbf40 8 // gamma correction array compensates for non-linearities
roysandberg 4:ab6b451bbf40 9 // https://learn.adafruit.com/led-tricks-gamma-correction/the-longer-fix
roysandberg 4:ab6b451bbf40 10 uint16_t redGamma[256];
roysandberg 4:ab6b451bbf40 11 uint16_t greenGamma[256];
roysandberg 4:ab6b451bbf40 12 uint16_t blueGamma[256];
roysandberg 4:ab6b451bbf40 13
roysandberg 4:ab6b451bbf40 14 #define GAMMA_FACTOR 2.8
roysandberg 4:ab6b451bbf40 15 #define GAMMA_MAX_IN 255
roysandberg 4:ab6b451bbf40 16 #define GAMMA_RED_MAX_OUT 0xFFFF
roysandberg 4:ab6b451bbf40 17 #define GAMMA_BLUE_MAX_OUT 0x4000
roysandberg 4:ab6b451bbf40 18 #define GAMMA_GREEN_MAX_OUT 0x8000
roysandberg 4:ab6b451bbf40 19
roysandberg 4:ab6b451bbf40 20 void buildGammaTable(float gammaFactor, uint16_t maxInput, uint16_t maxOutput, uint16_t* gamma) {
roysandberg 4:ab6b451bbf40 21 for(int i=0; i<=maxInput; i++) {
roysandberg 4:ab6b451bbf40 22 gamma[i] = (uint16_t) (pow((float)i / (float)maxInput, gammaFactor) * maxOutput + 0.5);
roysandberg 4:ab6b451bbf40 23 //printf("Max=%x, i=%d, val=%x\n\r", maxOutput, i, gamma[i]);
roysandberg 4:ab6b451bbf40 24 }
roysandberg 4:ab6b451bbf40 25 }
roysandberg 4:ab6b451bbf40 26
roysandberg 4:ab6b451bbf40 27 void rebuildGammaTables(uint8_t amplitude) {
roysandberg 4:ab6b451bbf40 28 buildGammaTable (GAMMA_FACTOR, GAMMA_MAX_IN, (uint16_t)((((long) GAMMA_RED_MAX_OUT)*amplitude)/0xFFl), redGamma);
roysandberg 4:ab6b451bbf40 29 buildGammaTable (GAMMA_FACTOR, GAMMA_MAX_IN, (uint16_t)((((long) GAMMA_GREEN_MAX_OUT)*amplitude)/0xFFl), greenGamma);
roysandberg 4:ab6b451bbf40 30 buildGammaTable (GAMMA_FACTOR, GAMMA_MAX_IN, (uint16_t)((((long) GAMMA_BLUE_MAX_OUT)*amplitude)/0xFFl), blueGamma);
roysandberg 4:ab6b451bbf40 31 }
roysandberg 4:ab6b451bbf40 32
roysandberg 4:ab6b451bbf40 33 TLC5955::TLC5955(PinName SCLK, PinName MOSI, PinName GSCLK,
roysandberg 4:ab6b451bbf40 34 PinName XLAT, const int number) : number(number),
roysandberg 4:ab6b451bbf40 35 spi(MOSI, NC, SCLK),
roysandberg 4:ab6b451bbf40 36 gsclk(GSCLK),
roysandberg 4:ab6b451bbf40 37 xlat(XLAT),
roysandberg 4:ab6b451bbf40 38 newGSData(false),
roysandberg 4:ab6b451bbf40 39 newControlData(false),
roysandberg 4:ab6b451bbf40 40 need_xlat(false)
roysandberg 4:ab6b451bbf40 41 {
roysandberg 4:ab6b451bbf40 42
roysandberg 4:ab6b451bbf40 43 rebuildGammaTables(0xFF); // oxFF is full amplitude
roysandberg 4:ab6b451bbf40 44
roysandberg 4:ab6b451bbf40 45 for (int i=0; i<(SHORTS_PER_CHANNEL * CHANNELS_PER_IC * NUMBER_OF_ICS); i++) {
roysandberg 4:ab6b451bbf40 46 internalData[i] = 0xFFFF; // invert pwm outputs because transistor will get pulled low when on
roysandberg 4:ab6b451bbf40 47 }
roysandberg 4:ab6b451bbf40 48 for (int i=0; i<(SHORTS_PER_CHANNEL * CHANNELS_PER_IC * NUMBER_OF_ICS)+1; i++) {
roysandberg 4:ab6b451bbf40 49 gsBuffer[i] = 0xFFFF;
roysandberg 4:ab6b451bbf40 50 }
roysandberg 4:ab6b451bbf40 51
roysandberg 4:ab6b451bbf40 52
roysandberg 4:ab6b451bbf40 53 // Configure SPI to 16 bits and SPI_SPEED
roysandberg 4:ab6b451bbf40 54 spi.format(8, 0);
roysandberg 4:ab6b451bbf40 55 spi.frequency(SPI_SPEED);
roysandberg 4:ab6b451bbf40 56
roysandberg 4:ab6b451bbf40 57
roysandberg 4:ab6b451bbf40 58
roysandberg 4:ab6b451bbf40 59
roysandberg 4:ab6b451bbf40 60 // Set lat pin state
roysandberg 4:ab6b451bbf40 61 xlat = 0;
roysandberg 4:ab6b451bbf40 62
roysandberg 4:ab6b451bbf40 63 // 62.5Hz should be fast enough
roysandberg 4:ab6b451bbf40 64 reset_ticker.attach_us(this, &TLC5955::reset, 16000);
roysandberg 4:ab6b451bbf40 65
roysandberg 4:ab6b451bbf40 66 // Outputs 8Mhz on pin
roysandberg 4:ab6b451bbf40 67 init_clock(GSCLK);
roysandberg 4:ab6b451bbf40 68 }
roysandberg 4:ab6b451bbf40 69 // https://github.com/FastLED/FastLED/wiki/FastLED-Color-Correction
roysandberg 4:ab6b451bbf40 70 // Red LEDs are the dimmest, so no scaling
roysandberg 4:ab6b451bbf40 71 // Blue LEDs are a bit brighter, so scale down by 0.9 (0xE6)
roysandberg 4:ab6b451bbf40 72 // Green LED are by far the brightest, so scale down by 0.6 (0x99)
roysandberg 4:ab6b451bbf40 73 void TLC5955::setChannel(int channelNum, unsigned short red, unsigned short green, unsigned short blue) {
roysandberg 4:ab6b451bbf40 74 if (red > 0xFF) red = 0xFF;
roysandberg 4:ab6b451bbf40 75 if (green > 0xFF) green = 0xFF;
roysandberg 4:ab6b451bbf40 76 if (blue > 0xFF) blue = 0xFF;
roysandberg 4:ab6b451bbf40 77
roysandberg 4:ab6b451bbf40 78 if (channelNum < CHANNELS_PER_IC * NUMBER_OF_ICS) {
roysandberg 4:ab6b451bbf40 79 // chip color values leave in b, r, g order, but that should map to r, g, b order
roysandberg 4:ab6b451bbf40 80
roysandberg 4:ab6b451bbf40 81 if (channelNum > 31) {
roysandberg 4:ab6b451bbf40 82 channelNum -= 32;
roysandberg 4:ab6b451bbf40 83 } else if (channelNum < 16) {
roysandberg 4:ab6b451bbf40 84 channelNum += 32;
roysandberg 4:ab6b451bbf40 85 }
roysandberg 4:ab6b451bbf40 86
roysandberg 4:ab6b451bbf40 87 // mappings are slightly different for first eight and last eight of each board (red and green get inverted)
roysandberg 4:ab6b451bbf40 88 if (channelNum % 16 < 8) {
roysandberg 4:ab6b451bbf40 89 internalData[channelNum*SHORTS_PER_CHANNEL + 1] = (0xFFFF - GAMMA_BLUE_MAX_OUT) + (GAMMA_BLUE_MAX_OUT - blueGamma[blue]);
roysandberg 4:ab6b451bbf40 90 internalData[channelNum*SHORTS_PER_CHANNEL + 0] = (0xFFFF - GAMMA_RED_MAX_OUT) + (GAMMA_RED_MAX_OUT - redGamma[red]);
roysandberg 4:ab6b451bbf40 91 internalData[channelNum*SHORTS_PER_CHANNEL + 2] = (0xFFFF-GAMMA_GREEN_MAX_OUT) + (GAMMA_GREEN_MAX_OUT - greenGamma[green]);
roysandberg 4:ab6b451bbf40 92 } else {
roysandberg 4:ab6b451bbf40 93 internalData[channelNum*SHORTS_PER_CHANNEL + 2] = (0xFFFF - GAMMA_BLUE_MAX_OUT) + (GAMMA_BLUE_MAX_OUT - blueGamma[blue]);
roysandberg 4:ab6b451bbf40 94 internalData[channelNum*SHORTS_PER_CHANNEL + 1] = (0xFFFF - GAMMA_GREEN_MAX_OUT) +(GAMMA_GREEN_MAX_OUT - greenGamma[green]);
roysandberg 4:ab6b451bbf40 95 internalData[channelNum*SHORTS_PER_CHANNEL + 0] = (0xFFFF - GAMMA_RED_MAX_OUT) + (GAMMA_RED_MAX_OUT - redGamma[red]);
roysandberg 4:ab6b451bbf40 96 }
roysandberg 4:ab6b451bbf40 97 }
roysandberg 4:ab6b451bbf40 98 }
roysandberg 4:ab6b451bbf40 99
roysandberg 4:ab6b451bbf40 100 void TLC5955::latchData() {
roysandberg 4:ab6b451bbf40 101 newGSData = true;
roysandberg 4:ab6b451bbf40 102 }
roysandberg 4:ab6b451bbf40 103
roysandberg 4:ab6b451bbf40 104 void TLC5955::setNewControlData(unsigned short _globalBrightnessRed, unsigned short _globalBrightnessGreen, unsigned short _globalBrightnessBlue,
roysandberg 4:ab6b451bbf40 105 led_power_t _maximumCurrentRed, led_power_t _maximumCurrentGreen, led_power_t _maximumCurrentBlue,
roysandberg 4:ab6b451bbf40 106 unsigned short* _dotCorrect) {
roysandberg 4:ab6b451bbf40 107 globalBrightnessRed = _globalBrightnessRed;
roysandberg 4:ab6b451bbf40 108 globalBrightnessGreen = _globalBrightnessGreen;
roysandberg 4:ab6b451bbf40 109 globalBrightnessBlue = _globalBrightnessBlue;
roysandberg 4:ab6b451bbf40 110 maximumCurrentRed = _maximumCurrentRed;
roysandberg 4:ab6b451bbf40 111 maximumCurrentGreen = _maximumCurrentGreen;
roysandberg 4:ab6b451bbf40 112 maximumCurrentBlue = _maximumCurrentBlue;
roysandberg 4:ab6b451bbf40 113 dotCorrect = _dotCorrect;
roysandberg 4:ab6b451bbf40 114
roysandberg 4:ab6b451bbf40 115 // Tell reset function that new DC data has been given
roysandberg 4:ab6b451bbf40 116 newControlData = true;
roysandberg 4:ab6b451bbf40 117 }
roysandberg 4:ab6b451bbf40 118
roysandberg 4:ab6b451bbf40 119 // clock out the data over spi such that the MSB is the control bit (so 769 bits total)
roysandberg 4:ab6b451bbf40 120 void TLC5955::clockOutData() {
roysandberg 4:ab6b451bbf40 121 // clock out buffer, where the first word contains
roysandberg 4:ab6b451bbf40 122 // unused leading bits that will get clocked past the registers.
roysandberg 4:ab6b451bbf40 123
roysandberg 4:ab6b451bbf40 124 for (int i=0; i< (SHORTS_PER_CHANNEL * CHANNELS_PER_IC * NUMBER_OF_ICS) + 1; i++) {
roysandberg 4:ab6b451bbf40 125 spi.write(gsBuffer[i]>>8);
roysandberg 4:ab6b451bbf40 126 spi.write(gsBuffer[i]&0xFF);
roysandberg 4:ab6b451bbf40 127 //printf ("%d:%x:%x\n\r",i, gsBuffer[i]>>8, gsBuffer[i]&0xFF);
roysandberg 4:ab6b451bbf40 128 }
roysandberg 4:ab6b451bbf40 129 }
roysandberg 4:ab6b451bbf40 130
roysandberg 4:ab6b451bbf40 131 // Need a way to assemble bits in random offsets, since the 769 bit sequence doesn't divide evenly.
roysandberg 4:ab6b451bbf40 132 // So depending on how many TLC5955s are daisy chained together, there are an arbitrary number of extra bits.
roysandberg 4:ab6b451bbf40 133 // Function that tracks next available bit location, and packs everything in is needed.
roysandberg 4:ab6b451bbf40 134
roysandberg 4:ab6b451bbf40 135
roysandberg 4:ab6b451bbf40 136 inline void TLC5955::clearBit (unsigned short* value, int bitOffset) {
roysandberg 4:ab6b451bbf40 137 *value = *value & ~(1<<bitOffset);
roysandberg 4:ab6b451bbf40 138 }
roysandberg 4:ab6b451bbf40 139
roysandberg 4:ab6b451bbf40 140 inline void TLC5955::setBit (unsigned short* value, int bitOffset) {
roysandberg 4:ab6b451bbf40 141 *value = *value | (1<<bitOffset);
roysandberg 4:ab6b451bbf40 142 }
roysandberg 4:ab6b451bbf40 143
roysandberg 4:ab6b451bbf40 144
roysandberg 4:ab6b451bbf40 145 inline void TLC5955::packBit(unsigned int aBit) {
roysandberg 4:ab6b451bbf40 146 // current bit location divided by 16 to get the short
roysandberg 4:ab6b451bbf40 147 int shortOffset = currentBitLocation / 16;
roysandberg 4:ab6b451bbf40 148
roysandberg 4:ab6b451bbf40 149 // current bit location mod 8 to get the bit to mask
roysandberg 4:ab6b451bbf40 150 int bitOffset = currentBitLocation % 16;
roysandberg 4:ab6b451bbf40 151
roysandberg 4:ab6b451bbf40 152 if (aBit == 0) {
roysandberg 4:ab6b451bbf40 153 // clear
roysandberg 4:ab6b451bbf40 154 clearBit (&(gsBuffer[shortOffset]), 15 - bitOffset);
roysandberg 4:ab6b451bbf40 155 } else {
roysandberg 4:ab6b451bbf40 156 // set
roysandberg 4:ab6b451bbf40 157 setBit (&(gsBuffer[shortOffset]), 15 - bitOffset);
roysandberg 4:ab6b451bbf40 158 }
roysandberg 4:ab6b451bbf40 159 currentBitLocation++;
roysandberg 4:ab6b451bbf40 160 }
roysandberg 4:ab6b451bbf40 161
roysandberg 4:ab6b451bbf40 162 void TLC5955::packByte (unsigned int aByte) {
roysandberg 4:ab6b451bbf40 163 // call packBit for 8 bits, starting at the current bit location
roysandberg 4:ab6b451bbf40 164 for (int i = 7; i >= 0;i--) { // MSB gets packed first
roysandberg 4:ab6b451bbf40 165 packBit( aByte & (1<<i));
roysandberg 4:ab6b451bbf40 166 }
roysandberg 4:ab6b451bbf40 167
roysandberg 4:ab6b451bbf40 168 }
roysandberg 4:ab6b451bbf40 169
roysandberg 4:ab6b451bbf40 170 void TLC5955::packShort (unsigned int aShort) {
roysandberg 4:ab6b451bbf40 171 packByte( aShort >> 8); // MSB first
roysandberg 4:ab6b451bbf40 172 packByte( aShort & 0xFF);
roysandberg 4:ab6b451bbf40 173 }
roysandberg 4:ab6b451bbf40 174
roysandberg 4:ab6b451bbf40 175 void TLC5955::reset()
roysandberg 4:ab6b451bbf40 176 {
roysandberg 4:ab6b451bbf40 177 // Do we have new control data to send?
roysandberg 4:ab6b451bbf40 178 if (newControlData)
roysandberg 4:ab6b451bbf40 179 {
roysandberg 4:ab6b451bbf40 180 // printf ("Control:\n\r");
roysandberg 4:ab6b451bbf40 181
roysandberg 4:ab6b451bbf40 182 currentBitLocation = 0;
roysandberg 4:ab6b451bbf40 183 for (int i=0; i < 16 - NUMBER_OF_ICS;i++) {
roysandberg 4:ab6b451bbf40 184 packBit(0); // stuff leading byte
roysandberg 4:ab6b451bbf40 185 }
roysandberg 4:ab6b451bbf40 186 for (int icNum=0; icNum < NUMBER_OF_ICS; icNum++) {
roysandberg 4:ab6b451bbf40 187 // TODO: For daisy-chaining, this will need to consider the number of boards when calculating how many clocked out bits to offset
roysandberg 4:ab6b451bbf40 188 //packShort(1); // set LSB to one, will clock into LSB spot when spi serializes it to trigger control data load when latched
roysandberg 4:ab6b451bbf40 189 packBit(1); // set LSB to one
roysandberg 4:ab6b451bbf40 190 packByte(0x96); // 8 bit command decoder must be set to 0x96
roysandberg 4:ab6b451bbf40 191
roysandberg 4:ab6b451bbf40 192 // 390 bits skipped, so could be anything
roysandberg 4:ab6b451bbf40 193 for (int i=0;i<389;i++) {
roysandberg 4:ab6b451bbf40 194 packBit(0);
roysandberg 4:ab6b451bbf40 195 }
roysandberg 4:ab6b451bbf40 196
roysandberg 4:ab6b451bbf40 197 // FC 5 bits
roysandberg 4:ab6b451bbf40 198 packBit (0); // LED short circuit detection voltage - don't care for this application
roysandberg 4:ab6b451bbf40 199 packBit (0); // Use conventional PWM for this application; it's compatible with daisy chaining
roysandberg 4:ab6b451bbf40 200 packBit (0); // auto data refresh disabled
roysandberg 4:ab6b451bbf40 201 packBit (0); // display timing reset disabled
roysandberg 4:ab6b451bbf40 202 packBit (1); // auto display repeat mode ENABLED
roysandberg 4:ab6b451bbf40 203
roysandberg 4:ab6b451bbf40 204 // BC, 21 bits
roysandberg 4:ab6b451bbf40 205 packBit (globalBrightnessRed & (1<<6));
roysandberg 4:ab6b451bbf40 206 packBit (globalBrightnessRed & (1<<5));
roysandberg 4:ab6b451bbf40 207 packBit (globalBrightnessRed & (1<<4));
roysandberg 4:ab6b451bbf40 208 packBit (globalBrightnessRed & (1<<3));
roysandberg 4:ab6b451bbf40 209 packBit (globalBrightnessRed & (1<<2));
roysandberg 4:ab6b451bbf40 210 packBit (globalBrightnessRed & (1<<1));
roysandberg 4:ab6b451bbf40 211 packBit (globalBrightnessRed & (1<<0));
roysandberg 4:ab6b451bbf40 212
roysandberg 4:ab6b451bbf40 213 packBit (globalBrightnessGreen & (1<<6));
roysandberg 4:ab6b451bbf40 214 packBit (globalBrightnessGreen & (1<<5));
roysandberg 4:ab6b451bbf40 215 packBit (globalBrightnessGreen & (1<<4));
roysandberg 4:ab6b451bbf40 216 packBit (globalBrightnessGreen & (1<<3));
roysandberg 4:ab6b451bbf40 217 packBit (globalBrightnessGreen & (1<<2));
roysandberg 4:ab6b451bbf40 218 packBit (globalBrightnessGreen & (1<<1));
roysandberg 4:ab6b451bbf40 219 packBit (globalBrightnessGreen & (1<<0));
roysandberg 4:ab6b451bbf40 220
roysandberg 4:ab6b451bbf40 221 packBit (globalBrightnessBlue & (1<<6));
roysandberg 4:ab6b451bbf40 222 packBit (globalBrightnessBlue & (1<<5));
roysandberg 4:ab6b451bbf40 223 packBit (globalBrightnessBlue & (1<<4));
roysandberg 4:ab6b451bbf40 224 packBit (globalBrightnessBlue & (1<<3));
roysandberg 4:ab6b451bbf40 225 packBit (globalBrightnessBlue & (1<<2));
roysandberg 4:ab6b451bbf40 226 packBit (globalBrightnessBlue & (1<<1));
roysandberg 4:ab6b451bbf40 227 packBit (globalBrightnessBlue & (1<<0));
roysandberg 4:ab6b451bbf40 228
roysandberg 4:ab6b451bbf40 229 // MC, 9 bits
roysandberg 4:ab6b451bbf40 230 packBit (maximumCurrentBlue & (1<<2));
roysandberg 4:ab6b451bbf40 231 packBit (maximumCurrentBlue & (1<<1));
roysandberg 4:ab6b451bbf40 232 packBit (maximumCurrentBlue & (1<<0));
roysandberg 4:ab6b451bbf40 233
roysandberg 4:ab6b451bbf40 234 packBit (maximumCurrentGreen & (1<<2));
roysandberg 4:ab6b451bbf40 235 packBit (maximumCurrentGreen & (1<<1));
roysandberg 4:ab6b451bbf40 236 packBit (maximumCurrentGreen & (1<<0));
roysandberg 4:ab6b451bbf40 237
roysandberg 4:ab6b451bbf40 238 packBit (maximumCurrentRed & (1<<2));
roysandberg 4:ab6b451bbf40 239 packBit (maximumCurrentRed & (1<<1));
roysandberg 4:ab6b451bbf40 240 packBit (maximumCurrentRed & (1<<0));
roysandberg 4:ab6b451bbf40 241
roysandberg 4:ab6b451bbf40 242 // DC 336 bits
roysandberg 4:ab6b451bbf40 243 // dot correct for each channel, starting with channel 48
roysandberg 4:ab6b451bbf40 244 for (int i=0; i<48; i++) {
roysandberg 4:ab6b451bbf40 245 packBit (dotCorrect[i] & (1<<6));
roysandberg 4:ab6b451bbf40 246 packBit (dotCorrect[i] & (1<<5));
roysandberg 4:ab6b451bbf40 247 packBit (dotCorrect[i] & (1<<4));
roysandberg 4:ab6b451bbf40 248 packBit (dotCorrect[i] & (1<<3));
roysandberg 4:ab6b451bbf40 249 packBit (dotCorrect[i] & (1<<2));
roysandberg 4:ab6b451bbf40 250 packBit (dotCorrect[i] & (1<<1));
roysandberg 4:ab6b451bbf40 251 packBit (dotCorrect[i] & (1<<0));
roysandberg 4:ab6b451bbf40 252 }
roysandberg 4:ab6b451bbf40 253 }
roysandberg 4:ab6b451bbf40 254 clockOutData();
roysandberg 4:ab6b451bbf40 255
roysandberg 4:ab6b451bbf40 256 // Latch
roysandberg 4:ab6b451bbf40 257 xlat = 0;
roysandberg 4:ab6b451bbf40 258 xlat = 1;
roysandberg 4:ab6b451bbf40 259 wait_us(10);
roysandberg 4:ab6b451bbf40 260 xlat = 0;
roysandberg 4:ab6b451bbf40 261
roysandberg 4:ab6b451bbf40 262
roysandberg 4:ab6b451bbf40 263 // No new data to send (we just sent it!)
roysandberg 4:ab6b451bbf40 264 newControlData = false;
roysandberg 4:ab6b451bbf40 265
roysandberg 4:ab6b451bbf40 266 } else if (newGSData) { // Do we have new GS data to send?
roysandberg 4:ab6b451bbf40 267 //printf ("Data:\n\r");
roysandberg 4:ab6b451bbf40 268
roysandberg 4:ab6b451bbf40 269 led2 = !led2;
roysandberg 4:ab6b451bbf40 270
roysandberg 4:ab6b451bbf40 271 currentBitLocation = 0;
roysandberg 4:ab6b451bbf40 272 for (int i=0; i < 16 - NUMBER_OF_ICS;i++) {
roysandberg 4:ab6b451bbf40 273 packBit(1); // stuff leading byte
roysandberg 4:ab6b451bbf40 274 }
roysandberg 4:ab6b451bbf40 275 for (int icNum=0; icNum < NUMBER_OF_ICS; icNum++) {
roysandberg 4:ab6b451bbf40 276 // TODO: For daisy-chaining, this will need to consider the number of boards when calculating how many clocked out bits to offset
roysandberg 4:ab6b451bbf40 277 //packShort(0); // set LSB to zero, will clock into LSB spot when spi serializes it to trigger control data load when latched
roysandberg 4:ab6b451bbf40 278 packBit(0); // set LSB to zero
roysandberg 4:ab6b451bbf40 279
roysandberg 4:ab6b451bbf40 280 // Send GS data backwards - this makes the GS_buffer[0] index correspond to OUT0
roysandberg 4:ab6b451bbf40 281 for (int i = (SHORTS_PER_CHANNEL * CHANNELS_PER_IC) - 1; i >= 0; i--)
roysandberg 4:ab6b451bbf40 282 {
roysandberg 4:ab6b451bbf40 283 packShort(internalData[i + (icNum*SHORTS_PER_CHANNEL * CHANNELS_PER_IC)]);
roysandberg 4:ab6b451bbf40 284 }
roysandberg 4:ab6b451bbf40 285 }
roysandberg 4:ab6b451bbf40 286 clockOutData();
roysandberg 4:ab6b451bbf40 287
roysandberg 4:ab6b451bbf40 288 // Latch
roysandberg 4:ab6b451bbf40 289 xlat = 0;
roysandberg 4:ab6b451bbf40 290 xlat = 1;
roysandberg 4:ab6b451bbf40 291 wait_us(10);
roysandberg 4:ab6b451bbf40 292 xlat = 0;
roysandberg 4:ab6b451bbf40 293
roysandberg 4:ab6b451bbf40 294 // No new data to send (we just sent it!)
roysandberg 4:ab6b451bbf40 295 newGSData = false;
roysandberg 4:ab6b451bbf40 296 }
roysandberg 4:ab6b451bbf40 297 }