?? des_mc33696.c
字號:
/******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2006 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
***************************************************************************//*!
*
* @file echo.c
*
* @author b06050
*
* @version 0.1
*
* @date 5-18-2007
*
* @brief The code for the Echo/Echo+ software device driver for MC9S12XEP100
* based on ECHO driver for HCS08.
*
* @note Compiler CodeWarrior for HCS12 V4.5
* Same changes made for PANGEA BCD project functionality.
* Additonal features of ECHO+ against ECHO not implemented.
*
******************************************************************************/
/******************************************************************************
* INCLUDE
******************************************************************************/
#include "des_mc33696.h" /* Include Echo driver header file */
/******************************************************************************
* PROTOTYPES OF UNEXPOSED FUNCTIONS
******************************************************************************/
void WaitN(unsigned int n);
void EchoCalcChecksum(unsigned char temp);
void EchoCopyTxBuf(void);
void Echo_EnterConfig(void);
void Echo_Config(unsigned char command, unsigned char *registerBuffer, \
unsigned char count);
void Echo_ExitConfig(void);
void Echo_ReadRegisters(unsigned char *out);
void Echo_KickOffTimer(void);
void Echo_StartDelayedConfig(void);
/******************************************************************************
* MACRO DEFINITIONS
******************************************************************************/
#define SPI_TxBufFull ((ECHO_SPIxSR & ECHO_SPIxSR_SPTEF) == 0)
#define SPI_RxBufEmpty ((ECHO_SPIxSR & ECHO_SPIxSR_SPIF) == 0)
/* Build a command byte - no checking of n, start or rw */
#define CMD_ONE 0 /* n=0 --> 1 register */
#define CMD_TWO 1 /* n=1 --> 2 register */
#define CMD_FOUR 2 /* n=2 --> 4 register */
#define CMD_EIGHT 3 /* n=3 --> 8 register */
#define BUILDCMD(n, start, rw) ((n<<6) | (start<<1) | rw)
/******************************************************************************
* VARIABLE DEFINITIONS
******************************************************************************/
tECHO_STATUS status; /* Status flags */
tECHO_TXCONFIG tx_config; /* Tx state machine configuration */
unsigned char echoDriverNextState; /* State to jump to on next interrupt */
unsigned char echoRegisters[13] = { /* Local copy of Echos registers */
ECHO_CONFIG1_REG_VALUE, ECHO_CONFIG2_REG_VALUE, ECHO_CONFIG3_REG_VALUE,
ECHO_COMMAND_REG_VALUE, ECHO_F1_REG_VALUE, ECHO_F0_REG_VALUE,
ECHO_FT2_REG_VALUE, ECHO_FT1_REG_VALUE, ECHO_FT0_REG_VALUE,
ECHO_RXONOFF_REG_VALUE, ECHO_ID_REG_VALUE, ECHO_HEADER_REG_VALUE,
ECHO_RSSI_REG_VALUE
};
unsigned char IDCounter; /* Number of ID's to repeat in continuous mode */
unsigned char bitCounter; /* Bits in current byte remaining to send */
unsigned char halfbitCounter; /* Halfbits in current byte remaining to send */
unsigned char byteCounter; /* Number of bytes remaining to send */
unsigned char data; /* Byte being sent */
unsigned char halfbit = 0; /* Manchester code halfbit order */
unsigned char *echoTxDataPtr; /* Pointer to retrieve data from Tx msg buffer */
/* Double buffering on the Tx side; buffer format detailed in design doc. */
unsigned char echoTransmitBuffer[ECHO_MAX_DATA_SIZE+4];
unsigned char echoInternalTxBuffer[ECHO_MAX_DATA_SIZE+4];
unsigned char echoChecksum; /* Incremental checksum calculation */
unsigned char echoDataLength; /* Length stored between Rx interrupts */
unsigned char *echoRxDataPtr; /* Pointer to store data into Rx msg buffer */
/* Set up space for the receive buffers */
unsigned char echoRxBuffer[(ECHO_MAX_DATA_SIZE+2)*ECHO_RX_BUF_COUNT];
unsigned char echoInternalRxBuffer[ECHO_MAX_DATA_SIZE+3]; /* need extra byte */
/* for chksum */
unsigned char *echoNextMessage; /* Pointer to the next full message buffer. */
/* Only valid after a call to */
/* Echo_DriverStatus which sets the MsgReady */
/* bit. */
unsigned char *echoFullPtr; /* Internal pntr. to start of next full buf */
unsigned char *echoEmptyPtr; /* Internal pntr. to start of next empty buf */
unsigned char echoRSSIResult; /* RSSI conversion results are placed here */
/* The analogue result may be either 8 or 10 bits */
#if ECHO_ATD_RES8 == 1
unsigned char echoAnalogueRSSIResult;
#else
unsigned int echoAnalogueRSSIResult;
#endif
/* Configuration parameters held while waiting for Echo to turn on */
unsigned char echoCommand; /* The command to send Echo */
unsigned char *echoRegPtr; /* Buffer to read from or write to */
unsigned char echoRegCounter; /* The number of registers to read or write */
/*****************************************************************************
* Wait for n loop iterations.
******************************************************************************/
#define ITERATIONS_6uS (17) /* both tested @ ECHO_MCU_BUS_SPEED=24MHz*/
#define ITERATIONS_1200uS (4111) /* (nonlinear dependence on BUS clock due*/
/* to variable BNE instr. cycle length) */
void WaitN(unsigned int n) {
asm {
PSHD
LDD n
loop:
ADDD #-1 ;2 cycles
CPD #0 ;3 cycles
BNE loop ;3 / 1 cycles
PULD
}
}
/******************************************************************************
* Helper function to calculate checksum.
* Taken from the Romeo.c driver.
******************************************************************************/
void EchoCalcChecksum(unsigned char temp) {
asm {
LDAA echoChecksum
ADDA temp
ADCA #$00
STAA echoChecksum
}
}
/******************************************************************************
* Copy the external Tx buffer into the internal Tx buffer.
******************************************************************************/
void EchoCopyTxBuf(void) {
int i;
for(i=0; i<sizeof(echoInternalTxBuffer); i++) {
echoInternalTxBuffer[i] = echoTransmitBuffer[i];
}
echoInternalTxBuffer[3] |= ECHO_BUFFER_FULL;/* Set buffer full flag */
echoTransmitBuffer[3] &= ~ECHO_BUFFER_FULL; /* Clear buffer full flag */
}
/******************************************************************************
* Put Echo into configuration mode. Enables the SPI, MCU as master and disables
* SPI interrupts as required before calling Echo_Config.
* Note: if Echo is already powered on, there should be a delay of approximately
* 5-6usec (3*Tdigclk) before calling Echo_Config after this function to allow
* Echo to move into config mode. If Echo may be in Standby mode, the delay
* required is 1.2ms!
******************************************************************************/
void Echo_EnterConfig(void) {
ECHO_CONFB = 1;
ECHO_SEB = 1;
ECHO_SPIxC1 &= ~ECHO_SPIxC1_SPIE; /* Turn off SPI interrupts */
ECHO_SPIxC1 |= ECHO_SPIxC1_MSTR; /* Set MCU to master */
ECHO_SPIxC1 |= ECHO_SPIxC1_SPE; /* Enable SPI */
ECHO_SEB = 0;
ECHO_CONFB = 0;
WaitN(ITERATIONS_6uS); /* 3*Tdigclk (~5-6usec) delay */
}
/******************************************************************************
* Send the command byte and then read/write to and from the registerBuffer.
* Assumes Echo is already in config mode and the SPI set up to talk to Echo
* (i.e. Echo_EnterConfig has been called before this!).
*
* Expects SPI to be configured (baud rate, clock phase etc.) and CONFB and SEB
* to be setup. No checking of count is performed to confirm this matches the
* command - make sure it is correct! Writes do not destroy the original
* register buffer.
******************************************************************************/
void Echo_Config(unsigned char command, unsigned char *registerBuffer, \
unsigned char count) {
unsigned char temp; /* Temporary storage for reading SPI */
unsigned char writeFlag; /* When writing, don't destroy the */
/* register buffer by reading back */
/* nothing from Echo and overwriting it */
ECHO_CONFB = 1;
ECHO_CONFB = 0;
/*--- The r/w bit is the LSB */
writeFlag = command & 0x01;
temp = ECHO_SPIxSR;
temp = ECHO_SPIxDR; /* Read data reg to clear receive flag */
/*--- Send the command byte */
ECHO_SPIxDR = command;
while(SPI_RxBufEmpty); /* Wait until byte gone */
temp = ECHO_SPIxDR; /* Read data reg to clear receive flag */
/*--- Now read/write the configuration bytes */
while(count>0) {
ECHO_SPIxDR = *registerBuffer; /* Send a byte */
while(SPI_RxBufEmpty); /* Wait until byte gone */
temp = ECHO_SPIxDR; /* Read a byte and clear */
/* receive flag */
if (!writeFlag) *registerBuffer = temp; /* If a read command, copy */
/* to buffer */
registerBuffer++;
count--;
}
/*-- Toggle CONFB to allow another command to be sent immediately */
// ECHO_CONFB = 1;
// ECHO_CONFB = 0;
}
/******************************************************************************
* Exit configuration mode.
* Leaves SEB=1, CONFB=1, SPI enabled and MCU set as slave.
******************************************************************************/
void Echo_ExitConfig(void) {
ECHO_CONFB = 1; /* Leave config mode */
ECHO_SEB = 1; /* Disable Echo serial interface */
ECHO_SPIxC1 &= ~ECHO_SPIxC1_MSTR; /* Set MCU to slave */
}
/******************************************************************************
* Read Echo's registers and store into the buffer at 'out'.
* Resets Echo, sets up CONFB and SEB pins (in case they haven't been already)
* and reinitializes the SPI. Echo is left in master mode and in Rx, MCU SPI is
* in slave mode, enabled, with interrupts turned on: essentially, driver set up
* for Rx.
******************************************************************************/
void Echo_ReadRegisters(unsigned char *out) {
/*--- Set up required pins */
ECHO_CONFB = 1;
ECHO_CONFB_DDR = 1;
ECHO_SEB = 1;
ECHO_SEB_DDR = 1;
ECHO_SPIxC1 = 0x04; /* disabled, no int's, slave, clk setup */
ECHO_SPIxBR = ((ECHO_SPI_BAUD_RATE_PRESCALER << 4) \
| ECHO_SPI_BAUD_RATE_DIVISOR);
/*--- Read the first 8 registers */
echoCommand = BUILDCMD(CMD_EIGHT,0,0);
echoRegPtr = out;
echoRegCounter = 8;
Echo_StartDelayedConfig();
while(status.Bits.Busy == 1);
/*--- Read the next 8 registers */
echoCommand = BUILDCMD(CMD_EIGHT,8,0);
echoRegPtr = out+8;
echoRegCounter = 8;
Echo_StartDelayedConfig();
while(status.Bits.Busy == 1);
}
/******************************************************************************
* Initialize Echo according to the config in Echo.h.
* Echo is left in standby mode.
******************************************************************************/
void Echo_Initialize(void) {
/*--- Reset Status */
status.Word = 0;
/*--- Set up required pins */
ECHO_CONFB = 1;
ECHO_CONFB_DDR = 1;
ECHO_SEB = 1;
ECHO_SEB_DDR = 1;
/*--- Set up optional pins */
#ifdef ECHO_RSSIC
ECHO_RSSIC = 0;
ECHO_RSSIC_DDR = 1;
#endif
#ifdef ECHO_ENABLEPA
ECHO_ENABLEPA = 0;
ECHO_ENABLEPA_DDR = 1;
#endif
#ifdef ECHO_ENABLELNA
ECHO_ENABLELNA = 0;
ECHO_ENABLELNA_DDR = 1;
#endif
#ifdef ECHO_LVD
ECHO_LVD_DDR = 0;
#endif
#ifdef ECHO_STROBE
ECHO_STROBE = 0;
ECHO_STROBE_DDR = 1;
#endif
/*--- Init the SPI interface */
ECHO_SPIxC1 = 0x04; /* disabled, no int's, slave, clk setup */
ECHO_SPIxBR = ((ECHO_SPI_BAUD_RATE_PRESCALER << 4) \
| ECHO_SPI_BAUD_RATE_DIVISOR);
/*--- Write the registers */
/* No need to send 13th byte - the RSSI is read only */
Echo_EnterConfig();
WaitN(ITERATIONS_1200uS);
Echo_Config(BUILDCMD(CMD_EIGHT,0,1),echoRegisters,8); /* first 8 regs. */
Echo_Config(BUILDCMD(CMD_FOUR,8,1),echoRegisters+8,4); /* next 4 regs. */
Echo_ExitConfig();
/*--- Clean up */
ECHO_SPIxC1 &= ~ECHO_SPIxC1_SPE; /* Disable SPI */
/*--- Set up pointers */
echoRxDataPtr = &echoInternalRxBuffer[0]; /* Point to internal Rx data */
/* buffer */
echoFullPtr = &echoRxBuffer[0]; /* Point full and empty to the Rx buf */
echoEmptyPtr = &echoRxBuffer[0];
}
/******************************************************************************
* Setup the timer, enable Echo and put into Rx mode.
* A startup delay of 2ms is initiated.
******************************************************************************/
void Echo_Enable(void) {
/*--- Indicate the driver status */
status.Bits.Enabled = 1;
status.Bits.EnableDelay = 1;
status.Bits.Busy = 1;
/*--- Turn on the LNA (for Rx) */
#ifdef ECHO_ENABLELNA
ECHO_ENABLELNA = 1;
#endif
/*--- Turn on the STROBE */
#ifdef ECHO_STROBE
ECHO_STROBE = 1;
#endif
/*--- Turn on Echo transceiver, and set mode to Rx */
echoRegisters[ECHO_CONFIG2_REG] |= ECHO_BIT_TRXE;
echoRegisters[ECHO_COMMAND_REG] &= ~ECHO_BIT_MODE;
Echo_EnterConfig();
WaitN(ITERATIONS_1200uS);
Echo_Config(BUILDCMD(CMD_ONE, ECHO_COMMAND_REG, 1),
&echoRegisters[ECHO_COMMAND_REG],
1);
Echo_Config(BUILDCMD(CMD_ONE, ECHO_CONFIG2_REG, 1),
&echoRegisters[ECHO_CONFIG2_REG],
1);
Echo_ExitConfig();
/*--- Disable SPI so timer channel pin can be used */
ECHO_SPIxC1 &= ~ECHO_SPIxC1_SPE;
/*--- Setup the timer and schedule 2ms delay */
bitCounter = ECHO_2MS_DELAY; /* Counter = # of bit-times in 2ms */
echoDriverNextState = ECHO_ENABLE_DELAY;
ECHO_TIOS |= ECHO_IC_OC; /* Select OC on used timer channel */
ECHO_TSCR2 |= ECHO_TCRE; /* Timer counter reset enable */
ECHO_TFLG1 |= ECHO_TIMER_INT; /* Clear any old interrupt pending */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -