增加RF-AP程序

This commit is contained in:
haifeng.wang 2025-04-07 09:18:02 +08:00
parent bd11de83c5
commit d9b1f12e24
18 changed files with 10777 additions and 0 deletions

View File

@ -0,0 +1,307 @@
#ifndef FR2433_RFSX
#define FR2433_RFSX
////////////////////////////////////////////////////////////////////////////////
// 版权: Haybin.Wu@studio
// 文件名:
// 版本: V1.0
// 工作环境: IAR v6.20
// 作者: Haybin
// 生成日期: 2016.05
// 功能: API for FR4133
// 修改日志:
////////////////////////////////////////////////////////////////////////////////
#include <MSP430FR2433.h>
#include <stdbool.h>
//======================================================================================
#define CPU_MCLK 8000000
#define DelayUs(us) __delay_cycles((CPU_MCLK/1000000UL) * us)
#define DelayMs(ms) __delay_cycles((CPU_MCLK/1000UL) * ms)
////////////////////////////////////////////////////////////////////////////////
//只需修改下列引脚
//SX1276 SPI I/O definitions
#define SPI_PSEL P1SEL0
#define SPI_PDIR P1DIR
#define SPI_POUT P1OUT
#define SPI_SI_BIT BIT2
#define SPI_SO_BIT BIT3
#define SPI_CLK_BIT BIT1
#define SPI_NSS_BIT BIT0
#define SPI_NSS_PDIR P1DIR
#define SPI_NSS_POUT P1OUT
//DIO0
#define DIO0_BIT BIT6
#define DIO0_DIR P1DIR
#define DIO0_IFG P1IFG
#define DIO0_IES P1IES
#define DIO0_IE P1IE
//DIO1
#define DIO1_BIT BIT7
#define DIO1_DIR P1DIR
#define DIO1_IFG P1IFG
#define DIO1_IES P1IES
#define DIO1_IE P1IE
//DIO3
#define DIO3_BIT BIT4
#define DIO3_DIR P2DIR
#define DIO3_IFG P2IFG
#define DIO3_IES P2IES
#define DIO3_IE P2IE
//RST
#define RST_BIT BIT1
#define RST_PDIR P3DIR
#define RST_POUT P3OUT
////////////////////////////////////////////////////////////////////////////////
//SX1276 SPI I/O definitions
//NSS
#define SPI_NSS_DIR_OUT SPI_NSS_PDIR |= SPI_NSS_BIT //片选 out
#define SPI_NSS_OUT_1 SPI_NSS_POUT |= SPI_NSS_BIT //1
#define SPI_NSS_OUT_0 SPI_NSS_POUT &= (~SPI_NSS_BIT) //1
//DIO0
#define DIO0_IFG_H DIO0_IFG |= DIO0_BIT
#define DIO0_IFG_L DIO0_IFG &= ~DIO0_BIT
#define DIO0_IES_H DIO0_IES |= DIO0_BIT
#define DIO0_IES_L DIO0_IES &= ~DIO0_BIT
#define DIO0_IE_H DIO0_IE |= DIO0_BIT
#define DIO0_IE_L DIO0_IE &= ~DIO0_BIT
//DIO1
#define DIO1_IFG_H DIO1_IFG |= DIO1_BIT
#define DIO1_IFG_L DIO1_IFG &= ~DIO1_BIT
#define DIO1_IES_H DIO1_IES |= DIO1_BIT
#define DIO1_IES_L DIO1_IES &= ~DIO1_BIT
#define DIO1_IE_H DIO1_IE |= DIO0_BIT
#define DIO1_IE_L DIO1_IE &= ~DIO1_BIT
//DIO3
#define DIO3_IFG_H DIO3_IFG |= DIO3_BIT
#define DIO3_IFG_L DIO3_IFG &= ~DIO3_BIT
#define DIO3_IES_H DIO3_IES |= DIO3_BIT
#define DIO3_IES_L DIO3_IES &= ~DIO3_BIT
#define DIO3_IE_H DIO3_IE |= DIO3_BIT
#define DIO3_IE_L DIO3_IE &= ~DIO3_BIT
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : SX1276 I/O pins definitions
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276Init_IO( void )
{
//DIO0为P2.0
//P2DIR &= ~BIT0;
//P2OUT |= BIT0; // Configure DIO0 as pulled-up
//P2REN |= BIT0; // DIO0pull-up register enable
DIO0_DIR&=~DIO0_BIT;
DIO0_IES_L; // DIO0 Hi/Low edge
DIO0_IE_L; // DIO0 interrupt enabled
DIO0_IFG_L; // DIO0IFG cleared
//DIO1为P2.1
//P2DIR &= ~BIT1;
//P2OUT |= BIT1; // Configure DIO1 as pulled-up
//P2REN |= BIT1; // DIO1pull-up register enable
DIO1_DIR&=~DIO1_BIT;
DIO1_IES_L; // DIO1 Hi/Low edge
DIO1_IE_L; // DIO1 interrupt enabled
DIO1_IFG_L; // DIO1IFG cleared
//DIO3为P2.3
//P2DIR &= ~BIT3;
//P2OUT |= BIT3; // Configure DIO3 as pulled-up
//P2REN |= BIT3; // DIO3pull-up register enable
DIO3_DIR&=~DIO3_BIT;
DIO3_IES_L; // DIO3 Hi/Low edge
DIO3_IE_L; // DIO3 interrupt enabled
DIO3_IFG_L; // DIO3IFG cleared
//SX1276 SPI I/O definitions
// Configure SPI
//SPI SET
SPI_NSS_DIR_OUT;
SPI_NSS_OUT_1; // /CS disable
// SPI option select
SPI_PSEL |= SPI_SI_BIT+SPI_SO_BIT+SPI_CLK_BIT;
UCB0CTLW0 |= UCSWRST; // **Put state machine in reset**
UCB0CTLW0 |= UCMST|UCSYNC|UCCKPH|UCMSB; // 3-pin, 8-bit SPI master
// Clock polarity high, MSB
UCB0CTLW0 |= UCSSEL__SMCLK; // SMCLK
UCB0BR0 = 1; // /2,fBitClock = fBRCLK/(UCBRx+1).
UCB0BR1 = 0; //
UCB0CTLW0 &= ~UCSWRST; // **Initialize USCI state machine**
//SX1276 RESET I/O definitions
RST_PDIR |= RST_BIT;
RST_POUT |= RST_BIT;
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : 开启睡眠超时定时器
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void ON_Sleep_Timerout(void)
{
//Timer1_A3 setup
TA1R =0; //清除定时器计数器
TA1CCTL0 = CCIE; // TACCR0 interrupt enabled
TA1CCR0 = 32768;
TA0CTL |= TASSEL_1 | MC_1; //开启超时定时器
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : 关闭睡眠超时定时器
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void OFF_Sleep_Timerout(void)
{
//TA0R =0; //清除定时器计数器
TA1CCTL0 = CCIE; // TACCR0 interrupt enabled
TA1CCR0 = 32768;
TA0CTL = TASSEL_1 | MC_0; //关闭定时器
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 复位
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276Reset(void)
{
RST_POUT &= ~RST_BIT; //硬件复位IO口输出0
DelayMs(6); //延时
RST_POUT |= RST_BIT; //输出为1
DelayMs(5);
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向寄存器地址连续发送数据
// 输入参数 : uint8_t addr,寄存器地址 uint8_t *buffer,发送数组指针 uint8_t size指针长度
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
uint8_t i;
SPI_PSEL |= SPI_SO_BIT;//SPI的bug引起的功耗异常
SPI_NSS_OUT_0;
// _NOP();_NOP();_NOP();_NOP();
// _NOP();_NOP();_NOP();_NOP();
UCB0IFG &= ~UCRXIFG; // Clear flag
UCB0TXBUF = (addr | 0x80); // Send address
while (!(UCB0IFG&UCTXIFG)); // Wait for TX to finish
UCB0IFG &= ~UCTXIFG; // Clear flag
for( i = 0; i < size; i++ )
{
UCB0TXBUF = buffer[i]; // Send data
while (!(UCB0IFG&UCTXIFG)); // Wait for TX to finish
UCB0IFG &= ~UCTXIFG;
}
// _NOP();_NOP();_NOP();_NOP();
// _NOP();_NOP();_NOP();_NOP();
SPI_NSS_OUT_1;
SPI_PSEL &= ~SPI_SO_BIT;//SPI的bug引起的功耗异常
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向寄存器地址连续读数据
// 输入参数 : uint8_t addr,寄存器地址 uint8_t *buffer,存储数组指针 uint8_t size要读的长度
// 返回参数 : 数据返回到*buffer中
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
uint8_t i;
SPI_PSEL |= SPI_SO_BIT;//SPI的bug引起的功耗异常
SPI_NSS_OUT_0;
// _NOP();_NOP();_NOP();_NOP();
// _NOP();_NOP();_NOP();_NOP();
UCB0IFG &= ~UCRXIFG; // Clear flag
UCB0TXBUF = (addr & 0x7F); // Send address
while (!(UCB0IFG&UCTXIFG)); // Wait for end of addr byte TX
UCB0IFG &= ~UCTXIFG; // Clear flag
for( i = 0; i < size; i++ )
{
UCB0TXBUF = 0; //Initiate next data RX
while (!(UCB0IFG&UCRXIFG)); // Wait for RX to finish
buffer[i] = UCB0RXBUF; // Store data from last data RX
//读取UCB0RXBUF后IFG自动Reset
}
// _NOP();_NOP();_NOP();_NOP();
// _NOP();_NOP();_NOP();_NOP();
SPI_NSS_OUT_1;
SPI_PSEL &= ~SPI_SO_BIT;//SPI的bug引起的功耗异常
UCB0IFG=0;
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向寄存器地址写1字节数据
// 输入参数 : uint8_t addr,寄存器地址 uint8_t data数据
// 返回参数 :
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276Write( uint8_t addr, uint8_t data )
{
SX1276WriteBuffer( addr, &data, 1 );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向寄存器地址读1字节数据
// 输入参数 : uint8_t addr,寄存器地址 uint8_t *data读数据存储地址
// 返回参数 :
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276Read( uint8_t addr, uint8_t *data )
{
SX1276ReadBuffer( addr, data, 1 );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向FIFO写数据
// 输入参数 : uint8_t *buffer,数组指针 uint8_t size长度
// 返回参数 :
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276WriteFifo( uint8_t *buffer, uint8_t size )
{
SX1276WriteBuffer( 0, buffer, size );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向FIFO读数据
// 输入参数 : uint8_t *buffer,数组指针 uint8_t size长度
// 返回参数 : uint8_t *buffer 存储读取内容
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276ReadFifo( uint8_t *buffer, uint8_t size )
{
SX1276ReadBuffer( 0, buffer, size );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF TX/RX的PA切换
// 输入参数 : bool txEnable 切换逻辑
// 返回参数 : 无
// 说明 :真作为TX。假作为RX 为硬件两个PA控制IO口
////////////////////////////////////////////////////////////////////////////////
void SX1276WriteRxTx( bool txEnable )
{
if( txEnable != 0 ) //如果为真为TX
{
;
}
else //为假为RX
{
;
}
}
//*****************************************************************************************
#endif

View File

@ -0,0 +1,525 @@
// Haybin_Wu
// Shenitech-RD
// 2016.5
// Built with IAR Embedded Workbench v6.2
//******************************************************************************
// Modify by Qian Xianghong
// 2020.10
// 修改日志将无线模块做成串口和RF双向透传模式。
//******************************************************************************
#include <msp430FR2433.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "FR2433-RFSX.h"
#include "RF_SX1276.h"
// 射频配置参数
lora_param_t Lora_Param;
#define TRAN_BUF_SIZE (1024)
// 用UA1串口做打印输出方便调试
char printBuf[200];
void uart_print()
{
#if 0 // 打印串口的2个引脚用作MD0、MD1模式选择
char *p = printBuf;
while(*p)
{
if(*p == '\n') // 换行前添加回车
{
while(!(UCA1IFG & UCTXIFG));
UCA1TXBUF = '\r';
}
while(!(UCA1IFG & UCTXIFG));
UCA1TXBUF = *p++;
}
#endif
}
// 可变参数的宏定义
#define PRINTF(format, ...) \
{ \
snprintf(printBuf, sizeof(printBuf), format, ##__VA_ARGS__); \
uart_print(); \
}
// UA0接收上位机数据的buf
uint8_t UA0_RxBuf[TRAN_BUF_SIZE] = {0};
uint16_t UA0_RxBuf_Length = 0;
uint16_t UA0_RxBuf_offset = 0;
// UA0接收超时
volatile uint8_t UA0_Rx_Timeout = 1;
// RF接收数据的buf
uint8_t RF_RxBuf[TRAN_BUF_SIZE] = {0};
uint16_t RF_RxBuf_Length = 0;
uint16_t RF_RxBuf_offset = 0;
// RF接收超时标志
volatile uint8_t RF_Rx_Timeout = 1;
////////////////////////////////////////////////////////////////////////////////
// 主串口初始化
void UA0_Init(uint32_t baudrate)
{
// Configure UART
UCA0CTLW0 |=(UCSSEL__SMCLK+UCSWRST);//UCPEN+UCPAR+
// Baud Rate calculation
if(baudrate == 115200)
{
UCA0BR0 = 4; // 8000000/16/115200//这位大于16 UCOS16位要置位
UCA0BR1 = 0; // Fractional portion = 0.44444
UCA0MCTLW = 0x5500 | UCOS16 | UCBRF_5;//微调Baud Rate
}
else if(baudrate == 38400)
{
UCA0BR0 = 13; // 8000000/16/38400 /这位大于16 UCOS16位要置位
UCA0BR1 = 0; // Fractional portion = 0.33333
UCA0MCTLW = 0x8400 | UCOS16 | UCBRF_0;//微调Baud Rate
}
else
{
UCA0BR0 = 52; // 8000000/16/9600 /这位大于16 UCOS16位要置位
UCA0BR1 = 0; // Fractional portion = 0.33333
UCA0MCTLW = 0x4900 | UCOS16 | UCBRF_1;//微调Baud Rate
}
UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI
UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt
}
// 主串口应答(配置命令)
void UA0_Response(char *s)
{
while(*s)
{
while(!(UCA0IFG & UCTXIFG));
UCA0TXBUF = *s++;
}
// 等待发送结束
while(!(UCA0IFG & UCTXCPTIFG));
DelayMs(2);
}
////////////////////////////////////////////////////////////////////////////////
//主函数
////////////////////////////////////////////////////////////////////////////////
int main(void)
{
uint8_t sendCh;
uint8_t sf = 6, bw = 9, cr = 0, ch = 9;
WDTCTL = (WDTPW | WDTHOLD); // Stop WDT
// Port Configuration all un-used pins to output low
P1DIR = 0xFF; P2DIR = 0xFF; P3DIR = 0xFF;
P1OUT = 0x00; P2OUT = 0x00; P3OUT = 0x00;
PM5CTL0 &= ~LOCKLPM5;//开引脚功能
// Configure DCO Clock
//外部时钟源启动
P2SEL0 |= (BIT0 | BIT1); // set XT1 pin as second function
do
{
CSCTL7 &= ~(XT1OFFG | DCOFFG); // Clear XT1 and DCO fault flag
SFRIFG1 &= ~OFIFG;
} while (SFRIFG1 & OFIFG); // Test oscillator fault flag
//上面清除标志有助于降低功耗
__bis_SR_register(SCG0); // disable FLL
CSCTL3 |= SELREF__XT1CLK; // 外部 32768hz reference source
CSCTL0 = 0; // clear DCO and MOD registers
CSCTL1 &= ~(DCORSEL_7); // Clear DCO frequency select bits first
CSCTL1 |= DCORSEL_3; //DCO=8Mhz
CSCTL2 = FLLD_0 + 243; // DCODIV = 8MHz
__delay_cycles(3);
__bic_SR_register(SCG0); // enable FLL
while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // Poll until FLL is locked
CSCTL4 = SELREF__XT1CLK + SELMS__DCOCLKDIV;// set XT1CLK(32768Hz) as ACLK source & MCLK/SMCLK=DCO
//Timer0_A0 setup
TA0CCTL0 = CCIE; // TACCR0 interrupt enabled
TA0CCR0 = 32768 / 32; // 串口接收超时: 1000/32=31.25ms
TA0CTL = MC__STOP | TACLR; // Stop mode, Clear counter
//Timer1_A0 setup
TA1CCTL0 = CCIE; // TACCR0 interrupt enabled
TA1CCR0 = 32768 / 4; // RF接收超时: 1000/4=250ms
TA1CTL = MC__STOP | TACLR; // Stop mode, Clear counter
// 设置无线模块缺省参数
Lora_Param.sof = 0xC2;
Lora_Param.addr = 0xADF2; // 通信地址0xADF2
Lora_Param.sf = sf; // sf=12
Lora_Param.baud = 7; // 9600
Lora_Param.cr = cr; // cr=4/8
Lora_Param.ch = ch; // 479MHz
Lora_Param.power = 1; // 17dBm
Lora_Param.bw = bw; // 500kHz
Lora_Param.unicast = 0; // unicast off
// Configure UART pins
P1SEL1 &= ~(BIT4 | BIT5); // set 2-UART pin as second function
P1SEL0 |= (BIT4 | BIT5); // set 2-UART pin as second function
if(Lora_Param.baud == 7)
UA0_Init(115200);
else if(Lora_Param.baud == 5)
UA0_Init(38400);
else
UA0_Init(9600);
#if 0 // 打印串口配置
// Configure UART pins
P2SEL1 &= ~(BIT5 | BIT6); // set 2-UART pin as second function
P2SEL0 |= (BIT5 | BIT6); // set 2-UART pin as second function
// Configure UART
UCA1CTLW0 |=(UCSSEL__SMCLK+UCSWRST);//UCPEN+UCPAR+
// Baud Rate calculation
UCA1BR0 = 4; // 8000000/16/115200//这位大于16 UCOS16位要置位
UCA1BR1 = 0; // Fractional portion = 0.44444
UCA1MCTLW = 0x5500 | UCOS16 | UCBRF_5;//微调Baud Rate
UCA1CTLW0 &= ~UCSWRST; // Initialize eUSCI
UCA1IE |= UCRXIE; // Enable USCI_A0 RX interrupt
// 打印复位原因(电源引起,不包括看门狗)
PRINTF("\nModule reseted: %04X\n", PMMIFG);
#else // MD0、MD1模式配置
P2SEL1 &= ~(BIT3 | BIT5 | BIT6); // set 2-UART pin as GPIO
P2SEL0 &= ~(BIT3 | BIT5 | BIT6); // set 2-UART pin as GPIO
P2DIR &= ~(BIT5 | BIT6); // Input
P2REN |= (BIT5 | BIT6); // enable pull
P2OUT &= ~(BIT5 | BIT6); // pull-down
P2DIR |= BIT3; // Output
P2OUT |= BIT3; // Output high
#endif
_EINT();
// 打印复位原因(电源引起,不包括看门狗)
// RF_RxBuf[0] = PMMIFG >> 8;
// RF_RxBuf[1] = PMMIFG & 0xFF;
// RF_RxBuf_Length = 2;
// RF_RxBuf_offset = 0;
// UCA0IE |= UCTXIE;
// while(UCA0IE & UCTXIE);
// 读寄存器,清除复位原因
SYSRSTIV;
//无线模块测试化
uint8_t try_count = 3; //最多初始化3次
while(try_count)
{
if(SX127x_initLora(&Lora_Param) == NORMAL)
break; //无线模块初始化失败复位
try_count--;
}
if(try_count == 0) //无线初始化失败处理
{
//P3OUT ^= 0xC0;
LPM4;
}
// 初始处于接收模式
LSD_RF_RXmode(RF_PAYLOAD_LEN);
// 默认发送信道
sendCh = Lora_Param.ch;
// 开启看门狗: 超时时间为2^27/SMCLK在8000000主频下约为16s
WDTCTL = (WDTPW | WDTCNTCL | WDTIS_1);
while(1)
{
#if 0
// for(cr = 0; cr <= 3; cr++)
{
for(ch = 0; ch <= 40; ch++)
{
// TODO: 喂狗
WDTCTL = (WDTPW | WDTCNTCL | WDTIS_1);
// 发送参数
RF_RxBuf[0] = cr;
RF_RxBuf[1] = ch;
RF_RxBuf_Length = 2;
RF_RxBuf_offset = 0;
UCA0IE |= UCTXIE;
while(UCA0IE & UCTXIE);
// 发送报文
Lora_Param.cr = cr;
Lora_Param.ch = ch;
uint8_t try_count = 3; //最多初始化3次
while(try_count)
{
if(SX127x_initLora(&Lora_Param) == NORMAL)
break; //无线模块初始化失败复位
try_count--;
}
if(try_count == 0) //无线初始化失败处理
{
//P3OUT ^= 0xC0;
LPM4;
}
UA0_RxBuf_offset = UA0_RxBuf_Length;
// 切换到接收模式
LSD_RF_FreqSet(Lora_Param.ch);
LSD_RF_RXmode(RF_PAYLOAD_LEN);
RF_RxBuf[0] = Lora_Param.sf;
RF_RxBuf[1] = Lora_Param.bw;
RF_RxBuf_Length = 2;
RF_RxBuf_offset = 0;
UCA0IE |= UCTXIE;
while(UCA0IE & UCTXIE);
// 延迟3秒
DelayMs(4000);
}
}
#else
#if 1
// TODO: 喂狗
WDTCTL = (WDTPW | WDTCNTCL | WDTIS_1);
// 配置模式
if((P2IN & (BIT5 | BIT6)) == (BIT5 | BIT6))
{
if(UA0_RxBuf_Length - UA0_RxBuf_offset >= 6)
{
P2OUT &= ~BIT3; // Output low
if(UA0_RxBuf[0] == 0xC2)
{
// 保存参数
memmove(&Lora_Param, UA0_RxBuf, sizeof(Lora_Param));
Lora_Param.addr = (UA0_RxBuf[1] << 8) | UA0_RxBuf[2];
//无线模块测试化
uint8_t try_count = 3; //最多初始化3次
while(try_count)
{
if(SX127x_initLora(&Lora_Param) == NORMAL)
break; //无线模块初始化失败复位
try_count--;
}
if(try_count == 0) //无线初始化失败处理
{
//P3OUT ^= 0xC0;
LPM4;
}
// 默认处于接收模式
LSD_RF_RXmode(RF_PAYLOAD_LEN);
// 默认发送信道
sendCh = Lora_Param.ch;
// 应答配置命令
UA0_Response("OK\r\n");
// 改变串口波特率
if(Lora_Param.baud == 7)
UA0_Init(115200);
else if(Lora_Param.baud == 5)
UA0_Init(38400);
else
UA0_Init(9600);
}
UA0_RxBuf_offset += 6;
P2OUT |= BIT3; // Output high
}
}
// 透传模式
else if((P2IN & (BIT5 | BIT6)) == 0)
#endif
{
if(UA0_RxBuf_Length > UA0_RxBuf_offset)
{
// 定点传输,用指定信道发送
if(Lora_Param.unicast && UA0_RxBuf_offset == 0 && UA0_RxBuf_Length > 3)
sendCh = UA0_RxBuf[2];
if(UA0_RxBuf_Length - UA0_RxBuf_offset >= RF_PAYLOAD_LEN)
{
LSD_RF_FreqSet(sendCh);
LSD_RF_SendPacket(UA0_RxBuf + UA0_RxBuf_offset, RF_PAYLOAD_LEN);
UA0_RxBuf_offset += RF_PAYLOAD_LEN;
PRINTF("Send packet\n");
// 切换到接收模式
LSD_RF_FreqSet(Lora_Param.ch);
LSD_RF_RXmode(RF_PAYLOAD_LEN);
}
else if(UA0_Rx_Timeout)
{
LSD_RF_FreqSet(sendCh);
LSD_RF_SendPacket(UA0_RxBuf + UA0_RxBuf_offset, UA0_RxBuf_Length - UA0_RxBuf_offset);
UA0_RxBuf_offset = UA0_RxBuf_Length;
PRINTF("Send packet\n");
// 切换到接收模式
LSD_RF_FreqSet(Lora_Param.ch);
LSD_RF_RXmode(RF_PAYLOAD_LEN);
}
}
}
#endif
}
}
// Port 1 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(PORT1_VECTOR))) Port_1 (void)
#else
#error Compiler not supported!
#endif
{
uint8_t offset = 0;
uint8_t len[1] = {0};
uint8_t buf[RF_PAYLOAD_LEN];
if(DIO0_IFG&DIO0_BIT) //数据传输中断处理
{
// 清中断
DIO0_IFG &= ~DIO0_BIT;
// 读取RF数据
LSD_RF_RxVariPacket(buf, len); //接收可变数据包,如果速率为大速率,只能用接收固定数据包长度
if(len[0] == 0)
return;
TA1CTL = MC__STOP | TACLR; // 停止定时器,复位计数器
TA1CTL = TASSEL__ACLK | MC__UP; // 重新开始计时
offset = 0;
if(RF_Rx_Timeout) // 新的一组数据到来
{
RF_Rx_Timeout = 0;
// 复位缓冲区
RF_RxBuf_Length = 0;
RF_RxBuf_offset = 0;
if(Lora_Param.unicast)
{
// 定点传输,地址和信道校验失败
if(len[0] <= 3 || buf[2] != Lora_Param.ch || ((buf[0] << 8) | buf[1]) != Lora_Param.addr)
return;
// 前3个字符丢掉
offset = 3;
len[0] -= offset;
}
}
PRINTF("Recv packet\n");
// 透传模式
if((P2IN & (BIT5 | BIT6)) == 0)
{
if(RF_RxBuf_Length + len[0] <= TRAN_BUF_SIZE)
{
memmove(RF_RxBuf + RF_RxBuf_Length, buf + offset, len[0]);
// 中断方式向串口转发
RF_RxBuf_Length += len[0];
UCA0IE |= UCTXIE;
}
}
}
}
// Timer0 A0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) Timer0_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
// 停止定时器,复位计数器
TA0CTL = MC__STOP | TACLR;
// 串口接收超时
UA0_Rx_Timeout = 1;
}
// Timer1 A0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER1_A0_VECTOR
__interrupt void Timer1_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER1_A0_VECTOR))) Timer1_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
// 停止定时器,复位计数器
TA1CTL = MC__STOP | TACLR;
// RF接收超时
RF_Rx_Timeout = 1;
}
// UAR0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
// 接收中断
if((UCA0IE & UCRXIE) && (UCA0IFG & UCRXIFG))
{
uint8_t c = UCA0RXBUF;
TA0CTL = MC__STOP | TACLR; // 停止定时器,复位计数器
TA0CTL = TASSEL__ACLK | MC__UP; // 重新开始计时
if(UA0_Rx_Timeout) // 新的一组数据到来
{
UA0_Rx_Timeout = 0;
// 复位缓冲区
UA0_RxBuf_Length = 0;
UA0_RxBuf_offset = 0;
}
if(UA0_RxBuf_Length < TRAN_BUF_SIZE)
{
#if 1
// 配置模式
if((P2IN & (BIT5 | BIT6)) == (BIT5 | BIT6))
{
// 第1个字符必须为0xC2
if(UA0_RxBuf_Length > 0 || c == 0xC2)
UA0_RxBuf[UA0_RxBuf_Length++] = c;
}
// 透传模式
else if((P2IN & (BIT5 | BIT6)) == 0)
#endif
{
// 主函数透传
UA0_RxBuf[UA0_RxBuf_Length++] = c;
}
}
}
// 发送中断
if((UCA0IE & UCTXIE) && (UCA0IFG & UCTXIFG))
{
UCA0TXBUF = RF_RxBuf[RF_RxBuf_offset++]; // 发送字符
if(RF_RxBuf_offset >= RF_RxBuf_Length) // 全部发送完
{
// 禁止中断
UCA0IE &= ~UCTXIE;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,307 @@
#ifndef FR2433_RFSX
#define FR2433_RFSX
////////////////////////////////////////////////////////////////////////////////
// 版权: Haybin.Wu@studio
// 文件名:
// 版本: V1.0
// 工作环境: IAR v6.20
// 作者: Haybin
// 生成日期: 2016.05
// 功能: API for FR4133
// 修改日志:
////////////////////////////////////////////////////////////////////////////////
#include <MSP430FR2433.h>
#include <stdbool.h>
//======================================================================================
#define CPU_MCLK 8000000
#define DelayUs(us) __delay_cycles((CPU_MCLK/1000000UL) * us)
#define DelayMs(ms) __delay_cycles((CPU_MCLK/1000UL) * ms)
////////////////////////////////////////////////////////////////////////////////
//只需修改下列引脚
//SX1276 SPI I/O definitions
#define SPI_PSEL P1SEL0
#define SPI_PDIR P1DIR
#define SPI_POUT P1OUT
#define SPI_SI_BIT BIT2
#define SPI_SO_BIT BIT3
#define SPI_CLK_BIT BIT1
#define SPI_NSS_BIT BIT0
#define SPI_NSS_PDIR P1DIR
#define SPI_NSS_POUT P1OUT
//DIO0
#define DIO0_BIT BIT6
#define DIO0_DIR P1DIR
#define DIO0_IFG P1IFG
#define DIO0_IES P1IES
#define DIO0_IE P1IE
//DIO1
#define DIO1_BIT BIT7
#define DIO1_DIR P1DIR
#define DIO1_IFG P1IFG
#define DIO1_IES P1IES
#define DIO1_IE P1IE
//DIO3
#define DIO3_BIT BIT4
#define DIO3_DIR P2DIR
#define DIO3_IFG P2IFG
#define DIO3_IES P2IES
#define DIO3_IE P2IE
//RST
#define RST_BIT BIT1
#define RST_PDIR P3DIR
#define RST_POUT P3OUT
////////////////////////////////////////////////////////////////////////////////
//SX1276 SPI I/O definitions
//NSS
#define SPI_NSS_DIR_OUT SPI_NSS_PDIR |= SPI_NSS_BIT //片选 out
#define SPI_NSS_OUT_1 SPI_NSS_POUT |= SPI_NSS_BIT //1
#define SPI_NSS_OUT_0 SPI_NSS_POUT &= (~SPI_NSS_BIT) //1
//DIO0
#define DIO0_IFG_H DIO0_IFG |= DIO0_BIT
#define DIO0_IFG_L DIO0_IFG &= ~DIO0_BIT
#define DIO0_IES_H DIO0_IES |= DIO0_BIT
#define DIO0_IES_L DIO0_IES &= ~DIO0_BIT
#define DIO0_IE_H DIO0_IE |= DIO0_BIT
#define DIO0_IE_L DIO0_IE &= ~DIO0_BIT
//DIO1
#define DIO1_IFG_H DIO1_IFG |= DIO1_BIT
#define DIO1_IFG_L DIO1_IFG &= ~DIO1_BIT
#define DIO1_IES_H DIO1_IES |= DIO1_BIT
#define DIO1_IES_L DIO1_IES &= ~DIO1_BIT
#define DIO1_IE_H DIO1_IE |= DIO0_BIT
#define DIO1_IE_L DIO1_IE &= ~DIO1_BIT
//DIO3
#define DIO3_IFG_H DIO3_IFG |= DIO3_BIT
#define DIO3_IFG_L DIO3_IFG &= ~DIO3_BIT
#define DIO3_IES_H DIO3_IES |= DIO3_BIT
#define DIO3_IES_L DIO3_IES &= ~DIO3_BIT
#define DIO3_IE_H DIO3_IE |= DIO3_BIT
#define DIO3_IE_L DIO3_IE &= ~DIO3_BIT
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : SX1276 I/O pins definitions
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276Init_IO( void )
{
//DIO0为P2.0
//P2DIR &= ~BIT0;
//P2OUT |= BIT0; // Configure DIO0 as pulled-up
//P2REN |= BIT0; // DIO0pull-up register enable
DIO0_DIR&=~DIO0_BIT;
DIO0_IES_L; // DIO0 Hi/Low edge
DIO0_IE_L; // DIO0 interrupt enabled
DIO0_IFG_L; // DIO0IFG cleared
//DIO1为P2.1
//P2DIR &= ~BIT1;
//P2OUT |= BIT1; // Configure DIO1 as pulled-up
//P2REN |= BIT1; // DIO1pull-up register enable
DIO1_DIR&=~DIO1_BIT;
DIO1_IES_L; // DIO1 Hi/Low edge
DIO1_IE_L; // DIO1 interrupt enabled
DIO1_IFG_L; // DIO1IFG cleared
//DIO3为P2.3
//P2DIR &= ~BIT3;
//P2OUT |= BIT3; // Configure DIO3 as pulled-up
//P2REN |= BIT3; // DIO3pull-up register enable
DIO3_DIR&=~DIO3_BIT;
DIO3_IES_L; // DIO3 Hi/Low edge
DIO3_IE_L; // DIO3 interrupt enabled
DIO3_IFG_L; // DIO3IFG cleared
//SX1276 SPI I/O definitions
// Configure SPI
//SPI SET
SPI_NSS_DIR_OUT;
SPI_NSS_OUT_1; // /CS disable
// SPI option select
SPI_PSEL |= SPI_SI_BIT+SPI_SO_BIT+SPI_CLK_BIT;
UCB0CTLW0 |= UCSWRST; // **Put state machine in reset**
UCB0CTLW0 |= UCMST|UCSYNC|UCCKPH|UCMSB; // 3-pin, 8-bit SPI master
// Clock polarity high, MSB
UCB0CTLW0 |= UCSSEL__SMCLK; // SMCLK
UCB0BR0 = 1; // /2,fBitClock = fBRCLK/(UCBRx+1).
UCB0BR1 = 0; //
UCB0CTLW0 &= ~UCSWRST; // **Initialize USCI state machine**
//SX1276 RESET I/O definitions
RST_PDIR |= RST_BIT;
RST_POUT |= RST_BIT;
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : 开启睡眠超时定时器
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void ON_Sleep_Timerout(void)
{
//Timer1_A3 setup
TA1R =0; //清除定时器计数器
TA1CCTL0 = CCIE; // TACCR0 interrupt enabled
TA1CCR0 = 32768;
TA0CTL |= TASSEL_1 | MC_1; //开启超时定时器
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : 关闭睡眠超时定时器
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void OFF_Sleep_Timerout(void)
{
//TA0R =0; //清除定时器计数器
TA1CCTL0 = CCIE; // TACCR0 interrupt enabled
TA1CCR0 = 32768;
TA0CTL = TASSEL_1 | MC_0; //关闭定时器
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 复位
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276Reset(void)
{
RST_POUT &= ~RST_BIT; //硬件复位IO口输出0
DelayMs(6); //延时
RST_POUT |= RST_BIT; //输出为1
DelayMs(5);
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向寄存器地址连续发送数据
// 输入参数 : uint8_t addr,寄存器地址 uint8_t *buffer,发送数组指针 uint8_t size指针长度
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
uint8_t i;
SPI_PSEL |= SPI_SO_BIT;//SPI的bug引起的功耗异常
SPI_NSS_OUT_0;
// _NOP();_NOP();_NOP();_NOP();
// _NOP();_NOP();_NOP();_NOP();
UCB0IFG &= ~UCRXIFG; // Clear flag
UCB0TXBUF = (addr | 0x80); // Send address
while (!(UCB0IFG&UCTXIFG)); // Wait for TX to finish
UCB0IFG &= ~UCTXIFG; // Clear flag
for( i = 0; i < size; i++ )
{
UCB0TXBUF = buffer[i]; // Send data
while (!(UCB0IFG&UCTXIFG)); // Wait for TX to finish
UCB0IFG &= ~UCTXIFG;
}
// _NOP();_NOP();_NOP();_NOP();
// _NOP();_NOP();_NOP();_NOP();
SPI_NSS_OUT_1;
SPI_PSEL &= ~SPI_SO_BIT;//SPI的bug引起的功耗异常
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向寄存器地址连续读数据
// 输入参数 : uint8_t addr,寄存器地址 uint8_t *buffer,存储数组指针 uint8_t size要读的长度
// 返回参数 : 数据返回到*buffer中
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
uint8_t i;
SPI_PSEL |= SPI_SO_BIT;//SPI的bug引起的功耗异常
SPI_NSS_OUT_0;
// _NOP();_NOP();_NOP();_NOP();
// _NOP();_NOP();_NOP();_NOP();
UCB0IFG &= ~UCRXIFG; // Clear flag
UCB0TXBUF = (addr & 0x7F); // Send address
while (!(UCB0IFG&UCTXIFG)); // Wait for end of addr byte TX
UCB0IFG &= ~UCTXIFG; // Clear flag
for( i = 0; i < size; i++ )
{
UCB0TXBUF = 0; //Initiate next data RX
while (!(UCB0IFG&UCRXIFG)); // Wait for RX to finish
buffer[i] = UCB0RXBUF; // Store data from last data RX
//读取UCB0RXBUF后IFG自动Reset
}
// _NOP();_NOP();_NOP();_NOP();
// _NOP();_NOP();_NOP();_NOP();
SPI_NSS_OUT_1;
SPI_PSEL &= ~SPI_SO_BIT;//SPI的bug引起的功耗异常
UCB0IFG=0;
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向寄存器地址写1字节数据
// 输入参数 : uint8_t addr,寄存器地址 uint8_t data数据
// 返回参数 :
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276Write( uint8_t addr, uint8_t data )
{
SX1276WriteBuffer( addr, &data, 1 );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向寄存器地址读1字节数据
// 输入参数 : uint8_t addr,寄存器地址 uint8_t *data读数据存储地址
// 返回参数 :
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276Read( uint8_t addr, uint8_t *data )
{
SX1276ReadBuffer( addr, data, 1 );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向FIFO写数据
// 输入参数 : uint8_t *buffer,数组指针 uint8_t size长度
// 返回参数 :
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276WriteFifo( uint8_t *buffer, uint8_t size )
{
SX1276WriteBuffer( 0, buffer, size );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向FIFO读数据
// 输入参数 : uint8_t *buffer,数组指针 uint8_t size长度
// 返回参数 : uint8_t *buffer 存储读取内容
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276ReadFifo( uint8_t *buffer, uint8_t size )
{
SX1276ReadBuffer( 0, buffer, size );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF TX/RX的PA切换
// 输入参数 : bool txEnable 切换逻辑
// 返回参数 : 无
// 说明 :真作为TX。假作为RX 为硬件两个PA控制IO口
////////////////////////////////////////////////////////////////////////////////
void SX1276WriteRxTx( bool txEnable )
{
if( txEnable != 0 ) //如果为真为TX
{
;
}
else //为假为RX
{
;
}
}
//*****************************************************************************************
#endif

View File

@ -0,0 +1,491 @@
// Haybin_Wu
// Shenitech-RD
// 2016.5
// Built with IAR Embedded Workbench v6.2
//******************************************************************************
// Modify by Qian Xianghong
// 2020.10
// 修改日志将无线模块做成串口和RF双向透传模式。
//******************************************************************************
#include <msp430FR2433.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "FR2433-RFSX.h"
#include "RF_SX1276.h"
// 射频配置参数
lora_param_t Lora_Param;
#define TRAN_BUF_SIZE (1024)
// 用UA1串口做打印输出方便调试
char printBuf[200];
void uart_print()
{
#if 0 // 打印串口的2个引脚用作MD0、MD1模式选择
char *p = printBuf;
while(*p)
{
if(*p == '\n') // 换行前添加回车
{
while(!(UCA1IFG & UCTXIFG));
UCA1TXBUF = '\r';
}
while(!(UCA1IFG & UCTXIFG));
UCA1TXBUF = *p++;
}
#endif
}
// 可变参数的宏定义
#define PRINTF(format, ...) \
{ \
snprintf(printBuf, sizeof(printBuf), format, ##__VA_ARGS__); \
uart_print(); \
}
// UA0接收上位机数据的buf
uint8_t UA0_RxBuf[TRAN_BUF_SIZE] = {0};
uint16_t UA0_RxBuf_Length = 0;
uint16_t UA0_RxBuf_offset = 0;
// UA0接收超时
volatile uint8_t UA0_Rx_Timeout = 1;
// RF接收数据的buf
uint8_t RF_RxBuf[TRAN_BUF_SIZE] = {0};
uint16_t RF_RxBuf_Length = 0;
uint16_t RF_RxBuf_offset = 0;
// RF接收超时标志
volatile uint8_t RF_Rx_Timeout = 1;
////////////////////////////////////////////////////////////////////////////////
// 主串口初始化
void UA0_Init(uint32_t baudrate)
{
// Configure UART
UCA0CTLW0 |=(UCSSEL__SMCLK+UCSWRST);//UCPEN+UCPAR+
// Baud Rate calculation
if(baudrate == 115200)
{
UCA0BR0 = 4; // 8000000/16/115200//这位大于16 UCOS16位要置位
UCA0BR1 = 0; // Fractional portion = 0.44444
UCA0MCTLW = 0x5500 | UCOS16 | UCBRF_5;//微调Baud Rate
}
else if(baudrate == 38400)
{
UCA0BR0 = 13; // 8000000/16/38400 /这位大于16 UCOS16位要置位
UCA0BR1 = 0; // Fractional portion = 0.33333
UCA0MCTLW = 0x8400 | UCOS16 | UCBRF_0;//微调Baud Rate
}
else
{
UCA0BR0 = 52; // 8000000/16/9600 /这位大于16 UCOS16位要置位
UCA0BR1 = 0; // Fractional portion = 0.33333
UCA0MCTLW = 0x4900 | UCOS16 | UCBRF_1;//微调Baud Rate
}
UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI
UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt
}
// 主串口应答(配置命令)
void UA0_Response(char *s)
{
while(*s)
{
while(!(UCA0IFG & UCTXIFG));
UCA0TXBUF = *s++;
}
// 等待发送结束
while(!(UCA0IFG & UCTXCPTIFG));
DelayMs(2);
}
////////////////////////////////////////////////////////////////////////////////
//主函数
////////////////////////////////////////////////////////////////////////////////
int main(void)
{
uint8_t sendCh;
WDTCTL = (WDTPW | WDTHOLD); // Stop WDT
// Port Configuration all un-used pins to output low
P1DIR = 0xFF; P2DIR = 0xFF; P3DIR = 0xFF;
P1OUT = 0x00; P2OUT = 0x00; P3OUT = 0x00;
PM5CTL0 &= ~LOCKLPM5;//开引脚功能
// Configure DCO Clock
//外部时钟源启动
P2SEL0 |= (BIT0 | BIT1); // set XT1 pin as second function
do
{
CSCTL7 &= ~(XT1OFFG | DCOFFG); // Clear XT1 and DCO fault flag
SFRIFG1 &= ~OFIFG;
} while (SFRIFG1 & OFIFG); // Test oscillator fault flag
//上面清除标志有助于降低功耗
__bis_SR_register(SCG0); // disable FLL
CSCTL3 |= SELREF__XT1CLK; // 外部 32768hz reference source
CSCTL0 = 0; // clear DCO and MOD registers
CSCTL1 &= ~(DCORSEL_7); // Clear DCO frequency select bits first
CSCTL1 |= DCORSEL_3; //DCO=8Mhz
CSCTL2 = FLLD_0 + 243; // DCODIV = 8MHz
__delay_cycles(3);
__bic_SR_register(SCG0); // enable FLL
while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // Poll until FLL is locked
CSCTL4 = SELREF__XT1CLK + SELMS__DCOCLKDIV;// set XT1CLK(32768Hz) as ACLK source & MCLK/SMCLK=DCO
//Timer0_A0 setup
TA0CCTL0 = CCIE; // TACCR0 interrupt enabled
TA0CCR0 = 32768 / 32; // 串口接收超时: 1000/32=31.25ms
TA0CTL = MC__STOP | TACLR; // Stop mode, Clear counter
//Timer1_A0 setup
TA1CCTL0 = CCIE; // TACCR0 interrupt enabled
TA1CCR0 = 32768 / 4; // RF接收超时: 1000/4=250ms
TA1CTL = MC__STOP | TACLR; // Stop mode, Clear counter
// 设置无线模块缺省参数
Lora_Param.sof = 0xC2;
Lora_Param.addr = 0xADF2; // 通信地址0xADF2
Lora_Param.sf = 6; // sf=12
Lora_Param.baud = 3; // 9600
Lora_Param.cr = 0; // cr=4/5
Lora_Param.ch = 9; // 479MHz
Lora_Param.power = 1; // 17dBm
Lora_Param.freqcast = 0; // freqcast off
Lora_Param.bw = 9; // 500kHz
Lora_Param.unicast = 0; // unicast off
// Configure UART pins
P1SEL1 &= ~(BIT4 | BIT5); // set 2-UART pin as second function
P1SEL0 |= (BIT4 | BIT5); // set 2-UART pin as second function
if(Lora_Param.baud == 7)
UA0_Init(115200);
else if(Lora_Param.baud == 5)
UA0_Init(38400);
else
UA0_Init(9600);
#if 0 // 配置打印串口
// Configure UART pins
P2SEL1 &= ~(BIT5 | BIT6); // set 2-UART pin as second function
P2SEL0 |= (BIT5 | BIT6); // set 2-UART pin as second function
// Configure UART
UCA1CTLW0 |=(UCSSEL__SMCLK+UCSWRST);//UCPEN+UCPAR+
// Baud Rate calculation
UCA1BR0 = 4; // 8000000/16/115200//这位大于16 UCOS16位要置位
UCA1BR1 = 0; // Fractional portion = 0.44444
UCA1MCTLW = 0x5500 | UCOS16 | UCBRF_5;//微调Baud Rate
UCA1CTLW0 &= ~UCSWRST; // Initialize eUSCI
UCA1IE |= UCRXIE; // Enable USCI_A0 RX interrupt
// 打印复位原因(电源引起,不包括看门狗)
PRINTF("\nModule reseted: %04X\n", PMMIFG);
#else // 配置MD0、MD1模式
P2SEL1 &= ~(BIT3 | BIT5 | BIT6); // set 2-UART pin as GPIO
P2SEL0 &= ~(BIT3 | BIT5 | BIT6); // set 2-UART pin as GPIO
P2DIR &= ~(BIT5 | BIT6); // Input
P2REN |= (BIT5 | BIT6); // enable pull
P2OUT &= ~(BIT5 | BIT6); // pull-down
P2DIR |= BIT3; // Output
P2OUT |= BIT3; // Output high
#endif
_EINT();
#if 0
// 打印复位原因(电源引起,不包括看门狗)
RF_RxBuf[0] = PMMIFG >> 8;
RF_RxBuf[1] = PMMIFG & 0xFF;
RF_RxBuf_Length = 2;
RF_RxBuf_offset = 0;
UCA0IE |= UCTXIE;
while(UCA0IE & UCTXIE);
#endif
// 读寄存器,清除复位原因
SYSRSTIV;
//无线模块初始化
uint8_t try_count = 3; //最多初始化3次
while(try_count)
{
if(SX127x_initLora(&Lora_Param) == NORMAL)
break;
try_count--;
}
if(try_count == 0) //无线初始化失败处理
{
//P3OUT ^= 0xC0;
LPM4;
}
// 初始处于接收模式
LSD_RF_RXmode(RF_PAYLOAD_LEN);
// 默认发送信道
sendCh = Lora_Param.ch;
// 开启看门狗: 超时时间为2^27/SMCLK在8000000主频下约为16s
WDTCTL = (WDTPW | WDTCNTCL | WDTIS_1);
while(1)
{
#if 1
// TODO: 喂狗
WDTCTL = (WDTPW | WDTCNTCL | WDTIS_1);
// 配置模式
if((P2IN & (BIT5 | BIT6)) == (BIT5 | BIT6))
{
if(UA0_RxBuf_Length - UA0_RxBuf_offset >= sizeof(Lora_Param))
{
if(UA0_RxBuf[UA0_RxBuf_offset] == 0xC2)
{
// 保存参数
memmove(&Lora_Param, UA0_RxBuf + UA0_RxBuf_offset, sizeof(Lora_Param));
// 颠倒地址高低字节
Lora_Param.addr = (Lora_Param.addr << 8) | (Lora_Param.addr >> 8);
//无线模块初始化
uint8_t try_count = 3; //最多初始化3次
while(try_count)
{
// 其它参数有变化,无线模块初始化
if(SX127x_initLora(&Lora_Param) == NORMAL)
break;
try_count--;
}
if(try_count == 0) //无线初始化失败处理
{
//P3OUT ^= 0xC0;
LPM4;
}
// 默认处于接收模式
LSD_RF_RXmode(RF_PAYLOAD_LEN);
// 默认发送信道
sendCh = Lora_Param.ch;
// 应答配置命令
UA0_Response("OK\r\n");
// 改变串口波特率
if(Lora_Param.baud == 7)
UA0_Init(115200);
else if(Lora_Param.baud == 5)
UA0_Init(38400);
else
UA0_Init(9600);
}
UA0_RxBuf_offset = UA0_RxBuf_Length;
}
}
// 透传模式
else if((P2IN & (BIT5 | BIT6)) == 0)
#endif
{
if(UA0_RxBuf_Length > UA0_RxBuf_offset)
{
// 定点传输,指定目标地址和信道发送
if(Lora_Param.unicast) // 定点发送
{
if(UA0_RxBuf_offset == 0 && UA0_RxBuf_Length > 3)
sendCh = UA0_RxBuf[2];
}
else if(Lora_Param.freqcast) // 指定信道发送
{
if(UA0_RxBuf_offset == 0 && UA0_RxBuf_Length > 1)
{
sendCh = UA0_RxBuf[0];
UA0_RxBuf_offset = 1; // 不发送第1发个字节
}
}
if(UA0_RxBuf_Length - UA0_RxBuf_offset >= RF_PAYLOAD_LEN)
{
LSD_RF_FreqSet(sendCh);
LSD_RF_SendPacket(UA0_RxBuf + UA0_RxBuf_offset, RF_PAYLOAD_LEN);
UA0_RxBuf_offset += RF_PAYLOAD_LEN;
PRINTF("Send packet\n");
// 切换到接收模式
LSD_RF_FreqSet(Lora_Param.ch);
LSD_RF_RXmode(RF_PAYLOAD_LEN);
}
else if(UA0_Rx_Timeout)
{
LSD_RF_FreqSet(sendCh);
LSD_RF_SendPacket(UA0_RxBuf + UA0_RxBuf_offset, UA0_RxBuf_Length - UA0_RxBuf_offset);
UA0_RxBuf_offset = UA0_RxBuf_Length;
PRINTF("Send packet\n");
// 切换到接收模式
LSD_RF_FreqSet(Lora_Param.ch);
LSD_RF_RXmode(RF_PAYLOAD_LEN);
}
}
}
if(UA0_Rx_Timeout && UA0_RxBuf_offset == UA0_RxBuf_Length)
P2OUT |= BIT3; // Output high
}
}
// Port 1 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(PORT1_VECTOR))) Port_1 (void)
#else
#error Compiler not supported!
#endif
{
uint8_t offset = 0;
uint8_t len[1] = {0};
uint8_t buf[RF_PAYLOAD_LEN];
if(DIO0_IFG&DIO0_BIT) //数据传输中断处理
{
// 清中断
DIO0_IFG &= ~DIO0_BIT;
// 读取RF数据
LSD_RF_RxVariPacket(buf, len); //接收可变数据包,如果速率为大速率,只能用接收固定数据包长度
if(len[0] == 0)
return;
TA1CTL = MC__STOP | TACLR; // 停止定时器,复位计数器
TA1CTL = TASSEL__ACLK | MC__UP; // 重新开始计时
offset = 0;
if(RF_Rx_Timeout) // 新的一组数据到来
{
RF_Rx_Timeout = 0;
// 复位缓冲区
RF_RxBuf_Length = 0;
RF_RxBuf_offset = 0;
if(Lora_Param.unicast)
{
// 定点传输,地址和信道校验失败
if(len[0] <= 3 || buf[2] != Lora_Param.ch || ((buf[0] << 8) | buf[1]) != Lora_Param.addr)
return;
// 前3个字符丢掉
offset = 3;
len[0] -= offset;
}
}
PRINTF("Recv packet\n");
// 透传模式
if((P2IN & (BIT5 | BIT6)) == 0)
{
if(RF_RxBuf_Length + len[0] <= TRAN_BUF_SIZE)
{
memmove(RF_RxBuf + RF_RxBuf_Length, buf + offset, len[0]);
// 中断方式向串口转发
RF_RxBuf_Length += len[0];
UCA0IE |= UCTXIE;
}
}
}
}
// Timer0 A0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) Timer0_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
// 停止定时器,复位计数器
TA0CTL = MC__STOP | TACLR;
// 串口接收超时
UA0_Rx_Timeout = 1;
}
// Timer1 A0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER1_A0_VECTOR
__interrupt void Timer1_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER1_A0_VECTOR))) Timer1_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
// 停止定时器,复位计数器
TA1CTL = MC__STOP | TACLR;
// RF接收超时
RF_Rx_Timeout = 1;
}
// UAR0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
// 接收中断
if((UCA0IE & UCRXIE) && (UCA0IFG & UCRXIFG))
{
uint8_t c = UCA0RXBUF;
TA0CTL = MC__STOP | TACLR; // 停止定时器,复位计数器
TA0CTL = TASSEL__ACLK | MC__UP; // 重新开始计时
if(UA0_Rx_Timeout) // 新的一组数据到来
{
UA0_Rx_Timeout = 0;
// 复位缓冲区
UA0_RxBuf_Length = 0;
UA0_RxBuf_offset = 0;
}
if(UA0_RxBuf_Length < TRAN_BUF_SIZE)
{
#if 1
// 配置模式
if((P2IN & (BIT5 | BIT6)) == (BIT5 | BIT6))
{
// 第1个字符必须为0xC2
if(UA0_RxBuf_Length > 0 || c == 0xC2)
UA0_RxBuf[UA0_RxBuf_Length++] = c;
}
// 透传模式
else if((P2IN & (BIT5 | BIT6)) == 0)
#endif
{
// 主函数透传
UA0_RxBuf[UA0_RxBuf_Length++] = c;
}
P2OUT &= ~BIT3; // Output low
}
}
// 发送中断
if((UCA0IE & UCTXIE) && (UCA0IFG & UCTXIFG))
{
UCA0TXBUF = RF_RxBuf[RF_RxBuf_offset++]; // 发送字符
if(RF_RxBuf_offset >= RF_RxBuf_Length) // 全部发送完
{
// 禁止中断
UCA0IE &= ~UCTXIE;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,307 @@
#ifndef FR2433_RFSX
#define FR2433_RFSX
////////////////////////////////////////////////////////////////////////////////
// 版权: Haybin.Wu@studio
// 文件名:
// 版本: V1.0
// 工作环境: IAR v6.20
// 作者: Haybin
// 生成日期: 2016.05
// 功能: API for FR4133
// 修改日志:
////////////////////////////////////////////////////////////////////////////////
#include <MSP430FR2433.h>
#include <stdbool.h>
//======================================================================================
#define CPU_MCLK 8000000
#define DelayUs(us) __delay_cycles((CPU_MCLK/1000000UL) * us)
#define DelayMs(ms) __delay_cycles((CPU_MCLK/1000UL) * ms)
////////////////////////////////////////////////////////////////////////////////
//只需修改下列引脚
//SX1276 SPI I/O definitions
#define SPI_PSEL P1SEL0
#define SPI_PDIR P1DIR
#define SPI_POUT P1OUT
#define SPI_SI_BIT BIT2
#define SPI_SO_BIT BIT3
#define SPI_CLK_BIT BIT1
#define SPI_NSS_BIT BIT0
#define SPI_NSS_PDIR P1DIR
#define SPI_NSS_POUT P1OUT
//DIO0
#define DIO0_BIT BIT6
#define DIO0_DIR P1DIR
#define DIO0_IFG P1IFG
#define DIO0_IES P1IES
#define DIO0_IE P1IE
//DIO1
#define DIO1_BIT BIT7
#define DIO1_DIR P1DIR
#define DIO1_IFG P1IFG
#define DIO1_IES P1IES
#define DIO1_IE P1IE
//DIO3
#define DIO3_BIT BIT4
#define DIO3_DIR P2DIR
#define DIO3_IFG P2IFG
#define DIO3_IES P2IES
#define DIO3_IE P2IE
//RST
#define RST_BIT BIT1
#define RST_PDIR P3DIR
#define RST_POUT P3OUT
////////////////////////////////////////////////////////////////////////////////
//SX1276 SPI I/O definitions
//NSS
#define SPI_NSS_DIR_OUT SPI_NSS_PDIR |= SPI_NSS_BIT //片选 out
#define SPI_NSS_OUT_1 SPI_NSS_POUT |= SPI_NSS_BIT //1
#define SPI_NSS_OUT_0 SPI_NSS_POUT &= (~SPI_NSS_BIT) //1
//DIO0
#define DIO0_IFG_H DIO0_IFG |= DIO0_BIT
#define DIO0_IFG_L DIO0_IFG &= ~DIO0_BIT
#define DIO0_IES_H DIO0_IES |= DIO0_BIT
#define DIO0_IES_L DIO0_IES &= ~DIO0_BIT
#define DIO0_IE_H DIO0_IE |= DIO0_BIT
#define DIO0_IE_L DIO0_IE &= ~DIO0_BIT
//DIO1
#define DIO1_IFG_H DIO1_IFG |= DIO1_BIT
#define DIO1_IFG_L DIO1_IFG &= ~DIO1_BIT
#define DIO1_IES_H DIO1_IES |= DIO1_BIT
#define DIO1_IES_L DIO1_IES &= ~DIO1_BIT
#define DIO1_IE_H DIO1_IE |= DIO0_BIT
#define DIO1_IE_L DIO1_IE &= ~DIO1_BIT
//DIO3
#define DIO3_IFG_H DIO3_IFG |= DIO3_BIT
#define DIO3_IFG_L DIO3_IFG &= ~DIO3_BIT
#define DIO3_IES_H DIO3_IES |= DIO3_BIT
#define DIO3_IES_L DIO3_IES &= ~DIO3_BIT
#define DIO3_IE_H DIO3_IE |= DIO3_BIT
#define DIO3_IE_L DIO3_IE &= ~DIO3_BIT
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : SX1276 I/O pins definitions
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276Init_IO( void )
{
//DIO0为P2.0
//P2DIR &= ~BIT0;
//P2OUT |= BIT0; // Configure DIO0 as pulled-up
//P2REN |= BIT0; // DIO0pull-up register enable
DIO0_DIR&=~DIO0_BIT;
DIO0_IES_L; // DIO0 Hi/Low edge
DIO0_IE_L; // DIO0 interrupt enabled
DIO0_IFG_L; // DIO0IFG cleared
//DIO1为P2.1
//P2DIR &= ~BIT1;
//P2OUT |= BIT1; // Configure DIO1 as pulled-up
//P2REN |= BIT1; // DIO1pull-up register enable
DIO1_DIR&=~DIO1_BIT;
DIO1_IES_L; // DIO1 Hi/Low edge
DIO1_IE_L; // DIO1 interrupt enabled
DIO1_IFG_L; // DIO1IFG cleared
//DIO3为P2.3
//P2DIR &= ~BIT3;
//P2OUT |= BIT3; // Configure DIO3 as pulled-up
//P2REN |= BIT3; // DIO3pull-up register enable
DIO3_DIR&=~DIO3_BIT;
DIO3_IES_L; // DIO3 Hi/Low edge
DIO3_IE_L; // DIO3 interrupt enabled
DIO3_IFG_L; // DIO3IFG cleared
//SX1276 SPI I/O definitions
// Configure SPI
//SPI SET
SPI_NSS_DIR_OUT;
SPI_NSS_OUT_1; // /CS disable
// SPI option select
SPI_PSEL |= SPI_SI_BIT+SPI_SO_BIT+SPI_CLK_BIT;
UCB0CTLW0 |= UCSWRST; // **Put state machine in reset**
UCB0CTLW0 |= UCMST|UCSYNC|UCCKPH|UCMSB; // 3-pin, 8-bit SPI master
// Clock polarity high, MSB
UCB0CTLW0 |= UCSSEL__SMCLK; // SMCLK
UCB0BR0 = 1; // /2,fBitClock = fBRCLK/(UCBRx+1).
UCB0BR1 = 0; //
UCB0CTLW0 &= ~UCSWRST; // **Initialize USCI state machine**
//SX1276 RESET I/O definitions
RST_PDIR |= RST_BIT;
RST_POUT |= RST_BIT;
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : 开启睡眠超时定时器
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void ON_Sleep_Timerout(void)
{
//Timer1_A3 setup
TA1R =0; //清除定时器计数器
TA1CCTL0 = CCIE; // TACCR0 interrupt enabled
TA1CCR0 = 32768;
TA0CTL |= TASSEL_1 | MC_1; //开启超时定时器
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : 关闭睡眠超时定时器
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void OFF_Sleep_Timerout(void)
{
//TA0R =0; //清除定时器计数器
TA1CCTL0 = CCIE; // TACCR0 interrupt enabled
TA1CCR0 = 32768;
TA0CTL = TASSEL_1 | MC_0; //关闭定时器
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 复位
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276Reset(void)
{
RST_POUT &= ~RST_BIT; //硬件复位IO口输出0
DelayMs(6); //延时
RST_POUT |= RST_BIT; //输出为1
DelayMs(5);
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向寄存器地址连续发送数据
// 输入参数 : uint8_t addr,寄存器地址 uint8_t *buffer,发送数组指针 uint8_t size指针长度
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
uint8_t i;
SPI_PSEL |= SPI_SO_BIT;//SPI的bug引起的功耗异常
SPI_NSS_OUT_0;
// _NOP();_NOP();_NOP();_NOP();
// _NOP();_NOP();_NOP();_NOP();
UCB0IFG &= ~UCRXIFG; // Clear flag
UCB0TXBUF = (addr | 0x80); // Send address
while (!(UCB0IFG&UCTXIFG)); // Wait for TX to finish
UCB0IFG &= ~UCTXIFG; // Clear flag
for( i = 0; i < size; i++ )
{
UCB0TXBUF = buffer[i]; // Send data
while (!(UCB0IFG&UCTXIFG)); // Wait for TX to finish
UCB0IFG &= ~UCTXIFG;
}
// _NOP();_NOP();_NOP();_NOP();
// _NOP();_NOP();_NOP();_NOP();
SPI_NSS_OUT_1;
SPI_PSEL &= ~SPI_SO_BIT;//SPI的bug引起的功耗异常
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向寄存器地址连续读数据
// 输入参数 : uint8_t addr,寄存器地址 uint8_t *buffer,存储数组指针 uint8_t size要读的长度
// 返回参数 : 数据返回到*buffer中
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
uint8_t i;
SPI_PSEL |= SPI_SO_BIT;//SPI的bug引起的功耗异常
SPI_NSS_OUT_0;
// _NOP();_NOP();_NOP();_NOP();
// _NOP();_NOP();_NOP();_NOP();
UCB0IFG &= ~UCRXIFG; // Clear flag
UCB0TXBUF = (addr & 0x7F); // Send address
while (!(UCB0IFG&UCTXIFG)); // Wait for end of addr byte TX
UCB0IFG &= ~UCTXIFG; // Clear flag
for( i = 0; i < size; i++ )
{
UCB0TXBUF = 0; //Initiate next data RX
while (!(UCB0IFG&UCRXIFG)); // Wait for RX to finish
buffer[i] = UCB0RXBUF; // Store data from last data RX
//读取UCB0RXBUF后IFG自动Reset
}
// _NOP();_NOP();_NOP();_NOP();
// _NOP();_NOP();_NOP();_NOP();
SPI_NSS_OUT_1;
SPI_PSEL &= ~SPI_SO_BIT;//SPI的bug引起的功耗异常
UCB0IFG=0;
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向寄存器地址写1字节数据
// 输入参数 : uint8_t addr,寄存器地址 uint8_t data数据
// 返回参数 :
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276Write( uint8_t addr, uint8_t data )
{
SX1276WriteBuffer( addr, &data, 1 );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向寄存器地址读1字节数据
// 输入参数 : uint8_t addr,寄存器地址 uint8_t *data读数据存储地址
// 返回参数 :
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276Read( uint8_t addr, uint8_t *data )
{
SX1276ReadBuffer( addr, data, 1 );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向FIFO写数据
// 输入参数 : uint8_t *buffer,数组指针 uint8_t size长度
// 返回参数 :
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276WriteFifo( uint8_t *buffer, uint8_t size )
{
SX1276WriteBuffer( 0, buffer, size );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向FIFO读数据
// 输入参数 : uint8_t *buffer,数组指针 uint8_t size长度
// 返回参数 : uint8_t *buffer 存储读取内容
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276ReadFifo( uint8_t *buffer, uint8_t size )
{
SX1276ReadBuffer( 0, buffer, size );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF TX/RX的PA切换
// 输入参数 : bool txEnable 切换逻辑
// 返回参数 : 无
// 说明 :真作为TX。假作为RX 为硬件两个PA控制IO口
////////////////////////////////////////////////////////////////////////////////
void SX1276WriteRxTx( bool txEnable )
{
if( txEnable != 0 ) //如果为真为TX
{
;
}
else //为假为RX
{
;
}
}
//*****************************************************************************************
#endif

View File

@ -0,0 +1,491 @@
// Haybin_Wu
// Shenitech-RD
// 2016.5
// Built with IAR Embedded Workbench v6.2
//******************************************************************************
// Modify by Qian Xianghong
// 2020.10
// 修改日志将无线模块做成串口和RF双向透传模式。
//******************************************************************************
#include <msp430FR2433.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "FR2433-RFSX.h"
#include "RF_SX1276.h"
// 射频配置参数
lora_param_t Lora_Param;
#define TRAN_BUF_SIZE (1024)
// 用UA1串口做打印输出方便调试
char printBuf[200];
void uart_print()
{
#if 0 // 打印串口的2个引脚用作MD0、MD1模式选择
char *p = printBuf;
while(*p)
{
if(*p == '\n') // 换行前添加回车
{
while(!(UCA1IFG & UCTXIFG));
UCA1TXBUF = '\r';
}
while(!(UCA1IFG & UCTXIFG));
UCA1TXBUF = *p++;
}
#endif
}
// 可变参数的宏定义
#define PRINTF(format, ...) \
{ \
snprintf(printBuf, sizeof(printBuf), format, ##__VA_ARGS__); \
uart_print(); \
}
// UA0接收上位机数据的buf
uint8_t UA0_RxBuf[TRAN_BUF_SIZE] = {0};
uint16_t UA0_RxBuf_Length = 0;
uint16_t UA0_RxBuf_offset = 0;
// UA0接收超时
volatile uint8_t UA0_Rx_Timeout = 1;
// RF接收数据的buf
uint8_t RF_RxBuf[TRAN_BUF_SIZE] = {0};
uint16_t RF_RxBuf_Length = 0;
uint16_t RF_RxBuf_offset = 0;
// RF接收超时标志
volatile uint8_t RF_Rx_Timeout = 1;
////////////////////////////////////////////////////////////////////////////////
// 主串口初始化
void UA0_Init(uint32_t baudrate)
{
// Configure UART
UCA0CTLW0 |=(UCSSEL__SMCLK+UCSWRST);//UCPEN+UCPAR+
// Baud Rate calculation
if(baudrate == 115200)
{
UCA0BR0 = 4; // 8000000/16/115200//这位大于16 UCOS16位要置位
UCA0BR1 = 0; // Fractional portion = 0.44444
UCA0MCTLW = 0x5500 | UCOS16 | UCBRF_5;//微调Baud Rate
}
else if(baudrate == 38400)
{
UCA0BR0 = 13; // 8000000/16/38400 /这位大于16 UCOS16位要置位
UCA0BR1 = 0; // Fractional portion = 0.33333
UCA0MCTLW = 0x8400 | UCOS16 | UCBRF_0;//微调Baud Rate
}
else
{
UCA0BR0 = 52; // 8000000/16/9600 /这位大于16 UCOS16位要置位
UCA0BR1 = 0; // Fractional portion = 0.33333
UCA0MCTLW = 0x4900 | UCOS16 | UCBRF_1;//微调Baud Rate
}
UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI
UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt
}
// 主串口应答(配置命令)
void UA0_Response(char *s)
{
while(*s)
{
while(!(UCA0IFG & UCTXIFG));
UCA0TXBUF = *s++;
}
// 等待发送结束
while(!(UCA0IFG & UCTXCPTIFG));
DelayMs(2);
}
////////////////////////////////////////////////////////////////////////////////
//主函数
////////////////////////////////////////////////////////////////////////////////
int main(void)
{
uint8_t sendCh;
WDTCTL = (WDTPW | WDTHOLD); // Stop WDT
// Port Configuration all un-used pins to output low
P1DIR = 0xFF; P2DIR = 0xFF; P3DIR = 0xFF;
P1OUT = 0x00; P2OUT = 0x00; P3OUT = 0x00;
PM5CTL0 &= ~LOCKLPM5;//开引脚功能
// Configure DCO Clock
//外部时钟源启动
P2SEL0 |= (BIT0 | BIT1); // set XT1 pin as second function
do
{
CSCTL7 &= ~(XT1OFFG | DCOFFG); // Clear XT1 and DCO fault flag
SFRIFG1 &= ~OFIFG;
} while (SFRIFG1 & OFIFG); // Test oscillator fault flag
//上面清除标志有助于降低功耗
__bis_SR_register(SCG0); // disable FLL
CSCTL3 |= SELREF__XT1CLK; // 外部 32768hz reference source
CSCTL0 = 0; // clear DCO and MOD registers
CSCTL1 &= ~(DCORSEL_7); // Clear DCO frequency select bits first
CSCTL1 |= DCORSEL_3; //DCO=8Mhz
CSCTL2 = FLLD_0 + 243; // DCODIV = 8MHz
__delay_cycles(3);
__bic_SR_register(SCG0); // enable FLL
while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // Poll until FLL is locked
CSCTL4 = SELREF__XT1CLK + SELMS__DCOCLKDIV;// set XT1CLK(32768Hz) as ACLK source & MCLK/SMCLK=DCO
//Timer0_A0 setup
TA0CCTL0 = CCIE; // TACCR0 interrupt enabled
TA0CCR0 = 32768 / 32; // 串口接收超时: 1000/32=31.25ms
TA0CTL = MC__STOP | TACLR; // Stop mode, Clear counter
//Timer1_A0 setup
TA1CCTL0 = CCIE; // TACCR0 interrupt enabled
TA1CCR0 = 32768 / 4; // RF接收超时: 1000/4=250ms
TA1CTL = MC__STOP | TACLR; // Stop mode, Clear counter
// 设置无线模块缺省参数
Lora_Param.sof = 0xC2;
Lora_Param.addr = 0xADF2; // 通信地址0xADF2
Lora_Param.sf = 6; // sf=12
Lora_Param.baud = 3; // 9600
Lora_Param.cr = 0; // cr=4/5
Lora_Param.ch = 9; // 479MHz
Lora_Param.power = 1; // 17dBm
Lora_Param.freqcast = 0; // freqcast off
Lora_Param.bw = 9; // 500kHz
Lora_Param.unicast = 0; // unicast off
// Configure UART pins
P1SEL1 &= ~(BIT4 | BIT5); // set 2-UART pin as second function
P1SEL0 |= (BIT4 | BIT5); // set 2-UART pin as second function
if(Lora_Param.baud == 7)
UA0_Init(115200);
else if(Lora_Param.baud == 5)
UA0_Init(38400);
else
UA0_Init(9600);
#if 0 // 配置打印串口
// Configure UART pins
P2SEL1 &= ~(BIT5 | BIT6); // set 2-UART pin as second function
P2SEL0 |= (BIT5 | BIT6); // set 2-UART pin as second function
// Configure UART
UCA1CTLW0 |=(UCSSEL__SMCLK+UCSWRST);//UCPEN+UCPAR+
// Baud Rate calculation
UCA1BR0 = 4; // 8000000/16/115200//这位大于16 UCOS16位要置位
UCA1BR1 = 0; // Fractional portion = 0.44444
UCA1MCTLW = 0x5500 | UCOS16 | UCBRF_5;//微调Baud Rate
UCA1CTLW0 &= ~UCSWRST; // Initialize eUSCI
UCA1IE |= UCRXIE; // Enable USCI_A0 RX interrupt
// 打印复位原因(电源引起,不包括看门狗)
PRINTF("\nModule reseted: %04X\n", PMMIFG);
#else // 配置MD0、MD1模式
P2SEL1 &= ~(BIT3 | BIT5 | BIT6); // set 2-UART pin as GPIO
P2SEL0 &= ~(BIT3 | BIT5 | BIT6); // set 2-UART pin as GPIO
P2DIR &= ~(BIT5 | BIT6); // Input
P2REN |= (BIT5 | BIT6); // enable pull
P2OUT &= ~(BIT5 | BIT6); // pull-down
P2DIR |= BIT3; // Output
P2OUT |= BIT3; // Output high
#endif
_EINT();
#if 0
// 打印复位原因(电源引起,不包括看门狗)
RF_RxBuf[0] = PMMIFG >> 8;
RF_RxBuf[1] = PMMIFG & 0xFF;
RF_RxBuf_Length = 2;
RF_RxBuf_offset = 0;
UCA0IE |= UCTXIE;
while(UCA0IE & UCTXIE);
#endif
// 读寄存器,清除复位原因
SYSRSTIV;
//无线模块初始化
uint8_t try_count = 3; //最多初始化3次
while(try_count)
{
if(SX127x_initLora(&Lora_Param) == NORMAL)
break;
try_count--;
}
if(try_count == 0) //无线初始化失败处理
{
//P3OUT ^= 0xC0;
LPM4;
}
// 初始处于接收模式
LSD_RF_RXmode(RF_PAYLOAD_LEN);
// 默认发送信道
sendCh = Lora_Param.ch;
// 开启看门狗: 超时时间为2^27/SMCLK在8000000主频下约为16s
WDTCTL = (WDTPW | WDTCNTCL | WDTIS_1);
while(1)
{
#if 1
// TODO: 喂狗
WDTCTL = (WDTPW | WDTCNTCL | WDTIS_1);
// 配置模式
if((P2IN & (BIT5 | BIT6)) == (BIT5 | BIT6))
{
if(UA0_RxBuf_Length - UA0_RxBuf_offset >= sizeof(Lora_Param))
{
if(UA0_RxBuf[UA0_RxBuf_offset] == 0xC2)
{
// 保存参数
memmove(&Lora_Param, UA0_RxBuf + UA0_RxBuf_offset, sizeof(Lora_Param));
// 颠倒地址高低字节
Lora_Param.addr = (Lora_Param.addr << 8) | (Lora_Param.addr >> 8);
//无线模块初始化
uint8_t try_count = 3; //最多初始化3次
while(try_count)
{
// 其它参数有变化,无线模块初始化
if(SX127x_initLora(&Lora_Param) == NORMAL)
break;
try_count--;
}
if(try_count == 0) //无线初始化失败处理
{
//P3OUT ^= 0xC0;
LPM4;
}
// 默认处于接收模式
LSD_RF_RXmode(RF_PAYLOAD_LEN);
// 默认发送信道
sendCh = Lora_Param.ch;
// 应答配置命令
UA0_Response("OK\r\n");
// 改变串口波特率
if(Lora_Param.baud == 7)
UA0_Init(115200);
else if(Lora_Param.baud == 5)
UA0_Init(38400);
else
UA0_Init(9600);
}
UA0_RxBuf_offset = UA0_RxBuf_Length;
}
}
// 透传模式
else if((P2IN & (BIT5 | BIT6)) == 0)
#endif
{
if(UA0_RxBuf_Length > UA0_RxBuf_offset)
{
// 定点传输,指定目标地址和信道发送
if(Lora_Param.unicast) // 定点发送
{
if(UA0_RxBuf_offset == 0 && UA0_RxBuf_Length > 3)
sendCh = UA0_RxBuf[2];
}
else if(Lora_Param.freqcast) // 指定信道发送
{
if(UA0_RxBuf_offset == 0 && UA0_RxBuf_Length > 1)
{
sendCh = UA0_RxBuf[0];
UA0_RxBuf_offset = 1; // 不发送第1发个字节
}
}
if(UA0_RxBuf_Length - UA0_RxBuf_offset >= RF_PAYLOAD_LEN)
{
LSD_RF_FreqSet(sendCh);
LSD_RF_SendPacket(UA0_RxBuf + UA0_RxBuf_offset, RF_PAYLOAD_LEN);
UA0_RxBuf_offset += RF_PAYLOAD_LEN;
PRINTF("Send packet\n");
// 切换到接收模式
LSD_RF_FreqSet(Lora_Param.ch);
LSD_RF_RXmode(RF_PAYLOAD_LEN);
}
else if(UA0_Rx_Timeout)
{
LSD_RF_FreqSet(sendCh);
LSD_RF_SendPacket(UA0_RxBuf + UA0_RxBuf_offset, UA0_RxBuf_Length - UA0_RxBuf_offset);
UA0_RxBuf_offset = UA0_RxBuf_Length;
PRINTF("Send packet\n");
// 切换到接收模式
LSD_RF_FreqSet(Lora_Param.ch);
LSD_RF_RXmode(RF_PAYLOAD_LEN);
}
}
}
if(UA0_Rx_Timeout && UA0_RxBuf_offset == UA0_RxBuf_Length)
P2OUT |= BIT3; // Output high
}
}
// Port 1 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(PORT1_VECTOR))) Port_1 (void)
#else
#error Compiler not supported!
#endif
{
uint8_t offset = 0;
uint8_t len[1] = {0};
uint8_t buf[RF_PAYLOAD_LEN];
if(DIO0_IFG&DIO0_BIT) //数据传输中断处理
{
// 清中断
DIO0_IFG &= ~DIO0_BIT;
// 读取RF数据
LSD_RF_RxVariPacket(buf, len); //接收可变数据包,如果速率为大速率,只能用接收固定数据包长度
if(len[0] == 0)
return;
TA1CTL = MC__STOP | TACLR; // 停止定时器,复位计数器
TA1CTL = TASSEL__ACLK | MC__UP; // 重新开始计时
offset = 0;
if(RF_Rx_Timeout) // 新的一组数据到来
{
RF_Rx_Timeout = 0;
// 复位缓冲区
RF_RxBuf_Length = 0;
RF_RxBuf_offset = 0;
if(Lora_Param.unicast)
{
// 定点传输,地址和信道校验失败
if(len[0] <= 3 || buf[2] != Lora_Param.ch || ((buf[0] << 8) | buf[1]) != Lora_Param.addr)
return;
// 前3个字符丢掉
offset = 3;
len[0] -= offset;
}
}
PRINTF("Recv packet\n");
// 透传模式
if((P2IN & (BIT5 | BIT6)) == 0)
{
if(RF_RxBuf_Length + len[0] <= TRAN_BUF_SIZE)
{
memmove(RF_RxBuf + RF_RxBuf_Length, buf + offset, len[0]);
// 中断方式向串口转发
RF_RxBuf_Length += len[0];
UCA0IE |= UCTXIE;
}
}
}
}
// Timer0 A0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) Timer0_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
// 停止定时器,复位计数器
TA0CTL = MC__STOP | TACLR;
// 串口接收超时
UA0_Rx_Timeout = 1;
}
// Timer1 A0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER1_A0_VECTOR
__interrupt void Timer1_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER1_A0_VECTOR))) Timer1_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
// 停止定时器,复位计数器
TA1CTL = MC__STOP | TACLR;
// RF接收超时
RF_Rx_Timeout = 1;
}
// UAR0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
// 接收中断
if((UCA0IE & UCRXIE) && (UCA0IFG & UCRXIFG))
{
uint8_t c = UCA0RXBUF;
TA0CTL = MC__STOP | TACLR; // 停止定时器,复位计数器
TA0CTL = TASSEL__ACLK | MC__UP; // 重新开始计时
if(UA0_Rx_Timeout) // 新的一组数据到来
{
UA0_Rx_Timeout = 0;
// 复位缓冲区
UA0_RxBuf_Length = 0;
UA0_RxBuf_offset = 0;
}
if(UA0_RxBuf_Length < TRAN_BUF_SIZE)
{
#if 1
// 配置模式
if((P2IN & (BIT5 | BIT6)) == (BIT5 | BIT6))
{
// 第1个字符必须为0xC2
if(UA0_RxBuf_Length > 0 || c == 0xC2)
UA0_RxBuf[UA0_RxBuf_Length++] = c;
}
// 透传模式
else if((P2IN & (BIT5 | BIT6)) == 0)
#endif
{
// 主函数透传
UA0_RxBuf[UA0_RxBuf_Length++] = c;
}
P2OUT &= ~BIT3; // Output low
}
}
// 发送中断
if((UCA0IE & UCTXIE) && (UCA0IFG & UCTXIFG))
{
UCA0TXBUF = RF_RxBuf[RF_RxBuf_offset++]; // 发送字符
if(RF_RxBuf_offset >= RF_RxBuf_Length) // 全部发送完
{
// 禁止中断
UCA0IE &= ~UCTXIE;
}
}
}

File diff suppressed because it is too large Load Diff

307
RF-AP/FR2433-RFSX.h Normal file
View File

@ -0,0 +1,307 @@
#ifndef FR2433_RFSX
#define FR2433_RFSX
////////////////////////////////////////////////////////////////////////////////
// 版权: Haybin.Wu@studio
// 文件名:
// 版本: V1.0
// 工作环境: IAR v6.20
// 作者: Haybin
// 生成日期: 2016.05
// 功能: API for FR4133
// 修改日志:
////////////////////////////////////////////////////////////////////////////////
#include <MSP430FR2433.h>
#include <stdbool.h>
//======================================================================================
#define CPU_MCLK 8000000
#define DelayUs(us) __delay_cycles((CPU_MCLK/1000000UL) * us)
#define DelayMs(ms) __delay_cycles((CPU_MCLK/1000UL) * ms)
////////////////////////////////////////////////////////////////////////////////
//只需修改下列引脚
//SX1276 SPI I/O definitions
#define SPI_PSEL P1SEL0
#define SPI_PDIR P1DIR
#define SPI_POUT P1OUT
#define SPI_SI_BIT BIT2
#define SPI_SO_BIT BIT3
#define SPI_CLK_BIT BIT1
#define SPI_NSS_BIT BIT0
#define SPI_NSS_PDIR P1DIR
#define SPI_NSS_POUT P1OUT
//DIO0
#define DIO0_BIT BIT6
#define DIO0_DIR P1DIR
#define DIO0_IFG P1IFG
#define DIO0_IES P1IES
#define DIO0_IE P1IE
//DIO1
#define DIO1_BIT BIT7
#define DIO1_DIR P1DIR
#define DIO1_IFG P1IFG
#define DIO1_IES P1IES
#define DIO1_IE P1IE
//DIO3
#define DIO3_BIT BIT4
#define DIO3_DIR P2DIR
#define DIO3_IFG P2IFG
#define DIO3_IES P2IES
#define DIO3_IE P2IE
//RST
#define RST_BIT BIT1
#define RST_PDIR P3DIR
#define RST_POUT P3OUT
////////////////////////////////////////////////////////////////////////////////
//SX1276 SPI I/O definitions
//NSS
#define SPI_NSS_DIR_OUT SPI_NSS_PDIR |= SPI_NSS_BIT //片选 out
#define SPI_NSS_OUT_1 SPI_NSS_POUT |= SPI_NSS_BIT //1
#define SPI_NSS_OUT_0 SPI_NSS_POUT &= (~SPI_NSS_BIT) //1
//DIO0
#define DIO0_IFG_H DIO0_IFG |= DIO0_BIT
#define DIO0_IFG_L DIO0_IFG &= ~DIO0_BIT
#define DIO0_IES_H DIO0_IES |= DIO0_BIT
#define DIO0_IES_L DIO0_IES &= ~DIO0_BIT
#define DIO0_IE_H DIO0_IE |= DIO0_BIT
#define DIO0_IE_L DIO0_IE &= ~DIO0_BIT
//DIO1
#define DIO1_IFG_H DIO1_IFG |= DIO1_BIT
#define DIO1_IFG_L DIO1_IFG &= ~DIO1_BIT
#define DIO1_IES_H DIO1_IES |= DIO1_BIT
#define DIO1_IES_L DIO1_IES &= ~DIO1_BIT
#define DIO1_IE_H DIO1_IE |= DIO0_BIT
#define DIO1_IE_L DIO1_IE &= ~DIO1_BIT
//DIO3
#define DIO3_IFG_H DIO3_IFG |= DIO3_BIT
#define DIO3_IFG_L DIO3_IFG &= ~DIO3_BIT
#define DIO3_IES_H DIO3_IES |= DIO3_BIT
#define DIO3_IES_L DIO3_IES &= ~DIO3_BIT
#define DIO3_IE_H DIO3_IE |= DIO3_BIT
#define DIO3_IE_L DIO3_IE &= ~DIO3_BIT
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : SX1276 I/O pins definitions
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276Init_IO( void )
{
//DIO0为P2.0
//P2DIR &= ~BIT0;
//P2OUT |= BIT0; // Configure DIO0 as pulled-up
//P2REN |= BIT0; // DIO0pull-up register enable
DIO0_DIR&=~DIO0_BIT;
DIO0_IES_L; // DIO0 Hi/Low edge
DIO0_IE_L; // DIO0 interrupt enabled
DIO0_IFG_L; // DIO0IFG cleared
//DIO1为P2.1
//P2DIR &= ~BIT1;
//P2OUT |= BIT1; // Configure DIO1 as pulled-up
//P2REN |= BIT1; // DIO1pull-up register enable
DIO1_DIR&=~DIO1_BIT;
DIO1_IES_L; // DIO1 Hi/Low edge
DIO1_IE_L; // DIO1 interrupt enabled
DIO1_IFG_L; // DIO1IFG cleared
//DIO3为P2.3
//P2DIR &= ~BIT3;
//P2OUT |= BIT3; // Configure DIO3 as pulled-up
//P2REN |= BIT3; // DIO3pull-up register enable
DIO3_DIR&=~DIO3_BIT;
DIO3_IES_L; // DIO3 Hi/Low edge
DIO3_IE_L; // DIO3 interrupt enabled
DIO3_IFG_L; // DIO3IFG cleared
//SX1276 SPI I/O definitions
// Configure SPI
//SPI SET
SPI_NSS_DIR_OUT;
SPI_NSS_OUT_1; // /CS disable
// SPI option select
SPI_PSEL |= SPI_SI_BIT+SPI_SO_BIT+SPI_CLK_BIT;
UCB0CTLW0 |= UCSWRST; // **Put state machine in reset**
UCB0CTLW0 |= UCMST|UCSYNC|UCCKPH|UCMSB; // 3-pin, 8-bit SPI master
// Clock polarity high, MSB
UCB0CTLW0 |= UCSSEL__SMCLK; // SMCLK
UCB0BR0 = 1; // /2,fBitClock = fBRCLK/(UCBRx+1).
UCB0BR1 = 0; //
UCB0CTLW0 &= ~UCSWRST; // **Initialize USCI state machine**
//SX1276 RESET I/O definitions
RST_PDIR |= RST_BIT;
RST_POUT |= RST_BIT;
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : 开启睡眠超时定时器
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void ON_Sleep_Timerout(void)
{
//Timer1_A3 setup
TA1R =0; //清除定时器计数器
TA1CCTL0 = CCIE; // TACCR0 interrupt enabled
TA1CCR0 = 32768;
TA0CTL |= TASSEL_1 | MC_1; //开启超时定时器
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : 关闭睡眠超时定时器
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void OFF_Sleep_Timerout(void)
{
//TA0R =0; //清除定时器计数器
TA1CCTL0 = CCIE; // TACCR0 interrupt enabled
TA1CCR0 = 32768;
TA0CTL = TASSEL_1 | MC_0; //关闭定时器
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 复位
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276Reset(void)
{
RST_POUT &= ~RST_BIT; //硬件复位IO口输出0
DelayMs(6); //延时
RST_POUT |= RST_BIT; //输出为1
DelayMs(5);
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向寄存器地址连续发送数据
// 输入参数 : uint8_t addr,寄存器地址 uint8_t *buffer,发送数组指针 uint8_t size指针长度
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
uint8_t i;
SPI_PSEL |= SPI_SO_BIT;//SPI的bug引起的功耗异常
SPI_NSS_OUT_0;
// _NOP();_NOP();_NOP();_NOP();
// _NOP();_NOP();_NOP();_NOP();
UCB0IFG &= ~UCRXIFG; // Clear flag
UCB0TXBUF = (addr | 0x80); // Send address
while (!(UCB0IFG&UCTXIFG)); // Wait for TX to finish
UCB0IFG &= ~UCTXIFG; // Clear flag
for( i = 0; i < size; i++ )
{
UCB0TXBUF = buffer[i]; // Send data
while (!(UCB0IFG&UCTXIFG)); // Wait for TX to finish
UCB0IFG &= ~UCTXIFG;
}
// _NOP();_NOP();_NOP();_NOP();
// _NOP();_NOP();_NOP();_NOP();
SPI_NSS_OUT_1;
SPI_PSEL &= ~SPI_SO_BIT;//SPI的bug引起的功耗异常
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向寄存器地址连续读数据
// 输入参数 : uint8_t addr,寄存器地址 uint8_t *buffer,存储数组指针 uint8_t size要读的长度
// 返回参数 : 数据返回到*buffer中
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
uint8_t i;
SPI_PSEL |= SPI_SO_BIT;//SPI的bug引起的功耗异常
SPI_NSS_OUT_0;
// _NOP();_NOP();_NOP();_NOP();
// _NOP();_NOP();_NOP();_NOP();
UCB0IFG &= ~UCRXIFG; // Clear flag
UCB0TXBUF = (addr & 0x7F); // Send address
while (!(UCB0IFG&UCTXIFG)); // Wait for end of addr byte TX
UCB0IFG &= ~UCTXIFG; // Clear flag
for( i = 0; i < size; i++ )
{
UCB0TXBUF = 0; //Initiate next data RX
while (!(UCB0IFG&UCRXIFG)); // Wait for RX to finish
buffer[i] = UCB0RXBUF; // Store data from last data RX
//读取UCB0RXBUF后IFG自动Reset
}
// _NOP();_NOP();_NOP();_NOP();
// _NOP();_NOP();_NOP();_NOP();
SPI_NSS_OUT_1;
SPI_PSEL &= ~SPI_SO_BIT;//SPI的bug引起的功耗异常
UCB0IFG=0;
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向寄存器地址写1字节数据
// 输入参数 : uint8_t addr,寄存器地址 uint8_t data数据
// 返回参数 :
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276Write( uint8_t addr, uint8_t data )
{
SX1276WriteBuffer( addr, &data, 1 );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向寄存器地址读1字节数据
// 输入参数 : uint8_t addr,寄存器地址 uint8_t *data读数据存储地址
// 返回参数 :
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276Read( uint8_t addr, uint8_t *data )
{
SX1276ReadBuffer( addr, data, 1 );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向FIFO写数据
// 输入参数 : uint8_t *buffer,数组指针 uint8_t size长度
// 返回参数 :
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276WriteFifo( uint8_t *buffer, uint8_t size )
{
SX1276WriteBuffer( 0, buffer, size );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF 向FIFO读数据
// 输入参数 : uint8_t *buffer,数组指针 uint8_t size长度
// 返回参数 : uint8_t *buffer 存储读取内容
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276ReadFifo( uint8_t *buffer, uint8_t size )
{
SX1276ReadBuffer( 0, buffer, size );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF TX/RX的PA切换
// 输入参数 : bool txEnable 切换逻辑
// 返回参数 : 无
// 说明 :真作为TX。假作为RX 为硬件两个PA控制IO口
////////////////////////////////////////////////////////////////////////////////
void SX1276WriteRxTx( bool txEnable )
{
if( txEnable != 0 ) //如果为真为TX
{
;
}
else //为假为RX
{
;
}
}
//*****************************************************************************************
#endif

491
RF-AP/RF-Module.c Normal file
View File

@ -0,0 +1,491 @@
// Haybin_Wu
// Shenitech-RD
// 2016.5
// Built with IAR Embedded Workbench v6.2
//******************************************************************************
// Modify by Qian Xianghong
// 2020.10
// 修改日志将无线模块做成串口和RF双向透传模式。
//******************************************************************************
#include <msp430FR2433.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "FR2433-RFSX.h"
#include "RF_SX1276.h"
// 射频配置参数
lora_param_t Lora_Param;
#define TRAN_BUF_SIZE (1024)
// 用UA1串口做打印输出方便调试
char printBuf[200];
void uart_print()
{
#if 0 // 打印串口的2个引脚用作MD0、MD1模式选择
char *p = printBuf;
while(*p)
{
if(*p == '\n') // 换行前添加回车
{
while(!(UCA1IFG & UCTXIFG));
UCA1TXBUF = '\r';
}
while(!(UCA1IFG & UCTXIFG));
UCA1TXBUF = *p++;
}
#endif
}
// 可变参数的宏定义
#define PRINTF(format, ...) \
{ \
snprintf(printBuf, sizeof(printBuf), format, ##__VA_ARGS__); \
uart_print(); \
}
// UA0接收上位机数据的buf
uint8_t UA0_RxBuf[TRAN_BUF_SIZE] = {0};
uint16_t UA0_RxBuf_Length = 0;
uint16_t UA0_RxBuf_offset = 0;
// UA0接收超时
volatile uint8_t UA0_Rx_Timeout = 1;
// RF接收数据的buf
uint8_t RF_RxBuf[TRAN_BUF_SIZE] = {0};
uint16_t RF_RxBuf_Length = 0;
uint16_t RF_RxBuf_offset = 0;
// RF接收超时标志
volatile uint8_t RF_Rx_Timeout = 1;
////////////////////////////////////////////////////////////////////////////////
// 主串口初始化
void UA0_Init(uint32_t baudrate)
{
// Configure UART
UCA0CTLW0 |=(UCSSEL__SMCLK+UCSWRST);//UCPEN+UCPAR+
// Baud Rate calculation
if(baudrate == 115200)
{
UCA0BR0 = 4; // 8000000/16/115200//这位大于16 UCOS16位要置位
UCA0BR1 = 0; // Fractional portion = 0.44444
UCA0MCTLW = 0x5500 | UCOS16 | UCBRF_5;//微调Baud Rate
}
else if(baudrate == 38400)
{
UCA0BR0 = 13; // 8000000/16/38400 /这位大于16 UCOS16位要置位
UCA0BR1 = 0; // Fractional portion = 0.33333
UCA0MCTLW = 0x8400 | UCOS16 | UCBRF_0;//微调Baud Rate
}
else
{
UCA0BR0 = 52; // 8000000/16/9600 /这位大于16 UCOS16位要置位
UCA0BR1 = 0; // Fractional portion = 0.33333
UCA0MCTLW = 0x4900 | UCOS16 | UCBRF_1;//微调Baud Rate
}
UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI
UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt
}
// 主串口应答(配置命令)
void UA0_Response(char *s)
{
while(*s)
{
while(!(UCA0IFG & UCTXIFG));
UCA0TXBUF = *s++;
}
// 等待发送结束
while(!(UCA0IFG & UCTXCPTIFG));
DelayMs(2);
}
////////////////////////////////////////////////////////////////////////////////
//主函数
////////////////////////////////////////////////////////////////////////////////
int main(void)
{
uint8_t sendCh;
WDTCTL = (WDTPW | WDTHOLD); // Stop WDT
// Port Configuration all un-used pins to output low
P1DIR = 0xFF; P2DIR = 0xFF; P3DIR = 0xFF;
P1OUT = 0x00; P2OUT = 0x00; P3OUT = 0x00;
PM5CTL0 &= ~LOCKLPM5;//开引脚功能
// Configure DCO Clock
//外部时钟源启动
P2SEL0 |= (BIT0 | BIT1); // set XT1 pin as second function
do
{
CSCTL7 &= ~(XT1OFFG | DCOFFG); // Clear XT1 and DCO fault flag
SFRIFG1 &= ~OFIFG;
} while (SFRIFG1 & OFIFG); // Test oscillator fault flag
//上面清除标志有助于降低功耗
__bis_SR_register(SCG0); // disable FLL
CSCTL3 |= SELREF__XT1CLK; // 外部 32768hz reference source
CSCTL0 = 0; // clear DCO and MOD registers
CSCTL1 &= ~(DCORSEL_7); // Clear DCO frequency select bits first
CSCTL1 |= DCORSEL_3; //DCO=8Mhz
CSCTL2 = FLLD_0 + 243; // DCODIV = 8MHz
__delay_cycles(3);
__bic_SR_register(SCG0); // enable FLL
while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // Poll until FLL is locked
CSCTL4 = SELREF__XT1CLK + SELMS__DCOCLKDIV;// set XT1CLK(32768Hz) as ACLK source & MCLK/SMCLK=DCO
//Timer0_A0 setup
TA0CCTL0 = CCIE; // TACCR0 interrupt enabled
TA0CCR0 = 32768 / 32; // 串口接收超时: 1000/32=31.25ms
TA0CTL = MC__STOP | TACLR; // Stop mode, Clear counter
//Timer1_A0 setup
TA1CCTL0 = CCIE; // TACCR0 interrupt enabled
TA1CCR0 = 32768 / 4; // RF接收超时: 1000/4=250ms
TA1CTL = MC__STOP | TACLR; // Stop mode, Clear counter
// 设置无线模块缺省参数
Lora_Param.sof = 0xC2;
Lora_Param.addr = 0xADF2; // 通信地址0xADF2
Lora_Param.sf = 6; // sf=12
Lora_Param.baud = 3; // 9600
Lora_Param.cr = 0; // cr=4/5
Lora_Param.ch = 9; // 479MHz
Lora_Param.power = 1; // 17dBm
Lora_Param.freqcast = 0; // freqcast off
Lora_Param.bw = 9; // 500kHz
Lora_Param.unicast = 0; // unicast off
// Configure UART pins
P1SEL1 &= ~(BIT4 | BIT5); // set 2-UART pin as second function
P1SEL0 |= (BIT4 | BIT5); // set 2-UART pin as second function
if(Lora_Param.baud == 7)
UA0_Init(115200);
else if(Lora_Param.baud == 5)
UA0_Init(38400);
else
UA0_Init(9600);
#if 0 // 配置打印串口
// Configure UART pins
P2SEL1 &= ~(BIT5 | BIT6); // set 2-UART pin as second function
P2SEL0 |= (BIT5 | BIT6); // set 2-UART pin as second function
// Configure UART
UCA1CTLW0 |=(UCSSEL__SMCLK+UCSWRST);//UCPEN+UCPAR+
// Baud Rate calculation
UCA1BR0 = 4; // 8000000/16/115200//这位大于16 UCOS16位要置位
UCA1BR1 = 0; // Fractional portion = 0.44444
UCA1MCTLW = 0x5500 | UCOS16 | UCBRF_5;//微调Baud Rate
UCA1CTLW0 &= ~UCSWRST; // Initialize eUSCI
UCA1IE |= UCRXIE; // Enable USCI_A0 RX interrupt
// 打印复位原因(电源引起,不包括看门狗)
PRINTF("\nModule reseted: %04X\n", PMMIFG);
#else // 配置MD0、MD1模式
P2SEL1 &= ~(BIT3 | BIT5 | BIT6); // set 2-UART pin as GPIO
P2SEL0 &= ~(BIT3 | BIT5 | BIT6); // set 2-UART pin as GPIO
P2DIR &= ~(BIT5 | BIT6); // Input
P2REN |= (BIT5 | BIT6); // enable pull
P2OUT &= ~(BIT5 | BIT6); // pull-down
P2DIR |= BIT3; // Output
P2OUT |= BIT3; // Output high
#endif
_EINT();
#if 0
// 打印复位原因(电源引起,不包括看门狗)
RF_RxBuf[0] = PMMIFG >> 8;
RF_RxBuf[1] = PMMIFG & 0xFF;
RF_RxBuf_Length = 2;
RF_RxBuf_offset = 0;
UCA0IE |= UCTXIE;
while(UCA0IE & UCTXIE);
#endif
// 读寄存器,清除复位原因
SYSRSTIV;
//无线模块初始化
uint8_t try_count = 3; //最多初始化3次
while(try_count)
{
if(SX127x_initLora(&Lora_Param) == NORMAL)
break;
try_count--;
}
if(try_count == 0) //无线初始化失败处理
{
//P3OUT ^= 0xC0;
LPM4;
}
// 初始处于接收模式
LSD_RF_RXmode(RF_PAYLOAD_LEN);
// 默认发送信道
sendCh = Lora_Param.ch;
// 开启看门狗: 超时时间为2^27/SMCLK在8000000主频下约为16s
WDTCTL = (WDTPW | WDTCNTCL | WDTIS_1);
while(1)
{
#if 1
// TODO: 喂狗
WDTCTL = (WDTPW | WDTCNTCL | WDTIS_1);
// 配置模式
if((P2IN & (BIT5 | BIT6)) == (BIT5 | BIT6))
{
if(UA0_RxBuf_Length - UA0_RxBuf_offset >= sizeof(Lora_Param))
{
if(UA0_RxBuf[UA0_RxBuf_offset] == 0xC2)
{
// 保存参数
memmove(&Lora_Param, UA0_RxBuf + UA0_RxBuf_offset, sizeof(Lora_Param));
// 颠倒地址高低字节
Lora_Param.addr = (Lora_Param.addr << 8) | (Lora_Param.addr >> 8);
//无线模块初始化
uint8_t try_count = 3; //最多初始化3次
while(try_count)
{
// 其它参数有变化,无线模块初始化
if(SX127x_initLora(&Lora_Param) == NORMAL)
break;
try_count--;
}
if(try_count == 0) //无线初始化失败处理
{
//P3OUT ^= 0xC0;
LPM4;
}
// 默认处于接收模式
LSD_RF_RXmode(RF_PAYLOAD_LEN);
// 默认发送信道
sendCh = Lora_Param.ch;
// 应答配置命令
UA0_Response("OK\r\n");
// 改变串口波特率
if(Lora_Param.baud == 7)
UA0_Init(115200);
else if(Lora_Param.baud == 5)
UA0_Init(38400);
else
UA0_Init(9600);
}
UA0_RxBuf_offset = UA0_RxBuf_Length;
}
}
// 透传模式
else if((P2IN & (BIT5 | BIT6)) == 0)
#endif
{
if(UA0_RxBuf_Length > UA0_RxBuf_offset)
{
// 定点传输,指定目标地址和信道发送
if(Lora_Param.unicast) // 定点发送
{
if(UA0_RxBuf_offset == 0 && UA0_RxBuf_Length > 3)
sendCh = UA0_RxBuf[2];
}
else if(Lora_Param.freqcast) // 指定信道发送
{
if(UA0_RxBuf_offset == 0 && UA0_RxBuf_Length > 1)
{
sendCh = UA0_RxBuf[0];
UA0_RxBuf_offset = 1; // 不发送第1发个字节
}
}
if(UA0_RxBuf_Length - UA0_RxBuf_offset >= RF_PAYLOAD_LEN)
{
LSD_RF_FreqSet(sendCh);
LSD_RF_SendPacket(UA0_RxBuf + UA0_RxBuf_offset, RF_PAYLOAD_LEN);
UA0_RxBuf_offset += RF_PAYLOAD_LEN;
PRINTF("Send packet\n");
// 切换到接收模式
LSD_RF_FreqSet(Lora_Param.ch);
LSD_RF_RXmode(RF_PAYLOAD_LEN);
}
else if(UA0_Rx_Timeout)
{
LSD_RF_FreqSet(sendCh);
LSD_RF_SendPacket(UA0_RxBuf + UA0_RxBuf_offset, UA0_RxBuf_Length - UA0_RxBuf_offset);
UA0_RxBuf_offset = UA0_RxBuf_Length;
PRINTF("Send packet\n");
// 切换到接收模式
LSD_RF_FreqSet(Lora_Param.ch);
LSD_RF_RXmode(RF_PAYLOAD_LEN);
}
}
}
if(UA0_Rx_Timeout && UA0_RxBuf_offset == UA0_RxBuf_Length)
P2OUT |= BIT3; // Output high
}
}
// Port 1 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(PORT1_VECTOR))) Port_1 (void)
#else
#error Compiler not supported!
#endif
{
uint8_t offset = 0;
uint8_t len[1] = {0};
uint8_t buf[RF_PAYLOAD_LEN];
if(DIO0_IFG&DIO0_BIT) //数据传输中断处理
{
// 清中断
DIO0_IFG &= ~DIO0_BIT;
// 读取RF数据
LSD_RF_RxVariPacket(buf, len); //接收可变数据包,如果速率为大速率,只能用接收固定数据包长度
if(len[0] == 0)
return;
TA1CTL = MC__STOP | TACLR; // 停止定时器,复位计数器
TA1CTL = TASSEL__ACLK | MC__UP; // 重新开始计时
offset = 0;
if(RF_Rx_Timeout) // 新的一组数据到来
{
RF_Rx_Timeout = 0;
// 复位缓冲区
RF_RxBuf_Length = 0;
RF_RxBuf_offset = 0;
if(Lora_Param.unicast)
{
// 定点传输,地址和信道校验失败
if(len[0] <= 3 || buf[2] != Lora_Param.ch || ((buf[0] << 8) | buf[1]) != Lora_Param.addr)
return;
// 前3个字符丢掉
offset = 3;
len[0] -= offset;
}
}
PRINTF("Recv packet\n");
// 透传模式
if((P2IN & (BIT5 | BIT6)) == 0)
{
if(RF_RxBuf_Length + len[0] <= TRAN_BUF_SIZE)
{
memmove(RF_RxBuf + RF_RxBuf_Length, buf + offset, len[0]);
// 中断方式向串口转发
RF_RxBuf_Length += len[0];
UCA0IE |= UCTXIE;
}
}
}
}
// Timer0 A0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) Timer0_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
// 停止定时器,复位计数器
TA0CTL = MC__STOP | TACLR;
// 串口接收超时
UA0_Rx_Timeout = 1;
}
// Timer1 A0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER1_A0_VECTOR
__interrupt void Timer1_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER1_A0_VECTOR))) Timer1_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
// 停止定时器,复位计数器
TA1CTL = MC__STOP | TACLR;
// RF接收超时
RF_Rx_Timeout = 1;
}
// UAR0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
// 接收中断
if((UCA0IE & UCRXIE) && (UCA0IFG & UCRXIFG))
{
uint8_t c = UCA0RXBUF;
TA0CTL = MC__STOP | TACLR; // 停止定时器,复位计数器
TA0CTL = TASSEL__ACLK | MC__UP; // 重新开始计时
if(UA0_Rx_Timeout) // 新的一组数据到来
{
UA0_Rx_Timeout = 0;
// 复位缓冲区
UA0_RxBuf_Length = 0;
UA0_RxBuf_offset = 0;
}
if(UA0_RxBuf_Length < TRAN_BUF_SIZE)
{
#if 1
// 配置模式
if((P2IN & (BIT5 | BIT6)) == (BIT5 | BIT6))
{
// 第1个字符必须为0xC2
if(UA0_RxBuf_Length > 0 || c == 0xC2)
UA0_RxBuf[UA0_RxBuf_Length++] = c;
}
// 透传模式
else if((P2IN & (BIT5 | BIT6)) == 0)
#endif
{
// 主函数透传
UA0_RxBuf[UA0_RxBuf_Length++] = c;
}
P2OUT &= ~BIT3; // Output low
}
}
// 发送中断
if((UCA0IE & UCTXIE) && (UCA0IFG & UCTXIFG))
{
UCA0TXBUF = RF_RxBuf[RF_RxBuf_offset++]; // 发送字符
if(RF_RxBuf_offset >= RF_RxBuf_Length) // 全部发送完
{
// 禁止中断
UCA0IE &= ~UCTXIE;
}
}
}

1306
RF-AP/RF_SX1276.h Normal file

File diff suppressed because it is too large Load Diff

388
RF-AP/Wuhabin/RF-AP-RX.c Normal file
View File

@ -0,0 +1,388 @@
// Haybin_Wu
// Shenitech-RD
// 2016.5
// Built with IAR Embedded Workbench v6.2
//******************************************************************************
#include <msp430FR2433.h>
#include <stdint.h>
#include "FR2433-RFSX.h"
#include "RF_SX1276.h"
uint32_t t=0;
void FRAM_Write (uint16_t FRAM_START,uint8_t *(Array),uint8_t Array_Long);
void FRAM_Read (uint16_t FRAM_START,uint8_t *(Array),uint8_t Array_Long);
void Set_DT(void);
void Refresh_Date(void);
void UART0_Tx(uint8_t data);
#define FRAM_Date_START 0x1800 //Date 存储起始地址
#define FRAM_ID_START 0x1806 //ID 存储起始地址
#define RTC_Data 1920 //定义RTC定时周期 RTC_Data/32=s
uint8_t Rx_Buf[64];
uint8_t RF_RxBuf[64];
uint8_t RF_RxBuf_size[1];
uint8_t Rx_Data=0;
uint8_t Date_Time[6]=
{
30,//0秒
16,//1分
10,//2时
22,//3日
05,//4月
16,//5年
};
uint8_t Device_ID[4]={0xA6,0x52,0x40,0x01,};//设备ID
//UART发送
void UART0_Tx(uint8_t data)
{
UCA0TXBUF = data;
while((UCTXIFG&UCA0IFG)==0);
UCA0IFG&=~UCTXIFG;
}
void Refresh_Date(void)
{
FRAM_Read(FRAM_Date_START,Date_Time,6);
Date_Time[0]=RTCCNT/32;
}
////////////////////////////////////////////////////////////////////////////////
//主函数
////////////////////////////////////////////////////////////////////////////////
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop WDT
// Port Configuration all un-used pins to output low
P1DIR = 0xFF; P2DIR = 0xFF; P3DIR = 0xFF;
P1OUT = 0x00; P2OUT = 0x00; P3OUT = 0x00;
PM5CTL0 &= ~LOCKLPM5;//开引脚功能
// Configure DCO Clock
//外部时钟源启动
P2SEL0 |= BIT0 | BIT1; // set XT1 pin as second function
do
{
CSCTL7 &= ~(XT1OFFG | DCOFFG); // Clear XT1 and DCO fault flag
SFRIFG1 &= ~OFIFG;
} while (SFRIFG1 & OFIFG); // Test oscillator fault flag
//上面清除标志有助于降低功耗
__bis_SR_register(SCG0); // disable FLL
CSCTL3 |= SELREF__XT1CLK; // 外部 32768hz reference source
CSCTL0 = 0; // clear DCO and MOD registers
CSCTL1 &= ~(DCORSEL_7); // Clear DCO frequency select bits first
CSCTL1 |= DCORSEL_3; //DCO=8Mhz
CSCTL2 = FLLD_0 + 243; // DCODIV = 8MHz
__delay_cycles(3);
__bic_SR_register(SCG0); // enable FLL
while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // Poll until FLL is locked
CSCTL4 = SELREF__XT1CLK + SELMS__DCOCLKDIV;// set XT1CLK(32768Hz) as ACLK source & MCLK/SMCLK=DCO
//Timer0_A3 setup
TA0CCTL0 = CCIE; // TACCR0 interrupt enabled
TA0CCR0 = 32768;
TA0CTL = TASSEL_1 | MC_1; // ACLK, continuous mode
// Initialize RTC
RTCMOD = RTC_Data;
RTCCTL = (RTCSS__XT1CLK + RTCPS__1024 + RTCIE);//+ RTCSR// Source = 32kHz crystal, divided by 1024
if(RTCCNT>RTC_Data){RTCCTL |= RTCSR;WDTCTL=0;}
Refresh_Date();//复位后刷新时间
//FRCTL0 = FRCTLPW | NWAITS_1;//FRRAM
FRAM_Read(FRAM_ID_START,Device_ID,4);//刷新设备ID
// Configure UART pins
P1SEL0 |= BIT4 | BIT5; // set 2-UART pin as second function
// Configure UART
UCA0CTLW0 |=(UCSSEL__SMCLK+UCSWRST);//UCPEN+UCPAR+
// Baud Rate calculation
UCA0BR0 = 52; // 8000000/8/9600//这位大于16 UCOS16位要置位
UCA0BR1 = 0x00; // Fractional portion = 0.083
//UCA0MCTLW = 0x11;//微调Baud Rate
UCA0MCTLW = 0x4900 | UCOS16 | UCBRF_1;//微调Baud Rate
UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI
UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt
_EINT();
//无线模块测试化
uint8_t RF_error_flag=0;
for(uint8_t i=0;i<5;i++)//最多初始化3次
{
if(SX127x_init(Init_LoRa_0_8K)==NORMAL) break; //无线模块初始化失败复位
else RF_error_flag=1;
}
if(RF_error_flag==1) //无线初始化失败处理
{
//P3OUT ^= 0xC0;
LPM4;
}
LSD_RF_RXmode(64);
//LSD_RF_SleepMode();//深度睡眠1.2uA
__bis_SR_register(LPM3_bits | GIE); // Enter LPM3
//uint32_t i=0;
__no_operation(); // For debugger
while(1)
{
//for(uint8_t i=0;i<64;i++)Rx_Buf[i-1]=i;
//LSD_RF_SendPacket(Rx_Buf,64); //发送64个字节数据测试
//P3OUT ^= 0xC0; // Toggle P3.6,7 (LED) every 1s
//UART0_Tx(0xE5);
//if(SX127x_init(Init_LoRa_0_8K)==NORMAL);
//LSD_RF_SleepMode();
LSD_RF_RXmode(64);
__bis_SR_register(LPM3_bits | GIE); // Enter LPM3
}
}
// Port 1 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(PORT1_VECTOR))) Port_1 (void)
#else
#error Compiler not supported!
#endif
{
if(DIO0_IFG&DIO0_BIT) //数据传输中断处理
{
LSD_RF_RxVariPacket(RF_RxBuf,RF_RxBuf_size); //接收可变数据包,如果速率为大速率,只能用接收固定数据包长度
DelayMs(10);
/*****************************************指令处理************************/
//if((RF_RxBuf[0]==0x01)&&(RF_RxBuf[1]==0x02))//(RF_rxBuf_size==(RF_RxBuf[3]+6))
{//判定指令是否有效!!!
for(uint8_t i=0;i<RF_RxBuf_size[0];i++)
{UART0_Tx(RF_RxBuf[i]);}
}
DIO0_IFG&=~DIO0_BIT;
}
// Clear P1.3 IFG
//__bic_SR_register_on_exit(LPM3_bits); // Exit LPM3
}
// Port 2 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(PORT2_VECTOR))) Port_2 (void)
#else
#error Compiler not supported!
#endif
{
P2IFG=0; // Clear P1.3 IFG
//__bic_SR_register_on_exit(LPM3_bits); // Exit LPM3
}
/*
// SPI-B0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{
while (!(UCB0IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
UCB0TXBUF = UCB0RXBUF; // Echo received data
}
*/
// Timer0 A0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) Timer0_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
t++;
if(t>5)
{
t=0;//WDTCTL=0;
//LSD_RF_RxVariPacket(Rxbuffer,Rxbuffer_size); //接收可变数据包,如果速率为大速率,只能用接收固定数据包长度
//LSD_RF_RXmode(30); //每次发送一包数据后进入接收状态等待B模块应答
__bic_SR_register_on_exit(LPM3_bits); // Exit LPM3
}
}
// Timer1 A0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER1_A0_VECTOR
__interrupt void Timer1_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER1_A0_VECTOR))) Timer1_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
;
//if(t>5)WDTCTL=0;//P3OUT ^= 0xC0;
}
// RTC interrupt service routine //一分钟一次
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=RTC_VECTOR
__interrupt void RTC_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(RTC_VECTOR))) RTC_ISR (void)
#else
#error Compiler not supported!
#endif
{
if(RTCIV&0x02)
{
Date_Time[0]=60;
Set_DT();//万年历
FRAM_Write (FRAM_Date_START,Date_Time,6);//写入铁电
}
}
// UAR0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
uint8_t CS=0;
if((UCA0IV&USCI_UART_UCRXIFG)==USCI_UART_UCRXIFG)
{
Rx_Buf[Rx_Data++] = UCA0RXBUF;
//UCA0IFG&=~UCRXIFG;
}
if(Rx_Data>=10)
{
for(uint8_t i=0;i<(Rx_Buf[3]+1);i++)
CS+=Rx_Buf[i+2];
if((Rx_Buf[0]==0x4D)&&(Rx_Buf[1]==0x4B)&&(Rx_Buf[Rx_Data-2]==0x55)&&(Rx_Buf[Rx_Data-1]==0x16))
{
FRAM_Read(FRAM_ID_START,Device_ID,4);//刷新设备ID
//功能码01 设置ID//4D 4B 01 08 00 00 00 00 ID ID ID ID CS 16
if((Rx_Buf[2]==0x01)&&(Rx_Buf[4]==Device_ID[0])&&(Rx_Buf[5]==Device_ID[1])&&(Rx_Buf[6]==Device_ID[2])&&(Rx_Buf[7]==Device_ID[3]))
{
Device_ID[0]=Rx_Buf[8];Device_ID[1]=Rx_Buf[9];Device_ID[2]=Rx_Buf[10];Device_ID[3]=Rx_Buf[11];
FRAM_Write(FRAM_ID_START,Device_ID,4);
//FRAM_Read(FRAM_ID_START,Device_ID,4);//刷新设备ID
UART0_Tx(0xE5);
Rx_Data=0;
}
//功能码06 读设备RTC//4D 4B 06 04 00 00 00 00 CS 16
if((Rx_Buf[2]==0x06)&&(Rx_Buf[4]==Device_ID[0])&&(Rx_Buf[5]==Device_ID[1])&&(Rx_Buf[6]==Device_ID[2])&&(Rx_Buf[7]==Device_ID[3]))
{
Refresh_Date();//refresh time
//Return 4D 4B 06 A0 ID ID ID ID DT DT DT DT DT DT E5 16
UART0_Tx(0x4D);UART0_Tx(0x4B);UART0_Tx(0x06);UART0_Tx(0xA0);UART0_Tx(Device_ID[0]);UART0_Tx(Device_ID[1]);UART0_Tx(Device_ID[2]);UART0_Tx(Device_ID[3]);
UART0_Tx(Date_Time[0]);UART0_Tx(Date_Time[1]);UART0_Tx(Date_Time[2]);UART0_Tx(Date_Time[3]);UART0_Tx(Date_Time[4]);UART0_Tx(Date_Time[5]);
UART0_Tx(0xE5);UART0_Tx(0x16);
Rx_Data=0;
}
//功能码07 同步RTC//4D 4B 06 04 00 00 00 00 CS 16
if((Rx_Buf[2]==0x07)&&(Rx_Buf[4]==Device_ID[0])&&(Rx_Buf[5]==Device_ID[1])&&(Rx_Buf[6]==Device_ID[2])&&(Rx_Buf[7]==Device_ID[3]))
{
;
}
}
}
}
//万年历程序
void Set_DT(void)
{
if(Date_Time[0]>59)//秒进位
{
Date_Time[1]++;
Date_Time[0]=0;
}
if(Date_Time[1]>59)//分进位
{
Date_Time[2]++;
Date_Time[1]=0;
}
if(Date_Time[2]>23)//小时进位
{
Date_Time[3]++;
Date_Time[2]=0;
}
//常31天情况
if((Date_Time[4]==1)||(Date_Time[4]==3)||(Date_Time[4]==5)||(Date_Time[4]==7)||(Date_Time[4]==8)||(Date_Time[4]==10)||(Date_Time[4]==12))
{
if(Date_Time[3]>31)
{
Date_Time[3]=1;
Date_Time[4]++;
}
if(Date_Time[4]>12)
{
Date_Time[4]=1;
Date_Time[5]++;
}
if(Date_Time[5]>99)Date_Time[5]=0;
}
//常30天情况
if((Date_Time[4]==4)||(Date_Time[4]==6)||(Date_Time[4]==9)||(Date_Time[4]==11))
{
if(Date_Time[3]>30)
{
Date_Time[3]=1;
Date_Time[4]++;
}
}
//2月特殊情况
if(Date_Time[4]==2)
{
if((Date_Time[5]%4==0&&Date_Time[5]%100!=0) ||(Date_Time[5]%400==0))//闰年
{
if(Date_Time[3]>29)
{
Date_Time[3]=1;
Date_Time[4]++;
}
}
else
{
if(Date_Time[3]>28)
{
Date_Time[3]=1;
Date_Time[4]++;
}
}
}
}
void FRAM_Write (uint16_t FRAM_START,uint8_t *(Array),uint8_t Array_Long)
{
SYSCFG0 &= ~DFWP; //Close FRAM Write Protection
//FRAM_Date_START=*0x1800;
for (uint8_t i = 0; i < Array_Long; i++)
{
*(uint8_t *)(FRAM_START+i)=Array[i];//
}
SYSCFG0 |= DFWP; //Open FRAM Write Protection
}
void FRAM_Read (uint16_t FRAM_START,uint8_t *(Array),uint8_t Array_Long)
{
for (uint8_t i = 0; i < Array_Long; i++)
{
Array[i]=*(uint8_t *)(FRAM_START+i);
}
}

395
RF-AP/Wuhabin/RF-AP-TX.c Normal file
View File

@ -0,0 +1,395 @@
// Haybin_Wu
// Shenitech-RD
// 2016.5
// Built with IAR Embedded Workbench v6.2
//******************************************************************************
#include <msp430FR2433.h>
#include <stdint.h>
#include "FR2433-RFSX.h"
#include "RF_SX1276.h"
uint32_t t=0;
void FRAM_Write (uint16_t FRAM_START,uint8_t *(Array),uint8_t Array_Long);
void FRAM_Read (uint16_t FRAM_START,uint8_t *(Array),uint8_t Array_Long);
void Set_DT(void);
void Refresh_Date(void);
void UART0_Tx(uint8_t data);
#define FRAM_Date_START 0x1800 //Date 存储起始地址
#define FRAM_ID_START 0x1806 //ID 存储起始地址
#define RTC_Data 1920 //定义RTC定时周期 RTC_Data/32=s
uint8_t Rx_Buf[64];
uint8_t Rx_Length=0;
uint8_t Rx_Flog=0;
uint8_t Rx_Data=0;
uint8_t Date_Time[6]=
{
30,//0秒
16,//1分
10,//2时
22,//3日
05,//4月
16,//5年
};
uint8_t Device_ID[4]={0xA6,0x52,0x40,0x01,};//设备ID
//UART发送
void UART0_Tx(uint8_t data)
{
UCA0TXBUF = data;
while((UCTXIFG&UCA0IFG)==0);
UCA0IFG&=~UCTXIFG;
}
void Refresh_Date(void)
{
FRAM_Read(FRAM_Date_START,Date_Time,6);
Date_Time[0]=RTCCNT/32;
}
////////////////////////////////////////////////////////////////////////////////
//主函数
////////////////////////////////////////////////////////////////////////////////
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop WDT
// Port Configuration all un-used pins to output low
P1DIR = 0xFF; P2DIR = 0xFF; P3DIR = 0xFF;
P1OUT = 0x00; P2OUT = 0x00; P3OUT = 0x00;
PM5CTL0 &= ~LOCKLPM5;//开引脚功能
// Configure DCO Clock
//外部时钟源启动
P2SEL0 |= BIT0 | BIT1; // set XT1 pin as second function
do
{
CSCTL7 &= ~(XT1OFFG | DCOFFG); // Clear XT1 and DCO fault flag
SFRIFG1 &= ~OFIFG;
} while (SFRIFG1 & OFIFG); // Test oscillator fault flag
//上面清除标志有助于降低功耗
__bis_SR_register(SCG0); // disable FLL
CSCTL3 |= SELREF__XT1CLK; // 外部 32768hz reference source
CSCTL0 = 0; // clear DCO and MOD registers
CSCTL1 &= ~(DCORSEL_7); // Clear DCO frequency select bits first
CSCTL1 |= DCORSEL_3; //DCO=8Mhz
CSCTL2 = FLLD_0 + 243; // DCODIV = 8MHz
__delay_cycles(3);
__bic_SR_register(SCG0); // enable FLL
while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // Poll until FLL is locked
CSCTL4 = SELREF__XT1CLK + SELMS__DCOCLKDIV;// set XT1CLK(32768Hz) as ACLK source & MCLK/SMCLK=DCO
//Timer0_A3 setup
//TA0CCTL0 = CCIE; // TACCR0 interrupt enabled
//TA0CCR0 = 32768;
//TA0CTL = TASSEL_1 | MC_1; // ACLK, continuous mode
// Initialize RTC
RTCMOD = RTC_Data;
RTCCTL = (RTCSS__XT1CLK + RTCPS__1024 + RTCIE);//+ RTCSR// Source = 32kHz crystal, divided by 1024
if(RTCCNT>RTC_Data){RTCCTL |= RTCSR;WDTCTL=0;}
Refresh_Date();//复位后刷新时间
//FRCTL0 = FRCTLPW | NWAITS_1;//FRRAM
FRAM_Read(FRAM_ID_START,Device_ID,4);//刷新设备ID
// Configure UART pins
P1SEL0 |= BIT4 | BIT5; // set 2-UART pin as second function
// Configure UART
UCA0CTLW0 |=(UCSSEL__SMCLK+UCSWRST);//UCPEN+UCPAR+
// Baud Rate calculation
UCA0BR0 = 52; // 8000000/8/9600//这位大于16 UCOS16位要置位
UCA0BR1 = 0x00; // Fractional portion = 0.083
//UCA0MCTLW = 0x11;//微调Baud Rate
UCA0MCTLW = 0x4900 | UCOS16 | UCBRF_1;//微调Baud Rate
UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI
UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt
_EINT();
//无线模块测试化
uint8_t RF_error_flag=0;
for(uint8_t i=0;i<5;i++)//最多初始化3次
{
if(SX127x_init(Init_LoRa_0_8K)==NORMAL) break; //无线模块初始化失败复位
else RF_error_flag=1;
}
if(RF_error_flag==1) //无线初始化失败处理
{
//P3OUT ^= 0xC0;
LPM4;
}
LSD_RF_SleepMode();//深度睡眠1.2uA
__bis_SR_register(LPM3_bits | GIE); // Enter LPM3
//uint32_t i=0;
__no_operation(); // For debugger
while(1)
{
//P3OUT ^= 0xC0;
//for(uint8_t i=0;i<Rx_Data;i++);
do
{
Rx_Flog=0;
DelayMs(450); //延时长短跟串口波特率有关系
}
while(Rx_Flog==1);
LSD_RF_SendPacket(Rx_Buf,Rx_Data); //发送个字节数据测试
DelayMs(800);//延时长短跟发送数据长短和速率有关系
Rx_Data=0;
//P3OUT ^= 0xC0; // Toggle P3.6,7 (LED) every 1s
//UART0_Tx(0xE5);
//if(SX127x_init(Init_LoRa_0_8K)==NORMAL);
LSD_RF_SleepMode();
__bis_SR_register(LPM3_bits | GIE); // Enter LPM3
}
}
// Port 2 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(PORT2_VECTOR))) Port_2 (void)
#else
#error Compiler not supported!
#endif
{
P2IFG=0; // Clear P1.3 IFG
//__bic_SR_register_on_exit(LPM3_bits); // Exit LPM3
}
/*
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
if(Rx_Length >= 100)
{
Rx_Length = 0;
}
Rx_Buf[Rx_Length]=UCA0RXBUF;
Rx_Length++;
Rx_Flog=1;
}
// SPI-B0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{
while (!(UCB0IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
UCB0TXBUF = UCB0RXBUF; // Echo received data
}
*/
// Timer0 A0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) Timer0_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
t++;
if(t>5)
{
t=0;//WDTCTL=0;
//LSD_RF_RxVariPacket(Rxbuffer,Rxbuffer_size); //接收可变数据包,如果速率为大速率,只能用接收固定数据包长度
//LSD_RF_RXmode(30); //每次发送一包数据后进入接收状态等待B模块应答
}
}
// Timer1 A0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER1_A0_VECTOR
__interrupt void Timer1_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER1_A0_VECTOR))) Timer1_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
;
//if(t>5)WDTCTL=0;//P3OUT ^= 0xC0;
}
// RTC interrupt service routine //一分钟一次
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=RTC_VECTOR
__interrupt void RTC_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(RTC_VECTOR))) RTC_ISR (void)
#else
#error Compiler not supported!
#endif
{
if(RTCIV&0x02)
{
Date_Time[0]=60;
Set_DT();//万年历
FRAM_Write (FRAM_Date_START,Date_Time,6);//写入铁电
}
}
// UAR0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
uint8_t CS=0;
if((UCA0IV&USCI_UART_UCRXIFG)==USCI_UART_UCRXIFG)
{
Rx_Flog=1;
Rx_Buf[Rx_Data] = UCA0RXBUF;
Rx_Data++;
//UCA0IFG&=~UCRXIFG;
}
if(Rx_Data>=10)
{
for(uint8_t i=0;i<(Rx_Buf[3]+1);i++)
CS+=Rx_Buf[i+2];
if((Rx_Buf[0]==0x4D)&&(Rx_Buf[1]==0x4B)&&(Rx_Buf[Rx_Data-2]==0x55)&&(Rx_Buf[Rx_Data-1]==0x16))
{
FRAM_Read(FRAM_ID_START,Device_ID,4);//刷新设备ID
//功能码01 设置ID//4D 4B 01 08 00 00 00 00 ID ID ID ID CS 16
if((Rx_Buf[2]==0x01)&&(Rx_Buf[4]==Device_ID[0])&&(Rx_Buf[5]==Device_ID[1])&&(Rx_Buf[6]==Device_ID[2])&&(Rx_Buf[7]==Device_ID[3]))
{
Device_ID[0]=Rx_Buf[8];Device_ID[1]=Rx_Buf[9];Device_ID[2]=Rx_Buf[10];Device_ID[3]=Rx_Buf[11];
FRAM_Write(FRAM_ID_START,Device_ID,4);
//FRAM_Read(FRAM_ID_START,Device_ID,4);//刷新设备ID
UART0_Tx(0xE5);
}
//功能码06 读设备RTC//4D 4B 06 04 00 00 00 00 CS 16
if((Rx_Buf[2]==0x06)&&(Rx_Buf[4]==Device_ID[0])&&(Rx_Buf[5]==Device_ID[1])&&(Rx_Buf[6]==Device_ID[2])&&(Rx_Buf[7]==Device_ID[3]))
{
Refresh_Date();//refresh time
//Return 4D 4B 06 A0 ID ID ID ID DT DT DT DT DT DT E5 16
UART0_Tx(0x4D);UART0_Tx(0x4B);UART0_Tx(0x06);UART0_Tx(0xA0);UART0_Tx(Device_ID[0]);UART0_Tx(Device_ID[1]);UART0_Tx(Device_ID[2]);UART0_Tx(Device_ID[3]);
UART0_Tx(Date_Time[0]);UART0_Tx(Date_Time[1]);UART0_Tx(Date_Time[2]);UART0_Tx(Date_Time[3]);UART0_Tx(Date_Time[4]);UART0_Tx(Date_Time[5]);
UART0_Tx(0xE5);UART0_Tx(0x16);
}
//功能码07 同步RTC//4D 4B 06 04 00 00 00 00 CS 16
if((Rx_Buf[2]==0x07)&&(Rx_Buf[4]==Device_ID[0])&&(Rx_Buf[5]==Device_ID[1])&&(Rx_Buf[6]==Device_ID[2])&&(Rx_Buf[7]==Device_ID[3]))
{
;
}
}
__bic_SR_register_on_exit(LPM3_bits); // Exit LPM3
}
}
//万年历程序
void Set_DT(void)
{
if(Date_Time[0]>59)//秒进位
{
Date_Time[1]++;
Date_Time[0]=0;
}
if(Date_Time[1]>59)//分进位
{
Date_Time[2]++;
Date_Time[1]=0;
}
if(Date_Time[2]>23)//小时进位
{
Date_Time[3]++;
Date_Time[2]=0;
}
//常31天情况
if((Date_Time[4]==1)||(Date_Time[4]==3)||(Date_Time[4]==5)||(Date_Time[4]==7)||(Date_Time[4]==8)||(Date_Time[4]==10)||(Date_Time[4]==12))
{
if(Date_Time[3]>31)
{
Date_Time[3]=1;
Date_Time[4]++;
}
if(Date_Time[4]>12)
{
Date_Time[4]=1;
Date_Time[5]++;
}
if(Date_Time[5]>99)Date_Time[5]=0;
}
//常30天情况
if((Date_Time[4]==4)||(Date_Time[4]==6)||(Date_Time[4]==9)||(Date_Time[4]==11))
{
if(Date_Time[3]>30)
{
Date_Time[3]=1;
Date_Time[4]++;
}
}
//2月特殊情况
if(Date_Time[4]==2)
{
if((Date_Time[5]%4==0&&Date_Time[5]%100!=0) ||(Date_Time[5]%400==0))//闰年
{
if(Date_Time[3]>29)
{
Date_Time[3]=1;
Date_Time[4]++;
}
}
else
{
if(Date_Time[3]>28)
{
Date_Time[3]=1;
Date_Time[4]++;
}
}
}
}
void FRAM_Write (uint16_t FRAM_START,uint8_t *(Array),uint8_t Array_Long)
{
SYSCFG0 &= ~DFWP; //Close FRAM Write Protection
//FRAM_Date_START=*0x1800;
for (uint8_t i = 0; i < Array_Long; i++)
{
*(uint8_t *)(FRAM_START+i)=Array[i];//
}
SYSCFG0 |= DFWP; //Open FRAM Write Protection
}
void FRAM_Read (uint16_t FRAM_START,uint8_t *(Array),uint8_t Array_Long)
{
for (uint8_t i = 0; i < Array_Long; i++)
{
Array[i]=*(uint8_t *)(FRAM_START+i);
}
}

View File

@ -0,0 +1,264 @@
////////////////////////////////////////////////////////////////////////////////
// 版权: 利尔达科技集团股份有限公司
// 文件名:
// 版本: v2.0
// 工作环境: IAR v5.30
// 作者: 于海波
// 生成日期: 2013.12
// 功能: API
// 相关文件:
// 修改日志:
// 见更新说明
////////////////////////////////////////////////////////////////////////////////
#include <stdint.h>
#include <stdbool.h>
#include "sx1276-LoRa.h"
#include "sx1276-f4152-Hal.h"
#include "LSD_RF_SX1276.h"
//===================================定义变量===================================================
float G_BandWidthKHz = 500.0;//本地计算Symbol周期使用
float G_TsXms = 1.024;//1.024ms
S_LoRaConfig G_LoRaConfig = {
470000000,
BW500KHZ,
SF08,
CR_4_5,
15,
true,
true,
true,
64,
};
bool LoRaConfig_Check()
{
if((G_LoRaConfig.LoRa_Freq<137000000)||(G_LoRaConfig.LoRa_Freq>525000000))
return false;
G_LoRaConfig.BandWidth = (t_BandWidth)(G_LoRaConfig.BandWidth&0xF0);
if(G_LoRaConfig.BandWidth>BW500KHZ)
return false;
//计算BandWidth
switch(G_LoRaConfig.BandWidth){
case BW500KHZ:G_BandWidthKHz = 500.0;break;
case BW250KHZ:G_BandWidthKHz = 250.0;break;
case BW125KHZ:G_BandWidthKHz = 125.0;break;
case BW62_50KHZ:G_BandWidthKHz = 62.5;break;
case BW41_66KHZ:G_BandWidthKHz = 41.66;break;
case BW31_25KHZ:G_BandWidthKHz = 31.25;break;
case BW20_83KHZ:G_BandWidthKHz = 20.83;break;
case BW15_62KHZ:G_BandWidthKHz = 15.62;break;
case BW10_41KHZ:G_BandWidthKHz = 10.41;break;
case BW7_81KHZ:G_BandWidthKHz = 7.81;break;
}
G_LoRaConfig.SpreadingFactor = (t_SpreadingFactor)(G_LoRaConfig.SpreadingFactor&0xF0);
if((G_LoRaConfig.SpreadingFactor>SF12)||(G_LoRaConfig.SpreadingFactor<SF06))
return false;
//计算LoRa码元周期单位ms
G_TsXms = (2<<((G_LoRaConfig.SpreadingFactor>>4)-1))/G_BandWidthKHz;
G_LoRaConfig.CodingRate = (t_CodingRate)(G_LoRaConfig.CodingRate&0x0E);
if((G_LoRaConfig.CodingRate>CR_4_8)||(G_LoRaConfig.CodingRate<CR_4_5))
return false;
if(G_LoRaConfig.PowerCfig>15)
return false;
if(G_LoRaConfig.PayloadLength>127)
return false;
return true;
}
//===================================子函数===================================================
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF初始化
// 输入参数 : tSX127xInitPara initPara 输入速率Init_LoRa_0_8K, Init_LoRa_4_8K , Init_LoRa_10k,
// 返回参数 : tSX127xError 错误枚举内容
// 说明 : 初始化时信道初始化默认为0信道
////////////////////////////////////////////////////////////////////////////////
tSX127xError SX127x_init()
{
if(false==LoRaConfig_Check()) //如果输入参数错误
{
return PARAMETER_INVALID; //报错输入
}
SX1276InitIo(); // PAIO口初始化
SX1276Reset(); //复位RF
SX1276SPISetup(); //SPI初始化
//切换到LoRamodestandby状态
SX1276Write( REG_LR_OPMODE, RFLR_OPMODE_SLEEP );
SX1276Write( REG_LR_OPMODE, 0x80|RFLR_OPMODE_SLEEP );
SX1276Write( REG_LR_OPMODE, 0x80|RFLR_OPMODE_STANDBY );
/*------------------------------------------------
SPI */
uint8_t test = 0;
SX1276Write( REG_LR_HOPPERIOD,0x91 );//选一个用不到的寄存器来做验证
SX1276Read( REG_LR_HOPPERIOD,&test);
if(test!=0x91)
return SPI_READCHECK_WRONG;
SX1276Write( REG_LR_DIOMAPPING2, RFLR_DIOMAPPING2_DIO4_01);
//Frequency Configuration
LSD_RF_FreqSet(); //设置频率
//PA Configuration
LSD_RF_PoutSet();
SX1276Write( REG_LR_PARAMP,RFLR_PARAMP_0100_US);
// ↑PA Ramp的时间如果用户LDO不能快速输出大电流泵能力适当增加PA Ramp时间
// ↑如果Ramp时间过短超过了LDO的能力时会出现进入TX后系统电流为发射电流但是RF信号不出现的现象
SX1276Write( REG_LR_OCP,0x20|RFLR_OCP_TRIM_240_MA);//电流过载保护 Over Current Protection
//PayloadLength 初始化
SX1276Write( REG_LR_PAYLOADLENGTH,G_LoRaConfig.PayloadLength);
//注意无头模式Implicit Header必须提前规定好收发双方的PL
//BW、CR、Header有无初始化
SX1276Write( REG_LR_MODEMCONFIG1,\
(((uint8_t)G_LoRaConfig.BandWidth)|((uint8_t)G_LoRaConfig.CodingRate))|(\
(true==G_LoRaConfig.ExplicitHeaderOn)?0x00:0x01));
//SF、CRC初始化
SX1276Write( REG_LR_MODEMCONFIG2,\
((uint8_t)G_LoRaConfig.SpreadingFactor)|(\
(true==G_LoRaConfig.CRCON)?0x04:0x00));
if(SF06==G_LoRaConfig.SpreadingFactor){ //慎用SF = 6需要的配置很特殊
uint8_t temp = 0;
SX1276Read( 0x31,&temp);
SX1276Write( 0x31,(temp& 0xF8)|0x05);
SX1276Write( 0x37,0x0C);
}
//低速率优化功能是否开启、AutoAGC默认开启
SX1276Write( REG_LR_MODEMCONFIG3,((G_TsXms>16.0)?\
RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_ON:RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_OFF\
)|RFLR_MODEMCONFIG3_AGCAUTO_ON);
return NORMAL;
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF发送数据包
// 输入参数 : uint8_t*data发送数据指针
// 返回参数 : 无
// 说明 : 设置为发送是, preamble改回默认值
////////////////////////////////////////////////////////////////////////////////
void SX1276_TxPacket(uint8_t*data)
{
SX1276Write( REG_LR_OPMODE, 0x80|RFLR_OPMODE_STANDBY );
SX1276Write( REG_LR_PREAMBLEMSB,0);
SX1276Write( REG_LR_PREAMBLELSB,10);
SX1276Write( REG_LR_PAYLOADLENGTH,G_LoRaConfig.PayloadLength);
SX1276WriteRxTx(true);
SX1276Write( REG_LR_FIFOADDRPTR,0x80);
SX1276WriteBuffer(REG_LR_FIFO,data,G_LoRaConfig.PayloadLength);
SX1276Write(REG_LR_IRQFLAGS,0xff);
SX1276Write( REG_LR_IRQFLAGSMASK, ~(RFLR_IRQFLAGS_TXDONE));
SX1276Write( REG_LR_DIOMAPPING1, RFLR_DIOMAPPING1_DIO0_01 );
SX1276Write( REG_LR_OPMODE, 0x80|RFLR_OPMODE_TRANSMITTER );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF进入接收状态
// 输入参数 :
// 返回参数 : 无
// 说明 : 进入接收后preamble设置回默认值为
////////////////////////////////////////////////////////////////////////////////
void Rx_mode()
{
SX1276Write( REG_LR_OPMODE, 0x80|RFLR_OPMODE_STANDBY );
SX1276Write( REG_LR_PREAMBLEMSB,0);
SX1276Write( REG_LR_PREAMBLELSB,10);
SX1276Write( REG_LR_PAYLOADLENGTH,G_LoRaConfig.PayloadLength);
SX1276Write( REG_LR_IRQFLAGSMASK, ~(RFLR_IRQFLAGS_RXDONE));
SX1276Write( REG_LR_DIOMAPPING1, RFLR_DIOMAPPING1_DIO0_00 );
SX1276WriteRxTx(false);
SX1276Write( REG_LR_FIFOADDRPTR,0x00);
SX1276Write(REG_LR_IRQFLAGS,0xff);
SX1276Write( REG_LR_OPMODE, 0x80|RFLR_OPMODE_RECEIVER );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF接收数据包
// 输入参数 : uint8_t*cbuf接收数组指针
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void LSD_RF_RxPacket(uint8_t*cbuf)
{
if(true==G_LoRaConfig.ExplicitHeaderOn){
//有头那么从寄存器中读否则按照G_LoRaConfig设置长度读取FIFO
SX1276Read(REG_LR_NBRXBYTES,&G_LoRaConfig.PayloadLength);
SX1276Write( REG_LR_FIFOADDRPTR,0x00);
}
SX1276ReadFifo(cbuf,G_LoRaConfig.PayloadLength);
SX1276Write(REG_LR_IRQFLAGS,0xff);
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF进入SLEEP状态
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void LSD_RF_SleepMode(void)
{
SX1276Write( REG_LR_OPMODE, 0x80|RFLR_OPMODE_STANDBY );
SX1276Write( REG_LR_OPMODE, 0x80|RFLR_OPMODE_SLEEP );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF进入standby状态
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void LSD_RF_StandbyMode(void)
{
SX1276Write( REG_LR_OPMODE, 0x80|RFLR_OPMODE_STANDBY );
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF配置频率
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
tSX127xError LSD_RF_FreqSet()
{
if((G_LoRaConfig.LoRa_Freq>525000000)||(G_LoRaConfig.LoRa_Freq<137000000))
return PARAMETER_INVALID;
uint32_t freq_reg = (uint32_t)(G_LoRaConfig.LoRa_Freq/FREQ_STEP);
uint8_t test_FRFMSB = 0,test_FRFMID=0,test_FRFLSB=0;
LSD_RF_StandbyMode();
// FREQ = 474.6MHz
SX1276Write( REG_LR_FRFMSB, (uint8_t)(freq_reg>>16));//Carrier Freq 470M
SX1276Write( REG_LR_FRFMID, (uint8_t)(freq_reg>>8) );
SX1276Write( REG_LR_FRFLSB, (uint8_t)(freq_reg) );
SX1276Read(REG_LR_FRFMSB,&test_FRFMSB);
SX1276Read(REG_LR_FRFMID,&test_FRFMID);
SX1276Read(REG_LR_FRFLSB,&test_FRFLSB);
if(test_FRFMSB != (uint8_t)(freq_reg>>16))
return SPI_READCHECK_WRONG;
if(test_FRFMID != (uint8_t)(freq_reg>>8))
return SPI_READCHECK_WRONG;
if(test_FRFLSB != (uint8_t)(freq_reg))
return SPI_READCHECK_WRONG;
return NORMAL;
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF配置功率
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
tSX127xError LSD_RF_PoutSet()
{
if(G_LoRaConfig.PowerCfig>15)
return PARAMETER_INVALID;
LSD_RF_StandbyMode();
SX1276Write( REG_LR_PACONFIG, 0xf0|G_LoRaConfig.PowerCfig);
uint8_t test = 0;
SX1276Read(REG_LR_PACONFIG,&test);
if((0xf0|G_LoRaConfig.PowerCfig)!=test)
return SPI_READCHECK_WRONG;
if(true==G_LoRaConfig.MaxPowerOn)
SX1276Write( REG_LR_PADAC, 0x80|RFLR_PADAC_20DBM_ON );
else
SX1276Write( REG_LR_PADAC, 0x80|RFLR_PADAC_20DBM_OFF );
return NORMAL;
}

View File

@ -0,0 +1,133 @@
////////////////////////////////////////////////////////////////////////////////
// 版权: 利尔达科技集团股份有限公司
// 文件名:
// 版本: v1.0
// 工作环境: IAR v5.30
// 作者: 佟亚波、于海波
// 生成日期: 2013.12
// 功能: API
// 相关文件:
// 修改日志:
////////////////////////////////////////////////////////////////////////////////
#ifndef LSD_RF_SX1276_H
#define LSD_RF_SX1276_H
//===================================定义===================================================
typedef enum
{
NORMAL, //正常
PARAMETER_INVALID, //参数不可用
SPI_READCHECK_WRONG, //SPI出错
}tSX127xError; //定义出错枚举
typedef enum
{
// LORA [0: 7.8 kHz, 1: 10.4 kHz, 2: 15.6 kHz, 3: 20.8 kHz, 4: 31.2 kHz,
// 5: 41.6 kHz, 6: 62.5 kHz, 7: 125 kHz, 8: 250 kHz, 9: 500 kHz, other: Reserved]
BW500KHZ = 0x90,
BW250KHZ = 0x80,
BW125KHZ = 0x70,
BW62_50KHZ = 0x60,
BW41_66KHZ = 0x50,
BW31_25KHZ = 0x40,
BW20_83KHZ = 0x30,
BW15_62KHZ = 0x20,
BW10_41KHZ = 0x10,
BW7_81KHZ = 0x00,
}t_BandWidth; //定义带宽枚举
typedef enum{
// LORA [6: 64, 7: 128, 8: 256, 9: 512, 10: 1024, 11: 2048, 12: 4096 chips]
SF12 = 0xC0,
SF11 = 0xB0,
SF10 = 0xA0,
SF09 = 0x90,
SF08 = 0x80,
SF07 = 0x70,
SF06 = 0x60,
}t_SpreadingFactor;
typedef enum{
// LORA [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
CR_4_8 = 0x08,
CR_4_7 = 0x06,
CR_4_6 = 0x04,
CR_4_5 = 0x02,
}t_CodingRate;
typedef struct S_LoRaConfig
{
uint32_t LoRa_Freq;
t_BandWidth BandWidth;
t_SpreadingFactor SpreadingFactor;
t_CodingRate CodingRate;
int8_t PowerCfig; //0~15,输出功率 = 2+PowerReg,具体参考数据手册
//如果开启MaxPowerPowerReg = 15时输出功率 = 19±1dBm
bool MaxPowerOn; // [false: OFF, true: ON]
bool CRCON; // [false: OFF, true: ON]
bool ExplicitHeaderOn; // [false: OFF, true: ON]
uint8_t PayloadLength; //1~127
}S_LoRaConfig;
extern S_LoRaConfig G_LoRaConfig;
extern float G_BandWidthKHz;//计算Symbol周期使用
extern float G_TsXms;//Symbol周期单位ms
//===================================函数声明===================================================
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF初始化
// 输入参数 :
// 返回参数 : tSX127xError 错误枚举内容
// 说明 : 初始化时调用全局变量G_LoRaConfig
////////////////////////////////////////////////////////////////////////////////
tSX127xError SX127x_init();
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF发送数据包
// 输入参数 : uint8_t*data发送数据指针uint8_t size发送数据长度
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void SX1276_TxPacket(uint8_t*data);
void SX1276_Process(void);
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF进入接收状态
// 输入参数 :
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void Rx_mode(void);
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF接收可变数据包
// 输入参数 : uint8_t*cbuf接收数组指针
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void LSD_RF_RxPacket(uint8_t*cbuf);
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF进入SLEEP状态
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void LSD_RF_SleepMode(void);
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF进入standby状态
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
void LSD_RF_StandbyMode(void);
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF设置频率
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
tSX127xError LSD_RF_FreqSet();
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : RF设置功率
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
tSX127xError LSD_RF_PoutSet();
//*****************************************************************************************
#endif

View File

@ -0,0 +1,262 @@
////////////////////////////////////////////////////////////////////////////////
// 版权: 利尔达科技集团股份有限公司
// 文件名: main_tx/rx
// 版本: v1.0
// 工作环境: IAR v5.30
// 作者: 于海波
// 生成日期: 2013.12
// 功能: A发送包书记给B黄灯闪烁B模块接到数据红灯闪烁B将数据回传给A模块
// A接到数据后红灯闪烁 循环次操作,
// 相关文件:
// 修改日志:
////////////////////////////////////////////////////////////////////////////////
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include "driver.h"
#include "sx1276-f4152-Hal.h"
#include "LSD_RF_SX1276.h"
#include "LSD_RF_APPrf.h"
#include "clock.h"
//===================================定义变量===================================================
long SysTick = 0;
uint8_t TXbuffer[30]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29};
uint8_t WakeAddr[8]={5,6,7,8,9,10,11,7};
uint8_t Rxbuffer[64];
//===================================函数声明===================================================
//===============================================================================================
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : 主函数
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
typedef enum{
Nope,
B300bps,//BW = 500KHz SF = 7 CR = 4_6
B1080bps,//BW = 125KHz SF = 9 CR = 4_6
B4000bps,//BW = 125KHz SF = 7 CR = 4_5
}t_Baudrate;
t_Baudrate Baudrate = Nope;
unsigned char *point;
unsigned char Reg_PKTSNR = 0;
unsigned char Reg_PKTRssi = 0;
unsigned char Reg_Rssi = 0;
unsigned char LCD_p[9] = {0,0,0,0,0,8,0,1,0xff};
int T_Cnt = 0;
int R_Cnt = 0;
bool RESET_Flag = false;
void main( void )
{
WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗
platform_init(); //测试底板初始化
LEDONBAND(LEDALL); //初始化过程点亮所有LED灯
KEYBOARD_DIR &=~ (KEY_S1+KEY_S2);
KEYBOARD_IFG &=~ (KEY_S1+KEY_S2);
KEYBOARD_IES |= (KEY_S1+KEY_S2);
KEYBOARD_IE |= (KEY_S1+KEY_S2);
point = (unsigned char *)(&(G_LoRaConfig.BandWidth));
flash_read(FLASH_ADDRESS_D,point,3*2);
if(G_LoRaConfig.BandWidth>BW500KHZ){
G_LoRaConfig.BandWidth=BW125KHZ;
G_LoRaConfig.SpreadingFactor = SF09;
G_LoRaConfig.CodingRate = CR_4_6;
flash_seg_clear(FLASH_ADDRESS_D);//写之前必清除
flash_write(FLASH_ADDRESS_D,point,3*2);
}
if(G_LoRaConfig.SpreadingFactor==SF11){
Baudrate = B300bps;
LCD_p[8] = 1;
}
else{
if(G_LoRaConfig.SpreadingFactor==SF07){
Baudrate = B4000bps;
LCD_p[8] = 3;
}
else{
Baudrate = B1080bps;
LCD_p[8] = 2;
}
}
LCD_p[7] = 0xff;LCD_p[6] = 0;LCD_p[5] = 0;LCD_p[4] = 0;
lcd_init();
LCD_Disp_ALL_Num(LCD_p);
//配置各个参数
G_LoRaConfig.LoRa_Freq = 474600000; //中心频点470MHz
//G_LoRaConfig.BandWidth = BW125KHZ; //BW = 125KHz
//G_LoRaConfig.SpreadingFactor = SF09; //SF = 9
//G_LoRaConfig.CodingRate = CR_4_6; //CR = 4/6
G_LoRaConfig.PowerCfig = 15; //19±dBm
G_LoRaConfig.MaxPowerOn = true;
G_LoRaConfig.CRCON = true; //CRC开启
G_LoRaConfig.ExplicitHeaderOn = true; //Header开启
G_LoRaConfig.PayloadLength = 20; //数据包长度
if(SX127x_init()!=NORMAL) WDTCTL=0; //无线模块初始化失败复位
KEYBOARD_IE |= (KEY_S1+KEY_S2);
_EINT(); //开总中断
LEDOFFBIT(LEDALL); //初始化完毕关闭所有LED灯
ON_Timerout(); //开启定时器1s一发数据
while(1)
{
LPM3;
if(RESET_Flag==true){
flash_seg_clear(FLASH_ADDRESS_D);//写之前必清除
flash_write(FLASH_ADDRESS_D,point,3*2);
WDTCTL = 0;//RESET
}
LSD_RF_RXmode(); //每次发送一包数据后进入接收状态等待B模块应答
/****RSSI*****/
//中断中已经算过符号
LCD_p[6] = Reg_PKTRssi/100%10;
LCD_p[5] = Reg_PKTRssi/10%10;
LCD_p[4] = Reg_PKTRssi%10;
LCD_p[0] = T_Cnt%10;
LCD_p[1] = T_Cnt/10%10;
LCD_p[2] = R_Cnt%10;
LCD_p[3] = R_Cnt/10%10;
/****Cnt *****/
//LCD_p[0] = T_Cnt%10;
//LCD_p[1] = T_Cnt/10%10;
//LCD_p[2] = R_Cnt%10;
//LCD_p[3] = R_Cnt/10%10;
LCD_ClrLcd_ALL();
LCD_Disp_ALL_Num(LCD_p);
if(T_Cnt>=100)
T_Cnt = 0;
if(R_Cnt>=100)
R_Cnt = 0;
}
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : 无线接收数据中断入口
// 输入参数 : 无
// 返回参数 : 无
// 说明 :
////////////////////////////////////////////////////////////////////////////////
#pragma vector = PORT1_VECTOR
__interrupt void port1_isr(void)
{
if(KEYBOARD_IFG&(KEY_ALL)){
char Keys_Flag = KEYBOARD_IFG&(KEY_ALL);
switch(Keys_Flag&(KEY_S1|KEY_S2)){
case KEY_S1:
switch(Baudrate){
case B1080bps:
G_LoRaConfig.BandWidth = BW125KHZ; //BW = 125KHz
G_LoRaConfig.SpreadingFactor = SF07; //SF = 9
G_LoRaConfig.CodingRate = CR_4_6; //CR = 4/6
Baudrate = B4000bps;
break;
case B4000bps:
G_LoRaConfig.BandWidth = BW125KHZ; //BW = 125KHz
G_LoRaConfig.SpreadingFactor = SF11; //SF = 9
G_LoRaConfig.CodingRate = CR_4_8; //CR = 4/6
Baudrate = B300bps;
break;
case B300bps:
default:
G_LoRaConfig.BandWidth = BW125KHZ; //BW = 125KHz
G_LoRaConfig.SpreadingFactor = SF09; //SF = 9
G_LoRaConfig.CodingRate = CR_4_6; //CR = 4/6
Baudrate = B1080bps;
break;
}
RESET_Flag = true;
LPM3_EXIT;
break;
case KEY_S2:
T_Cnt = 0;
R_Cnt = 0;
break;
default:
break;
}
KEYBOARD_IFG &= ~KEY_ALL;
return;
}
if(DIO0_IFG) //判断是否是DIO0引起的中断
{
DIO0_IFG = 0; //清除DIO0中断标志位
LSD_RF_RxPacket(Rxbuffer); //接收数据包
#include "sx1276-LoRa.h"
signed int temp = 0,test;
SX1276Read( REG_LR_PKTSNRVALUE,&Reg_PKTSNR);
test = (signed char)Reg_PKTSNR;
if((Reg_PKTSNR&0x80)!=0){//负数
//LCD_p[3] = 10;//Reg_PKTSNR
Reg_PKTSNR = ~(Reg_PKTSNR)+1;
temp = -Reg_PKTSNR;
}
else{
//LCD_p[3] = 0xff;//Reg_PKTSNR
temp = Reg_PKTSNR;
}
test++;
SX1276Read( REG_LR_PKTRSSIVALUE,&Reg_PKTRssi);
if(temp>0){
temp = -164+Reg_PKTRssi*16/15;
//if(temp>-50)
//temp = -137+Reg_PKTRssi;
}
else{
temp = -164+Reg_PKTRssi+(signed char)(temp*0.25+0.5);
}
if(temp<0){
LCD_p[7] = 10;
Reg_PKTRssi = -temp;
}
else{
LCD_p[7] = 0xff;
Reg_PKTRssi = temp;
}
//SX1276Read( REG_LR_RSSIVALUE,&Reg_Rssi);
//Reg_Rssi
if(memcmp(Rxbuffer,TXbuffer,20)==0)
{
LEDONBIT(LED1); //状态指示灯
DelayMs(60);
LEDOFFBIT(LED1); //状态指示灯
R_Cnt++;
}
LPM3_EXIT;
}
P1IFG=0;
}
////////////////////////////////////////////////////////////////////////////////
// 功能描述 : 超时定时器
// 输入参数 : 无
// 返回参数 : 无
// 说明 : 用于误唤醒或唤醒失败后超时时间到后重新进入WOR
////////////////////////////////////////////////////////////////////////////////
#pragma vector = TIMER1_A0_VECTOR
__interrupt void Timer1_A0_ISR()
{
static uint8 t=0;
t++;
if(Baudrate >= B1080bps)
t = 5;
if(Baudrate == B300bps)
t++;
if(t >= 5)
{
LEDONBIT(LED3);//发送状态指示灯
G_LoRaConfig.PayloadLength = 20;
SX1276Reset();
if(SX127x_init()!=NORMAL) WDTCTL=0;
LSD_RF_SendPacket(TXbuffer);//发送30个字节数据测试
T_Cnt++;
LEDOFFBIT(LED3);//发送状态指示灯
LPM3_EXIT;
t = 0;
}
}

View File

@ -0,0 +1,880 @@
#ifndef __SX1276_LORA_H__
#define __SX1276_LORA_H__
/*!
* SX1276 LoRa General parameters definition
*/
typedef struct sLoRaSettings
{
uint32_t RFFrequency;
int8_t Power;
uint8_t SignalBw; // LORA [0: 7.8 kHz, 1: 10.4 kHz, 2: 15.6 kHz, 3: 20.8 kHz, 4: 31.2 kHz,
// 5: 41.6 kHz, 6: 62.5 kHz, 7: 125 kHz, 8: 250 kHz, 9: 500 kHz, other: Reserved]
uint8_t SpreadingFactor; // LORA [6: 64, 7: 128, 8: 256, 9: 512, 10: 1024, 11: 2048, 12: 4096 chips]
uint8_t ErrorCoding; // LORA [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
bool CrcOn; // [0: OFF, 1: ON]
bool ImplicitHeaderOn; // [0: OFF, 1: ON]
bool RxSingleOn; // [0: Continuous, 1 Single]
bool FreqHopOn; // [0: OFF, 1: ON]
uint8_t HopPeriod; // Hops every frequency hopping period symbols
uint32_t TxPacketTimeout;
uint32_t RxPacketTimeout;
uint8_t PayloadLength;
}tLoRaSettings;
/*!
* RF packet definition
*/
#define RF_BUFFER_SIZE_MAX 128
#define RF_BUFFER_SIZE 80
/*!
* RF state machine
*/
//LoRa
typedef enum
{
RFLR_STATE_IDLE,
RFLR_STATE_RX_INIT,
RFLR_STATE_RX_RUNNING,
RFLR_STATE_RX_DONE,
RFLR_STATE_RX_TIMEOUT,
RFLR_STATE_TX_INIT,
RFLR_STATE_TX_RUNNING,
RFLR_STATE_TX_DONE,
RFLR_STATE_TX_TIMEOUT,
RFLR_STATE_CAD_INIT,
RFLR_STATE_CAD_RUNNING,
}tRFLRStates;
/*!
* SX1276 definitions
*/
#define XTAL_FREQ 32000000
#define FREQ_STEP 61.03515625
/*!
* SX1276 Internal registers Address
*/
#define REG_LR_FIFO 0x00
// Common settings
#define REG_LR_OPMODE 0x01
//#define REG_LR_BANDSETTING 0x04
#define REG_LR_FRFMSB 0x06
#define REG_LR_FRFMID 0x07
#define REG_LR_FRFLSB 0x08
// Tx settings
#define REG_LR_PACONFIG 0x09
#define REG_LR_PARAMP 0x0A
#define REG_LR_OCP 0x0B
// Rx settings
#define REG_LR_LNA 0x0C
// LoRa registers
#define REG_LR_FIFOADDRPTR 0x0D
#define REG_LR_FIFOTXBASEADDR 0x0E
#define REG_LR_FIFORXBASEADDR 0x0F
#define REG_LR_FIFORXCURRENTADDR 0x10
#define REG_LR_IRQFLAGSMASK 0x11
#define REG_LR_IRQFLAGS 0x12
#define REG_LR_NBRXBYTES 0x13
#define REG_LR_RXHEADERCNTVALUEMSB 0x14
#define REG_LR_RXHEADERCNTVALUELSB 0x15
#define REG_LR_RXPACKETCNTVALUEMSB 0x16
#define REG_LR_RXPACKETCNTVALUELSB 0x17
#define REG_LR_MODEMSTAT 0x18
#define REG_LR_PKTSNRVALUE 0x19
#define REG_LR_PKTRSSIVALUE 0x1A
#define REG_LR_RSSIVALUE 0x1B
#define REG_LR_HOPCHANNEL 0x1C
#define REG_LR_MODEMCONFIG1 0x1D
#define REG_LR_MODEMCONFIG2 0x1E
#define REG_LR_SYMBTIMEOUTLSB 0x1F
#define REG_LR_PREAMBLEMSB 0x20
#define REG_LR_PREAMBLELSB 0x21
#define REG_LR_PAYLOADLENGTH 0x22
#define REG_LR_PAYLOADMAXLENGTH 0x23
#define REG_LR_HOPPERIOD 0x24
#define REG_LR_FIFORXBYTEADDR 0x25
#define REG_LR_MODEMCONFIG3 0x26
// end of documented register in datasheet
// I/O settings
#define REG_LR_DIOMAPPING1 0x40
#define REG_LR_DIOMAPPING2 0x41
// Version
#define REG_LR_VERSION 0x42
// Additional settings
#define REG_LR_PLLHOP 0x44
#define REG_LR_TCXO 0x4B
#define REG_LR_PADAC 0x4D
#define REG_LR_FORMERTEMP 0x5B
#define REG_LR_BITRATEFRAC 0x5D
#define REG_LR_AGCREF 0x61
#define REG_LR_AGCTHRESH1 0x62
#define REG_LR_AGCTHRESH2 0x63
#define REG_LR_AGCTHRESH3 0x64
/*!
* SX1276 LoRa bit control definition
*/
/*!
* RegFifo
*/
/*!
* RegOpMode
*/
#define RFLR_OPMODE_LONGRANGEMODE_MASK 0x7F
#define RFLR_OPMODE_LONGRANGEMODE_OFF 0x00 // Default
#define RFLR_OPMODE_LONGRANGEMODE_ON 0x80
#define RFLR_OPMODE_ACCESSSHAREDREG_MASK 0xBF
#define RFLR_OPMODE_ACCESSSHAREDREG_ENABLE 0x40
#define RFLR_OPMODE_ACCESSSHAREDREG_DISABLE 0x00 // Default
#define RFLR_OPMODE_FREQMODE_ACCESS_MASK 0xF7
#define RFLR_OPMODE_FREQMODE_ACCESS_LF 0x08 // Default
#define RFLR_OPMODE_FREQMODE_ACCESS_HF 0x00
#define RFLR_OPMODE_MASK 0xF8
#define RFLR_OPMODE_SLEEP 0x00
#define RFLR_OPMODE_STANDBY 0x01 // Default
#define RFLR_OPMODE_SYNTHESIZER_TX 0x02
#define RFLR_OPMODE_TRANSMITTER 0x03
#define RFLR_OPMODE_SYNTHESIZER_RX 0x04
#define RFLR_OPMODE_RECEIVER 0x05
// LoRa specific modes
#define RFLR_OPMODE_RECEIVER_SINGLE 0x06
#define RFLR_OPMODE_CAD 0x07
/*!
* RegBandSetting
*/
#define RFLR_BANDSETTING_MASK 0x3F
#define RFLR_BANDSETTING_AUTO 0x00 // Default
#define RFLR_BANDSETTING_DIV_BY_1 0x40
#define RFLR_BANDSETTING_DIV_BY_2 0x80
#define RFLR_BANDSETTING_DIV_BY_6 0xC0
/*!
* RegFrf (MHz)
*/
#define RFLR_FRFMSB_434_MHZ 0x6C // Default
#define RFLR_FRFMID_434_MHZ 0x80 // Default
#define RFLR_FRFLSB_434_MHZ 0x00 // Default
#define RFLR_FRFMSB_470_MHZ 0x75
#define RFLR_FRFMID_470_MHZ 0x80
#define RFLR_FRFLSB_470_MHZ 0x00
#define RFLR_FRFMSB_475_MHZ 0x76
#define RFLR_FRFMID_475_MHZ 0xC0
#define RFLR_FRFLSB_475_MHZ 0x00
#define RFLR_FRFMSB_863_MHZ 0xD7
#define RFLR_FRFMID_863_MHZ 0xC0
#define RFLR_FRFLSB_863_MHZ 0x00
#define RFLR_FRFMSB_864_MHZ 0xD8
#define RFLR_FRFMID_864_MHZ 0x00
#define RFLR_FRFLSB_864_MHZ 0x00
#define RFLR_FRFMSB_865_MHZ 0xD8
#define RFLR_FRFMID_865_MHZ 0x40
#define RFLR_FRFLSB_865_MHZ 0x00
#define RFLR_FRFMSB_866_MHZ 0xD8
#define RFLR_FRFMID_866_MHZ 0x80
#define RFLR_FRFLSB_866_MHZ 0x00
#define RFLR_FRFMSB_867_MHZ 0xD8
#define RFLR_FRFMID_867_MHZ 0xC0
#define RFLR_FRFLSB_867_MHZ 0x00
#define RFLR_FRFMSB_868_MHZ 0xD9
#define RFLR_FRFMID_868_MHZ 0x00
#define RFLR_FRFLSB_868_MHZ 0x00
#define RFLR_FRFMSB_869_MHZ 0xD9
#define RFLR_FRFMID_869_MHZ 0x40
#define RFLR_FRFLSB_869_MHZ 0x00
#define RFLR_FRFMSB_870_MHZ 0xD9
#define RFLR_FRFMID_870_MHZ 0x80
#define RFLR_FRFLSB_870_MHZ 0x00
#define RFLR_FRFMSB_902_MHZ 0xE1
#define RFLR_FRFMID_902_MHZ 0x80
#define RFLR_FRFLSB_902_MHZ 0x00
#define RFLR_FRFMSB_903_MHZ 0xE1
#define RFLR_FRFMID_903_MHZ 0xC0
#define RFLR_FRFLSB_903_MHZ 0x00
#define RFLR_FRFMSB_904_MHZ 0xE2
#define RFLR_FRFMID_904_MHZ 0x00
#define RFLR_FRFLSB_904_MHZ 0x00
#define RFLR_FRFMSB_905_MHZ 0xE2
#define RFLR_FRFMID_905_MHZ 0x40
#define RFLR_FRFLSB_905_MHZ 0x00
#define RFLR_FRFMSB_906_MHZ 0xE2
#define RFLR_FRFMID_906_MHZ 0x80
#define RFLR_FRFLSB_906_MHZ 0x00
#define RFLR_FRFMSB_907_MHZ 0xE2
#define RFLR_FRFMID_907_MHZ 0xC0
#define RFLR_FRFLSB_907_MHZ 0x00
#define RFLR_FRFMSB_908_MHZ 0xE3
#define RFLR_FRFMID_908_MHZ 0x00
#define RFLR_FRFLSB_908_MHZ 0x00
#define RFLR_FRFMSB_909_MHZ 0xE3
#define RFLR_FRFMID_909_MHZ 0x40
#define RFLR_FRFLSB_909_MHZ 0x00
#define RFLR_FRFMSB_910_MHZ 0xE3
#define RFLR_FRFMID_910_MHZ 0x80
#define RFLR_FRFLSB_910_MHZ 0x00
#define RFLR_FRFMSB_911_MHZ 0xE3
#define RFLR_FRFMID_911_MHZ 0xC0
#define RFLR_FRFLSB_911_MHZ 0x00
#define RFLR_FRFMSB_912_MHZ 0xE4
#define RFLR_FRFMID_912_MHZ 0x00
#define RFLR_FRFLSB_912_MHZ 0x00
#define RFLR_FRFMSB_913_MHZ 0xE4
#define RFLR_FRFMID_913_MHZ 0x40
#define RFLR_FRFLSB_913_MHZ 0x00
#define RFLR_FRFMSB_914_MHZ 0xE4
#define RFLR_FRFMID_914_MHZ 0x80
#define RFLR_FRFLSB_914_MHZ 0x00
#define RFLR_FRFMSB_915_MHZ 0xE4 // Default
#define RFLR_FRFMID_915_MHZ 0xC0 // Default
#define RFLR_FRFLSB_915_MHZ 0x00 // Default
#define RFLR_FRFMSB_916_MHZ 0xE5
#define RFLR_FRFMID_916_MHZ 0x00
#define RFLR_FRFLSB_916_MHZ 0x00
#define RFLR_FRFMSB_917_MHZ 0xE5
#define RFLR_FRFMID_917_MHZ 0x40
#define RFLR_FRFLSB_917_MHZ 0x00
#define RFLR_FRFMSB_918_MHZ 0xE5
#define RFLR_FRFMID_918_MHZ 0x80
#define RFLR_FRFLSB_918_MHZ 0x00
#define RFLR_FRFMSB_919_MHZ 0xE5
#define RFLR_FRFMID_919_MHZ 0xC0
#define RFLR_FRFLSB_919_MHZ 0x00
#define RFLR_FRFMSB_920_MHZ 0xE6
#define RFLR_FRFMID_920_MHZ 0x00
#define RFLR_FRFLSB_920_MHZ 0x00
#define RFLR_FRFMSB_921_MHZ 0xE6
#define RFLR_FRFMID_921_MHZ 0x40
#define RFLR_FRFLSB_921_MHZ 0x00
#define RFLR_FRFMSB_922_MHZ 0xE6
#define RFLR_FRFMID_922_MHZ 0x80
#define RFLR_FRFLSB_922_MHZ 0x00
#define RFLR_FRFMSB_923_MHZ 0xE6
#define RFLR_FRFMID_923_MHZ 0xC0
#define RFLR_FRFLSB_923_MHZ 0x00
#define RFLR_FRFMSB_924_MHZ 0xE7
#define RFLR_FRFMID_924_MHZ 0x00
#define RFLR_FRFLSB_924_MHZ 0x00
#define RFLR_FRFMSB_925_MHZ 0xE7
#define RFLR_FRFMID_925_MHZ 0x40
#define RFLR_FRFLSB_925_MHZ 0x00
#define RFLR_FRFMSB_926_MHZ 0xE7
#define RFLR_FRFMID_926_MHZ 0x80
#define RFLR_FRFLSB_926_MHZ 0x00
#define RFLR_FRFMSB_927_MHZ 0xE7
#define RFLR_FRFMID_927_MHZ 0xC0
#define RFLR_FRFLSB_927_MHZ 0x00
#define RFLR_FRFMSB_928_MHZ 0xE8
#define RFLR_FRFMID_928_MHZ 0x00
#define RFLR_FRFLSB_928_MHZ 0x00
/*!
* RegPaConfig
*/
#define RFLR_PACONFIG_PASELECT_MASK 0x7F
#define RFLR_PACONFIG_PASELECT_PABOOST 0x80
#define RFLR_PACONFIG_PASELECT_RFO 0x00 // Default
#define RFLR_PACONFIG_MAX_POWER_MASK 0x8F
#define RFLR_PACONFIG_OUTPUTPOWER_MASK 0xF0
/*!
* RegPaRamp
*/
#define RFLR_PARAMP_TXBANDFORCE_MASK 0xEF
#define RFLR_PARAMP_TXBANDFORCE_BAND_SEL 0x10
#define RFLR_PARAMP_TXBANDFORCE_AUTO 0x00 // Default
#define RFLR_PARAMP_MASK 0xF0
#define RFLR_PARAMP_3400_US 0x00
#define RFLR_PARAMP_2000_US 0x01
#define RFLR_PARAMP_1000_US 0x02
#define RFLR_PARAMP_0500_US 0x03
#define RFLR_PARAMP_0250_US 0x04
#define RFLR_PARAMP_0125_US 0x05
#define RFLR_PARAMP_0100_US 0x06
#define RFLR_PARAMP_0062_US 0x07
#define RFLR_PARAMP_0050_US 0x08
#define RFLR_PARAMP_0040_US 0x09 // Default
#define RFLR_PARAMP_0031_US 0x0A
#define RFLR_PARAMP_0025_US 0x0B
#define RFLR_PARAMP_0020_US 0x0C
#define RFLR_PARAMP_0015_US 0x0D
#define RFLR_PARAMP_0012_US 0x0E
#define RFLR_PARAMP_0010_US 0x0F
/*!
* RegOcp
*/
#define RFLR_OCP_MASK 0xDF
#define RFLR_OCP_ON 0x20 // Default
#define RFLR_OCP_OFF 0x00
#define RFLR_OCP_TRIM_MASK 0xE0
#define RFLR_OCP_TRIM_045_MA 0x00
#define RFLR_OCP_TRIM_050_MA 0x01
#define RFLR_OCP_TRIM_055_MA 0x02
#define RFLR_OCP_TRIM_060_MA 0x03
#define RFLR_OCP_TRIM_065_MA 0x04
#define RFLR_OCP_TRIM_070_MA 0x05
#define RFLR_OCP_TRIM_075_MA 0x06
#define RFLR_OCP_TRIM_080_MA 0x07
#define RFLR_OCP_TRIM_085_MA 0x08
#define RFLR_OCP_TRIM_090_MA 0x09
#define RFLR_OCP_TRIM_095_MA 0x0A
#define RFLR_OCP_TRIM_100_MA 0x0B // Default
#define RFLR_OCP_TRIM_105_MA 0x0C
#define RFLR_OCP_TRIM_110_MA 0x0D
#define RFLR_OCP_TRIM_115_MA 0x0E
#define RFLR_OCP_TRIM_120_MA 0x0F
#define RFLR_OCP_TRIM_130_MA 0x10
#define RFLR_OCP_TRIM_140_MA 0x11
#define RFLR_OCP_TRIM_150_MA 0x12
#define RFLR_OCP_TRIM_160_MA 0x13
#define RFLR_OCP_TRIM_170_MA 0x14
#define RFLR_OCP_TRIM_180_MA 0x15
#define RFLR_OCP_TRIM_190_MA 0x16
#define RFLR_OCP_TRIM_200_MA 0x17
#define RFLR_OCP_TRIM_210_MA 0x18
#define RFLR_OCP_TRIM_220_MA 0x19
#define RFLR_OCP_TRIM_230_MA 0x1A
#define RFLR_OCP_TRIM_240_MA 0x1B
/*!
* RegLna
*/
#define RFLR_LNA_GAIN_MASK 0x1F
#define RFLR_LNA_GAIN_G1 0x20 // Default
#define RFLR_LNA_GAIN_G2 0x40
#define RFLR_LNA_GAIN_G3 0x60
#define RFLR_LNA_GAIN_G4 0x80
#define RFLR_LNA_GAIN_G5 0xA0
#define RFLR_LNA_GAIN_G6 0xC0
#define RFLR_LNA_BOOST_LF_MASK 0xE7
#define RFLR_LNA_BOOST_LF_DEFAULT 0x00 // Default
#define RFLR_LNA_BOOST_LF_GAIN 0x08
#define RFLR_LNA_BOOST_LF_IP3 0x10
#define RFLR_LNA_BOOST_LF_BOOST 0x18
#define RFLR_LNA_RXBANDFORCE_MASK 0xFB
#define RFLR_LNA_RXBANDFORCE_BAND_SEL 0x04
#define RFLR_LNA_RXBANDFORCE_AUTO 0x00 // Default
#define RFLR_LNA_BOOST_HF_MASK 0xFC
#define RFLR_LNA_BOOST_HF_OFF 0x00 // Default
#define RFLR_LNA_BOOST_HF_ON 0x03
/*!
* RegFifoAddrPtr
*/
#define RFLR_FIFOADDRPTR 0x00 // Default
/*!
* RegFifoTxBaseAddr
*/
#define RFLR_FIFOTXBASEADDR 0x80 // Default
/*!
* RegFifoTxBaseAddr
*/
#define RFLR_FIFORXBASEADDR 0x00 // Default
/*!
* RegFifoRxCurrentAddr (Read Only)
*/
/*!
* RegIrqFlagsMask
*/
#define RFLR_IRQFLAGS_RXTIMEOUT_MASK 0x80
#define RFLR_IRQFLAGS_RXDONE_MASK 0x40
#define RFLR_IRQFLAGS_PAYLOADCRCERROR_MASK 0x20
#define RFLR_IRQFLAGS_VALIDHEADER_MASK 0x10
#define RFLR_IRQFLAGS_TXDONE_MASK 0x08
#define RFLR_IRQFLAGS_CADDONE_MASK 0x04
#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL_MASK 0x02
#define RFLR_IRQFLAGS_CADDETECTED_MASK 0x01
/*!
* RegIrqFlags
*/
#define RFLR_IRQFLAGS_RXTIMEOUT 0x80
#define RFLR_IRQFLAGS_RXDONE 0x40
#define RFLR_IRQFLAGS_PAYLOADCRCERROR 0x20
#define RFLR_IRQFLAGS_VALIDHEADER 0x10
#define RFLR_IRQFLAGS_TXDONE 0x08
#define RFLR_IRQFLAGS_CADDONE 0x04
#define RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL 0x02
#define RFLR_IRQFLAGS_CADDETECTED 0x01
/*!
* RegFifoRxNbBytes (Read Only) //
*/
/*!
* RegRxHeaderCntValueMsb (Read Only) //
*/
/*!
* RegRxHeaderCntValueLsb (Read Only) //
*/
/*!
* RegRxPacketCntValueMsb (Read Only) //
*/
/*!
* RegRxPacketCntValueLsb (Read Only) //
*/
/*!
* RegModemStat (Read Only) //
*/
#define RFLR_MODEMSTAT_RX_CR_MASK 0x1F
#define RFLR_MODEMSTAT_MODEM_STATUS_MASK 0xE0
/*!
* RegPktSnrValue (Read Only) //
*/
/*!
* RegPktRssiValue (Read Only) //
*/
/*!
* RegRssiValue (Read Only) //
*/
/*!
* RegModemConfig1
*/
#define RFLR_MODEMCONFIG1_BW_MASK 0x0F
#define RFLR_MODEMCONFIG1_BW_7_81_KHZ 0x00
#define RFLR_MODEMCONFIG1_BW_10_41_KHZ 0x10
#define RFLR_MODEMCONFIG1_BW_15_62_KHZ 0x20
#define RFLR_MODEMCONFIG1_BW_20_83_KHZ 0x30
#define RFLR_MODEMCONFIG1_BW_31_25_KHZ 0x40
#define RFLR_MODEMCONFIG1_BW_41_66_KHZ 0x50
#define RFLR_MODEMCONFIG1_BW_62_50_KHZ 0x60
#define RFLR_MODEMCONFIG1_BW_125_KHZ 0x70 // Default
#define RFLR_MODEMCONFIG1_BW_250_KHZ 0x80
#define RFLR_MODEMCONFIG1_BW_500_KHZ 0x90
#define RFLR_MODEMCONFIG1_CODINGRATE_MASK 0xF1
#define RFLR_MODEMCONFIG1_CODINGRATE_4_5 0x02
#define RFLR_MODEMCONFIG1_CODINGRATE_4_6 0x04 // Default
#define RFLR_MODEMCONFIG1_CODINGRATE_4_7 0x06
#define RFLR_MODEMCONFIG1_CODINGRATE_4_8 0x08
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK 0xFE
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_ON 0x01
#define RFLR_MODEMCONFIG1_IMPLICITHEADER_OFF 0x00 // Default
/*!
* RegModemConfig2
*/
#define RFLR_MODEMCONFIG2_SF_MASK 0x0F
#define RFLR_MODEMCONFIG2_SF_6 0x60
#define RFLR_MODEMCONFIG2_SF_7 0x70 // Default
#define RFLR_MODEMCONFIG2_SF_8 0x80
#define RFLR_MODEMCONFIG2_SF_9 0x90
#define RFLR_MODEMCONFIG2_SF_10 0xA0
#define RFLR_MODEMCONFIG2_SF_11 0xB0
#define RFLR_MODEMCONFIG2_SF_12 0xC0
#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_MASK 0xF7
#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_ON 0x08
#define RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_OFF 0x00
#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK 0xFB
#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_ON 0x04
#define RFLR_MODEMCONFIG2_RXPAYLOADCRC_OFF 0x00 // Default
#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK 0xFC
#define RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB 0x00 // Default
/*!
* RegHopChannel (Read Only)
*/
#define RFLR_HOPCHANNEL_PLL_LOCK_TIMEOUT_MASK 0x7F
#define RFLR_HOPCHANNEL_PLL_LOCK_FAIL 0x80
#define RFLR_HOPCHANNEL_PLL_LOCK_SUCCEED 0x00 // Default
#define RFLR_HOPCHANNEL_PAYLOAD_CRC16_MASK 0xBF
#define RFLR_HOPCHANNEL_PAYLOAD_CRC16_ON 0x40
#define RFLR_HOPCHANNEL_PAYLOAD_CRC16_OFF 0x00 // Default
#define RFLR_HOPCHANNEL_CHANNEL_MASK 0x3F
/*!
* RegSymbTimeoutLsb
*/
#define RFLR_SYMBTIMEOUTLSB_SYMBTIMEOUT 0x64 // Default
/*!
* RegPreambleLengthMsb
*/
#define RFLR_PREAMBLELENGTHMSB 0x00 // Default
/*!
* RegPreambleLengthLsb
*/
#define RFLR_PREAMBLELENGTHLSB 0x08 // Default
/*!
* RegPayloadLength
*/
#define RFLR_PAYLOADLENGTH 0x0E // Default
/*!
* RegPayloadMaxLength
*/
#define RFLR_PAYLOADMAXLENGTH 0xFF // Default
/*!
* RegHopPeriod
*/
#define RFLR_HOPPERIOD_FREQFOPPINGPERIOD 0x00 // Default
/*!
* RegDioMapping1
*/
#define RFLR_DIOMAPPING1_DIO0_MASK 0x3F
#define RFLR_DIOMAPPING1_DIO0_00 0x00 // Default
#define RFLR_DIOMAPPING1_DIO0_01 0x40
#define RFLR_DIOMAPPING1_DIO0_10 0x80
#define RFLR_DIOMAPPING1_DIO0_11 0xC0
#define RFLR_DIOMAPPING1_DIO1_MASK 0xCF
#define RFLR_DIOMAPPING1_DIO1_00 0x00 // Default
#define RFLR_DIOMAPPING1_DIO1_01 0x10
#define RFLR_DIOMAPPING1_DIO1_10 0x20
#define RFLR_DIOMAPPING1_DIO1_11 0x30
#define RFLR_DIOMAPPING1_DIO2_MASK 0xF3
#define RFLR_DIOMAPPING1_DIO2_00 0x00 // Default
#define RFLR_DIOMAPPING1_DIO2_01 0x04
#define RFLR_DIOMAPPING1_DIO2_10 0x08
#define RFLR_DIOMAPPING1_DIO2_11 0x0C
#define RFLR_DIOMAPPING1_DIO3_MASK 0xFC
#define RFLR_DIOMAPPING1_DIO3_00 0x00 // Default
#define RFLR_DIOMAPPING1_DIO3_01 0x01
#define RFLR_DIOMAPPING1_DIO3_10 0x02
#define RFLR_DIOMAPPING1_DIO3_11 0x03
/*!
* RegDioMapping2
*/
#define RFLR_DIOMAPPING2_DIO4_MASK 0x3F
#define RFLR_DIOMAPPING2_DIO4_00 0x00 // Default
#define RFLR_DIOMAPPING2_DIO4_01 0x40
#define RFLR_DIOMAPPING2_DIO4_10 0x80
#define RFLR_DIOMAPPING2_DIO4_11 0xC0
#define RFLR_DIOMAPPING2_DIO5_MASK 0xCF
#define RFLR_DIOMAPPING2_DIO5_00 0x00 // Default
#define RFLR_DIOMAPPING2_DIO5_01 0x10
#define RFLR_DIOMAPPING2_DIO5_10 0x20
#define RFLR_DIOMAPPING2_DIO5_11 0x30
#define RFLR_DIOMAPPING2_MAP_MASK 0xFE
#define RFLR_DIOMAPPING2_MAP_PREAMBLEDETECT 0x01
#define RFLR_DIOMAPPING2_MAP_RSSI 0x00 // Default
/*!
* RegVersion (Read Only)
*/
/*!
* RegAgcRef
*/
/*!
* RegAgcThresh1
*/
/*!
* RegAgcThresh2
*/
/*!
* RegAgcThresh3
*/
/*!
* RegFifoRxByteAddr (Read Only)
*/
/*!
* RegPllHop
*/
#define RFLR_PLLHOP_FASTHOP_MASK 0x7F
#define RFLR_PLLHOP_FASTHOP_ON 0x80
#define RFLR_PLLHOP_FASTHOP_OFF 0x00 // Default
/*!
* RegTcxo
*/
#define RFLR_TCXO_TCXOINPUT_MASK 0xEF
#define RFLR_TCXO_TCXOINPUT_ON 0x10
#define RFLR_TCXO_TCXOINPUT_OFF 0x00 // Default
/*!
* RegPaDac
*/
#define RFLR_PADAC_20DBM_MASK 0xF8
#define RFLR_PADAC_20DBM_ON 0x07
#define RFLR_PADAC_20DBM_OFF 0x04 // Default
/*!
* RegPll
*/
#define RFLR_PLL_BANDWIDTH_MASK 0x3F
#define RFLR_PLL_BANDWIDTH_75 0x00
#define RFLR_PLL_BANDWIDTH_150 0x40
#define RFLR_PLL_BANDWIDTH_225 0x80
#define RFLR_PLL_BANDWIDTH_300 0xC0 // Default
/*!
* RegPllLowPn
*/
#define RFLR_PLLLOWPN_BANDWIDTH_MASK 0x3F
#define RFLR_PLLLOWPN_BANDWIDTH_75 0x00
#define RFLR_PLLLOWPN_BANDWIDTH_150 0x40
#define RFLR_PLLLOWPN_BANDWIDTH_225 0x80
#define RFLR_PLLLOWPN_BANDWIDTH_300 0xC0 // Default
/*!
* RegModemConfig3
*/
#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK 0xF7
#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_ON 0x08
#define RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_OFF 0x00 // Default
#define RFLR_MODEMCONFIG3_AGCAUTO_MASK 0xFB
#define RFLR_MODEMCONFIG3_AGCAUTO_ON 0x04 // Default
#define RFLR_MODEMCONFIG3_AGCAUTO_OFF 0x00
/*!
* RegFormerTemp
*/
typedef struct sSX1276LR
{
uint8_t RegFifo; // 0x00
// Common settings
uint8_t RegOpMode; // 0x01
uint8_t RegTestReserved02[0x06 - 0x02]; // 0x02-0x05
// uint8_t RegRes02; // 0x02
// uint8_t RegRes03; // 0x03
// uint8_t RegBandSetting; // 0x04
// uint8_t RegRes05; // 0x05
uint8_t RegFrfMsb; // 0x06
uint8_t RegFrfMid; // 0x07
uint8_t RegFrfLsb; // 0x08
// Tx settings
uint8_t RegPaConfig; // 0x09
uint8_t RegPaRamp; // 0x0A
uint8_t RegOcp; // 0x0B
// Rx settings
uint8_t RegLna; // 0x0C
// LoRa registers
uint8_t RegFifoAddrPtr; // 0x0D
uint8_t RegFifoTxBaseAddr; // 0x0E
uint8_t RegFifoRxBaseAddr; // 0x0F
uint8_t RegFifoRxCurrentAddr; // 0x10
uint8_t RegIrqFlagsMask; // 0x11
uint8_t RegIrqFlags; // 0x12
uint8_t RegNbRxBytes; // 0x13
uint8_t RegRxHeaderCntValueMsb; // 0x14
uint8_t RegRxHeaderCntValueLsb; // 0x15
uint8_t RegRxPacketCntValueMsb; // 0x16
uint8_t RegRxPacketCntValueLsb; // 0x17
uint8_t RegModemStat; // 0x18
uint8_t RegPktSnrValue; // 0x19
uint8_t RegPktRssiValue; // 0x1A
uint8_t RegRssiValue; // 0x1B
uint8_t RegHopChannel; // 0x1C
uint8_t RegModemConfig1; // 0x1D
uint8_t RegModemConfig2; // 0x1E
uint8_t RegSymbTimeoutLsb; // 0x1F
uint8_t RegPreambleMsb; // 0x20
uint8_t RegPreambleLsb; // 0x21
uint8_t RegPayloadLength; // 0x22
uint8_t RegMaxPayloadLength; // 0x23
uint8_t RegHopPeriod; // 0x24
uint8_t RegFifoRxByteAddr; // 0x25
uint8_t RegModemConfig3; // 0x26
uint8_t RegTestReserved27[0x31 - 0x27]; // 0x27-0x30
//void SX1276LoRaSetNbTrigPeaks( uint8_t value )Óõ½
uint8_t RegTestReserved31; // 0x31
uint8_t RegTestReserved32[0x40 - 0x32]; // 0x32-0x3F
// I/O settings
uint8_t RegDioMapping1; // 0x40
uint8_t RegDioMapping2; // 0x41
// Version
uint8_t RegVersion; // 0x42
uint8_t RegTestReserved43[0x4B - 0x43]; // 0x43-0x4A
uint8_t RegTcxo; // 0x4B
uint8_t RegTestReserved4C; // 0x4C
uint8_t RegPaDac; // 0x4D
uint8_t RegTestReserved4E[0x5B - 0x4E]; // 0x4E-0x5A
uint8_t RegFormerTemp; // 0x5B
uint8_t RegTestReserved5C[0x61 - 0x5C]; // 0x5C-0x60
// Additional settings
uint8_t RegAgcRef; // 0x61
uint8_t RegAgcThresh1; // 0x62
uint8_t RegAgcThresh2; // 0x63
uint8_t RegAgcThresh3; // 0x64
uint8_t RegTestReserved65[0x70 - 0x65]; // 0x65-0x6F
uint8_t RegPll; // 0x70
}tSX1276LR;
extern tSX1276LR* SX1276LR;
/*!
* \brief Initializes the SX1276
*/
void SX1276LoRaInit( void );
/*!
* \brief Sets the SX1276 to datasheet default values
*/
void SX1276LoRaSetDefaults( void );
/*!
* \brief Enables/Disables the LoRa modem
*
* \param [IN]: enable [true, false]
*/
void SX1276LoRaSetLoRaOn( bool enable );
/*!
* \brief Sets the SX1276 operating mode
*
* \param [IN] opMode New operating mode
*/
void SX1276LoRaSetOpMode( uint8_t opMode );
/*!
* \brief Gets the SX1276 operating mode
*
* \retval opMode Current operating mode
*/
uint8_t SX1276LoRaGetOpMode( void );
/*!
* \brief Reads the current Rx gain setting
*
* \retval rxGain Current gain setting
*/
uint8_t SX1276LoRaReadRxGain( void );
/*!
* \brief Trigs and reads the current RSSI value
*
* \retval rssiValue Current RSSI value in [dBm]
*/
double SX1276LoRaReadRssi( void );
/*!
* \brief Gets the Rx gain value measured while receiving the packet
*
* \retval rxGainValue Current Rx gain value
*/
uint8_t SX1276LoRaGetPacketRxGain( void );
/*!
* \brief Gets the SNR value measured while receiving the packet
*
* \retval snrValue Current SNR value in [dB]
*/
int8_t SX1276LoRaGetPacketSnr( void );
/*!
* \brief Gets the RSSI value measured while receiving the packet
*
* \retval rssiValue Current RSSI value in [dBm]
*/
double SX1276LoRaGetPacketRssi( void );
/*!
* \brief Sets the radio in Rx mode. Waiting for a packet
*/
void SX1276LoRaStartRx( void );
/*!
* \brief Gets a copy of the current received buffer
*
* \param [IN]: buffer Buffer pointer
* \param [IN]: size Buffer size
*/
void SX1276LoRaGetRxPacket( void *buffer, uint16_t *size );
/*!
* \brief Sets a copy of the buffer to be transmitted
*
* \param [IN]: buffer Buffer pointer
* \param [IN]: size Buffer size
*/
void SX1276LoRaSetTxPacket( const void *buffer, uint16_t size );
/*!
* \brief Gets the current RFState
*
* \retval rfState Current RF state [RF_IDLE, RF_BUSY,
* RF_RX_DONE, RF_RX_TIMEOUT,
* RF_TX_DONE, RF_TX_TIMEOUT]
*/
tRFLRStates SX1276LoRaGetRFState( void );
/*!
* \brief Sets the new state of the RF state machine
*
* \param [IN]: state New RF state machine state
*/
void SX1276LoRaSetRFState( tRFLRStates state );
/*!
* \brief Process the LoRa modem Rx and Tx state machines depending on the
* SX1276 operating mode.
*
* \retval rfState Current RF state [RF_IDLE, RF_BUSY,
* RF_RX_DONE, RF_RX_TIMEOUT,
* RF_TX_DONE, RF_TX_TIMEOUT]
*/
uint32_t SX1276LoRaProcess( void );
#endif //__SX1276_LORA_H__