📄 phy_layer.c
字号:
/*********************************************************************************
* ST 7538 DEMOBOARD SOFTWARE Phy_Layer.c *
* *
* SPI uc<->modem functions V1.2 *
***********************************************************************************/
#include "global.h"
#pragma DATA_SEG APP_RAM
BYTE SPI_Bits; // How many BITS have been sent/received
BYTE SPI_RxIn; // How many BYTES have been received in BUFFER
BYTE SPI_RxOut; // How many BYTES received in BUFFER have been setnt to PC interface
BYTE SPI_TxOut; // How many BYTES have been TXED from BUFFER
BYTE SPI_TxIn; // How many BYTES to TX into the BUFFER
BYTE SPI_DR; // the SW SPI Data register
BYTE SPI_LoopStart; // start of packet in looping mode
BYTE Nb_byte_to_receive; //In synchro mode, the total nb of byte received in the frame
BYTE Nb_byte_to_receive_rest; //In synhro mode, during rx of data, the resting number of byte to receive
WORD Header;
BYTE Loop; //number of Tx frame to repeat
WORD Mask;
WORD Head_Reg;
#pragma CODE_SEG APPLI_CODE
/**********************************************************************************
* SPI_Init function: HW initialization
**********************************************************************************/
void SPI_Init(void)
{
SPI_Flags = 0;
Repeated_Mode = REPEAT_MODE_OFF;
Repeating_Number = 0;
// Configuration of TX SPI I/O
TX_SPI_DIR |= (TX_DATA_MASK); // in output push pull set to 0
TX_SPI_OP_R |= (TX_DATA_MASK);
TX_SPI_PORT &=~(TX_DATA_MASK);
// Configuration of RX SPI I/O
RX_SPI_DIR &= ~(RX_DATA_MASK); // in input floating
RX_SPI_OP_R &= ~(RX_DATA_MASK);
// Configuration of CLRT
CLRT_DIR &= ~(CLRT_MASK); // in input floating, but not yet
CLRT_OP_R &= ~(CLRT_MASK); // in pull up interrupt
MISCR1 = MISCR1 & 0x3F;
MISCR1 = MISCR1 | 0x40; // CLRT int on rising edge
//RX/TX_
RX_TX_DIR |= (RX_TX_MASK); // RXTX in output push pull in RX mode by default.
RX_TX_OP_R |= (RX_TX_MASK);
RX_TX_PORT |= (RX_TX_MASK);
//REG/DATA_
REG_DTA_DIR |= REG_DTA_MASK; // in output push pull in DATA mode
REG_DTA_OP_R|= REG_DTA_MASK;
REG_DTA_PORT&= ~(REG_DTA_MASK);
//Carrier/Preamble detection
CD_PD_DIR &= ~(CD_PD_MASK); // in input floating
CD_PD_OP_R &= ~(CD_PD_MASK);
//Configure REG_OK pin
REG_OK_DIR &= ~(REG_OK_MASK); // in input floating
//Configure TOUT pin (time out)
TIMEOUT_DIR &= ~(TIMEOUT_MASK); // in input floating
TIMEOUT_OP_R&= ~(TIMEOUT_MASK);
//BAND in USED
BANDUSED_DIR &= ~(BANDUSED_MASK); // in input floating
//BANDUSED_OP_R &= ~(BANDUSED_MASK);
// Zero Crossing detection signal
XCROSS_DIR &= ~(XCROSS_MASK); // in input floating
XCROSS_OP_R &= ~(XCROSS_MASK);
ST7538_CR=0x00; // initialization of CR
CLRT_OP_R |= CLRT_MASK; //always active
}
/**********************************************************************************
* SPI_Enable function: enable SPI interrupt on falling edge of CLR/T pin
**********************************************************************************/
void SPI_Enable(void)
{
if(SPI_Flags&SPI_IN_TX_MASK) {
SPI_TxOut = 0;
SPI_DR = SPI_Buffer[SPI_TxOut];
if(SPI_DR&0x80)
TX_SPI_PORT |= TX_DATA_MASK;
else
TX_SPI_PORT &= ~(TX_DATA_MASK);
SPI_DR <<= 1;
SPI_Bits = 1;
}
else {
SPI_Bits = 0;
SPI_RxIn = 0;
SPI_DR = 0;
}
CLRT_OP_R |= CLRT_MASK;
}
/**********************************************************************************
* SPI_Disable function: disable SPI interrupt
**********************************************************************************/
void SPI_Disable(void)
{
//CLRT_OP_R &= ~(CLRT_MASK);
SPI_Flags &= ~(SPI_IN_RX_MASK|SPI_IN_TX_MASK|SPI_REG_MASK|SPI_SYNCHRO_MASK|SPI_RXED_SYN_MASK);
RX_TX_PORT |= RX_TX_MASK;
REG_DTA_PORT &= ~(REG_DTA_MASK);
TX_SPI_PORT &= ~TX_DATA_MASK;
}
/**********************************************************************************
* SPI_Interrupt function: SPI interrupt routine
**********************************************************************************/
#pragma TRAP_PROC //SAVE_REGS
void SPI_Interrupt(void)
{
// const static char Byte_Size = 8; //used for transmit/receive a number of bit != 8
// RX MODE
if(SPI_Flags&SPI_IN_RX_MASK) {
SPI_DR = SPI_DR << 1;
Head_Reg = Head_Reg << 1;
if(RX_SPI_PORT&RX_DATA_MASK) {
SPI_DR |= 0x01;
Head_Reg |= 0x01;
}
else {
SPI_DR &= 0xFE;
Head_Reg &= 0xFFFE;
}
if(SPI_Bits<15)
SPI_Bits++;
// RX Synchro Mode
if((SPI_Flags&SPI_RXED_SYN_MASK)&&!(SPI_Flags&SPI_SYNCHRO_MASK)) {
// Waiting for synchronization
if(SPI_Bits<15)
return;
if(((Head_Reg^Header)&Mask)==0) { // Synchronized!
SPI_Flags = SPI_Flags | SPI_SYNCHRO_MASK;
SPI_Bits = 0;
SPI_DR = 0;
Nb_byte_to_receive_rest = Nb_byte_to_receive;
}
}
// Reception enabled (synchronized or synchronization not required)
else {
if(SPI_Bits<8) {
return;
}
//if((SPI_Flags&SPI_REG_MASK)||(PING_Status==PS_WAIT)) {
// DI;
// SPI_Buffer[SPI_RxIn++] = SPI_DR;
// SPI_RxIn &= SPI_BUFFER_MASK;
// EI;
//}
//else {
DI;
SPI_Buffer[SPI_RxIn] = SPI_DR;
SPI_RxIn = SPI_RxIn + 1;
SPI_RxIn &= SPI_BUFFER_MASK;
EI;
//}
SPI_DR = 0;
SPI_Bits = 0;
if(SPI_Flags&SPI_RXED_SYN_MASK) {
if(--Nb_byte_to_receive_rest==0) {
DI;
SPI_Flags &= ~SPI_SYNCHRO_MASK;
Head_Reg = 0;
SPI_Bits = 0;
if (PING_Status==PS_WAIT)
{
PING_Flags |=PF_RECV;
SPI_RxIn = 0;
SPI_RxOut = 0;
}
EI;
}
}
}
}
// TX_MODE
else if(SPI_Flags&SPI_IN_TX_MASK) {
if(SPI_Bits<8) {
if(SPI_DR&0x80)
TX_SPI_PORT |= TX_DATA_MASK;
else
TX_SPI_PORT &= ~(TX_DATA_MASK);
SPI_DR = SPI_DR << 1;
SPI_Bits++;
}
else {
if(SPI_TxOut!=SPI_TxIn) {
SPI_Bits = 0;
SPI_TxOut = (SPI_TxOut+1)&(SPI_BUFFER_MASK);
SPI_DR = SPI_Buffer[SPI_TxOut];
if(SPI_DR&0x80)
TX_SPI_PORT |= TX_DATA_MASK;
else
TX_SPI_PORT &= ~(TX_DATA_MASK);
SPI_DR = SPI_DR << 1;
SPI_Bits++;
}
else {
if(!(SPI_Flags&SPI_LOOP_MASK)) {
SPI_Disable();
}
else {
SPI_TxOut = 0;
SPI_Bits = 0;
SPI_DR = SPI_Buffer[SPI_TxOut];
if(SPI_DR&0x80)
TX_SPI_PORT |= TX_DATA_MASK;
else
TX_SPI_PORT &= ~(TX_DATA_MASK);
SPI_DR = SPI_DR << 1;
SPI_Bits++;
}
}
}
}
}
/**********************************************************************************
* GetControlRegister function: get always 48 bit and put them on RS-232 buffer.
* If lsbits (from 24 to 0 bits )are all "0" or "1" invert three upper bytes with three
* lower bytes in order to have always in last positions of RS-232 buffer [4,5,6] the CR
* bits from 24 to 0.
**********************************************************************************/
BYTE GetControlRegister(unsigned char *CTRL_REG)
{
unsigned char tim;
// Waits for CLR/T low
SPI_Disable();
DI;
MISCR1 = MISCR1 & 0x3F; //rising edge
MISCR1 = MISCR1 | 0x40;
EI;
tim = TIMEOUT_Open(2);
while(!TIMEOUT_Expired(tim)) {
if(!(CLRT_PORT&CLRT_MASK))
break;
WatchDogRefresh();
}
TIMEOUT_Close(tim);
tim = TIMEOUT_Open(100);
// Select Lines
RX_TX_PORT |= (RX_TX_MASK);
REG_DTA_PORT |= REG_DTA_MASK;
SPI_Flags |= (SPI_IN_RX_MASK|SPI_REG_MASK);
SPI_RxIn = 0;
SPI_Enable();
// Waits for 6 bytes read
while(SPI_RxIn<6) {
if(TIMEOUT_Expired(tim))
{
SPI_Disable();
TIMEOUT_Close(tim);
REG_DTA_PORT &= ~REG_DTA_MASK;
return 1;
}
WatchDogRefresh();
}
SPI_Disable();
REG_DTA_PORT &= ~REG_DTA_MASK;
DI;
if (((SPI_Buffer[3]==0xFF)&&(SPI_Buffer[4]==0xFF)&&(SPI_Buffer[5]==0xFF))
||((SPI_Buffer[3]==0x00)&&(SPI_Buffer[4]==0x00)&&(SPI_Buffer[5]==0x00))) {
// 24 bit register
memcpy(((BYTE *)&ST7538_CR)+1,SPI_Buffer,3);
memcpy(CTRL_REG,SPI_Buffer+3,3);
memcpy(CTRL_REG+3,SPI_Buffer,3);
(*(CTRL_REG + 6)) = 0x00; //information byte
}
else {
// 48 bit register
memcpy(((BYTE*)&ST7538_CR)+1,SPI_Buffer+3,3);
memcpy(CTRL_REG,SPI_Buffer,3);
memcpy(CTRL_REG+3,SPI_Buffer+3,3);
(*(CTRL_REG + 6)) = 0xFF; //information byte
}
EI;
TIMEOUT_Close(tim);
return 0;
}
/**********************************************************************************
* SetControlRegister function: write 48 CR
**********************************************************************************/
BYTE SetControlRegister(unsigned char *CTRL_Reg)
{
unsigned char tim;
SPI_Disable();
DI;
MISCR1 = MISCR1 & 0x3F; //falling edge
MISCR1 = MISCR1 | 0x80;
memcpy(SPI_Buffer,CTRL_Reg,6); //put all bytes on SPI buffer
memcpy(((BYTE*)&ST7538_CR)+1,CTRL_Reg+3,3); //update CR (only bits from 24 to 0)
EI;
// Waits for CLR/T low
tim = TIMEOUT_Open(2);
while(!TIMEOUT_Expired(tim)) {
if(!(CLRT_PORT&CLRT_MASK))
break;
WatchDogRefresh();
}
TIMEOUT_Close(tim);
tim = TIMEOUT_Open(100);
// Select Lines
RX_TX_PORT &= ~(RX_TX_MASK);
REG_DTA_PORT |= REG_DTA_MASK;
SPI_Flags |= (SPI_IN_TX_MASK|SPI_REG_MASK);
SPI_TxIn = 6;
SPI_Enable();
while(SPI_TxOut!=SPI_TxIn) {
if(TIMEOUT_Expired(tim))
{
SPI_Disable();
TIMEOUT_Close(tim);
return 1;
}
WatchDogRefresh();
}
SPI_Disable();
TIMEOUT_Close(tim);
return 0;
}
/**********************************************************************************
* SPI_OnRx function: return 1 if SPI is running in RX mode, 0 otherwise
**********************************************************************************/
unsigned char SPI_OnRx(void)
{
return ((SPI_Flags&SPI_IN_RX_MASK)&&!(SPI_Flags&SPI_REG_MASK));
}
/**********************************************************************************
* SPI_OnTx function: return 1 if SPI is running in TX mode, 0 otherwise
**********************************************************************************/
unsigned char SPI_OnTx(void)
{
return (SPI_Flags&SPI_IN_TX_MASK);
}
/**********************************************************************************
* SPI_OnRun function: return 1 if SPI is running in RX or Tx mode, 0 otherwise
**********************************************************************************/
unsigned char SPI_OnRun(void)
{
return (SPI_Flags&(SPI_IN_RX_MASK|SPI_IN_TX_MASK));
}
/**********************************************************************************
* Tx_Data function: copy data to sent in SPI buffer and set TX flags depending of type of Tx
**********************************************************************************/
void Tx_Data(unsigned char msg_rep, unsigned char msg_len, char *msg)
{
DI;
memcpy(SPI_Buffer,msg,msg_len);
EI;
SPI_Flags &= ~(SPI_LOOP_MASK);
Repeated_Mode = REPEAT_MODE_OFF;
if(msg_rep==0) { // Continuous Transmission
SPI_Flags |= SPI_LOOP_MASK;
}
else { // Repeated Transmission
if(msg_rep>1) {
Repeated_Mode = REPEAT_MODE_ON;
Repeating_Number = msg_rep;
refresh_200mS_Delay();
}
}
DI;
MISCR1 = MISCR1 & 0x3F; //falling edge
MISCR1 = MISCR1 | 0x80;
EI;
SPI_TxIn = msg_len-1;
SPI_Flags |= SPI_IN_TX_MASK;
REG_DTA_PORT &= ~(REG_DTA_MASK);
RX_TX_PORT &= ~(RX_TX_MASK);
SPI_Enable();
}
/**********************************************************************************
* Rx_Data function: set RX flags depending of type of Rx
**********************************************************************************/
void Rx_Data(unsigned char Rx_Type,unsigned short Rx_Head,
unsigned short Rx_Mask,unsigned char Rx_Len)
{
SPI_Flags &= ~(SPI_RXED_SYN_MASK);
DI;
MISCR1 = MISCR1 & 0x3F; //rising edge
MISCR1 = MISCR1 | 0x40;
EI;
switch (Rx_Type) {
case RX_SYN_TXDH:
TX_SPI_PORT |= TX_DATA_MASK;
case RX_SYN:
Header = Rx_Head;
Mask = Rx_Mask;
Nb_byte_to_receive = Rx_Len;
SPI_Flags |= SPI_RXED_SYN_MASK;
case RX_TXDH:
if(Rx_Type==RX_TXDH)
TX_SPI_PORT |= TX_DATA_MASK;
case RX_NO_SYN:
SPI_Flags |= SPI_IN_RX_MASK;
RX_TX_PORT |= RX_TX_MASK;
REG_DTA_PORT &= ~(REG_DTA_MASK);
SPI_Enable();
break;
}
}
/**********************************************************************************
* RepMode_Analyze function: manages repeated Tx mode (every 200ms)
**********************************************************************************/
void RepMode_Analyze(void)
{
if(Repeating_Number>1) {
if(_200mS_Delay_Elapsed()&&!SPI_OnRun()) {
DI;
Repeating_Number--;
SPI_TxOut = 0;
SPI_Flags |= SPI_IN_TX_MASK;
RX_TX_PORT &= ~(RX_TX_MASK);
REG_DTA_PORT &= ~(REG_DTA_MASK);
refresh_200mS_Delay();
MISCR1 = MISCR1 & 0x3F; //falling edge
MISCR1 = MISCR1 | 0x80;
EI;
SPI_Enable();
}
}
else {
Repeated_Mode = REPEAT_MODE_OFF;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -