Beispiel #1
0
/*****************************************************************************
  Function:
	void WF_SpiEnableChipSelect(void)

  Summary:
	Enables the MRF24WB0M SPI chip select.

  Description:
	Enables the MRF24WB0M SPI chip select as part of the sequence of SPI 
	communications.

  Precondition:
	None

  Parameters:
	None

  Returns:
  	None
  	
  Remarks:
	If the SPI bus is shared with other peripherals then the current SPI context
	is saved.
*****************************************************************************/
void WF_SpiEnableChipSelect(void)
{
    #if defined(__18CXX)    
    static volatile UINT8 dummy;    
    #endif

    #if defined(SPI_IS_SHARED)    
    SaveSpiContext();
    ConfigureSpiMRF24WB0M();
    #endif     

    /* set Slave Select low (enable SPI chip select on MRF24WB0M) */
    WF_CS_IO = 0;
    
    /* clear any pending interrupts */
    #if defined(__18CXX)
        dummy = WF_SSPBUF;
        ClearSPIDoneFlag();
    #endif
    

}    
/*****************************************************************************
 * FUNCTION: zgHALSpiTxRx
 *
 * RETURNS:  True is successful, else False
 *
 * PARAMS:   None
 *
 *  NOTES: SPI Tx/Rx mechansim between Host CPU and ZG2100.
 *****************************************************************************/
tZGBool zgHALSpiTxRx(tZGVoidInput)
{
    #if defined(__18CXX)
        volatile tZGU8 dummy;
    #endif
    tZGU16 numRxPreambleBytes, numTxPreambleBytes;
    tZGU16 numRxDataBytes, numTxDataBytes;
    tZGU16 totalNumBytes;
    tZGU8 *p_txPreBuf, *p_rxPreBuf;
    tZGU8 *p_txDataBuf, *p_rxDataBuf;
    tZGU8 ROM *p_txDataRomBuf;
    tZGU8 romFlag;
    tZGU8 rxTrash;

    numRxPreambleBytes = SPICXT.rxPreambleLength;
    numTxPreambleBytes = SPICXT.txPreambleLength;

    numRxDataBytes     = SPICXT.rxBufferLength + SPICXT.excessRxLength;
    numTxDataBytes     = SPICXT.txLength;

    p_rxPreBuf         = SPICXT.pRxPreambleBuffer;
    p_txPreBuf         = SPICXT.pTxPreambleBuffer;

    p_txDataBuf        = SPICXT.pTxBuffer;
    p_txDataRomBuf     = SPICXT.pTxRomBuffer;
    p_rxDataBuf        = SPICXT.pRxBuffer;
    
    // if more tx bytes than rx bytes, or the same count for both
    if ( (numTxPreambleBytes + numTxDataBytes) >= (numRxPreambleBytes + numRxDataBytes) )
    {
        totalNumBytes = numTxPreambleBytes + numTxDataBytes;
    }    
    // else more rx bytes than tx bytes
    else
    {
        totalNumBytes = numRxPreambleBytes + numRxDataBytes;        
    } 
    
    // if any tx data
    if (numTxDataBytes > 0u)
    {
        // if using tx RAM buffer
        if (SPICXT.pTxBuffer != 0u)
        {
            romFlag = kZGBoolFalse;
        }
        else if (SPICXT.pTxRomBuffer != 0u)
        {
            romFlag = kZGBoolTrue;
        }    
        else
        {
            ZGSYS_DRIVER_ASSERT(5, (ROM char *)"SpiTxRx: Invalid Tx pointer.\n");
        }    
            
    }       

    spiSuppressDoneHandlerCall = SPICXT.suppressDoneHandlerCall;
    SPICXT.suppressDoneHandlerCall = FALSE;  // set back to default state of false, only raw txrx will set true

#ifndef DEDICATED_SPI_ZG
    // Save SPI context so we can restore it to function entry state at end of this function
    SaveSpiContext();

    /*---------------------------------------------*/
    /* Configure SPI I/O for ZG2100 communications */
    /*---------------------------------------------*/
    /* enable the SPI clocks */
    /* set as master */
    /* clock idles high */
    /* ms bit first */
    /* 8 bit tranfer length */
    /* data changes on falling edge */
    /* data is sampled on rising edge */
    /* set the clock divider */
    // Set up SPI
    #if defined(__18CXX)
        ZG_SPICON1 = 0x30;      // SSPEN bit is set, SPI in master mode, (0x30 is for FOSC/4),
                                //   IDLE state is high level (0x32 is for FOSC/64)
        ZG_SPISTATbits.CKE = 0; // Transmit data on falling edge of clock
        ZG_SPISTATbits.SMP = 1; // Input sampled at end? of data output time
    #elif defined(__C30__)
        ZG_SPICON1 = 0x027B;    // Fcy Primary prescaler 1:1, secondary prescaler 2:1, CKP=1, CKE=0, SMP=1
        ZG_SPICON2 = 0x0000;
        ZG_SPISTAT = 0x8000;    // Enable the module
    #elif defined( __PIC32MX__ )
        ZG_SPI_BRG = (GetPeripheralClock()-1ul)/2ul/ZG_MAX_SPI_FREQ;
        ZG_SPICON1 = 0x00000260;    // sample at end, data change idle to active, clock idle high, master
        ZG_SPICON1bits.ON = 1;
    #else
        #error Configure SPI for the selected processor
    #endif
#endif /* DEDICATED_SPI_ZG */

    /* set SS low */
    ZG_CS_IO = 0;

    /* clear any pending interrupts */
    #if defined(__18CXX)
        dummy = ZG_SSPBUF;
        ClearSPIDoneFlag();
    #endif

    // while Tx and/or Rx bytes left to handle
    while (totalNumBytes > 0u)
    {
#if 0
        {
            unsigned short i = 400;  // 0x40; fails on PIC18
            while(i--)
            {
                Nop();
                Nop();
            }
        }    
#endif                
        
        // if still outputting tx preamble bytes
        if (numTxPreambleBytes > 0u)
        {
            --numTxPreambleBytes;
            ZG_SSPBUF = *p_txPreBuf++;
        }
        // else if still outputting tx data bytes
        else if (numTxDataBytes > 0u)
        {
            --numTxDataBytes;
            // if outputting from RAM buffer
            if (!romFlag)
            {
                ZG_SSPBUF = *p_txDataBuf++;
            }        
            // else outputting from ROM buffer
            else
            {
                ZG_SSPBUF = *p_txDataRomBuf++;
            }    
        }       
        // else there were no Tx bytes to output or we are done, so just stuff an FF into SPI tx register
        else
        {
           ZG_SSPBUF = 0xff; 
        }    
        
        // wait until tx/rx byte completely clocked out
        WaitForDataByte();
         
        
        // if still reading Rx preamble bytes
        if (numRxPreambleBytes > 0u)
        {
            --numRxPreambleBytes;
            *p_rxPreBuf++ = ZG_SSPBUF;
        }   
        // else if still reading Rx data bytes 
        else if (numRxDataBytes > 0u)
        {
            --numRxDataBytes;
            *p_rxDataBuf++ = ZG_SSPBUF;
        }  
        // else done with Rx data
        else
        {
            // throw away rx byte
            rxTrash = ZG_SSPBUF;
            
        }      
        
        --totalNumBytes;
    } // end while    


    /* Disable the interrupt */
    #if defined( __PIC32MX__ )
        ZG_SPI_IE_CLEAR = ZG_SPI_INT_BITS;
    #else
        ZG_SPI_IE = 0;
    #endif

    /* set SS high */
    ZG_CS_IO = 1;

    if ( !spiSuppressDoneHandlerCall )
    {
        zgDriverSpiTxRxDoneHandler();
    }


    #ifndef DEDICATED_SPI_ZG
        // Restore SPI I/O state to what it was when this function was entered
        RestoreSpiContext();
    #endif

    return kZGBoolTrue;
}