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

mmSPI.cpp

Committer:
gatedClock
Date:
2013-08-18
Revision:
14:35717622a4fb
Parent:
13:3e6886a96aea
Child:
15:d6cc57c4e23d

File content as of revision 14:35717622a4fb:

/*----------------------------------------------//------------------------------
    student   : m-moore
    class     : external SPI interface
    directory : mmSPI
    file      : mmSPI.cpp
------------------------------------------------//----------------------------*/
    #include "mmSPI.h"
/*----------------------------------------------//------------------------------
------------------------------------------------//----------------------------*/
//==============================================//==============================
    mmSPI::mmSPI()                              // constructor.
    {
      allocations();                            // object allocations.
    }
//----------------------------------------------//------------------------------    
    mmSPI::~mmSPI()                             // destructor.
    {
                                                // deallocations.
      if (pMOSI)   {delete pMOSI;   pMOSI   = NULL;}
      if (pMISO)   {delete pMISO;   pMISO   = NULL;}
      if (pSCLK)   {delete pSCLK;   pSCLK   = NULL;}
      if (pCPUclk) {delete pCPUclk; pCPUclk = NULL;}
    } 
//----------------------------------------------//------------------------------
    void mmSPI::allocations(void)               // object allocations.
    {
      pMOSI   = new DigitalOut(mmSPI_MOSI);       // SPI MOSI pin object.
      if (!pMOSI) error("\n\r mmSPI::allocations : FATAL malloc error for pMOSI. \n\r"); 
      
      pMISO   = new DigitalOut(mmSPI_MISO);      // SPI MISO pin object.
      if (!pMISO) error("\n\r mmSPI::allocations : FATAL malloc error for pMISO. \n\r"); 
    
      pSCLK   = new DigitalOut(mmSPI_SCLK);       // SPI SCLK pin object.
      if (!pSCLK) error("\n\r mmSPI::allocations : FATAL malloc error for pSCLK. \n\r"); 
      
      pCPUclk = new DigitalOut(mmCPU_CLK);          // SPI SCLK pin object.
      if (!pCPUclk) error("\n\r mmSPI::allocations : FATAL malloc error for pCPUclk. \n\r");
    } 
//----------------------------------------------//------------------------------    
    void mmSPI::setSPIfrequency(float fFreq)    // set SPI clock frequency.
    {
      fSPIfreq = fFreq;                         // promote to object scope.
      if (fSPIfreq < .05)                       // don't get near divide-by-zero.
      error("\n\r mmSPI::setSPIfrequency : FATAL SPI frequency set too low. \n\r"); 
      fSPIquarterP = (1 / fSPIfreq) / 4;        // figure quarter-cycle period.
    }
//----------------------------------------------//------------------------------
//  we're not going for speed, so lets go for good setup / hold.

                                                // send/receive a byte over SPI.
                                                // MSB out/in first.
    void mmSPI::transceive_byte(char *cReceive, char *cSend)
    {
      *cReceive = 0;                            // clear receive byte.                                    
      for (dLoop01 = 7; dLoop01 >= 0; dLoop01--)// loop for 8 bits in the byte.
      {
        *pSCLK = 0;                             // SPI clock negedge.
        wait(fSPIquarterP);                     // until middle of clock low.
        *pMOSI = (*cSend >> dLoop01) & 1;       // assert MOSI.
        wait(fSPIquarterP);                     // MOSI setup time
        *pSCLK = 1;                             // SPI clock posedge.
        wait(fSPIquarterP);                     // MISO setup time.
        *cReceive = *cReceive | (*pMISO << dLoop01);
        wait(fSPIquarterP);                     // finish-out cycle.
      }
    }
//----------------------------------------------//------------------------------
                                                // transceive a character array.
                                                // limit is 256 characters.
                                                // MSB out/in first.
    void mmSPI::transceive_vector(char *cReceive, char *cSend, char cNumBytes)
    {       
                                                // the first SPI pulse after the
                                                // CPU clock goes low is used for
                                                // parallel-load of the SPI shadow
                                                // registers, not for shifting.
      if (0)
      {
        *pSCLK = 1;                              
        wait(fSPIquarterP); 
        wait(fSPIquarterP); 
        *pSCLK = 0;
        wait(fSPIquarterP); 
        wait(fSPIquarterP); 
      }
    
      for (dLoop02 = (cNumBytes - 1); dLoop02 >= 0; dLoop02--)
      transceive_byte(&(cReceive[dLoop02]), &(cSend[dLoop02]));
      
      *pSCLK = 0;                               // SPI clock rests low.
      
      *pCPUclk = 1;                             // pulse the CPU clock.
      wait(fSPIquarterP); 
      wait(fSPIquarterP);     
      *pCPUclk = 0;  
      wait(fSPIquarterP); 
      wait(fSPIquarterP); 
    }
//----------------------------------------------//------------------------------
                                                // transceive a character array.
                                                // limit is 256 characters.
                                                // MSB out/in first.
    void mmSPI::test_toggle_cpu_clock(void)
    {    
      DigitalOut led0(LED4);
      while (1)
      {
        *pCPUclk = 1;  led0 = 1;
        wait(1.0);
        *pCPUclk = 0;  led0 = 0;
        wait(1.0);
      }
    }
//----------------------------------------------//------------------------------


    
    
   




//----------------------------------------------//------------------------------