📄 drivers.c
字号:
/**************************************************************
* 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.
**************************************************************/
/**************************************************************
* Includes
**************************************************************/
#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 "simple_phy.h"
/**************************************************************
* Defines
**************************************************************/
#define AssertCE MC13192_CE = 0 /* Asserts the MC13192 CE pin */
#define DeAssertCE MC13192_CE = 1 /* Deasserts the MC13192 CE pin */
#define SPIClkInvert SPIC1 |= 0x04; /*Set CPHA bit of SPCR (clk polarity) */
#define SPIClkNormal SPIC1 &= 0xFB; /*clr CPHA bit of SPCR (clk polarity) */
/**************************************************************
* Globals
**************************************************************/
rx_packet_t *drv_rx_packet;
cca_measurement_t drv_cca_reading;
__uint8__ irq_value = 0;
extern byte rtx_mode;
/**************************************************************
* Interrupt: MC13192 initiated interrupt handler
* Parameters: none
* Return: The interrupt will RTI unless valid data is recvd.
* In this case a pd_data_indication function call-back
* will be executed first, followed by a RTI
**************************************************************/
interrupt void irq_isr(void)
{
/* The vector is defined in vectortable.c */
volatile __uint16__ status_content, reg; /* Result of the status register read. */
__uint8__ dataLength = 0; /* Data length for the RX packet */
CLEAR_IRQ_FLAG; /* Acknowledge the interrupt. MC13192 IRQ pin still low. */
status_content = drv_read_spi_1(STATUS_ADDR); /* Read the MC13192 status register. */
/* Replace this with C code, if possible!!!!!!!!!!!!*/
/* Test for IRQ glitch or possible fast double IRQ. */
asm
{
BIH irq_high
}
/* IRQ is low. Re-read status. */
CLEAR_IRQ_FLAG; /* Acknowledge the interrupt. MC13192 IRQ pin still low. */
reg = drv_read_spi_1(STATUS_ADDR); /* Read the MC13192 status register. */
status_content = status_content | reg; /* Actual status is the OR of both. */
asm
{
irq_high:
}
status_content &= TX_IRQ_MASK | RX_IRQ_MASK | ATTN_IRQ_MASK | CRC_VALID_MASK | TIMER1_IRQ_MASK | CCA_IRQ_MASK | LO_LOCK_IRQ_MASK;
if (rtx_mode != RX_MODE_WTO)
{
/* If timeout not being used, mask out timer. */
status_content &= ~(TIMER1_IRQ_MASK);
}
if ((status_content & ~(CRC_VALID_MASK)) == 0)
{
/* If no status bits are set just return. */
return;
}
/* DOZE Complete Interrupt */
if ((status_content & DOZE_IRQ_MASK) != 0)
{
/* Not implemented!!!!!!!!!!!!!! */
}
/* ATTN IRQ Handler*/
if ((status_content & 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. */
status_content = drv_read_spi_1(RESIND_ADDR); /* Read the MC13192 reset indicator register. */
status_content &= RESET_BIT_MASK;
if (status_content == 0) /* Reset */
{
rtx_mode = MC13192_RESET_MODE; /* Set the rtx_state mirror to idle with attn. */
PLME_MC13192_reset_indication();
return;
}
else
{
rtx_mode = IDLE_MODE_ATTN; /* Set the rtx_state mirror to idle with attn. */
return;
}
}
/* TIMER1 IRQ Handler (Used for receiver timeout notification) */
if ((status_content & TIMER1_IRQ_MASK) != 0)
{
/* If a timeout (and timeout enabled) is done, update the mode mirror state. */
if (rtx_mode == RX_MODE_WTO)
{
/* Clear Timer1 if in RX_MODE_WTO */
drv_write_spi_1(T1_HI_ADDR, 0x8000); /* Disables TC1 and clears the IRQ. */
drv_write_spi_1(T1_LO_ADDR, 0x0000);
drv_rx_packet->status = TIMEOUT;
DeAssertRTXEN(); /* Forces the MC13192 to idle. */
rtx_mode = IDLE_MODE;
/* TIMEOUT notification */
pd_data_indication();
return;
}
}
/* LO LOCK IRQ - Occurs when MC13192 loses LOCK */
/* For receive cycles, re-enable. For transmit/CCA, abort. */
if ((status_content & LO_LOCK_IRQ_MASK) != 0)
{
DeAssertRTXEN(); /* Forces the MC13192 to idle. */
if ((rtx_mode == RX_MODE) || (rtx_mode == RX_MODE_WTO) || (rtx_mode == CCA_MODE)) /* Unlock from receive cycles */
{
status_content = (drv_read_spi_1(MODE_ADDR) & 0xFF7F); /* Read the MC13192 trx register. Timer trigger off. */
drv_write_spi_1(MODE_ADDR, status_content); /* Re-write the trx register. */
AssertRTXEN(); /* Re-start the sequence. */
}
else
{
rtx_mode = IDLE_MODE;
}
return;
}
if ((rtx_mode == IDLE_MODE) || ((status_content & CCA_IRQ_MASK) != 0) || ((status_content & TX_IRQ_MASK) != 0))
{
/* If in idle mode already or if CCA or TX is done, just return. */
DeAssertRTXEN(); /* Forces the MC13192 to idle. */
rtx_mode = IDLE_MODE;
return;
}
/* If rx is done */
if ((status_content & RX_IRQ_MASK) != 0)
{
DeAssertRTXEN(); /* Forces the MC13192 to idle. */
if ((status_content & CRC_VALID_MASK) == 0)
{
/* If an invalid CRC, restart receiver. */
status_content = (drv_read_spi_1(MODE_ADDR) & 0xFF7F); /* Read the MC13192 trx register. Timer trigger off. */
drv_write_spi_1(MODE_ADDR, status_content); /* Update the trx register. */
AssertRTXEN(); /* Forces the MC13192 to enter the receive mode. */
return;
}
else
{
dataLength = (__uint8__) (drv_read_spi_1(RX_PKT_LEN) & 0x7F); /* Read received packet length register and mask off length bits */
if (dataLength < 3) /* Rx_pkt_length is bad when 0, 1 or 2. */
{
status_content = (drv_read_spi_1(MODE_ADDR) & 0xFF7F); /* Read the MC13192 trx register. Timer trigger off. */
drv_write_spi_1(MODE_ADDR, status_content); /* Update the trx register. */
AssertRTXEN(); /* Forces the MC13192 to enter the receive mode. */
return;
}
/* A valid packet has been received. */
rtx_mode = IDLE_MODE; /* set the rtx_state to idle */
drv_write_spi_1(T1_HI_ADDR, 0x8000); /* Disables TC1 and clears the IRQ. */
drv_write_spi_1(T1_LO_ADDR, 0x0000);
drv_rx_packet->dataLength = dataLength;
drv_rx_packet->status = SUCCESS;
pd_data_indication(); /* Notify PHY that there is data available. */
return;
}
}
}
/**************************************************************
* Function: Wake the MC13192 from Hibernate/Doze mode
* Parameters: none
* Return:
**************************************************************/
void Wake_MC13192 (void)
{
MC13192_ATTN = 0; /* Assert ATTN */
MC13192_ATTN = 1; /* Deassert ATTN */
}
/**************************************************************
* Function: Deassert the MC13192 RTXEN pin (forces IC to idle)
* Parameters: none
* Return:
**************************************************************/
void DeAssertRTXEN(void)
{
MC13192_RTXEN = 0; /* Deassert RTXEN */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -