This is an involuntary fork, created because the repository would not update mmSPI. SPI library used to communicate with an altera development board attached to four zigbee-header pins.

Dependents:   Embedded_RTOS_Project

Fork of mmSPI by Mike Moore

Committer:
gatedClock
Date:
Tue Aug 20 14:02:56 2013 +0000
Revision:
21:e90dd0f8aaa1
Parent:
20:2d5cd38047ca
Child:
22:7524dee5c753
remove obsolete code.

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 16:0e422fd263c6 53 // transceive a character array.
gatedClock 16:0e422fd263c6 54 // limit is 256 characters.
gatedClock 16:0e422fd263c6 55 // MSB out/in first.
gatedClock 16:0e422fd263c6 56 void mmSPI::transceive_vector2(char *pcReceive, char *pcSend, int dNumBytes)
gatedClock 16:0e422fd263c6 57 {
gatedClock 16:0e422fd263c6 58 int dClear;
gatedClock 16:0e422fd263c6 59 int dIndex;
gatedClock 16:0e422fd263c6 60 int dMosiByteIndex;
gatedClock 16:0e422fd263c6 61 int dMosiBitIndex;
gatedClock 16:0e422fd263c6 62 int dMisoByteIndex;
gatedClock 16:0e422fd263c6 63 int dMisoBitIndex;
gatedClock 16:0e422fd263c6 64
gatedClock 16:0e422fd263c6 65 dIndex = (dNumBytes * 8) - 1;
gatedClock 16:0e422fd263c6 66 dMosiByteIndex = dIndex / 8;
gatedClock 16:0e422fd263c6 67 dMosiBitIndex = dIndex % 8;
gatedClock 16:0e422fd263c6 68
gatedClock 16:0e422fd263c6 69 for (dClear = 0; dClear < dNumBytes; dClear++) pcReceive[dClear] = 0;
gatedClock 16:0e422fd263c6 70
gatedClock 16:0e422fd263c6 71
gatedClock 16:0e422fd263c6 72 *pCPUclk = 1; // pulse the CPU clock.
gatedClock 16:0e422fd263c6 73 wait(fSPIquarterP);
gatedClock 16:0e422fd263c6 74 wait(fSPIquarterP);
gatedClock 16:0e422fd263c6 75 *pCPUclk = 0;
gatedClock 16:0e422fd263c6 76 wait(fSPIquarterP);
gatedClock 16:0e422fd263c6 77 wait(fSPIquarterP);
gatedClock 16:0e422fd263c6 78
gatedClock 16:0e422fd263c6 79 *pSCLK = 1; // pulse the SPI clock for parallel load.
gatedClock 16:0e422fd263c6 80 wait(fSPIquarterP);
gatedClock 16:0e422fd263c6 81 wait(fSPIquarterP);
gatedClock 16:0e422fd263c6 82 *pSCLK = 0;
gatedClock 16:0e422fd263c6 83 // pre-assert MOSI.
gatedClock 16:0e422fd263c6 84 *pMOSI = ((pcSend[dMosiByteIndex]) >> dMosiBitIndex) & 1;
gatedClock 16:0e422fd263c6 85 wait(fSPIquarterP);
gatedClock 16:0e422fd263c6 86 wait(fSPIquarterP);
gatedClock 16:0e422fd263c6 87
gatedClock 16:0e422fd263c6 88
gatedClock 16:0e422fd263c6 89 for (dIndex = (dNumBytes * 8) - 1; dIndex >= 0; dIndex--)
gatedClock 16:0e422fd263c6 90 {
gatedClock 16:0e422fd263c6 91 dMisoByteIndex = dIndex / 8;
gatedClock 16:0e422fd263c6 92 dMisoBitIndex = dIndex % 8;
gatedClock 18:4a29cad91540 93 pcReceive[dMisoByteIndex] = pcReceive[dMisoByteIndex] | (*pMISO << dMisoBitIndex);
gatedClock 16:0e422fd263c6 94 *pSCLK = 1;
gatedClock 16:0e422fd263c6 95 wait(fSPIquarterP);
gatedClock 16:0e422fd263c6 96 wait(fSPIquarterP);
gatedClock 16:0e422fd263c6 97 *pSCLK = 0;
gatedClock 16:0e422fd263c6 98
gatedClock 16:0e422fd263c6 99 if (dIndex < 0) dIndex = 0;
gatedClock 16:0e422fd263c6 100 dMosiByteIndex = (dIndex - 1) / 8;
gatedClock 16:0e422fd263c6 101 dMosiBitIndex = (dIndex - 1) % 8;
gatedClock 16:0e422fd263c6 102 *pMOSI = ((pcSend[dMosiByteIndex]) >> dMosiBitIndex) & 1;
gatedClock 16:0e422fd263c6 103 wait(fSPIquarterP);
gatedClock 16:0e422fd263c6 104 wait(fSPIquarterP);
gatedClock 16:0e422fd263c6 105 }
gatedClock 7:b3e8b537d5c2 106 }
gatedClock 7:b3e8b537d5c2 107 //----------------------------------------------//------------------------------
gatedClock 16:0e422fd263c6 108 void mmSPI::write_register(char cRegister, char cValue, char * pcReceive, char * pcSend)
gatedClock 16:0e422fd263c6 109 {
gatedClock 18:4a29cad91540 110 int dLoop; // loop index.
gatedClock 18:4a29cad91540 111
gatedClock 18:4a29cad91540 112 // clear transmit vector.
gatedClock 18:4a29cad91540 113 for (dLoop = 0; dLoop < 8; dLoop++) pcSend[dLoop] = 0x00;
gatedClock 18:4a29cad91540 114
gatedClock 18:4a29cad91540 115 pcSend[7] = 0x02; // mbed sends a command.
gatedClock 18:4a29cad91540 116
gatedClock 18:4a29cad91540 117 // align into instruction word.
gatedClock 16:0e422fd263c6 118 pcSend[1] = ((cRegister & 0x07) << 2) | 0xA0;
gatedClock 18:4a29cad91540 119 pcSend[0] = cValue & 0xFF; // immediate value to i.w.
gatedClock 17:b81c0c1f312f 120
gatedClock 18:4a29cad91540 121 transceive_vector2(pcReceive, pcSend, 8); // transmit command.
gatedClock 18:4a29cad91540 122
gatedClock 18:4a29cad91540 123 // clear transmit vector.
gatedClock 18:4a29cad91540 124 for (dLoop = 0; dLoop < 8; dLoop++) pcSend[dLoop] = 0x00;
gatedClock 17:b81c0c1f312f 125 }
gatedClock 17:b81c0c1f312f 126 //----------------------------------------------//------------------------------
gatedClock 17:b81c0c1f312f 127 // returns the content of
gatedClock 17:b81c0c1f312f 128 // a CPU register.
gatedClock 17:b81c0c1f312f 129 char mmSPI::read_register(char cRegister, char * pcReceive, char * pcSend)
gatedClock 17:b81c0c1f312f 130 {
gatedClock 19:c2b753533b93 131 int dLoop;
gatedClock 21:e90dd0f8aaa1 132
gatedClock 19:c2b753533b93 133
gatedClock 21:e90dd0f8aaa1 134 // send all 0.
gatedClock 18:4a29cad91540 135 for (dLoop = 0; dLoop < 8; dLoop++) pcSend[dLoop] = 0x00;
gatedClock 18:4a29cad91540 136
gatedClock 17:b81c0c1f312f 137 transceive_vector2(pcReceive, pcSend, 8); // snap & scan-out reg contents.
gatedClock 17:b81c0c1f312f 138
gatedClock 19:c2b753533b93 139 return (pcReceive[6 - cRegister]); // return the particular reg value.
gatedClock 17:b81c0c1f312f 140 }
gatedClock 17:b81c0c1f312f 141 //----------------------------------------------//------------------------------
gatedClock 18:4a29cad91540 142 void mmSPI::write_memory(char cHData, char cLdata, char cAddress, char * pcReceive, char * pcSend)
gatedClock 18:4a29cad91540 143 {
gatedClock 18:4a29cad91540 144 int dLoop; // loop index.
gatedClock 18:4a29cad91540 145
gatedClock 18:4a29cad91540 146 // clear transmit vector.
gatedClock 18:4a29cad91540 147 for (dLoop = 0; dLoop < 8; dLoop++) pcSend[dLoop] = 0x00;
gatedClock 19:c2b753533b93 148
gatedClock 18:4a29cad91540 149 // R3 <- address.
gatedClock 18:4a29cad91540 150 // R2 <- high-data.
gatedClock 18:4a29cad91540 151 // R1 <- low-data.
gatedClock 18:4a29cad91540 152 write_register(0x03,cAddress, pcReceive, pcSend);
gatedClock 20:2d5cd38047ca 153 write_register(0x02,cHData, pcReceive, pcSend);
gatedClock 20:2d5cd38047ca 154 write_register(0x01,cLdata, pcReceive, pcSend);
gatedClock 18:4a29cad91540 155
gatedClock 20:2d5cd38047ca 156 pcSend[7] = 0x00; // write-enable high.
gatedClock 20:2d5cd38047ca 157 pcSend[1] = 0x02;
gatedClock 20:2d5cd38047ca 158 pcSend[0] = 0x00;
gatedClock 20:2d5cd38047ca 159 transceive_vector2(pcReceive, pcSend, 8);
gatedClock 18:4a29cad91540 160
gatedClock 20:2d5cd38047ca 161 pcSend[7] = 0x00; // write-enable low.
gatedClock 20:2d5cd38047ca 162 pcSend[1] = 0x00;
gatedClock 20:2d5cd38047ca 163 pcSend[0] = 0x00;
gatedClock 20:2d5cd38047ca 164 transceive_vector2(pcReceive, pcSend, 8);
gatedClock 18:4a29cad91540 165
gatedClock 18:4a29cad91540 166 // clear transmit vector.
gatedClock 18:4a29cad91540 167 for (dLoop = 0; dLoop < 8; dLoop++) pcSend[dLoop] = 0x00;
gatedClock 19:c2b753533b93 168
gatedClock 18:4a29cad91540 169 }
gatedClock 18:4a29cad91540 170 //----------------------------------------------//------------------------------
gatedClock 18:4a29cad91540 171 // fetch a word from main memory.
gatedClock 18:4a29cad91540 172 unsigned int mmSPI::read_memory(char cAddress, char * pcReceive, char * pcSend)
gatedClock 18:4a29cad91540 173 {
gatedClock 18:4a29cad91540 174 int dLoop; // loop index.
gatedClock 18:4a29cad91540 175 unsigned int udMemoryContent; // return variable.
gatedClock 18:4a29cad91540 176 char cHData; // returned data-high.
gatedClock 18:4a29cad91540 177 char cLData; // returned data-low.
gatedClock 18:4a29cad91540 178
gatedClock 18:4a29cad91540 179 // clear transmit vector.
gatedClock 18:4a29cad91540 180 for (dLoop = 0; dLoop < 8; dLoop++) pcSend[dLoop] = 0x00;
gatedClock 21:e90dd0f8aaa1 181
gatedClock 19:c2b753533b93 182
gatedClock 18:4a29cad91540 183 // R3 <- address.
gatedClock 18:4a29cad91540 184 write_register(0x03,cAddress, pcReceive, pcSend);
gatedClock 18:4a29cad91540 185
gatedClock 18:4a29cad91540 186 pcSend[7] = 0x02; // mbed sends command.
gatedClock 20:2d5cd38047ca 187 pcSend[1] = 0xC8; // R2 <- MM[R3]
gatedClock 18:4a29cad91540 188 pcSend[0] = 0x00;
gatedClock 18:4a29cad91540 189 transceive_vector2(pcReceive, pcSend, 8); // send command.
gatedClock 18:4a29cad91540 190
gatedClock 18:4a29cad91540 191 pcSend[7] = 0x02; // mbed sends command.
gatedClock 20:2d5cd38047ca 192 pcSend[1] = 0xC4; // R1 <- MM[R3]
gatedClock 18:4a29cad91540 193 pcSend[0] = 0x00;
gatedClock 18:4a29cad91540 194 transceive_vector2(pcReceive, pcSend, 8); // send command.
gatedClock 18:4a29cad91540 195
gatedClock 18:4a29cad91540 196 // obtain MM content.
gatedClock 20:2d5cd38047ca 197 cHData = read_register(0x02, pcReceive, pcSend);
gatedClock 20:2d5cd38047ca 198 cLData = read_register(0x01, pcReceive, pcSend);
gatedClock 18:4a29cad91540 199
gatedClock 18:4a29cad91540 200
gatedClock 18:4a29cad91540 201 udMemoryContent = (cHData << 8) + cLData; // build the memory word.
gatedClock 18:4a29cad91540 202
gatedClock 18:4a29cad91540 203 // clear transmit vector.
gatedClock 18:4a29cad91540 204 for (dLoop = 0; dLoop < 8; dLoop++) pcSend[dLoop] = 0x00;
gatedClock 18:4a29cad91540 205
gatedClock 18:4a29cad91540 206 return udMemoryContent; // return the memory word.
gatedClock 18:4a29cad91540 207 }
gatedClock 18:4a29cad91540 208 //----------------------------------------------//------------------------------
gatedClock 17:b81c0c1f312f 209
gatedClock 17:b81c0c1f312f 210
gatedClock 5:b14dcaae260e 211
gatedClock 5:b14dcaae260e 212
gatedClock 5:b14dcaae260e 213
gatedClock 5:b14dcaae260e 214
gatedClock 5:b14dcaae260e 215
gatedClock 5:b14dcaae260e 216
gatedClock 5:b14dcaae260e 217
gatedClock 7:b3e8b537d5c2 218
gatedClock 7:b3e8b537d5c2 219
gatedClock 7:b3e8b537d5c2 220
gatedClock 7:b3e8b537d5c2 221
gatedClock 7:b3e8b537d5c2 222
gatedClock 15:d6cc57c4e23d 223