📄 drivers.c
字号:
/*!
* Copyright (c) 2005, Freescale Semiconductor
*
* Freescale Confidential Proprietary
* \file drivers.c
* \brief This is the SMAC C source driver file for the HC(S)08
* MCU and MC13192 transceiver.
* \author r01160
* \version 4.1a
* \date 2005/07/29 03:30:40
*
* \b Description:
*
* The driver controls all interfaces to/from the MC13192 by the SPI,
* selected interrupt source and MCU GPIO's assigned to other MC13192
* pins.The SMAC driver is the lowest layer of C code.
* Actual hardware interconnects from the MCU to the MC13192 are
* defined in the MC13192_hw_config.h header file.
*
* \b Department: Freescale Radio Products Division
*
* \b Project: SMAC (Simple Media Access Controller)
*
* \b History:
* - 16/11/2005 Doc. update to Doxygen compliant by Mario Rodriguez r12369c
*/
#include "mcu_hw_config.h"
#include "pub_def.h"
#include "drivers.h"
#include "simple_phy.h"
#include "MC13192_hw_config.h"
#include "MC13192_regs.h"
/* Globals */
tRxPacket *psDrvRxPacket; //!< Where the packet received will be stored
tCCAMeasurement sDrvCCAReading; //!< NOT USED
extern UINT8 gu8RTxMode; //!< Global mode mirror. MC13192 Status.
UINT8 gu8IRQValue = 0; //!< IRQ value
extern tPhyOptions gsPhyOptions;
volatile UINT16 u16StatusContent;
/*!
* \brief MC13192 initiated IRQ interrupt handler.
* The vector is defined in vectortable.c
*
* \return The interrupt will RTI unless valid data is recvd.
* In this case a PDDataIndication function call-back will be
* executed first, followed by a RTI.
*
*/
interrupt void IRQIsr(void)
{
/* Result of the status register read */
volatile UINT16 u16StatusContent, u16Reg, u16Temp;
/* Data length for the RX packet */
UINT8 u8DataLength = 0;
UINT8 u8MinLen = 0;
#if defined (HCS08G) | defined (HCS08R) | defined (HCS08Q)
/* Acknowledge the interrupt. MC13192 IRQ pin still low.*/
CLEAR_IRQ_FLAG();
#endif
u16StatusContent = SPIDrvRead(STATUS_ADDR); /*
* Read the MC13192 status
* register.
*/
/* Test for IRQ glitch or possible fast double IRQ. */
if(IRQPinLow()) //__isflag_int_enabled
{
CLEAR_IRQ_FLAG(); /* Acknowledge the interrupt. MC13192 IRQ pin still low. */
u16Reg = SPIDrvRead(STATUS_ADDR); /* Read the MC13192 status register. */
u16StatusContent = u16StatusContent | u16Reg; /*
* Actual status is the OR
* of both.
*/
}
if (gsPhyOptions.Bits.u1PromiscuousMode)
u8MinLen = 3;
else
u8MinLen = 5;
u16StatusContent &= TX_IRQ_MASK | RX_IRQ_MASK | ATTN_IRQ_MASK | \
CRC_VALID_MASK | TIMER1_IRQ_MASK | CCA_IRQ_MASK | \
LO_LOCK_IRQ_MASK | DOZE_IRQ_MASK | CCA_BIT_MASK;
if (gu8RTxMode != RX_MODE_WTO) {
/* If timeout not being used, mask out timer. */
u16StatusContent &= ~(TIMER1_IRQ_MASK);
}
if ((u16StatusContent & ~(CRC_VALID_MASK)) == 0) {
/* If no status bits are set just return. */
return;
}
/* DOZE Complete Interrupt */
if ((u16StatusContent & DOZE_IRQ_MASK) != 0) {
SPIDrvWrite(T2_HI_ADDR, 0x8000); /* disable the timer2 */
u16Temp= SPIDrvRead(MODE2_ADDR);
u16Temp &= 0xFFFC;
SPIDrvWrite(MODE2_ADDR, u16Temp);/* disable doze/hibernate modes */
gu8RTxMode = IDLE_MODE;
}
/* ATTN IRQ Handler*/
if ((u16StatusContent & ATTN_IRQ_MASK) != 0) {
/*
* If attn interrupt, set the rtx_state mirror.
* For MC13192 V2.x devices, read the reset indication in R25/7 first.
* If a reset is indicated, call back to a reset handler.
*/
u16StatusContent = SPIDrvRead(RESIND_ADDR); /*
* Read the MC13192 reset
* indicator register.
*/
u16StatusContent &= RESET_BIT_MASK;
if (u16StatusContent == 0) { /* Reset */
gu8RTxMode = MC13192_RESET_MODE; /*
* Set the rtx_state mirror to
* idle with attn.
*/
PLMEMC13192ResetIndication();
return;
}
else {
gu8RTxMode = IDLE_MODE_ATTN; /*
* Set the rtx_state mirror to idle
* with attn.
*/
return;
}
}
/* TIMER1 IRQ Handler (Used for receiver timeout notification) */
if ((u16StatusContent & TIMER1_IRQ_MASK) != 0) {
/* If timeout ocurs (and timeout enabled), update mode mirror state. */
if (gu8RTxMode == RX_MODE_WTO) {
/* Clear Timer1 if in RX_MODE_WTO */
SPIDrvWrite(T1_HI_ADDR, 0x8000); /* Disables TC1 and clears IRQ */
SPIDrvWrite(T1_LO_ADDR, 0x0000);
psDrvRxPacket->u8Status = TIMEOUT;
RTXENDeAssert(); /* Forces the MC13192 to idle. */
gu8RTxMode = IDLE_MODE;
PDDataIndication(); /* TIMEOUT notification */
return;
}
}
/* LO LOCK IRQ - Occurs when MC13192 loses LOCK */
/* For receive cycles, re-enable. For transmit/CCA, abort. */
if ((u16StatusContent & LO_LOCK_IRQ_MASK) != 0) {
RTXENDeAssert(); /* Forces the MC13192 to idle. */
/* Unlock from receive cycles */
if ((gu8RTxMode == RX_MODE) || (gu8RTxMode == RX_MODE_WTO) || \
(gu8RTxMode == CCA_MODE) || (gu8RTxMode == PULSE_TX_MODE)) {
/* Read the MC13192 trx register. Timer trigger off. */
u16StatusContent = (SPIDrvRead(MODE_ADDR) & 0xFF7F);
SPIDrvWrite(MODE_ADDR, u16StatusContent); /*
* Re-write the trx
* register.
*/
RTXENAssert(); /* Re-start the sequence. */
}
else {
gu8RTxMode = IDLE_MODE;
}
return;
}
if ((gu8RTxMode == IDLE_MODE) || ((u16StatusContent & CCA_IRQ_MASK) != 0) || \
((u16StatusContent & TX_IRQ_MASK) != 0)) {
/* If in idle mode already or if CCA or TX is done, just return. */
RTXENDeAssert(); /* Forces the MC13192 to idle. */
/* Check for Pulse TX Mode for PRBS9 Test mode sequence */
if (gu8RTxMode == PULSE_TX_MODE) {
u16StatusContent = (SPIDrvRead(MODE_ADDR) & 0xFF7F); /* Read the MC13192 trx register. Timer trigger off. */
SPIDrvWrite(MODE_ADDR, u16StatusContent); /* Re-write the trx register. */
RTXENAssert(); /* Re-start the sequence. */
#if defined (PA)
MC13192_PA_CTRL = PA_OFF; //Turn off the PA when TX is complete
#endif
return;
}
gu8RTxMode = IDLE_MODE;
return;
}
/* If rx is done */
if ((u16StatusContent & RX_IRQ_MASK) != 0)
{
RTXENDeAssert(); /* Forces the MC13192 to idle. */
if (((u16StatusContent & CRC_VALID_MASK) == 0) && ((gsPhyOptions.Bits.u1PromiscuousMode == FALSE)))
{
/* If an invalid CRC, restart receiver. */
/* Read the MC13192 trx register. Timer trigger off. */
u16StatusContent = (SPIDrvRead(MODE_ADDR) & 0xFF7F);
/* Update the trx register */
SPIDrvWrite(MODE_ADDR, u16StatusContent);
RTXENAssert(); /* Forces the MC13192 to enter the receive mode. */
return;
}
else {
/* Read received packet length register and mask off length bits */
u8DataLength = (UINT8) (SPIDrvRead(RX_PKT_LEN) & 0x7F);
if (u8DataLength < u8MinLen) /* Rx_pkt_length is bad when <5 because of CRC and byte codes. */
{
/* Read the MC13192 trx register. Timer trigger off. */
u16StatusContent = (SPIDrvRead(MODE_ADDR) & 0xFF7F);
/* Update the trx register. */
SPIDrvWrite(MODE_ADDR, u16StatusContent);
/* Forces the MC13192 to enter the receive mode. */
RTXENAssert();
return;
}
/* Test the Byte Codes */
if (gsPhyOptions.Bits.u1PromiscuousMode == 0)
{
u16Temp = SPIDrvRead2(RX_PKT); /* Get the code bytes */
if ((u16Temp != 0xFF7E) && ((gsPhyOptions.Bits.u1PromiscuousMode == FALSE)))
{
/* Read the MC13192 trx register. Timer trigger off. */
u16StatusContent = (SPIDrvRead(MODE_ADDR) & 0xFF7F);
/* Update the trx register. */
SPIDrvWrite(MODE_ADDR, u16StatusContent);
/* Forces the MC13192 to enter the receive mode. */
RTXENAssert();
return;
}
}
/* A valid packet has been received. */
gu8RTxMode = IDLE_MODE; /* Set the rtx_state to idle */
SPIDrvWrite(T1_HI_ADDR, 0x8000); /*
* Disables TC1 and clears the
* IRQ.
*/
SPIDrvWrite(T1_LO_ADDR, 0x0000);
psDrvRxPacket->u8DataLength = u8DataLength;
psDrvRxPacket->u8Status = SUCCESS;
PDDataIndication(); /* Notify PHY that there is data available. */
return;
}
}
}
/*!
* \brief SPIDrvWrite : Write 1 word to SPI
*
* \param u8Addr - SPI address
* \param u16Content - Data to send
*
*/
void SPIDrvWrite(UINT8 u8Addr, UINT16 u16Content)
{
UINT8 u8TempValue=0;
SPIClearRecieveStatReg(&u8TempValue); /* Clear status register (possible SPRF, SPTEF) */
SPIClearRecieveDataReg(&u8TempValue); /*
* Clear receive data register. SPI entirely ready
* for read or write
*/
MC13192DisableInterrupts(); /* Necessary to prevent double SPI access */
AssertCE(); /* Enables MC13192 SPI */
SPISendChar(u8Addr & 0x3F); /*
* Mask address, 6bit addr.
* Set write bit (i.e. 0).
*/
SPIWaitTransferDone(); /*
* For this bit to be set, SPTED MUST be set.
* Now write content MSB
*/
SPIClearRecieveDataReg(&u8TempValue); /*
* Clear receive data register. SPI entirely
* ready for read or write
*/
SPISendChar((UINT8)(u16Content >> 8)); /* Write MSB */
SPIWaitTransferDone(); /*
* For this bit to be set, SPTED MUST be set.
* Now write content LSB
*/
SPIClearRecieveDataReg(&u8TempValue); /*
* Clear receive data register. SPI entirely
* ready for read or write
*/
SPISendChar((UINT8)(u16Content & 0x00FF)); /* Write LSB */
SPIWaitTransferDone(); /*
* For this bit to be set, SPTED MUST be set.
* Now read last of garbage
*/
SPIClearRecieveDataReg(&u8TempValue); /*
* Clear receive data register. SPI entirely
* ready for read or write
*/
DeAssertCE(); /* Disables MC13192 SPI */
MC13192RestoreInterrupts(); /* Restore MC13192 interrupt status */
}
/*!
* \brief SPIDrvRead : Read 1 word from SPI
*
* \param u8Addr - SPI address
*
* \return u16Data - u16Data[0] is the MSB, u16Data[1] is the LSB
*/
UINT16 SPIDrvRead(UINT8 u8Addr)
{
UINT8 u8TempValue=0;
UINT16 u16Data=0; /* u16Data[0] is MSB, u16Data[1] is LSB */
SPIClearRecieveStatReg(&u8TempValue); /* Clear status register (possible SPRF, SPTEF) */
SPIClearRecieveDataReg(&u8TempValue); /*
* Clear receive data register. SPI entirely
* ready for read or write
*/
MC13192DisableInterrupts(); /* Necessary to prevent double SPI access */
AssertCE(); /* Enables MC13192 SPI */
SPISendChar((u8Addr & 0x3f) | 0x80); /* Mask address, 6bit addr, Set
* read bit.
*/
SPIWaitTransferDone(); /* For this bit to be set, SPTED MUST be set */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -