📄 main_ezlink.c
字号:
/*
** ============================================================================
**
** FILE
** main.c
**
** DESCRIPTION
** This is the main file of the project.
** HW platform EZLink module with C8051F93x Silabs MCU
**
** CREATED
** Silicon Laboratories Hungary Ltd
**
** COPYRIGHT
** Copyright 2009 Silicon Laboratories, Inc.
** http://www.silabs.com
**
** ============================================================================
*/
/* ======================================================== *
* INCLUDE *
* ======================================================== */
#include "C8051F930_defs.h"
#include "compiler_defs.h"
#include "string.h"
/* ================================================================ *
* C8051F930 Pin definitions for Software Development Board *
* (using compiler_def.h macros) *
* ================================================================ */
SBIT (NSS, SFR_P1, 3);
SBIT (NIRQ, SFR_P0, 6);
SBIT (SDN, SFR_P0, 1);
SBIT (RX_LED, SFR_P2, 0);
SBIT (TX_LED, SFR_P1, 6);
SBIT (PB, SFR_P0, 7);
/* ======================================================== *
* Function PROTOTYPES *
* ======================================================== */
//MCU initialization
void MCU_Init(void);
//SPI functions
void SpiWriteRegister (U8, U8);
U8 SpiReadRegister (U8);
void main(void)
{
U8 ItStatus1,ItStatus2;
U16 delay;
U8 length,temp8;
U8 payload[10];
//Initialize the MCU:
// - set IO ports for the Software Development board
// - set MCU clock source
// - initialize the SPI port
// - turn ofF LEDs
MCU_Init();
/* ======================================================== *
* Initialize the Si443x ISM chip *
* ======================================================== */
//Turn on the radio by pulling down the PWRDN pin
SDN = 0;
//Wait at least 15ms befory any initialization SPI commands are sent to the radio
// (wait for the power on reset sequence)
for (temp8=0;temp8<15;temp8++)
{
for(delay=0;delay<10000;delay++);
}
//read interrupt status registers to clear the interrupt flags and release NIRQ pin
ItStatus1 = SpiReadRegister(0x03); //read the Interrupt Status1 register
ItStatus2 = SpiReadRegister(0x04); //read the Interrupt Status2 register
//SW reset
SpiWriteRegister(0x07, 0x80); //write 0x80 to the Operating & Function Control1 register
//wait for POR interrupt from the radio (while the nIRQ pin is high)
while ( NIRQ == 1);
//read interrupt status registers to clear the interrupt flags and release NIRQ pin
ItStatus1 = SpiReadRegister(0x03); //read the Interrupt Status1 register
ItStatus2 = SpiReadRegister(0x04); //read the Interrupt Status2 register
//wait for chip ready interrupt from the radio (while the nIRQ pin is high)
while ( NIRQ == 1);
//read interrupt status registers to clear the interrupt flags and release NIRQ pin
ItStatus1 = SpiReadRegister(0x03); //read the Interrupt Status1 register
ItStatus2 = SpiReadRegister(0x04); //read the Interrupt Status2 register
/*set the physical signal parameters*/
//set the center frequency to 915 MHz
SpiWriteRegister(0x75, 0x75); //write 0x75 to the Frequency Band Select register
SpiWriteRegister(0x76, 0xBB); //write 0xBB to the Nominal Carrier Frequency1 register
SpiWriteRegister(0x77, 0x80); //write 0x80 to the Nominal Carrier Frequency0 register
/*set the modem parameters according to the exel calculator(parameters: 9.6 kbps, deviation: 45 kHz, channel filter BW: 112.1 kHz*/
SpiWriteRegister(0x1C, 0x1E); //write 0x1E to the IF Filter Bandwidth register
SpiWriteRegister(0x20, 0xD0); //write 0xD0 to the Clock Recovery Oversampling Ratio register
SpiWriteRegister(0x21, 0x00); //write 0x00 to the Clock Recovery Offset 2 register
SpiWriteRegister(0x22, 0x9D); //write 0x9D to the Clock Recovery Offset 1 register
SpiWriteRegister(0x23, 0x49); //write 0x49 to the Clock Recovery Offset 0 register
SpiWriteRegister(0x24, 0x00); //write 0x00 to the Clock Recovery Timing Loop Gain 1 register
SpiWriteRegister(0x25, 0x24); //write 0x24 to the Clock Recovery Timing Loop Gain 0 register
SpiWriteRegister(0x1D, 0x40); //write 0x40 to the AFC Loop Gearshift Override register
SpiWriteRegister(0x1E, 0x0A); //write 0x0A to the AFC Timing Control register
SpiWriteRegister(0x2A, 0x20); //write 0x20 to the AFC Limiter register
/*Configure the receive packet handler*/
//Disable header bytes; set variable packet length (the length of the payload is defined by the
//received packet length field of the packet); set the synch word to two bytes long
SpiWriteRegister(0x33, 0x02); //write 0x02 to the Header Control2 register
//Disable the receive header filters
SpiWriteRegister(0x32, 0x00); //write 0x00 to the Header Control1 register
//Set the sync word pattern to 0x2DD4
SpiWriteRegister(0x36, 0x2D); //write 0x2D to the Sync Word 3 register
SpiWriteRegister(0x37, 0xD4); //write 0xD4 to the Sync Word 2 register
//Enable the receive packet handler and CRC-16 (IBM) check
SpiWriteRegister(0x30, 0x85); //write 0x85 to the Data Access Control register
//Enable FIFO mode and GFSK modulation
SpiWriteRegister(0x71, 0x63); //write 0x63 to the Modulation Mode Control 2 register
//set preamble detection threshold to 20bits
SpiWriteRegister(0x35, 0x2A); //write 0x2A to the Preamble Detection Control register
//set preamble length to 5bytes
SpiWriteRegister(0x34, 0x0A); //write 0x0A to the Preamble Length register
/*Set the GPIO's to control the RF switch*/
SpiWriteRegister(0x0C, 0x12); //write 0x12 to the GPIO1 Configuration(set the TX state)
SpiWriteRegister(0x0D, 0x15); //write 0x15 to the GPIO2 Configuration(set the RX state)
/*set the non-default Si443x registers*/
//set Crystal Oscillator Load Capacitance register
SpiWriteRegister(0x09, 0xD7); //write 0xD7 to the Crystal Oscillator Load Capacitance register
/*enable receiver chain*/
SpiWriteRegister(0x07, 0x05); //write 0x05 to the Operating Function Control 1 register
//Enable two interrupts:
// a) one which shows that a valid packet received: 'ipkval'
// b) second shows if the packet received with incorrect CRC: 'icrcerror'
SpiWriteRegister(0x05, 0x03); //write 0x03 to the Interrupt Enable 1 register
SpiWriteRegister(0x06, 0x00); //write 0x00 to the Interrupt Enable 2 register
//read interrupt status registers to release all pending interrupts
ItStatus1 = SpiReadRegister(0x03); //read the Interrupt Status1 register
ItStatus2 = SpiReadRegister(0x04); //read the Interrupt Status2 register
/*MAIN Loop*/
while(1)
{
//wait for the interrupt event
if( NIRQ == 0 )
{
//read interrupt status registers
ItStatus1 = SpiReadRegister(0x03); //read the Interrupt Status1 register
ItStatus2 = SpiReadRegister(0x04); //read the Interrupt Status2 register
/*CRC Error interrupt occured*/
if( (ItStatus1 & 0x01) == 0x01 )
{
//disable the receiver chain
SpiWriteRegister(0x07, 0x01); //write 0x01 to the Operating Function Control 1 register
//reset the RX FIFO
SpiWriteRegister(0x08, 0x02); //write 0x02 to the Operating Function Control 2 register
SpiWriteRegister(0x08, 0x00); //write 0x00 to the Operating Function Control 2 register
//blink all LEDs to show the error
RX_LED = 1;
TX_LED = 1;
for(delay = 0; delay < 10000;delay++);
RX_LED = 0;
TX_LED = 0;
//enable the receiver chain again
SpiWriteRegister(0x07, 0x05); //write 0x05 to the Operating Function Control 1 register
}
/*packet received interrupt occured*/
if( (ItStatus1 & 0x02) == 0x02 )
{
//disable the receiver chain
SpiWriteRegister(0x07, 0x01); //write 0x01 to the Operating Function Control 1 register
//Read the length of the received payload
length = SpiReadRegister(0x4B); //read the Received Packet Length register
//check whether the received payload is not longer than the allocated buffer in the MCU
if(length < 11)
{
//Get the reeived payload from the RX FIFO
for(temp8=0;temp8 < length;temp8++)
{
payload[temp8] = SpiReadRegister(0x7F); //read the FIFO Access register
}
//check whether the content of the packet is what the demo expects
if( length == 8 )
{
if( memcmp(&payload[0], "BUTTON1", 7) == 0 )
{
//blink LED1 to show that the packet received
RX_LED = 1;
for(delay = 0; delay < 10000;delay++);
RX_LED = 0;
}
}
}
//reset the RX FIFO
SpiWriteRegister(0x08, 0x02); //write 0x02 to the Operating Function Control 2 register
SpiWriteRegister(0x08, 0x00); //write 0x00 to the Operating Function Control 2 register
//enable the receiver chain again
SpiWriteRegister(0x07, 0x05); //write 0x05 to the Operating Function Control 1 register
}
}
}
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ FUNCTION NAME: void MCU_Init(void)
+
+ DESCRIPTION: This function configures the MCU
+
+ INPUT: None
+
+ RETURN: None
+
+ NOTES: None
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void MCU_Init(void)
{
//Disable the Watch Dog timer of the MCU
PCA0MD &= ~0x40;
// Set the clock source of the MCU: 10MHz, using the internal RC osc.
CLKSEL = 0x14;
// Initialize the the IO ports and the cross bar
P0SKIP |= 0x40; // skip P0.6
XBR1 |= 0x40; // Enable SPI1 (3 wire mode)
P1MDOUT |= 0x01; // Enable SCK push pull
P1MDOUT |= 0x04; // Enable MOSI push pull
P1SKIP |= 0x08; // skip NSS
P1MDOUT |= 0x08; // Enable NSS push pull
P1SKIP |= 0x40; // skip TX_LED
P1MDOUT |= 0x40; // Enable TX_LED push pull
P2SKIP |= 0x01; // skip RX_LED
P2MDOUT |= 0x01; // Enable RX_LED push pull
P0SKIP |= 0x02; // skip SDN
P0MDOUT |= 0x02; // Enable SDN push pull
P0SKIP |= 0x80; // skip PB
SFRPAGE = CONFIG_PAGE;
P0DRV = 0x12; // TX high current mode
P1DRV = 0x4D; // MOSI, SCK, NSS, TX_LED high current mode
P2DRV = 0x01; // RX_LED high current mode
SFRPAGE = LEGACY_PAGE;
XBR2 |= 0x40; // enable Crossbar
// For the SPI communication the hardware peripheral of the MCU is used
//in 3 wires Single Master Mode. The select pin of the radio is controlled
//from software
SPI1CFG = 0x40; // Master SPI, CKPHA=0, CKPOL=0
SPI1CN = 0x00; // 3-wire Single Master, SPI enabled
SPI1CKR = 0x00;
SPI1EN = 1; // Enable SPI interrupt
NSS = 1;
// Turn off the LEDs
TX_LED = 0;
RX_LED = 0;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ FUNCTION NAME: void SpiWriteRegister(U8 reg, U8 value)
+
+ DESCRIPTION: This function writes the registers
+
+ INPUT: U8 reg - register address
+ U8 value - value write to register
+
+ RETURN: None
+
+ NOTES: Write uses a Double buffered transfer
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void SpiWriteRegister (U8 reg, U8 value)
{
// Send SPI data using double buffered write
//Select the radio by pulling the nSEL pin to low
NSS = 0;
//write the address of the register into the SPI buffer of the MCU
//(important to set the MSB bit)
SPI1DAT = (reg|0x80); //write data into the SPI register
//wait until the MCU finishes sending the byte
while( SPIF1 == 0);
SPIF1 = 0;
//write the new value of the radio register into the SPI buffer of the MCU
SPI1DAT = value; //write data into the SPI register
//wait until the MCU finishes sending the byte
while( SPIF1 == 0); //wait for sending the data
SPIF1 = 0;
//Deselect the radio by pulling high the nSEL pin
NSS = 1;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ FUNCTION NAME: U8 SpiReadRegister(U8 reg)
+
+ DESCRIPTION: This function reads the registers
+
+ INPUT: U8 reg - register address
+
+ RETURN: SPI1DAT - the register content
+
+ NOTES: none
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
U8 SpiReadRegister (U8 reg)
{
//Select the radio by pulling the nSEL pin to low
NSS = 0;
//Write the address of the register into the SPI buffer of the MCU
//(important to clear the MSB bit)
SPI1DAT = reg; //write data into the SPI register
//Wait untill the MCU finishes sending the byte
while( SPIF1 == 0);
SPIF1 = 0;
//Write a dummy data byte into the SPI buffer of the MCU. During sending
//this byte the MCU will read the value of the radio register and save it
//in its SPI buffer.
SPI1DAT = 0xFF; //write dummy data into the SPI register
//Wait untill the MCU finishes sending the byte
while( SPIF1 == 0);
SPIF1 = 0;
//Deselect the radio by pulling high the nSEL pin
NSS = 1;
//Read the received radio register value and return with it
return SPI1DAT;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -