SPI library used to communicate with an altera development board attached to four zigbee-header pins.

Committer:
gatedClock
Date:
Sat Aug 31 02:19:42 2013 +0000
Revision:
34:d5553509f31a
Parent:
32:5a5d9525c6c4
Child:
35:6152c9709697
IR can now be written from the UI.  test is passing.  needs some cleanup.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gatedClock 0:fb42c5acf810 1 /*----------------------------------------------//------------------------------
gatedClock 0:fb42c5acf810 2 student : m-moore
gatedClock 32:5a5d9525c6c4 3 email : gated.clock@gmail.com
gatedClock 32:5a5d9525c6c4 4 class : usb device drivers
gatedClock 0:fb42c5acf810 5 directory : mmSPI
gatedClock 0:fb42c5acf810 6 file : mmSPI.cpp
gatedClock 32:5a5d9525c6c4 7 date : september 3, 2013.
gatedClock 0:fb42c5acf810 8 ------------------------------------------------//----------------------------*/
gatedClock 0:fb42c5acf810 9 #include "mmSPI.h"
gatedClock 0:fb42c5acf810 10 /*----------------------------------------------//------------------------------
gatedClock 0:fb42c5acf810 11 ------------------------------------------------//----------------------------*/
gatedClock 0:fb42c5acf810 12 //==============================================//==============================
gatedClock 0:fb42c5acf810 13 mmSPI::mmSPI() // constructor.
gatedClock 0:fb42c5acf810 14 {
gatedClock 3:de99451ab3c0 15 allocations(); // object allocations.
gatedClock 15:d6cc57c4e23d 16
gatedClock 32:5a5d9525c6c4 17 *pSCLK = 0; // initialize.
gatedClock 32:5a5d9525c6c4 18 *pCPUclk = 0; // initialize.
gatedClock 32:5a5d9525c6c4 19 ulSPIclkCount = 0; // initialize.
gatedClock 32:5a5d9525c6c4 20 ulCPUclkCount = 0; // initialize.
gatedClock 32:5a5d9525c6c4 21 } // constructor.
gatedClock 0:fb42c5acf810 22 //----------------------------------------------//------------------------------
gatedClock 0:fb42c5acf810 23 mmSPI::~mmSPI() // destructor.
gatedClock 0:fb42c5acf810 24 {
gatedClock 8:e2d8bbc3e659 25 // deallocations.
gatedClock 8:e2d8bbc3e659 26 if (pMOSI) {delete pMOSI; pMOSI = NULL;}
gatedClock 8:e2d8bbc3e659 27 if (pMISO) {delete pMISO; pMISO = NULL;}
gatedClock 8:e2d8bbc3e659 28 if (pSCLK) {delete pSCLK; pSCLK = NULL;}
gatedClock 8:e2d8bbc3e659 29 if (pCPUclk) {delete pCPUclk; pCPUclk = NULL;}
gatedClock 32:5a5d9525c6c4 30 } // destructor.
gatedClock 3:de99451ab3c0 31 //----------------------------------------------//------------------------------
gatedClock 3:de99451ab3c0 32 void mmSPI::allocations(void) // object allocations.
gatedClock 3:de99451ab3c0 33 {
gatedClock 32:5a5d9525c6c4 34 pMOSI = new DigitalOut(mmSPI_MOSI); // SPI MOSI pin object.
gatedClock 3:de99451ab3c0 35 if (!pMOSI) error("\n\r mmSPI::allocations : FATAL malloc error for pMOSI. \n\r");
gatedClock 3:de99451ab3c0 36
gatedClock 32:5a5d9525c6c4 37 pMISO = new DigitalOut(mmSPI_MISO); // SPI MISO pin object.
gatedClock 3:de99451ab3c0 38 if (!pMISO) error("\n\r mmSPI::allocations : FATAL malloc error for pMISO. \n\r");
gatedClock 3:de99451ab3c0 39
gatedClock 32:5a5d9525c6c4 40 pSCLK = new DigitalOut(mmSPI_SCLK); // SPI SCLK pin object.
gatedClock 3:de99451ab3c0 41 if (!pSCLK) error("\n\r mmSPI::allocations : FATAL malloc error for pSCLK. \n\r");
gatedClock 8:e2d8bbc3e659 42
gatedClock 32:5a5d9525c6c4 43 pCPUclk = new DigitalOut(mmCPU_CLK); // SPI SCLK pin object.
gatedClock 8:e2d8bbc3e659 44 if (!pCPUclk) error("\n\r mmSPI::allocations : FATAL malloc error for pCPUclk. \n\r");
gatedClock 32:5a5d9525c6c4 45 } // allocations.
gatedClock 4:aa1fe8707bef 46 //----------------------------------------------//------------------------------
gatedClock 4:aa1fe8707bef 47 void mmSPI::setSPIfrequency(float fFreq) // set SPI clock frequency.
gatedClock 4:aa1fe8707bef 48 {
gatedClock 4:aa1fe8707bef 49 fSPIfreq = fFreq; // promote to object scope.
gatedClock 4:aa1fe8707bef 50 if (fSPIfreq < .05) // don't get near divide-by-zero.
gatedClock 4:aa1fe8707bef 51 error("\n\r mmSPI::setSPIfrequency : FATAL SPI frequency set too low. \n\r");
gatedClock 4:aa1fe8707bef 52 fSPIquarterP = (1 / fSPIfreq) / 4; // figure quarter-cycle period.
gatedClock 4:aa1fe8707bef 53 }
gatedClock 22:7524dee5c753 54 //----------------------------------------------//------------------------------
gatedClock 22:7524dee5c753 55 // obtain SPI send buffer pointer.
gatedClock 22:7524dee5c753 56 void mmSPI::setSendBuffer(char * pcSendBuffer)
gatedClock 22:7524dee5c753 57 {
gatedClock 22:7524dee5c753 58 pcSend = pcSendBuffer; // promote to object scope.
gatedClock 32:5a5d9525c6c4 59 } // setSendBuffer.
gatedClock 22:7524dee5c753 60 //----------------------------------------------//------------------------------
gatedClock 22:7524dee5c753 61 // obtain SPI receive buffer pointer.
gatedClock 22:7524dee5c753 62 void mmSPI::setReceiveBuffer(char * pcReceiveBuffer)
gatedClock 22:7524dee5c753 63 {
gatedClock 22:7524dee5c753 64 pcReceive = pcReceiveBuffer; // promote to object scope.
gatedClock 32:5a5d9525c6c4 65 } // setReceiveBuffer.
gatedClock 0:fb42c5acf810 66 //----------------------------------------------//------------------------------
gatedClock 22:7524dee5c753 67 // obtain number of SPI bytes.
gatedClock 22:7524dee5c753 68 void mmSPI::setNumberOfBytes(int dNumberOfBytes)
gatedClock 22:7524dee5c753 69 {
gatedClock 22:7524dee5c753 70 dNumBytes = dNumberOfBytes; // promote to object scope.
gatedClock 32:5a5d9525c6c4 71 } // setNumberOfBytes.
gatedClock 22:7524dee5c753 72 //----------------------------------------------//------------------------------
gatedClock 16:0e422fd263c6 73 // transceive a character array.
gatedClock 16:0e422fd263c6 74 // MSB out/in first.
gatedClock 31:ea7b25e494b5 75 // normal inputs: [1,1,1,0]
gatedClock 31:ea7b25e494b5 76 // CPUstep input : [0,0,1,1]
gatedClock 31:ea7b25e494b5 77 void mmSPI::transceive_vector(char cPreCPU, char cPreSPI, char cScan, char cPostCPU)
gatedClock 16:0e422fd263c6 78 {
gatedClock 16:0e422fd263c6 79 int dClear;
gatedClock 16:0e422fd263c6 80 int dIndex;
gatedClock 16:0e422fd263c6 81 int dMosiByteIndex;
gatedClock 16:0e422fd263c6 82 int dMosiBitIndex;
gatedClock 16:0e422fd263c6 83 int dMisoByteIndex;
gatedClock 16:0e422fd263c6 84 int dMisoBitIndex;
gatedClock 16:0e422fd263c6 85
gatedClock 16:0e422fd263c6 86 dIndex = (dNumBytes * 8) - 1;
gatedClock 31:ea7b25e494b5 87 dMosiByteIndex = dIndex / 8;
gatedClock 31:ea7b25e494b5 88 dMosiBitIndex = dIndex % 8;
gatedClock 16:0e422fd263c6 89
gatedClock 16:0e422fd263c6 90 for (dClear = 0; dClear < dNumBytes; dClear++) pcReceive[dClear] = 0;
gatedClock 16:0e422fd263c6 91
gatedClock 31:ea7b25e494b5 92 if (cPreCPU) // if pre-CPU clock.
gatedClock 31:ea7b25e494b5 93 {
gatedClock 31:ea7b25e494b5 94 *pCPUclk = 1; // pulse the CPU clock.
gatedClock 31:ea7b25e494b5 95 wait(fSPIquarterP);
gatedClock 31:ea7b25e494b5 96 wait(fSPIquarterP);
gatedClock 31:ea7b25e494b5 97 *pCPUclk = 0;
gatedClock 31:ea7b25e494b5 98 wait(fSPIquarterP);
gatedClock 31:ea7b25e494b5 99 wait(fSPIquarterP);
gatedClock 32:5a5d9525c6c4 100 ulCPUclkCount++;
gatedClock 31:ea7b25e494b5 101 } // if pre-CPU clock.
gatedClock 16:0e422fd263c6 102
gatedClock 31:ea7b25e494b5 103 if (cPreSPI) // if pre-SPI pulse.
gatedClock 31:ea7b25e494b5 104 {
gatedClock 31:ea7b25e494b5 105 *pSCLK = 1; // pulse the SPI clock for parallel load.
gatedClock 31:ea7b25e494b5 106 wait(fSPIquarterP);
gatedClock 31:ea7b25e494b5 107 wait(fSPIquarterP);
gatedClock 31:ea7b25e494b5 108 *pSCLK = 0;
gatedClock 32:5a5d9525c6c4 109 ulSPIclkCount++;
gatedClock 31:ea7b25e494b5 110 } // if pre-SPI pulse.
gatedClock 31:ea7b25e494b5 111
gatedClock 31:ea7b25e494b5 112 if (cScan) // if cScan.
gatedClock 31:ea7b25e494b5 113 {
gatedClock 16:0e422fd263c6 114 // pre-assert MOSI.
gatedClock 31:ea7b25e494b5 115 *pMOSI = ((pcSend[dMosiByteIndex]) >> dMosiBitIndex) & 1;
gatedClock 31:ea7b25e494b5 116 wait(fSPIquarterP);
gatedClock 31:ea7b25e494b5 117 wait(fSPIquarterP);
gatedClock 16:0e422fd263c6 118
gatedClock 16:0e422fd263c6 119
gatedClock 32:5a5d9525c6c4 120 // main SPI scan loop.
gatedClock 31:ea7b25e494b5 121 for (dIndex = (dNumBytes * 8) - 1; dIndex >= 0; dIndex--)
gatedClock 31:ea7b25e494b5 122 {
gatedClock 31:ea7b25e494b5 123 dMisoByteIndex = dIndex / 8;
gatedClock 31:ea7b25e494b5 124 dMisoBitIndex = dIndex % 8;
gatedClock 31:ea7b25e494b5 125 pcReceive[dMisoByteIndex] = pcReceive[dMisoByteIndex] | (*pMISO << dMisoBitIndex);
gatedClock 31:ea7b25e494b5 126 *pSCLK = 1;
gatedClock 31:ea7b25e494b5 127 wait(fSPIquarterP);
gatedClock 31:ea7b25e494b5 128 wait(fSPIquarterP);
gatedClock 31:ea7b25e494b5 129 *pSCLK = 0;
gatedClock 31:ea7b25e494b5 130 if (dIndex < 0) dIndex = 0;
gatedClock 31:ea7b25e494b5 131 dMosiByteIndex = (dIndex - 1) / 8;
gatedClock 31:ea7b25e494b5 132 dMosiBitIndex = (dIndex - 1) % 8;
gatedClock 31:ea7b25e494b5 133 *pMOSI = ((pcSend[dMosiByteIndex]) >> dMosiBitIndex) & 1;
gatedClock 31:ea7b25e494b5 134 wait(fSPIquarterP);
gatedClock 31:ea7b25e494b5 135 wait(fSPIquarterP);
gatedClock 32:5a5d9525c6c4 136 ulSPIclkCount++;
gatedClock 32:5a5d9525c6c4 137 } // main SPI scan loop.
gatedClock 31:ea7b25e494b5 138 } // if cScan.
gatedClock 31:ea7b25e494b5 139
gatedClock 31:ea7b25e494b5 140 if (cPostCPU) // if post-CPU pulse.
gatedClock 16:0e422fd263c6 141 {
gatedClock 31:ea7b25e494b5 142 *pCPUclk = 1; // pulse the CPU clock.
gatedClock 31:ea7b25e494b5 143 wait(fSPIquarterP);
gatedClock 31:ea7b25e494b5 144 wait(fSPIquarterP);
gatedClock 31:ea7b25e494b5 145 *pCPUclk = 0;
gatedClock 31:ea7b25e494b5 146 wait(fSPIquarterP);
gatedClock 32:5a5d9525c6c4 147 wait(fSPIquarterP);
gatedClock 32:5a5d9525c6c4 148 ulCPUclkCount++;
gatedClock 31:ea7b25e494b5 149
gatedClock 31:ea7b25e494b5 150 *pSCLK = 1; // clear-out the SPI parallel-load enable.
gatedClock 16:0e422fd263c6 151 wait(fSPIquarterP);
gatedClock 16:0e422fd263c6 152 wait(fSPIquarterP);
gatedClock 31:ea7b25e494b5 153 *pSCLK = 0;
gatedClock 32:5a5d9525c6c4 154 ulSPIclkCount++;
gatedClock 31:ea7b25e494b5 155 } // if post-CPU pulse.
gatedClock 32:5a5d9525c6c4 156 } // transceive_vector.
gatedClock 7:b3e8b537d5c2 157 //----------------------------------------------//------------------------------
gatedClock 26:26a8f31a31b8 158 // cRegister -> CPU_register
gatedClock 26:26a8f31a31b8 159 // 0 R0
gatedClock 26:26a8f31a31b8 160 // 1 R1
gatedClock 26:26a8f31a31b8 161 // 2 R2
gatedClock 26:26a8f31a31b8 162 // 3 R3
gatedClock 26:26a8f31a31b8 163 // 4 PC
gatedClock 26:26a8f31a31b8 164 // 5 <meta, don't do>
gatedClock 26:26a8f31a31b8 165 // 6 <nothing>
gatedClock 26:26a8f31a31b8 166 // 7 <nothing>
gatedClock 26:26a8f31a31b8 167
gatedClock 23:dbd89a56716d 168 void mmSPI::write_register(char cRegister, char cValue)
gatedClock 16:0e422fd263c6 169 {
gatedClock 24:d3b8c68f41f2 170 clear_transmit_vector(); // clear transmit vector.
gatedClock 18:4a29cad91540 171
gatedClock 18:4a29cad91540 172 pcSend[7] = 0x02; // mbed sends a command.
gatedClock 18:4a29cad91540 173
gatedClock 18:4a29cad91540 174 // align into instruction word.
gatedClock 16:0e422fd263c6 175 pcSend[1] = ((cRegister & 0x07) << 2) | 0xA0;
gatedClock 18:4a29cad91540 176 pcSend[0] = cValue & 0xFF; // immediate value to i.w.
gatedClock 17:b81c0c1f312f 177
gatedClock 31:ea7b25e494b5 178 transceive_vector(1,1,1,0); // transmit command.
gatedClock 18:4a29cad91540 179
gatedClock 24:d3b8c68f41f2 180 clear_transmit_vector(); // clear transmit vector.
gatedClock 32:5a5d9525c6c4 181 } // write_register.
gatedClock 34:d5553509f31a 182 //----------------------------------------------//------------------------------
gatedClock 34:d5553509f31a 183 // write instruction register.
gatedClock 34:d5553509f31a 184 void mmSPI::write_IR(char cValueH, char cValueL)
gatedClock 34:d5553509f31a 185 {
gatedClock 34:d5553509f31a 186 clear_transmit_vector(); // clear transmit vector.
gatedClock 34:d5553509f31a 187
gatedClock 34:d5553509f31a 188 pcSend[7] = 0x06; // mbed sends a command.
gatedClock 34:d5553509f31a 189
gatedClock 34:d5553509f31a 190 pcSend[1] = (cValueH & 0xFF); // load IR shadow with new IR content.
gatedClock 34:d5553509f31a 191 pcSend[0] = (cValueL & 0xFF);
gatedClock 34:d5553509f31a 192
gatedClock 34:d5553509f31a 193 transceive_vector(1,1,1,0); // transmit command.
gatedClock 34:d5553509f31a 194
gatedClock 34:d5553509f31a 195 clear_transmit_vector(); // clear transmit vector.
gatedClock 34:d5553509f31a 196 } // write instruction register.
gatedClock 17:b81c0c1f312f 197 //----------------------------------------------//------------------------------
gatedClock 26:26a8f31a31b8 198 // cRegister -> CPU_register
gatedClock 26:26a8f31a31b8 199 // 0 -> R0
gatedClock 26:26a8f31a31b8 200 // 1 -> R1
gatedClock 26:26a8f31a31b8 201 // 2 -> R2
gatedClock 26:26a8f31a31b8 202 // 3 -> R3
gatedClock 26:26a8f31a31b8 203 // 4 -> PC
gatedClock 26:26a8f31a31b8 204 // 5 -> IR-H
gatedClock 26:26a8f31a31b8 205 // 6 -> IR-L
gatedClock 26:26a8f31a31b8 206 // 7 -> <never-use>
gatedClock 17:b81c0c1f312f 207 // returns the content of
gatedClock 17:b81c0c1f312f 208 // a CPU register.
gatedClock 23:dbd89a56716d 209 char mmSPI::read_register(char cRegister)
gatedClock 17:b81c0c1f312f 210 {
gatedClock 24:d3b8c68f41f2 211 clear_transmit_vector(); // clear transmit vector.
gatedClock 29:4ed71dfee7d8 212
gatedClock 29:4ed71dfee7d8 213 pcSend[7] = 0x02; // suppress cpu operation.
gatedClock 29:4ed71dfee7d8 214
gatedClock 31:ea7b25e494b5 215 transceive_vector(1,1,1,0); // snap & scan-out reg contents.
gatedClock 17:b81c0c1f312f 216
gatedClock 19:c2b753533b93 217 return (pcReceive[6 - cRegister]); // return the particular reg value.
gatedClock 32:5a5d9525c6c4 218 } // read_register.
gatedClock 17:b81c0c1f312f 219 //----------------------------------------------//------------------------------
gatedClock 23:dbd89a56716d 220 void mmSPI::write_memory(char cHData, char cLdata, char cAddress)
gatedClock 18:4a29cad91540 221 {
gatedClock 24:d3b8c68f41f2 222 clear_transmit_vector(); // clear transmit vector.
gatedClock 24:d3b8c68f41f2 223
gatedClock 24:d3b8c68f41f2 224 write_register(0x03,cAddress); // R3 <- address.
gatedClock 24:d3b8c68f41f2 225 write_register(0x02,cHData); // R2 <- high-data.
gatedClock 24:d3b8c68f41f2 226 write_register(0x01,cLdata); // R1 <- low-data.
gatedClock 18:4a29cad91540 227
gatedClock 27:fb63c8b70bc2 228 pcSend[7] = 0x02; // mbed sends command.
gatedClock 27:fb63c8b70bc2 229 pcSend[1] = 0x02; // write-enable high.
gatedClock 27:fb63c8b70bc2 230 pcSend[0] = 0x00; // remainder of instruction.
gatedClock 31:ea7b25e494b5 231 transceive_vector(1,1,1,0);
gatedClock 18:4a29cad91540 232
gatedClock 27:fb63c8b70bc2 233 pcSend[7] = 0x02; // mbed sends command.
gatedClock 27:fb63c8b70bc2 234 pcSend[1] = 0x00; // write-enable low.
gatedClock 27:fb63c8b70bc2 235 pcSend[0] = 0x00; // remainder of instruction.
gatedClock 31:ea7b25e494b5 236 transceive_vector(1,1,1,0);
gatedClock 24:d3b8c68f41f2 237
gatedClock 24:d3b8c68f41f2 238 clear_transmit_vector(); // clear transmit vector.
gatedClock 32:5a5d9525c6c4 239 } // write_memory.
gatedClock 18:4a29cad91540 240 //----------------------------------------------//------------------------------
gatedClock 18:4a29cad91540 241 // fetch a word from main memory.
gatedClock 23:dbd89a56716d 242 unsigned int mmSPI::read_memory(char cAddress)
gatedClock 24:d3b8c68f41f2 243 {
gatedClock 18:4a29cad91540 244 unsigned int udMemoryContent; // return variable.
gatedClock 18:4a29cad91540 245 char cHData; // returned data-high.
gatedClock 18:4a29cad91540 246 char cLData; // returned data-low.
gatedClock 24:d3b8c68f41f2 247
gatedClock 24:d3b8c68f41f2 248 clear_transmit_vector(); // clear transmit vector.
gatedClock 21:e90dd0f8aaa1 249
gatedClock 24:d3b8c68f41f2 250 write_register(0x03,cAddress); // R3 <= address.
gatedClock 18:4a29cad91540 251
gatedClock 18:4a29cad91540 252 pcSend[7] = 0x02; // mbed sends command.
gatedClock 20:2d5cd38047ca 253 pcSend[1] = 0xC8; // R2 <- MM[R3]
gatedClock 18:4a29cad91540 254 pcSend[0] = 0x00;
gatedClock 31:ea7b25e494b5 255 transceive_vector(1,1,1,0); // send command.
gatedClock 18:4a29cad91540 256
gatedClock 18:4a29cad91540 257 pcSend[7] = 0x02; // mbed sends command.
gatedClock 20:2d5cd38047ca 258 pcSend[1] = 0xC4; // R1 <- MM[R3]
gatedClock 18:4a29cad91540 259 pcSend[0] = 0x00;
gatedClock 31:ea7b25e494b5 260 transceive_vector(1,1,1,0); // send command.
gatedClock 18:4a29cad91540 261
gatedClock 24:d3b8c68f41f2 262 cHData = read_register(0x02); // obtain MM high-data-byte.
gatedClock 24:d3b8c68f41f2 263 cLData = read_register(0x01); // obtain MM low-data-byte.
gatedClock 31:ea7b25e494b5 264
gatedClock 18:4a29cad91540 265 udMemoryContent = (cHData << 8) + cLData; // build the memory word.
gatedClock 24:d3b8c68f41f2 266
gatedClock 24:d3b8c68f41f2 267 clear_transmit_vector(); // clear transmit vector.
gatedClock 18:4a29cad91540 268
gatedClock 18:4a29cad91540 269 return udMemoryContent; // return the memory word.
gatedClock 32:5a5d9525c6c4 270 } // read_memory.
gatedClock 18:4a29cad91540 271 //----------------------------------------------//------------------------------
gatedClock 30:331c7c7d8bc1 272 void mmSPI::step(void) // step the CPU.
gatedClock 30:331c7c7d8bc1 273 {
gatedClock 31:ea7b25e494b5 274 clear_transmit_vector(); // clear transmit vector.
gatedClock 31:ea7b25e494b5 275 transceive_vector(0,0,1,0); // enable CPU mode.
gatedClock 31:ea7b25e494b5 276 transceive_vector(0,0,0,1); // advance CPU, clear shadow-load.
gatedClock 31:ea7b25e494b5 277 pcSend[7] = 0x02; // ready to disable CPU mode.
gatedClock 31:ea7b25e494b5 278 transceive_vector(0,0,1,0); // disable CPU mode.
gatedClock 32:5a5d9525c6c4 279 } // step.
gatedClock 30:331c7c7d8bc1 280 //----------------------------------------------//------------------------------
gatedClock 24:d3b8c68f41f2 281 void mmSPI::clear_transmit_vector(void) // fill transmit buffer with 0.
gatedClock 24:d3b8c68f41f2 282 {
gatedClock 24:d3b8c68f41f2 283 int dLoop;
gatedClock 24:d3b8c68f41f2 284 for (dLoop = 0; dLoop < dNumBytes; dLoop++) pcSend[dLoop] = 0x00;
gatedClock 32:5a5d9525c6c4 285 } // clear_transmit_vector.
gatedClock 32:5a5d9525c6c4 286 //----------------------------------------------//------------------------------
gatedClock 32:5a5d9525c6c4 287 // getters.
gatedClock 32:5a5d9525c6c4 288 unsigned long mmSPI::SPIClockCount() {return ulSPIclkCount;}
gatedClock 32:5a5d9525c6c4 289 unsigned long mmSPI::CPUClockCount() {return ulCPUclkCount;}
gatedClock 24:d3b8c68f41f2 290 //----------------------------------------------//------------------------------
gatedClock 17:b81c0c1f312f 291
gatedClock 17:b81c0c1f312f 292
gatedClock 5:b14dcaae260e 293
gatedClock 5:b14dcaae260e 294
gatedClock 5:b14dcaae260e 295
gatedClock 5:b14dcaae260e 296
gatedClock 5:b14dcaae260e 297
gatedClock 5:b14dcaae260e 298