📄 drivers.c
字号:
/**
* Copyright (c) 2004, Freescale Semiconductor
* Freescale Confidential Proprietary
*
* File name : drivers.c
* Project name: SMAC (Simple Media Access Controller)
*
* Department : Freescale Radio Products Division
*
* Description : This is the SMAC C source driver file for the HC(S)08 MCU and
* MC13192 transceiver.
* 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.
*
* $Author: r01160 $
* $Date: 2005/07/29 03:30:40 $
* $Name: $
*/
#include "device_header.h"
#include "pub_def.h"
#include "drivers.h"
#include "MC13192_regs.h"
#include "MC13192_hw_config.h"
#include "mcu_hw_config.h"
#include "mcu_spi_config.h"
#include "simple_phy.h"
/* Globals */
tRxPacket *psDrvRxPacket;
tCCAMeasurement sDrvCCAReading; /* NOT USED */
UINT8 gu8IRQValue = 0;
extern UINT8 gu8RTxMode;
/*
* IRQIsr : MC13192 initiated IRQ interrupt handler
*
* Parameters : None
*
* 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.
*/
#if defined (HCS08G) | defined (HCS08R) | defined (_HCS12)
void interrupt IRQIsr(void)
#elif defined (_56F800E)
void IRQIsr(void)
#endif
{
/* The vector is defined in vectortable.c */
volatile UINT16 u16StatusContent, u16Reg, u16Temp; /*
* Result of the status register
* read
*/
UINT8 u8DataLength = 0; /* Data length for the RX packet */
#if defined (HCS08G) | defined (HCS08R)
CLEAR_IRQ_FLAG(); /* Acknowledge the interrupt. MC13192 IRQ pin still low. */
#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.
*/
}
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;
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)) {
/* 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)
{
/* 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 < 5) /* 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 */
u16Temp = SPIDrvRead2(RX_PKT); /* Get the code bytes */
if (u16Temp != 0xFF7E)
{
/* 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;
}
}
}
/*
* SPIDrvWrite : Write 1 word to SPI
*
* Parameters : u8Addr - SPI address
* u16Content - Data to send
*
* Return : None
*/
void SPIDrvWrite(UINT8 u8Addr, UINT16 u16Content)
{
UINT8 u8TempValue;
SPIClearRecieveStatReg(); /* Clear status register (possible SPRF, SPTEF) */
SPIClearRecieveDataReg(); /*
* Clear receive data register. SPI entirely ready
* for read or write
*/
MC13192DisableInterrupts(); /* Necessary to prevent double SPI access */
AssertCE(); /* Enables MC13192 SPI */
SPISendChar((UINT8)(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(); /*
* 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(); /*
* 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(); /*
* Clear receive data register. SPI entirely
* ready for read or write
*/
DeAssertCE(); /* Disables MC13192 SPI */
MC13192RestoreInterrupts(); /* Restore MC13192 interrupt status */
}
/*
* SPIDrvRead : Read 1 word from SPI
*
* Parameters : u8Addr - SPI address
*
* Return : u16Data - u16Data[0] is the MSB, u16Data[1] is the LSB
*/
UINT16 SPIDrvRead(UINT8 u8Addr)
{
UINT8 u8TempValue;
UINT16 u16Data; /* u16Data[0] is MSB, u16Data[1] is LSB */
SPIClearRecieveStatReg(); /* Clear status register (possible SPRF, SPTEF) */
SPIClearRecieveDataReg(); /*
* Clear receive data register. SPI entirely
* ready for read or write
*/
MC13192DisableInterrupts(); /* Necessary to prevent double SPI access */
AssertCE(); /* Enables MC13192 SPI */
SPISendChar((UINT8)((u8Addr & 0x3f) | 0x80)); /* Mask address, 6bit addr, Set
* read bit.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -