/***************************************************************************** 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; }