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

Committer:
gatedClock
Date:
Mon Aug 19 04:41:29 2013 +0000
Revision:
15:d6cc57c4e23d
Parent:
14:35717622a4fb
Child:
16:0e422fd263c6
experimental spi receive phase correction.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gatedClock 0:fb42c5acf810 1 /*----------------------------------------------//------------------------------
gatedClock 0:fb42c5acf810 2 student : m-moore
gatedClock 0:fb42c5acf810 3 class : external SPI interface
gatedClock 0:fb42c5acf810 4 directory : mmSPI
gatedClock 0:fb42c5acf810 5 file : mmSPI.cpp
gatedClock 0:fb42c5acf810 6 ------------------------------------------------//----------------------------*/
gatedClock 0:fb42c5acf810 7 #include "mmSPI.h"
gatedClock 0:fb42c5acf810 8 /*----------------------------------------------//------------------------------
gatedClock 0:fb42c5acf810 9 ------------------------------------------------//----------------------------*/
gatedClock 0:fb42c5acf810 10 //==============================================//==============================
gatedClock 15:d6cc57c4e23d 11 // consider resetting the fpga around here, because
gatedClock 15:d6cc57c4e23d 12 // the micro may be wiggling these signals before here.
gatedClock 0:fb42c5acf810 13 mmSPI::mmSPI() // constructor.
gatedClock 0:fb42c5acf810 14 {
gatedClock 3:de99451ab3c0 15 allocations(); // object allocations.
gatedClock 15:d6cc57c4e23d 16
gatedClock 15:d6cc57c4e23d 17 *pSCLK = 0; // initialize.
gatedClock 15:d6cc57c4e23d 18 *pCPUclk = 0; // initialize.
gatedClock 0:fb42c5acf810 19 }
gatedClock 0:fb42c5acf810 20 //----------------------------------------------//------------------------------
gatedClock 0:fb42c5acf810 21 mmSPI::~mmSPI() // destructor.
gatedClock 0:fb42c5acf810 22 {
gatedClock 8:e2d8bbc3e659 23 // deallocations.
gatedClock 8:e2d8bbc3e659 24 if (pMOSI) {delete pMOSI; pMOSI = NULL;}
gatedClock 8:e2d8bbc3e659 25 if (pMISO) {delete pMISO; pMISO = NULL;}
gatedClock 8:e2d8bbc3e659 26 if (pSCLK) {delete pSCLK; pSCLK = NULL;}
gatedClock 8:e2d8bbc3e659 27 if (pCPUclk) {delete pCPUclk; pCPUclk = NULL;}
gatedClock 3:de99451ab3c0 28 }
gatedClock 3:de99451ab3c0 29 //----------------------------------------------//------------------------------
gatedClock 3:de99451ab3c0 30 void mmSPI::allocations(void) // object allocations.
gatedClock 3:de99451ab3c0 31 {
gatedClock 8:e2d8bbc3e659 32 pMOSI = new DigitalOut(mmSPI_MOSI); // SPI MOSI pin object.
gatedClock 3:de99451ab3c0 33 if (!pMOSI) error("\n\r mmSPI::allocations : FATAL malloc error for pMOSI. \n\r");
gatedClock 3:de99451ab3c0 34
gatedClock 8:e2d8bbc3e659 35 pMISO = new DigitalOut(mmSPI_MISO); // SPI MISO pin object.
gatedClock 3:de99451ab3c0 36 if (!pMISO) error("\n\r mmSPI::allocations : FATAL malloc error for pMISO. \n\r");
gatedClock 3:de99451ab3c0 37
gatedClock 8:e2d8bbc3e659 38 pSCLK = new DigitalOut(mmSPI_SCLK); // SPI SCLK pin object.
gatedClock 3:de99451ab3c0 39 if (!pSCLK) error("\n\r mmSPI::allocations : FATAL malloc error for pSCLK. \n\r");
gatedClock 8:e2d8bbc3e659 40
gatedClock 8:e2d8bbc3e659 41 pCPUclk = new DigitalOut(mmCPU_CLK); // SPI SCLK pin object.
gatedClock 8:e2d8bbc3e659 42 if (!pCPUclk) error("\n\r mmSPI::allocations : FATAL malloc error for pCPUclk. \n\r");
gatedClock 3:de99451ab3c0 43 }
gatedClock 4:aa1fe8707bef 44 //----------------------------------------------//------------------------------
gatedClock 4:aa1fe8707bef 45 void mmSPI::setSPIfrequency(float fFreq) // set SPI clock frequency.
gatedClock 4:aa1fe8707bef 46 {
gatedClock 4:aa1fe8707bef 47 fSPIfreq = fFreq; // promote to object scope.
gatedClock 4:aa1fe8707bef 48 if (fSPIfreq < .05) // don't get near divide-by-zero.
gatedClock 4:aa1fe8707bef 49 error("\n\r mmSPI::setSPIfrequency : FATAL SPI frequency set too low. \n\r");
gatedClock 4:aa1fe8707bef 50 fSPIquarterP = (1 / fSPIfreq) / 4; // figure quarter-cycle period.
gatedClock 4:aa1fe8707bef 51 }
gatedClock 0:fb42c5acf810 52 //----------------------------------------------//------------------------------
gatedClock 5:b14dcaae260e 53 // we're not going for speed, so lets go for good setup / hold.
gatedClock 6:b480fc4e87e5 54
gatedClock 6:b480fc4e87e5 55 // send/receive a byte over SPI.
gatedClock 7:b3e8b537d5c2 56 // MSB out/in first.
gatedClock 6:b480fc4e87e5 57 void mmSPI::transceive_byte(char *cReceive, char *cSend)
gatedClock 1:15706d15d123 58 {
gatedClock 6:b480fc4e87e5 59 *cReceive = 0; // clear receive byte.
gatedClock 12:a1b7ce9c1d64 60 for (dLoop01 = 7; dLoop01 >= 0; dLoop01--)// loop for 8 bits in the byte.
gatedClock 5:b14dcaae260e 61 {
gatedClock 5:b14dcaae260e 62 *pSCLK = 0; // SPI clock negedge.
gatedClock 5:b14dcaae260e 63 wait(fSPIquarterP); // until middle of clock low.
gatedClock 12:a1b7ce9c1d64 64 *pMOSI = (*cSend >> dLoop01) & 1; // assert MOSI.
gatedClock 15:d6cc57c4e23d 65 // capture MISO.
gatedClock 15:d6cc57c4e23d 66 *cReceive = *cReceive | (*pMISO << dLoop01);
gatedClock 15:d6cc57c4e23d 67 wait(fSPIquarterP); // finish-out cycle.
gatedClock 5:b14dcaae260e 68 *pSCLK = 1; // SPI clock posedge.
gatedClock 15:d6cc57c4e23d 69 wait(fSPIquarterP); // finish-out cycle.
gatedClock 5:b14dcaae260e 70 wait(fSPIquarterP); // finish-out cycle.
gatedClock 5:b14dcaae260e 71 }
gatedClock 1:15706d15d123 72 }
gatedClock 5:b14dcaae260e 73 //----------------------------------------------//------------------------------
gatedClock 7:b3e8b537d5c2 74 // transceive a character array.
gatedClock 7:b3e8b537d5c2 75 // limit is 256 characters.
gatedClock 7:b3e8b537d5c2 76 // MSB out/in first.
gatedClock 7:b3e8b537d5c2 77 void mmSPI::transceive_vector(char *cReceive, char *cSend, char cNumBytes)
gatedClock 13:3e6886a96aea 78 {
gatedClock 13:3e6886a96aea 79 // the first SPI pulse after the
gatedClock 13:3e6886a96aea 80 // CPU clock goes low is used for
gatedClock 13:3e6886a96aea 81 // parallel-load of the SPI shadow
gatedClock 13:3e6886a96aea 82 // registers, not for shifting.
gatedClock 13:3e6886a96aea 83 if (0)
gatedClock 13:3e6886a96aea 84 {
gatedClock 13:3e6886a96aea 85 *pSCLK = 1;
gatedClock 13:3e6886a96aea 86 wait(fSPIquarterP);
gatedClock 13:3e6886a96aea 87 wait(fSPIquarterP);
gatedClock 13:3e6886a96aea 88 *pSCLK = 0;
gatedClock 13:3e6886a96aea 89 wait(fSPIquarterP);
gatedClock 13:3e6886a96aea 90 wait(fSPIquarterP);
gatedClock 13:3e6886a96aea 91 }
gatedClock 13:3e6886a96aea 92
gatedClock 12:a1b7ce9c1d64 93 for (dLoop02 = (cNumBytes - 1); dLoop02 >= 0; dLoop02--)
gatedClock 12:a1b7ce9c1d64 94 transceive_byte(&(cReceive[dLoop02]), &(cSend[dLoop02]));
gatedClock 13:3e6886a96aea 95
gatedClock 15:d6cc57c4e23d 96
gatedClock 13:3e6886a96aea 97
gatedClock 13:3e6886a96aea 98 *pCPUclk = 1; // pulse the CPU clock.
gatedClock 13:3e6886a96aea 99 wait(fSPIquarterP);
gatedClock 13:3e6886a96aea 100 wait(fSPIquarterP);
gatedClock 13:3e6886a96aea 101 *pCPUclk = 0;
gatedClock 13:3e6886a96aea 102 wait(fSPIquarterP);
gatedClock 13:3e6886a96aea 103 wait(fSPIquarterP);
gatedClock 7:b3e8b537d5c2 104 }
gatedClock 7:b3e8b537d5c2 105 //----------------------------------------------//------------------------------
gatedClock 9:0551307e3b15 106 // transceive a character array.
gatedClock 9:0551307e3b15 107 // limit is 256 characters.
gatedClock 9:0551307e3b15 108 // MSB out/in first.
gatedClock 9:0551307e3b15 109 void mmSPI::test_toggle_cpu_clock(void)
gatedClock 9:0551307e3b15 110 {
gatedClock 11:17207edac925 111 DigitalOut led0(LED4);
gatedClock 9:0551307e3b15 112 while (1)
gatedClock 9:0551307e3b15 113 {
gatedClock 11:17207edac925 114 *pCPUclk = 1; led0 = 1;
gatedClock 9:0551307e3b15 115 wait(1.0);
gatedClock 11:17207edac925 116 *pCPUclk = 0; led0 = 0;
gatedClock 9:0551307e3b15 117 wait(1.0);
gatedClock 9:0551307e3b15 118 }
gatedClock 9:0551307e3b15 119 }
gatedClock 9:0551307e3b15 120 //----------------------------------------------//------------------------------
gatedClock 15:d6cc57c4e23d 121 void mmSPI::force_write(char cDataHIgh, char cDataLow, char cAddress)
gatedClock 15:d6cc57c4e23d 122 {
gatedClock 15:d6cc57c4e23d 123 char pcReceive[8];
gatedClock 15:d6cc57c4e23d 124 char pcSend [8];
gatedClock 15:d6cc57c4e23d 125 int dLoop;
gatedClock 15:d6cc57c4e23d 126
gatedClock 15:d6cc57c4e23d 127 for (dLoop = 0; dLoop < 8; dLoop++) pcSend[dLoop] = 0;
gatedClock 15:d6cc57c4e23d 128
gatedClock 15:d6cc57c4e23d 129
gatedClock 15:d6cc57c4e23d 130 // high data to R2.
gatedClock 15:d6cc57c4e23d 131 pcSend[7] = 0x02; pcSend[1] = 0xA8; pcSend[0] = cDataHIgh;
gatedClock 15:d6cc57c4e23d 132 transceive_vector(pcReceive, pcSend, 8);
gatedClock 5:b14dcaae260e 133
gatedClock 5:b14dcaae260e 134
gatedClock 15:d6cc57c4e23d 135 // low data to R1.
gatedClock 15:d6cc57c4e23d 136 pcSend[7] = 0x02; pcSend[1] = 0xA4; pcSend[0] = cDataLow;
gatedClock 15:d6cc57c4e23d 137 transceive_vector(pcReceive, pcSend, 8);
gatedClock 15:d6cc57c4e23d 138
gatedClock 15:d6cc57c4e23d 139
gatedClock 15:d6cc57c4e23d 140 // address to R3.
gatedClock 15:d6cc57c4e23d 141 pcSend[7] = 0x02; pcSend[1] = 0xAC; pcSend[0] = cAddress;
gatedClock 15:d6cc57c4e23d 142 transceive_vector(pcReceive, pcSend, 8);
gatedClock 15:d6cc57c4e23d 143
gatedClock 15:d6cc57c4e23d 144
gatedClock 15:d6cc57c4e23d 145
gatedClock 15:d6cc57c4e23d 146 pcSend[7] = 0x02; pcSend[1] = 0x02; pcSend[0] = 0; // WE high.
gatedClock 15:d6cc57c4e23d 147 transceive_vector(pcReceive, pcSend, 8);
gatedClock 15:d6cc57c4e23d 148
gatedClock 15:d6cc57c4e23d 149 pcSend[7] = 0x02; pcSend[1] = 0x00; pcSend[0] = 0; // WE low.
gatedClock 15:d6cc57c4e23d 150 transceive_vector(pcReceive, pcSend, 8);
gatedClock 15:d6cc57c4e23d 151
gatedClock 15:d6cc57c4e23d 152 }
gatedClock 15:d6cc57c4e23d 153 //----------------------------------------------//------------------------------
gatedClock 14:35717622a4fb 154
gatedClock 15:d6cc57c4e23d 155 void mmSPI::force_read(char cAddress)
gatedClock 15:d6cc57c4e23d 156 {
gatedClock 15:d6cc57c4e23d 157 char pcReceive[8];
gatedClock 15:d6cc57c4e23d 158 char pcSend [8];
gatedClock 15:d6cc57c4e23d 159 int dLoop;
gatedClock 15:d6cc57c4e23d 160
gatedClock 15:d6cc57c4e23d 161 for (dLoop = 0; dLoop < 8; dLoop++) pcSend[dLoop] = 0;
gatedClock 15:d6cc57c4e23d 162
gatedClock 15:d6cc57c4e23d 163
gatedClock 15:d6cc57c4e23d 164
gatedClock 15:d6cc57c4e23d 165
gatedClock 15:d6cc57c4e23d 166 // address to R3.
gatedClock 15:d6cc57c4e23d 167 pcSend[7] = 0x02; pcSend[1] = 0xAC; pcSend[0] = cAddress;
gatedClock 15:d6cc57c4e23d 168 transceive_vector(pcReceive, pcSend, 8);
gatedClock 15:d6cc57c4e23d 169
gatedClock 15:d6cc57c4e23d 170 // R2 gets data-H from memory.
gatedClock 15:d6cc57c4e23d 171 pcSend[7] = 0x02; pcSend[1] = 0xC8; pcSend[0] = cAddress;
gatedClock 15:d6cc57c4e23d 172 transceive_vector(pcReceive, pcSend, 8);
gatedClock 15:d6cc57c4e23d 173
gatedClock 15:d6cc57c4e23d 174 // R1 gets data-L from memory.
gatedClock 15:d6cc57c4e23d 175 pcSend[7] = 0x02; pcSend[1] = 0xC4; pcSend[0] = cAddress;
gatedClock 15:d6cc57c4e23d 176 transceive_vector(pcReceive, pcSend, 8);
gatedClock 15:d6cc57c4e23d 177
gatedClock 15:d6cc57c4e23d 178
gatedClock 15:d6cc57c4e23d 179
gatedClock 15:d6cc57c4e23d 180
gatedClock 15:d6cc57c4e23d 181 // pcSend[7] = 0x02; // force IR.
gatedClock 15:d6cc57c4e23d 182 // pcSend[1] = 0xA4; // R1 <- immediate.
gatedClock 15:d6cc57c4e23d 183 // pcSend[0] = 0xEE; // immediate value.
gatedClock 15:d6cc57c4e23d 184 /// transceive_vector(pcReceive, pcSend, 8);
gatedClock 15:d6cc57c4e23d 185
gatedClock 15:d6cc57c4e23d 186
gatedClock 15:d6cc57c4e23d 187
gatedClock 15:d6cc57c4e23d 188 // no-op scan.
gatedClock 15:d6cc57c4e23d 189 pcSend[7] = 0x02; pcSend[1] = 0x0; pcSend[0] = 0;
gatedClock 15:d6cc57c4e23d 190 transceive_vector(pcReceive, pcSend, 8);
gatedClock 15:d6cc57c4e23d 191
gatedClock 15:d6cc57c4e23d 192 }
gatedClock 14:35717622a4fb 193 //----------------------------------------------//------------------------------
gatedClock 5:b14dcaae260e 194
gatedClock 5:b14dcaae260e 195
gatedClock 5:b14dcaae260e 196
gatedClock 5:b14dcaae260e 197
gatedClock 5:b14dcaae260e 198
gatedClock 5:b14dcaae260e 199
gatedClock 5:b14dcaae260e 200
gatedClock 7:b3e8b537d5c2 201
gatedClock 7:b3e8b537d5c2 202
gatedClock 7:b3e8b537d5c2 203
gatedClock 7:b3e8b537d5c2 204
gatedClock 7:b3e8b537d5c2 205
gatedClock 15:d6cc57c4e23d 206
gatedClock 15:d6cc57c4e23d 207
gatedClock 15:d6cc57c4e23d 208
gatedClock 15:d6cc57c4e23d 209
gatedClock 15:d6cc57c4e23d 210
gatedClock 15:d6cc57c4e23d 211
gatedClock 15:d6cc57c4e23d 212
gatedClock 15:d6cc57c4e23d 213
gatedClock 15:d6cc57c4e23d 214
gatedClock 15:d6cc57c4e23d 215
gatedClock 15:d6cc57c4e23d 216
gatedClock 15:d6cc57c4e23d 217