河北水利局项目

This commit is contained in:
2025-12-15 16:07:49 +08:00
commit f11a7c2b95
1146 changed files with 452892 additions and 0 deletions

114
APP/Basedefine.h Normal file
View File

@@ -0,0 +1,114 @@
#ifndef _BASEDEFINE_H_
#define _BASEDEFINE_H_
/*——————————————————————————
* 文 件 名Basedefine.h
* 文件说明:基础库头文件
*
* 当前版本V8.0
* 作 者ZL
* 开始日期2013-12-30
*———————————————————————————*/
/***************标准库函数************/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
/************stm32固件库头文件******/
#include "stm32f10x.h"
#define true TRUE
#define false FALSE
//真假值
typedef enum
{
FALSE = 0, //假
TRUE = !FALSE //真
}bool;
//模式
typedef enum
{
MODE_BPSK = 4, //BPSK模式
MODE_QPSK = 5, //QPSK模式
MODE_ENHANCE = 7, //ENHANCE模式
MODE_ROBUST = 8 //鲁棒模式
}eMode;
//设备类型
typedef enum
{
TYPE_MASTER, //主节点
TYPE_METER_SINGLE, //单相载波表节点
TYPE_METER_THREE, //三相载波表节点
TYPE_COLLECT_I, //I型采集器节点
TYPE_COLLECT_II, //II型采集器节点
TYPE_RELAY, //中继节点
TYPE_METER_485, //485表非载波节点
TYPE_UNKNOWN //未知设备类型
}eType;
//路由状态
typedef enum
{
ROUTE_PTOP, //点对点
ROUTE_SOURCE, //源路由
ROUTE_BLIND, //盲中继
ROUTE_UNKNOWN //未知路由
}eRouteStatus;
//路由方式
typedef enum
{
MODE_PTOP, //点对点
MODE_SOURCE, //源路由
MODE_BLIND //盲中继
}eRouteMode;
//网络标识
typedef enum
{
NET_SELF, //本网
NET_ALL //全网
}eNet;
//抄读标志
typedef enum
{
READ_PREPARE, //待抄读
READ_SUCCESS_PART, //部分抄读成功
READ_SUCCESS_ALL, //全部抄读成功
READ_FAIL //全部抄读失败
}eReadFlag;
//地址模式
typedef enum
{
ADDRTYPE_LONG, //长地址模式
ADDRTYPE_SHORT //短地址模式
}eAddrType;
typedef struct
{
GPIO_TypeDef* GPIO_port;
uint32_t GPIO_clk;
uint16_t GPIO_Pin;
GPIOMode_TypeDef GPIO_mode;
}st_gpio_config;
//喂狗
#define FEED_WDG do{IWDG_ReloadCounter();}while(0)
#define USE_LORA_MODE
#endif

2332
APP/Cmd.c Normal file

File diff suppressed because it is too large Load Diff

1913
APP/Cmd.c.bak Normal file

File diff suppressed because it is too large Load Diff

57
APP/Cmd.h Normal file
View File

@@ -0,0 +1,57 @@
/*—————————————————————----------
* 文 件 名Cmd.h
* 作 者:邹亮
* 日 期2013-12-30
* 文件说明:控制台头文件
*——————————————————————————*/
#ifndef _CMD_H
#define _CMD_H
#include "Basedefine.h"
#include "uart.h"
typedef const struct
{
const u8 *cmd;
void (*action)(void);
const u8 *info;
} sCmd;
extern void add_in_flash(void);
extern void add_list_node(void);
extern char change_parity(u16 parity);
extern float change_stop_bits(u16 uart_stopbit);
extern u16 change_string_to_arry16(char * input);
extern u8 CharToU8(u8 data);
extern void Cmd_Exe(void);
extern void Cmd_Proc(void);
extern void delete_space_key(u8 *buf);
extern u8 find_cmd_length(u8 * buf);
extern u16 find_string16_len(char * str);
extern u8 GetStrPara(u8* buffer, u8 index);
extern void GetTime(void);
extern void GetU16Para(u16 *para,u8 index);
extern void GetU8Para(u8 *para,u8 index);
extern void ListCmd(void);
extern void lora_cmd_tx(void );
extern void mbus_direct_tx(void);
extern void printf_uart_port(st_uart_int port_init);
extern void read_curent_protocl(void);
extern void read_local_addr(void);
extern void read_maintain(void);
extern void read_mbus_power(void);
extern void release_debug(void);
extern void SetTime(void);
extern void set_gMeterConfig(void);
extern void set_local_addr(void);
extern void set_mbus_port(void);
extern void set_mbus_power(void);
extern void simul_plc_rx(void);
extern void simul_read_meter(void);
extern void write_maintain(void);
extern void scan_ports(void);
#endif

166
APP/Flash.c Normal file
View File

@@ -0,0 +1,166 @@
/*——————————————————————————
* 文 件 名Flash.c
* 作 者:于涛
* 日 期2014-01-15
* 文件说明内部FLASH源文件
*——————————————————————————*/
#include "Flash.h"
#include "General.h"
#include "Mem.h"
/*——————————————————————————
* 函 数 名STM32_FlashPageErase
* 输入参数pageAddr 页地址
* 输出参数None
* 返 回 值0 成功
1 失败
* 功能说明内部FLASH页擦除
*——————————————————————————*/
u8 STM32_FlashPageErase(u32 pageAddr)
{
FLASH_Status status = FLASH_COMPLETE;
FEED_WDG;
FLASH_Unlock();
/* Clear All pending flags */
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
//FLHDBG(printf("STM32_FlashPageErase pageAddr = %08x\r\n",pageAddr););
status = FLASH_ErasePage(pageAddr);
if(status != FLASH_COMPLETE)
{
printf("STM32_FlashPageErase Err pageAddr = %08x status = %d\r\n",pageAddr,status);
return FLH_ERASE_ERR;
}
FLASH_Lock();
return FLH_SUCCESS;
}
/*——————————————————————————
* 函 数 名STM32_FlashWrite
* 输入参数programAddr 写地址
pBuffer 写缓冲区
size 写缓冲区大小
* 输出参数None
* 返 回 值0 成功
>0 失败
* 功能说明内部FLASH写操作
*——————————————————————————*/
u8 STM32_FlashWrite(u32 programAddr, u8* pBuffer, u16 size)
{
u8 sflag;
u16 offset = 0,len = size;
FLASH_Status status = FLASH_COMPLETE;
FLASH_Unlock();
/* Clear All pending flags */
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
sflag = len%2;
if(sflag)
{
len --;
}
for(offset = 0; offset < len; offset += 2)
{
status = FLASH_ProgramHalfWord(programAddr + offset, ((u16)(pBuffer[offset + 1]) << 8) | (pBuffer[offset]));
if(status != FLASH_COMPLETE)
{
printf("STM32_FlashWrite Err programAddr = %08x size = %d offset = %d status = %d\r\n",programAddr,size,offset,status);
return FLH_WRITE_ERR;
}
}
if(sflag && size>=1)
{
u16 val;
val = pBuffer[size - 1]|0xFF00;
status = FLASH_ProgramHalfWord(programAddr + offset, val);
if(status != FLASH_COMPLETE)
{
printf("STM32_FlashWrite Err programAddr = %08x size = %d offset = %d status = %d\r\n",programAddr,size,offset,status);
return FLH_WRITE_ERR;
}
}
FLASH_Lock();
return FLH_SUCCESS;
}
/*——————————————————————————
* 函 数 名STM32_FlashWriteZero
* 输入参数None
* 输出参数None
* 返 回 值:见错误代码表
* 功能说明:对某一地址写0
*——————————————————————————*/
u8 STM32_FlashWriteZero(u32 programAddr, u16 size)
{
u16 offset = 0;
FLASH_Status status = FLASH_COMPLETE;
FLASH_Unlock();
/* Clear All pending flags */
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
if (size%2==1)
{
size +=1;
}
for(offset = 0; offset < size; offset += 2)
{
status = FLASH_ProgramHalfWord(programAddr + offset, 0);
if(status != FLASH_COMPLETE)
{
//FLHDBG(printf("STM32FLASH: Write zero error."););
return FLH_WRITE_ERR;
}
}
FLASH_Lock();
return FLH_SUCCESS;
}
/*****************************************************************************
* Function : read_unique_id
* Description : none
* Input : u8 * id
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
bool read_unique_id(u8 * id)
{
for (u8 i = 0; i < 12; i++)
{
id[i] = *((u8*)(FLASH_ID_IDDR + i));
}
for (u8 i = 0; i < 12; i++)
{
if (id[i] != 0xFF)
{
return TRUE;
}
}
return FALSE;
}

43
APP/Flash.h Normal file
View File

@@ -0,0 +1,43 @@
/*——————————————————————————
* 文 件 名Flash.h
* 作 者:于涛
* 日 期2014-01-15
* 文件说明内部FLASH头文件
*——————————————————————————*/
#ifndef _FLASH_H
#define _FLASH_H
#include "Basedefine.h"
//#include "Sys.h"
#ifdef STM32F10X_HD
#define PAGE_SIZE (0x800)
#else
#define PAGE_SIZE (0x400)
#endif
#define FLASH_ID_IDDR 0x1FFFF7E8
#define FLASH_KEY_ADDRESS 0x08003800
typedef enum
{
FLH_SUCCESS = 0, //返回成功
FLH_ERASE_ERR,
FLH_WRITE_ERR,
FLH_WADDR_ERR,
FLH_RADDR_ERR,
FLH_NOSPACE_ERR,
FLH_NOVAILD_ERR,
FLH_NOFIELD_ERR,
}eFlashRet;
u8 STM32_FlashPageErase(u32 pageAddr);
u8 STM32_FlashWrite(u32 programAddr, u8* pBuffer, u16 size);
u8 STM32_FlashWriteZero(u32 programAddr, u16 size);
bool read_unique_id(u8 * id);
#endif

309
APP/General.c Normal file
View File

@@ -0,0 +1,309 @@
/*——————————————————————————
* 文 件 名General.c
* 文件说明: 普通函数源文件
*
* 当前版本V8.0
* 作 者ZL
* 开始日期2013-12-30
*———————————————————————————*/
#include "General.h"
const u16 CRC16_Table[256] =
{
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, 0x8C48, 0x9DC1, 0xAF5A,
0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C,
0x75B7, 0x643E, 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, 0x2102,
0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1,
0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5,
0x453C, 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, 0x4204, 0x538D,
0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868,
0x99E1, 0xAB7A, 0xBAF3, 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, 0x6306, 0x728F, 0x4014,
0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3,
0x8A78, 0x9BF1, 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, 0xFFCF,
0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, 0x8408, 0x9581, 0xA71A, 0xB693,
0xC22C, 0xD3A5, 0xE13E, 0xF0B7, 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76,
0x7CFF, 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, 0x18C1, 0x0948,
0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E,
0xF2A7, 0xC03C, 0xD1B5, 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, 0x39C3, 0x284A, 0x1AD1,
0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1,
0xA33A, 0xB2B3, 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, 0xD68D,
0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, 0x5AC5, 0x4B4C, 0x79D7, 0x685E,
0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238,
0x93B1, 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, 0xF78F, 0xE606,
0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3,
0x2C6A, 0x1EF1, 0x0F78,
};
u8 auchCRCHi[]=
{
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40
};
u8 auchCRCLo[] =
{
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
0x40
};
/*——————————————————————————
* 函 数 名GetCRC16
* 输入参数:*buff:内存指针 len:数据长度
* 输出参数None
* 返 回 值:检验结果
* 功能说明计算一个数组的CRC结果
*——————————————————————————*/
u16 GetCRC16(u8 *buff, u16 len)
{
u16 crc16 = 0xFFFF;
while (len--)
{
crc16 = (crc16 >> 8 ) ^ CRC16_Table[(crc16 ^ *buff++) & 0xFF];
}
crc16 ^= 0xFFFF;
return crc16;
}
u16 MODBUS_CRC16(u8 *updata, u16 len)
{
u8 uchCRCHi=0xff;
u8 uchCRCLo=0xff;
u16 uindex;
while(len--)
{
uindex=uchCRCHi^*updata++;
uchCRCHi=uchCRCLo^auchCRCHi[uindex];
uchCRCLo=auchCRCLo[uindex];
}
return ( uchCRCLo<<8| uchCRCHi);
}
/*——————————————————————————
* 函 数 名GetCRC16
* 输入参数:*buff:内存指针 len:数据长度
* 输出参数None
* 返 回 值:检验结果
* 功能说明计算一个数组的CRC结果
*——————————————————————————*/
u16 GetXYDXCRC16(u8 *buff, u16 len,u16 seed)
{
//u16 crc16 = 0xFFFF;
u16 crc16 = seed;
while (len--)
{
crc16 = (crc16 >> 8 ) ^ CRC16_Table[(crc16 ^ *buff++) & 0xFF];
}
crc16 ^= 0xFFFF;
return crc16;
}
/*************** 函数实现 ***************/
/*——————————————————————————
* 函 数 GetSum
* 输入参数pMem:内存指针 Len-数据长度
* 输出参数None
* 返 回 值:算术累加值
* 功能说明:获取指定长度内存算术累加值
*——————————————————————————*/
u8 GetSum(u8 * buffer, u16 length)
{
u8 sum = 0;
for (u8 i = 0; i < length; i++)
{
sum += buffer[i];
}
return sum;
}
/*****************************************************************************
* Function : cmp_datas
* Description : none
* Input : u8 * buf1
u8* buf2
u8 length
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
bool cmp_datas(u8 * buf1, u8* buf2, u8 length)
{
for (u8 i = 0; i < length; i++)
{
if ( buf1[i] != buf2[i] )
{
return FALSE;
}
}
return TRUE;
}
/*——————————————————————————
* 函 数 名CheckBCDFormat
* 输入参数:*pDat:内存指针 dataLen-数据长度
* 输出参数None
* 返 回 值None
* 功能说明检查是否是bcd码格式
*——————————————————————————*/
bool CheckBCDFormat(u8 *pDat, u16 dataLen)
{
int tmp, flag;
flag = 0;
while(dataLen--)
{
if (flag == 0)
{
tmp = *pDat&0x0f;
}
else
{
tmp = (*pDat>>4)&0x0f;
pDat++;
}
flag = !flag;
if (!( (tmp>=0) && (tmp<= 9) ) )
{
return FALSE;
}
}
return TRUE;
}
/*——————————————————————————
* 函 数 名HexToBCD
* 输入参数uValue:需要转换的数据
* 输出参数None
* 返 回 值:转换结果
* 功能说明将Hex转换成BCD码
*——————————————————————————*/
u8 HexToBCD(u8 uValue)
{
u8 uh, ul;
if(uValue > 99)
{
return 0xFF;
}
uh = (uValue / 10);
ul = uValue % 10;
return (uh << 4) + (ul);
}
/*——————————————————————————
* 函 数 名BCDToHex
* 输入参数uValue:需要转换的数据
* 输出参数None
* 返 回 值:转换结果
* 功能说明将BCD转换成Hex码
*——————————————————————————*/
u8 BCDToHex(u8 uValue)
{
u8 uh, ul;
uh = (uValue >> 4);
if(uh > 9)
{
return 0xFF;
}
ul = uValue & 0x0F;
if(ul > 9)
{
return 0xFF;
}
return (uh * 10) + (ul);
}
/*——————————————————————————
* 函 数 名ShortLToH
* 输入参数uValue:需要转换的数据
* 输出参数None
* 返 回 值:转换结果
* 功能说明将16位数高低位调换
*——————————————————————————*/
u16 ShortLToH(u16 uValue)
{
u16 uNewValue;
uNewValue = uValue << 8 | uValue >> 8;
return uNewValue;
}
/*****************************************************************************
* Function : SysReset
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170313
* Author : barry
* Modification: Created function
*****************************************************************************/
void SysReset(void)
{
__set_FAULTMASK(1);// 关闭所有中断
NVIC_SystemReset();// 复位
}

97
APP/General.h Normal file
View File

@@ -0,0 +1,97 @@
#ifndef _GENERAL_H
#define _GENERAL_H
/*——————————————————————————
* 文 件 名General.h
* 文件说明: 普通函数源文件
*
* 当前版本V8.0
* 作 者ZL
* 开始日期2013-12-30
*———————————————————————————*/
#include "Basedefine.h"
#define CRC16_POLY 0x8005
#define CRC16_INIT 0xFFFF
/*************** 函数声明 ***************/
/*——————————————————————————
* 函 数 名GetSum
* 输入参数pMem:内存指针 Len-数据长度
* 输出参数None
* 返 回 值:算术累加值
* 功能说明:获取指定长度内存算术累加值
*——————————————————————————*/
u8 GetSum(u8 * buffer, u16 length);
/*——————————————————————————
* 函 数 名CheckBCDFormat
* 输入参数:*pDat:内存指针 dataLen-数据长度
* 输出参数None
* 返 回 值None
* 功能说明检查是否是bcd码格式
*——————————————————————————*/
bool CheckBCDFormat(u8 *pDat, u16 dataLen);
/*——————————————————————————
* 函 数 名GetCRC16
* 输入参数:*buff:内存指针 len:数据长度
* 输出参数None
* 返 回 值:检验结果
* 功能说明计算一个数组的CRC结果
*——————————————————————————*/
u16 GetCRC16(u8 *buff, u16 len);
/*——————————————————————————
* 函 数 名HexToBCD
* 输入参数uValue:需要转换的数据
* 输出参数None
* 返 回 值:转换结果
* 功能说明将Hex转换成BCD码
*——————————————————————————*/
u8 HexToBCD(u8 uValue);
/*——————————————————————————
* 函 数 名BCDToHex
* 输入参数uValue:需要转换的数据
* 输出参数None
* 返 回 值:转换结果
* 功能说明将BCD转换成Hex码
*——————————————————————————*/
u8 BCDToHex(u8 uValue);
/*——————————————————————————
* 函 数 名ShortLToH
* 输入参数uValue:需要转换的数据
* 输出参数None
* 返 回 值:转换结果
* 功能说明将16位数高低位调换
*——————————————————————————*/
u16 ShortLToH(u16 uValue);
/*——————————————————————————
* 函 数 名PrintBuffer
* 输入参数pBuf:内存指针
len:数据长度
* 输出参数None
* 返 回 值None
* 功能说明:内存打印
*——————————————————————————*/
bool cmp_datas(u8 * buf1, u8* buf2, u8 length);
u16 MODBUS_CRC16(u8 *updata, u16 len);
void SysReset(void);
u16 GetXYDXCRC16(u8 *buff, u16 len,u16 seed);
#define DATA_COUNT_MAX (24*30)
//#define DATA_COUNT_MAX (24*3)
#define CUR_DATA_LEN (5)
#define SUM_DATA_LEN (5)
#define SURPLUS_DATA_LEN (6)
#define ALA_DATA_LEN (4)
#endif

165
APP/Init.c Normal file
View File

@@ -0,0 +1,165 @@
/*——————————————————————————
* 文 件 名Init.c
* 文件说明: 初始化源文件
*
* 当前版本V8.0
* 作 者ZL
* 开始日期2013-12-30
*———————————————————————————*/
#include "Init.h"
void RCC_Init(void)
{
/* Enable Clock Security System(CSS): this will generate an NMI exception
when HSE clock fails */
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = RCC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
RCC_ClockSecuritySystemCmd(ENABLE);
}
void gpio_init(st_gpio_config ioconfig)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(ioconfig.GPIO_clk, ENABLE);
GPIO_InitStructure.GPIO_Pin = ioconfig.GPIO_Pin;
GPIO_InitStructure.GPIO_Mode = ioconfig.GPIO_mode;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(ioconfig.GPIO_port, &GPIO_InitStructure);
}
/*—————————————————————————
* 函 数 名NVIC_Init
* 输入参数None
* 输出参数None
* 返 回 值None
* 功能说明:中断向量初始化
*——————————————————————————*/
#define FLASH_APP_ADDRESS 0x08005000
void Nvic_Init(void)
{
// NVIC_InitTypeDef NVIC_InitStructure;
//NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);//重定义中断向量表的位置
NVIC_SetVectorTable(NVIC_VectTab_FLASH,FLASH_APP_ADDRESS);
//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* Enable and configure RCC global IRQ channel */
/*
NVIC_InitStructure.NVIC_IRQChannel = SysTick_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
*/
/* Enable and configure RCC global IRQ channel */
/*
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel4_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 6;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
*/
}
/*——————————————————————————
* 函 数 名RCC_IRQHandler
* 输入参数None
* 输出参数None
* 返 回 值None
* 功能说明RCC中断服务函数
*——————————————————————————*/
void RCC_IRQHandler(void)
{
if(RCC_GetITStatus(RCC_IT_HSERDY) != RESET)
{
/* Clear HSERDY interrupt pending bit */
RCC_ClearITPendingBit(RCC_IT_HSERDY);
/* Check if the HSE clock is still available */
if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET)
{
/* Enable PLL: once the PLL is ready the PLLRDY interrupt is generated */
RCC_PLLCmd(ENABLE);
}
}
if(RCC_GetITStatus(RCC_IT_PLLRDY) != RESET)
{
/* Clear PLLRDY interrupt pending bit */
RCC_ClearITPendingBit(RCC_IT_PLLRDY);
/* Check if the PLL is still locked */
if (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) != RESET)
{
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
}
}
}

44
APP/Init.h Normal file
View File

@@ -0,0 +1,44 @@
#ifndef _INIT_H
#define _INIT_H
/*——————————————————————————
* 文 件 名Init.h
* 文件说明: 初始化源文件
*
* 当前版本V8.0
* 作 者ZL
* 开始日期2013-12-30
*———————————————————————————*/
#include "Basedefine.h"
/*************函数声明 **************/
/*——————————————————————————
* 函 数 名RCC_Init
* 输入参数None
* 输出参数None
* 返 回 值None
* 功能说明RCC时钟初始化
*——————————————————————————*/
void RCC_Init(void);
/*——————————————————————————
* 函 数 名Nvic_Init
* 输入参数None
* 输出参数None
* 返 回 值None
* 功能说明:中断向量初始化
*——————————————————————————*/
void Nvic_Init(void);
/*——————————————————————————
* 函 数 名Iwdg_Init
* 输入参数None
* 输出参数None
* 返 回 值None
* 功能说明:看门狗程序初始化
*——————————————————————————*/
void Iwdg_Init(u8 timeout);
#define GIPO_CFG(name) name##_PIN_CFG
void gpio_init(st_gpio_config ioconfig );
#endif

724
APP/IrDA.c Normal file
View File

@@ -0,0 +1,724 @@
#include "stm32f10x.h"
#include "uart.h"
#include "IrDA.h"
#include "Mem.h"
#include "debug_printf.h"
#include "hal_radio.h"
enum
{
IRDA_STATUS_NONE,
IRDA_STATUS_TX,
IRDA_STATUS_RX,
IRDA_STATUS_RECEIVE,
};
enum
{
END = 0,
FINISH,
WAIT,
};
typedef struct
{
u8 fLen;
u8 index;
}IRDA_FLAG;
enum
{
IRDA_ERR = 0x0000,
IRDA_TX_START = 0x0001,
IRDA_RX_START = 0x0002,
IRDA_TX_FINISH = 0x0004,
IRDA_RX_FINISH = 0x0008,
IRDA_RX_ERR = 0x0010,
IRDA_RX_WAIT = 0x0020,
};
#define IRDA_TX_TIMEOUT 1000
#define IRDA_RX_TIMEOUT 1000
static IRDA_FLAG IRDA_TX_flag;
u8 IRDA_TX_buf[IRDA_TX_BUFFER_SIZE];
static IRDA_FLAG IRDA_RX_flag;
u8 IRDA_RX_buf[IRDA_RX_BUFFER_SIZE];
static u8 IRDA_status = IRDA_STATUS_NONE;
TaskHandle_t IRDA_task_handle;
/*****************************************************************************
* Function : IRDA_RX_start
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170515
* Author : barry
* Modification: Created function
*****************************************************************************/
void IRDA_RX_start(void)
{
IRDA_GPIO_RX_init();
IRDA_RX_flag.fLen = 0;
IRDA_RX_flag.index = 0;
IRDA_status = IRDA_STATUS_RX;
}
/*****************************************************************************
* Function : IRDA_RX_stop
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170515
* Author : barry
* Modification: Created function
*****************************************************************************/
void IRDA_RX_stop(void)
{
TIM_Cmd(IRDA_BAUD_TIMER, DISABLE);
hal_sRF_FSK_ITConfig(IRDA_RX_LINE , DISABLE);
GPIO_SetBits(IRDA_TX_PORT, IRDA_TX_PIN);
IRDA_RX_flag.fLen = 0;
IRDA_RX_flag.index = 0;
}
/*****************************************************************************
* Function : IRDA_GPIO_RX_init
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170515
* Author : barry
* Modification: Created function
*****************************************************************************/
void IRDA_GPIO_RX_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(IRDA_RX_PORT_CLK, ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = IRDA_RX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init( IRDA_RX_PORT, &GPIO_InitStructure );
EXTI_ClearITPendingBit(IRDA_RX_LINE);
GPIO_EXTILineConfig(IRDA_RX_PORT_SOURCE, IRDA_RX_PIN_SOURCE);
EXTI_InitStructure.EXTI_Line = IRDA_RX_LINE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*****************************************************************************
* Function : IRDA_GPIO_TX_init
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170515
* Author : barry
* Modification: Created function
*****************************************************************************/
void IRDA_GPIO_TX_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(IRDA_TX_PORT_CLK | RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = IRDA_TX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init( IRDA_TX_PORT, &GPIO_InitStructure );
GPIO_SetBits(IRDA_TX_PORT, IRDA_TX_PIN);
}
/*****************************************************************************
* Function : GPIO_TX_high
* Description : 发送高电平时无需加载载波,开始时已经启动定时器
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170515
* Author : barry
* Modification: Created function
*****************************************************************************/
void GPIO_TX_high(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_Cmd(PWM_TIMER, DISABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = IRDA_TX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init( IRDA_TX_PORT, &GPIO_InitStructure );
GPIO_SetBits(IRDA_TX_PORT, IRDA_TX_PIN);
}
/*****************************************************************************
* Function : GPIO_TX_low
* Description : IRDA发送时低电平需要加载载波信号
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170515
* Author : barry
* Modification: Created function
*****************************************************************************/
void GPIO_TX_low(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
IRDA_GPIO_TX_init();
RCC_APB1PeriphClockCmd(PWM_TIMER_CLK, ENABLE); //时钟使能
TIM_TimeBaseStructure.TIM_Period = PWM_PERIOD; // period
TIM_TimeBaseStructure.TIM_Prescaler = PWM_PRESC; // 时钟分频
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(PWM_TIMER, &TIM_TimeBaseStructure);
//初始化TIM2 Channel1 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OCInitStructure.TIM_Pulse = PWM_PERIOD / 2;
TIM_OC1Init(PWM_TIMER, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(PWM_TIMER, TIM_OCPreload_Enable); //使能在CCR2上的预装载寄存器
TIM_CtrlPWMOutputs(PWM_TIMER, ENABLE);
TIM_Cmd(PWM_TIMER, ENABLE);
}
/*****************************************************************************
* Function : baud_timer_init
* Description : none
* Input : u32 preriod
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170515
* Author : barry
* Modification: Created function
*****************************************************************************/
void baud_timer_init(u32 preriod)
{
RCC_APB1PeriphClockCmd(IRDA_BAUD_TIMER_CLK, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseStructure.TIM_Period = preriod; // period
TIM_TimeBaseStructure.TIM_Prescaler = IRDA_BAUD_PRESC; // 时钟分频
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(IRDA_BAUD_TIMER, &TIM_TimeBaseStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ClearFlag(IRDA_BAUD_TIMER, TIM_FLAG_Update);
TIM_ITConfig(IRDA_BAUD_TIMER, TIM_IT_Update, ENABLE); //允许更新中断
TIM_Cmd(IRDA_BAUD_TIMER, ENABLE);
}
/*****************************************************************************
* Function : IRDA_TX_bit
* Description : none
* Input : u8 bitVal
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170515
* Author : barry
* Modification: Created function
*****************************************************************************/
void IRDA_TX_bit(u8 bitVal)
{
if (bitVal == 0)
{
GPIO_TX_low();
}
else
{
GPIO_TX_high();
}
}
/*****************************************************************************
* Function : IRDA_TX
* Description : none
* Input : u8 *buf
u8 length
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170515
* Author : barry
* Modification: Created function
*****************************************************************************/
void IRDA_TX(u8 *buf, u8 length)
{
IRDA_RX_stop();
IRDA_TX_flag.fLen = length;
IRDA_TX_flag.index = 0;
if ((IRDA_status != IRDA_STATUS_RECEIVE) || (IRDA_status != IRDA_STATUS_TX))
{
IRDA_GPIO_TX_init();
IRDA_status = IRDA_STATUS_TX ;
MemCpy(IRDA_TX_buf, buf, length);
hal_sRF_FSK_ITConfig(IRDA_RX_LINE , DISABLE);
TIM_ClearITPendingBit(IRDA_BAUD_TIMER, TIM_IT_Update);
baud_timer_init(IRDA_BAUD_PERIOD);
xTaskNotify(IRDA_task_handle, IRDA_TX_START, eSetBits);
printf("IRDA start tx\r\n");
}
else
{
printf("IRDA tx when rx\r\n");
}
}
/*****************************************************************************
* Function : IRDA_task
* Description : none
* Input : void *ptr
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170515
* Author : barry
* Modification: Created function
*****************************************************************************/
void IRDA_task(void *ptr)
{
TickType_t xTicksToWait;
TimeOut_t xTimeOut;
IRDA_GPIO_RX_init();
IRDA_GPIO_TX_init();
//IRDA_RX_start();
for (;;)
{
uint32_t notifyValue = 0;
xTaskNotifyWait(0xFF, 0xFF, &notifyValue, portMAX_DELAY);
if (notifyValue == IRDA_TX_START)
{
xTicksToWait = IRDA_TX_TIMEOUT / portTICK_RATE_MS;
vTaskSetTimeOutState(&xTimeOut);
while(1)
{
if (xTaskCheckForTimeOut(&xTimeOut, &xTicksToWait) == pdFALSE)
{
xTaskNotifyWait(0xFF, 0xFF, &notifyValue, xTicksToWait);
if (notifyValue == IRDA_TX_FINISH)
{
printf("IRDA tx finish\r\n");
break;
}
}
else
{
printf("IRDA tx timeout\r\n");
break;
}
}
IRDA_RX_start();
}
else if (notifyValue == IRDA_RX_START)
{
xTicksToWait = IRDA_RX_TIMEOUT / portTICK_RATE_MS;
vTaskSetTimeOutState(&xTimeOut);
while(1)
{
if (xTaskCheckForTimeOut(&xTimeOut, &xTicksToWait) == pdFALSE)
{
xTaskNotifyWait(0xFF, 0xFF, &notifyValue, xTicksToWait);
if (notifyValue == IRDA_RX_FINISH)
{
break;
}
else if (notifyValue == IRDA_RX_ERR)
{
break;
}
}
else
{
break;
}
}
IRDA_RX_start();
}
}
}
/*****************************************************************************
* Function : create_IRDA_task
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170515
* Author : barry
* Modification: Created function
*****************************************************************************/
void create_IRDA_task(void)
{
xTaskCreate(IRDA_task, NULL, 100, NULL, 2, &IRDA_task_handle);
}
/*****************************************************************************
Prototype : DLT645_protocol_receive
Description :
Input :
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
u32 DLT645_protocol_receive(u8 * rxBuf, IRDA_FLAG * rx_flag)
{
u32 status = IRDA_RX_WAIT;
switch(rx_flag->index)
{
case 0:
if(rxBuf[rx_flag->index] != 0x68)
{
rx_flag->index = 0;
status = IRDA_RX_ERR;
}
else
{
rx_flag->index++;
}
break;
case 9:
rx_flag->fLen = rxBuf[rx_flag->index] + 12;
rx_flag->index++;
break;
default:
rx_flag->index++;
if (rx_flag->index > 9)
{
if ( rx_flag->index == rx_flag->fLen )
{
if ( (rxBuf[rx_flag->index - 1] == 0x16) && (rxBuf[rx_flag->index -2] == GetSum(rxBuf, rx_flag->fLen - 2)))
{
status = IRDA_RX_FINISH;
rx_flag->index = 0;
}
else
{
status = IRDA_RX_ERR;
rx_flag->index = 0;
}
}
}
break;
}
return status;
}
/*****************************************************************************
* Function : IRDA_BAUD_IRQHandler
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170515
* Author : barry
* Modification: Created function
*****************************************************************************/
void IRDA_BAUD_IRQHandler(void)
{
u8 start_bit = 0;
u8 end_bit = 1;
u8 check_bit;
static u8 rxByte = 0;
static u8 tx_bit_pos = 0;
static u8 rx_bit_pos = 0;
BaseType_t pxHigherPriorityTaskWoken = pdFALSE;
u8 status;
if (TIM_GetITStatus(IRDA_BAUD_TIMER, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(IRDA_BAUD_TIMER, TIM_IT_Update);
if (IRDA_status == IRDA_STATUS_TX)
{
switch (tx_bit_pos)
{
case 0:
if (IRDA_TX_flag.index >= IRDA_TX_flag.fLen)
{
TIM_Cmd(IRDA_BAUD_TIMER, DISABLE);
IRDA_status = IRDA_STATUS_NONE;
xTaskNotifyFromISR(IRDA_task_handle, IRDA_TX_FINISH, eSetBits, &pxHigherPriorityTaskWoken);
}
else
{
IRDA_TX_bit( start_bit );
}
tx_bit_pos++;
break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
IRDA_TX_bit( (IRDA_TX_buf[IRDA_TX_flag.index] >> (tx_bit_pos - 1)) & 0x01);
tx_bit_pos++;
break;
case 9:
check_bit = 0;
for (u8 i = 0; i < 8; i++)
{
check_bit += ((IRDA_TX_buf[IRDA_TX_flag.index] >> i) & 0x01);
}
check_bit = check_bit % 2;
IRDA_TX_bit(check_bit);
tx_bit_pos++;
break;
case 10:
IRDA_TX_bit(end_bit);
IRDA_TX_flag.index++;
tx_bit_pos = 0;
break;
default:
break;
}
}
else if (IRDA_status == IRDA_STATUS_RECEIVE)
{
switch(rx_bit_pos)
{
case 0:
if (IRDA_RX_BIT_VAL == 0)
{
baud_timer_init(IRDA_BAUD_PERIOD);
rxByte = 0;
rx_bit_pos++;
}
else
{
TIM_Cmd(IRDA_BAUD_TIMER, DISABLE);
hal_sRF_FSK_ITConfig(IRDA_RX_LINE , ENABLE);
IRDA_RX_start();
}
break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
rxByte += IRDA_RX_BIT_VAL << (rx_bit_pos - 1);
rx_bit_pos++;
break;
case 9:
check_bit = 0;
for (u8 i = 0; i < 8; i++)
{
check_bit += ((rxByte >> i) & 0x01);
}
check_bit = check_bit % 2;
if (IRDA_RX_BIT_VAL != check_bit)
{
rx_bit_pos = 0;
IRDA_RX_flag.index = 0;
TIM_Cmd(IRDA_BAUD_TIMER, DISABLE);
hal_sRF_FSK_ITConfig(IRDA_RX_LINE , ENABLE);
}
else
{
rx_bit_pos++;
}
break;
case 10:
rx_bit_pos = 0;
if (IRDA_RX_BIT_VAL == 1)//停止位正确
{
if (IRDA_RX_flag.index >= IRDA_RX_BUFFER_SIZE)
{
IRDA_RX_flag.index = 0;
}
IRDA_RX_buf[IRDA_RX_flag.index++] = rxByte;
if (IRDA_RX_flag.index == 1)
{
xTaskNotifyFromISR(IRDA_task_handle, IRDA_RX_START, eSetBits, &pxHigherPriorityTaskWoken);
}
status = DLT645_protocol_receive(IRDA_RX_buf, &IRDA_RX_flag);
if (status == IRDA_RX_WAIT)
{
TIM_Cmd(IRDA_BAUD_TIMER, DISABLE);
hal_sRF_FSK_ITConfig(IRDA_RX_LINE , ENABLE);
}
else
{
IRDA_status = IRDA_STATUS_NONE;
IRDA_RX_flag.index = 0;
TIM_Cmd(IRDA_BAUD_TIMER, DISABLE);
xTaskNotifyFromISR(IRDA_task_handle, status, eSetBits, &pxHigherPriorityTaskWoken);
}
}
else //停止位错误
{
IRDA_status = IRDA_STATUS_NONE;
IRDA_RX_flag.index = 0;
TIM_Cmd(IRDA_BAUD_TIMER, DISABLE);
xTaskNotifyFromISR(IRDA_task_handle, IRDA_RX_ERR, eSetBits, &pxHigherPriorityTaskWoken);
}
break;
}
}
}
}
/*****************************************************************************
* Function : RX_START_IRQHandler
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170515
* Author : barry
* Modification: Created function
*****************************************************************************/
void RX_START_IRQHandler(void)
{
if(EXTI_GetITStatus(IRDA_RX_LINE) != RESET)
{
EXTI_ClearITPendingBit(IRDA_RX_LINE);
if ((IRDA_status == IRDA_STATUS_RX) || (IRDA_status == IRDA_STATUS_RECEIVE))
{
IRDA_status = IRDA_STATUS_RECEIVE;
hal_sRF_FSK_ITConfig(IRDA_RX_LINE , DISABLE);
baud_timer_init(IRDA_BAUD_PERIOD/2);
}
}
}

59
APP/IrDA.h Normal file
View File

@@ -0,0 +1,59 @@
#ifndef _IRDA_H_
#define _IRDA_H_
#include "stm32f10x_gpio.h"
enum
{
CHECK_ODD,
CHECK_EVEN,
CHECK_NONE,
};
#define IRDA_BAUD 1200
#define IRDA_DATABITS 8
#define IRDA_CHECKBIT CHECK_EVEN
#define IRDA_STOPBIT 1
#define IRDA_BAUD_TIMER TIM3
#define IRDA_BAUD_TIMER_CLK RCC_APB1Periph_TIM3
#define IRDA_BAUD_IRQHandler TIM3_IRQHandler
#define IRDA_BAUD_PRESC 100
#define IRDA_BAUD_PERIOD (SystemCoreClock/IRDA_BAUD_PRESC/IRDA_BAUD)
#define IRDA_TX_PIN GPIO_Pin_0
#define IRDA_TX_PORT GPIOA
#define IRDA_TX_PORT_CLK RCC_APB2Periph_GPIOA
#define IRDA_RX_PIN GPIO_Pin_1
#define IRDA_RX_PORT GPIOC
#define IRDA_RX_PORT_CLK RCC_APB2Periph_GPIOC
#define IRDA_RX_PORT_SOURCE GPIO_PortSourceGPIOC
#define IRDA_RX_PIN_SOURCE GPIO_PinSource1
#define IRDA_RX_LINE EXTI_Line1
#define RX_START_IRQHandler EXTI1_IRQHandler
#define IRDA_RX_BIT_VAL GPIO_ReadInputDataBit(IRDA_RX_PORT, IRDA_RX_PIN)
#define IRDA_TX_BUFFER_SIZE 255
#define IRDA_RX_BUFFER_SIZE 255
#define PWM_TIMER TIM2
#define PWM_TIMER_CLK RCC_APB1Periph_TIM2
#define PWM_TIMER_CHANNEL 1
#define PWM_PRESC 100
#define PWM_FRE 38000
#define PWM_PERIOD (SystemCoreClock/PWM_FRE/PWM_PRESC)
#define IRDA_BAUD_COFF ((11.0 * 1000.0) / IRDA_BAUD)
void IRDA_PWM_Init();
void IRDA_GPIO_RX_init(void);
void IRDA_TX(u8 *buf, u8 length);
void baud_timer_init(u32 preriod);
void create_IRDA_task(void);
#endif

248
APP/Led.c Normal file
View File

@@ -0,0 +1,248 @@
/*——————————————————————————
* 文 件 名Led.c
* 文件说明Led源文件
*
* 当前版本V8.0
* 作 者ZL
* 开始日期2013-12-30
*———————————————————————————*/
#include "Led.h"
#include "include.h"
bool OLDNEW_VERSION_DETECT = false;//false 旧版本true 新版本
/*
st_gpio_config up_send_led = LED_INIT(UP_SEND);
st_gpio_config up_receive_led = LED_INIT(UP_RECEIVE);
st_gpio_config down_send_led = LED_INIT(DOWN_SEND);
st_gpio_config down_receive_led = LED_INIT(DOWN_RECEIVE);
st_gpio_config alarm_led = LED_INIT(ALARM);
st_gpio_config running_led = LED_INIT(RUNNING);
*/
/*
st_gpio_config running_led = {GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_1, GPIO_Mode_IPU}; //PA1 运行
st_gpio_config alarm_led = {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_3, GPIO_Mode_IPU}; //PC3 告警
st_gpio_config plcRx_led = {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_0, GPIO_Mode_IPU}; //PC0 PLC RX
st_gpio_config plcTx_led = {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_2, GPIO_Mode_IPU}; //PC2 PLC TX
st_gpio_config up_RS485Rx_led = {GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_12, GPIO_Mode_IPU}; //PA12 4851RX 485上行
st_gpio_config up_RS485Tx_led = {GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_11, GPIO_Mode_IPU}; //PA11 4851TX
st_gpio_config MBUS1Rx_led = {GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_8, GPIO_Mode_IPU}; //PA8 MBUS1RX
st_gpio_config MBUS1Tx_led = {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_9, GPIO_Mode_IPU}; //PC9 MBUS1TX
st_gpio_config dn_RS485Rx_led = {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_8, GPIO_Mode_IPU}; //PC8 4852RX 485下行
st_gpio_config dn_RS485Rx_led = {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_7, GPIO_Mode_IPU}; //PC7 4852TX
st_gpio_config MBUS2Rx_led = {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_6, GPIO_Mode_IPU}; //PC6 MBUS2RX
st_gpio_config MBUS2Tx_led = {GPIOB, RCC_APB2Periph_GPIOB, GPIO_Pin_15, GPIO_Mode_IPU}; //PB15 MBUS2TX
*/
st_gpio_config led_boardharddetect[1] =
{
{GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_1, GPIO_Mode_IPU}, //PA1 运行
};
st_gpio_config led_list[] =
{
#if HARDBOARD_VERSION == 0
{GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_1, GPIO_Mode_IPU}, //PA1 运行
{GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_3, GPIO_Mode_IPU}, //PC3 告警
{GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_0, GPIO_Mode_IPU}, //PC0 PLC RX RED
{GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_2, GPIO_Mode_IPU}, //PC2 PLC TX
{GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_12, GPIO_Mode_IPU}, //PA12 4851RX RED
{GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_11, GPIO_Mode_IPU}, //PA11 4851TX GREEN
{GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_8, GPIO_Mode_IPU}, //PA8 MBUS1RX
{GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_9, GPIO_Mode_IPU}, //PC9 MBUS1TX
{GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_8, GPIO_Mode_IPU}, //PC8 4852RX
{GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_7, GPIO_Mode_IPU}, //PC7 4852TX
{GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_6, GPIO_Mode_IPU}, //PC6 MBUS2RX
{GPIOB, RCC_APB2Periph_GPIOB, GPIO_Pin_15, GPIO_Mode_IPU}, //PB15 MBUS2TX
// {GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_1, GPIO_Mode_IPD}, //PA1 运行
// {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_3, GPIO_Mode_IPD}, //PC3 告警
//
// {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_0, GPIO_Mode_IPD}, //PC0 PLC RX RED
// {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_2, GPIO_Mode_IPD}, //PC2 PLC TX
//
// {GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_12, GPIO_Mode_IPD}, //PA12 4851RX RED
// {GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_11, GPIO_Mode_IPD}, //PA11 4851TX GREEN
//
// {GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_8, GPIO_Mode_IPD}, //PA8 MBUS1RX
// {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_9, GPIO_Mode_IPD}, //PC9 MBUS1TX
//
// {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_8, GPIO_Mode_IPD}, //PC8 4852RX
// {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_7, GPIO_Mode_IPD}, //PC7 4852TX
//
// {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_6, GPIO_Mode_IPD}, //PC6 MBUS2RX
// {GPIOB, RCC_APB2Periph_GPIOB, GPIO_Pin_15, GPIO_Mode_IPD}, //PB15 MBUS2TX
#else
{GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_1, GPIO_Mode_Out_OD}, //PA1 运行
{GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_3, GPIO_Mode_Out_OD}, //PC3 告警
{GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_0, GPIO_Mode_Out_OD}, //PC0 PLC RX RED
{GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_2, GPIO_Mode_Out_OD}, //PC2 PLC TX
{GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_12, GPIO_Mode_Out_OD}, //PA12 4851RX RED
{GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_11, GPIO_Mode_Out_OD}, //PA11 4851TX GREEN
{GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_8, GPIO_Mode_Out_OD}, //PA8 MBUS1RX
{GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_9, GPIO_Mode_Out_OD}, //PC9 MBUS1TX
{GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_8, GPIO_Mode_Out_OD}, //PC8 4852RX
{GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_7, GPIO_Mode_Out_OD}, //PC7 4852TX
{GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_6, GPIO_Mode_Out_OD}, //PC6 MBUS2RX
{GPIOB, RCC_APB2Periph_GPIOB, GPIO_Pin_15, GPIO_Mode_Out_OD}, //PB15 MBUS2TX
#endif
};
st_gpio_config * CurrentOperationLED = &led_list[0];
/*——————————————————————————
* 函 数 名LED_Init
* 输入参数led 灯
* 输出参数None
* 返 回 值None
* 功能说明初始化LED灯
*——————————————————————————*/
void LED_Init(st_gpio_config led)
{
gpio_init(led);
LED_Off(led);
}
void init_all_led(void)
{
LED_Init(led_boardharddetect[0]);
if(GPIO_ReadInputDataBit(led_boardharddetect[0].GPIO_port,led_boardharddetect[0].GPIO_Pin) == 0x01)
{
OLDNEW_VERSION_DETECT = true;
}
else
{
OLDNEW_VERSION_DETECT = false;
}
for (u8 i = 0; i < sizeof(led_list) / sizeof(st_gpio_config); i++)
{
if(OLDNEW_VERSION_DETECT == false)
{
led_list[i].GPIO_mode = GPIO_Mode_IPU;
}
else
{
led_list[i].GPIO_mode = GPIO_Mode_Out_OD;
}
LED_Init(led_list[i]);
LED_Off(led_list[i]);
}
}
void test_led(void)
{
for (u8 i = 0; i < sizeof(led_list) / sizeof(st_gpio_config); i++)
{
COM_led_on(i);
//vTaskDelay( 1000 / portTICK_RATE_MS );
//COM_led_off(i);
//vTaskDelay( 1000 / portTICK_RATE_MS );
}
printf("OK\r\n");
}
void COM_led_init(u8 led)
{
LED_Init(led_list[led]);
}
void COM_led_on(u8 led)
{
LED_On(led_list[led]);
}
void COM_led_off(u8 led)
{
LED_Off(led_list[led]);
}
/*——————————————————————————
* 函 数 名LED_On
* 输入参数led 灯
* 输出参数None
* 返 回 值None
* 功能说明点亮Led灯
*——————————————————————————*/
void LED_On(st_gpio_config led)
{
//#if HARDBOARD_VERSION == 0
if(OLDNEW_VERSION_DETECT == false)
led.GPIO_port->BSRR = led.GPIO_Pin;//GPIO_PIN[led]; //设置位为 1
//#else
else
led.GPIO_port->BRR = led.GPIO_Pin;
//#endif
}
/*——————————————————————————
* 函 数 名LED_Off
* 输入参数led 灯
* 输出参数None
* 返 回 值None
* 功能说明关闭Led灯
*——————————————————————————*/
void LED_Off(st_gpio_config led)
{
//#if HARDBOARD_VERSION == 0
if(OLDNEW_VERSION_DETECT == false)
led.GPIO_port->BRR = led.GPIO_Pin;//GPIO_PIN[led]; //清除位为 0
//#else
else
led.GPIO_port->BSRR = led.GPIO_Pin;
//#endif
}
/*——————————————————————————
* 函 数 名LED_Toggle
* 输入参数led 灯
* 输出参数None
* 返 回 值None
* 功能说明:电平反转
*——————————————————————————*/
void LED_Toggle(st_gpio_config led)
{
//#if HARDBOARD_VERSION == 0
if(OLDNEW_VERSION_DETECT == false)
led.GPIO_port->ODR ^= led.GPIO_Pin;//GPIO_PIN[led];
//#else
else
led.GPIO_port->ODR ^= led.GPIO_Pin;
//#endif
}
void off_all_led(void)
{
for (u8 i = 0; i < sizeof(led_list) / sizeof(st_gpio_config); i++)
{
//LED_Init(led_list[i]);
LED_Off(led_list[i]);
}
}

115
APP/Led.h Normal file
View File

@@ -0,0 +1,115 @@
/*——————————————————————————
* 文 件 名Led.h
* 文件说明Led头文件
*
* 当前版本V8.0
* 作 者ZL
* 开始日期2013-12-30
*———————————————————————————*/
#ifndef _LED_H
#define _LED_H
#include "Basedefine.h"
/*************** 宏定义 ***************/
#define UP_SEND_LED_PIN GPIO_Pin_7
#define UP_SEND_LED_PORT GPIOC
#define UP_SEND_LED_PORT_CLK RCC_APB2Periph_GPIOC
#define UP_RECEIVE_LED_PIN GPIO_Pin_8
#define UP_RECEIVE_LED_PORT GPIOC
#define UP_RECEIVE_LED_PORT_CLK RCC_APB2Periph_GPIOC
#define ALARM_LED_PIN GPIO_Pin_3
#define ALARM_LED_PORT GPIOC
#define ALARM_LED_PORT_CLK RCC_APB2Periph_GPIOC
#define RUNNING_LED_PIN GPIO_Pin_1
#define RUNNING_LED_PORT GPIOA
#define RUNNING_LED_PORT_CLK RCC_APB2Periph_GPIOA
#define DOWN_SEND_LED_PIN GPIO_Pin_9
#define DOWN_SEND_LED_PORT GPIOC
#define DOWN_SEND_LED_PORT_CLK RCC_APB2Periph_GPIOC
#define DOWN_RECEIVE_LED_PIN GPIO_Pin_8
#define DOWN_RECEIVE_LED_PORT GPIOC
#define DOWN_RECEIVE_LED_PORT_CLK RCC_APB2Periph_GPIOC
#define LED_PIN(name) name##_LED_PIN
#define LED_PORT(name) name##_LED_PORT
#define LED_CLK(name) name##_LED_PORT_CLK
#define LED_INIT(name) {LED_PIN(name), LED_PORT(name), LED_CLK(name)}
typedef enum
{
RUNING_LED = 0,
ALARM_LED,
PLC_RX_LED,
PLC_TX_LED,
RS4851_RX_LED,
RS4851_TX_LED ,
MBUS1RX_LED,
MBUS1TX_LED,
RS4852_RX_LED,
RS4852_TX_LED ,
MBUS2RX_LED,
MBUS2TX_LED,
}EN_LED_TYPE;
/*************** 函数实现 ***************/
/*——————————————————————————
* 函 数 名LED_Init
* 输入参数led 灯
* 输出参数None
* 返 回 值None
* 功能说明初始化LED灯
*——————————————————————————*/
void LED_Init(st_gpio_config led);
/*——————————————————————————
* 函 数 名LED_On
* 输入参数led 灯
* 输出参数None
* 返 回 值None
* 功能说明点亮Led灯
*——————————————————————————*/
void LED_On (st_gpio_config led);
/*——————————————————————————
* 函 数 名LED_Off
* 输入参数led 灯
* 输出参数None
* 返 回 值None
* 功能说明关闭Led灯
*——————————————————————————*/
void LED_Off(st_gpio_config led);
/*——————————————————————————
* 函 数 名LED_Toggle
* 输入参数led 灯
* 输出参数None
* 返 回 值None
* 功能说明:电平反转
*——————————————————————————*/
void LED_Toggle(st_gpio_config led);
void init_all_led(void);
void all_light_delay(void);
void test_led(void );
void COM_led_on(u8 led);
void COM_led_off(u8 led);
void COM_led_init(u8 led);
void off_all_led(void);
extern st_gpio_config * CurrentOperationLED;
extern st_gpio_config led_list[] ;
#endif
/******************* (C) COPYRIGHT 2011 Leaguer Microelectronics *****END OF FILE****/

189
APP/MD5.c Normal file
View File

@@ -0,0 +1,189 @@
#include "MD5.h"
#include "Mem.h"
#include "string.h"
unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
void MD5Init(MD5_CTX *context)
{
context->count[0] = 0;
context->count[1] = 0;
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
}
void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen)
{
unsigned int i = 0,index = 0,partlen = 0;
index = (context->count[0] >> 3) & 0x3F;
partlen = 64 - index;
context->count[0] += inputlen << 3;
if(context->count[0] < (inputlen << 3))
context->count[1]++;
context->count[1] += inputlen >> 29;
if(inputlen >= partlen)
{
memcpy(&context->buffer[index],input,partlen);
MD5Transform(context->state,context->buffer);
for(i = partlen;i+64 <= inputlen;i+=64)
MD5Transform(context->state,&input[i]);
index = 0;
}
else
{
i = 0;
}
memcpy(&context->buffer[index],&input[i],inputlen-i);
}
void MD5Final(MD5_CTX *context,unsigned char digest[16])
{
unsigned int index = 0,padlen = 0;
unsigned char bits[8];
index = (context->count[0] >> 3) & 0x3F;
padlen = (index < 56)?(56-index):(120-index);
MD5Encode(bits,context->count,8);
MD5Update(context,PADDING,padlen);
MD5Update(context,bits,8);
MD5Encode(digest,context->state,16);
}
void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len)
{
unsigned int i = 0,j = 0;
while(j < len)
{
output[j] = input[i] & 0xFF;
output[j+1] = (input[i] >> 8) & 0xFF;
output[j+2] = (input[i] >> 16) & 0xFF;
output[j+3] = (input[i] >> 24) & 0xFF;
i++;
j+=4;
}
}
void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len)
{
unsigned int i = 0,j = 0;
while(j < len)
{
output[i] = (input[j]) |
(input[j+1] << 8) |
(input[j+2] << 16) |
(input[j+3] << 24);
i++;
j+=4;
}
}
void MD5Transform(unsigned int state[4],unsigned char block[64])
{
unsigned int a = state[0];
unsigned int b = state[1];
unsigned int c = state[2];
unsigned int d = state[3];
unsigned int x[64];
MD5Decode(x,block,64);
FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */
FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */
FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */
FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */
FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */
FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */
FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */
FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */
FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */
FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */
FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */
FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */
FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */
FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */
FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */
FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */
/* Round 2 */
GG(a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */
GG(d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */
GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */
GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */
GG(a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */
GG(d, a, b, c, x[10], 9, 0x2441453); /* 22 */
GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */
GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */
GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */
GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */
GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */
GG(b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */
GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */
GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */
GG(c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */
GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH(a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */
HH(d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */
HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */
HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */
HH(a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */
HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */
HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */
HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */
HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */
HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */
HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */
HH(b, c, d, a, x[ 6], 23, 0x4881d05); /* 44 */
HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */
HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */
HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */
HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */
/* Round 4 */
II(a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */
II(d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */
II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */
II(b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */
II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */
II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */
II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */
II(b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */
II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */
II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */
II(c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */
II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */
II(a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */
II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */
II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */
II(b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
}
void MD5_TEST(void)
{
int i;
unsigned char encrypt[] ="admin";//21232f297a57a5a743894a0e4a801fc3
unsigned char decrypt[16];
MD5_CTX md5;
MD5Init(&md5);
MD5Update(&md5,encrypt,strlen((char *)encrypt));
MD5Final(&md5,decrypt);
printf("¼ÓÃÜǰ:%s\n¼ÓÃܺó:",encrypt);
for(i=0;i<16;i++)
{
printf("%02x",decrypt[i]);
}
}
void MD5_code(u8 * buf, u8 * outbuf, u32 len)
{
MD5_CTX md5;
MD5Init(&md5);
MD5Update(&md5,buf, len);
MD5Final(&md5,outbuf);
}

53
APP/MD5.h Normal file
View File

@@ -0,0 +1,53 @@
#ifndef MD5_H
#define MD5_H
typedef struct
{
unsigned int count[2];
unsigned int state[4];
unsigned char buffer[64];
}MD5_CTX;
#define F(x,y,z) ((x & y) | (~x & z))
#define G(x,y,z) ((x & z) | (y & ~z))
#define H(x,y,z) (x^y^z)
#define I(x,y,z) (y ^ (x | ~z))
#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))
#define FF(a,b,c,d,x,s,ac) \
{\
a += F(b,c,d) + x + ac;\
a = ROTATE_LEFT(a,s);\
a += b;\
}
#define GG(a,b,c,d,x,s,ac) \
{\
a += G(b,c,d) + x + ac;\
a = ROTATE_LEFT(a,s);\
a += b;\
}
#define HH(a,b,c,d,x,s,ac) \
{\
a += H(b,c,d) + x + ac;\
a = ROTATE_LEFT(a,s);\
a += b;\
}
#define II(a,b,c,d,x,s,ac) \
{\
a += I(b,c,d) + x + ac;\
a = ROTATE_LEFT(a,s); \
a += b;\
}
void MD5Init(MD5_CTX *context);
void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen);
void MD5Final(MD5_CTX *context,unsigned char digest[16]);
void MD5Transform(unsigned int state[4],unsigned char block[64]);
void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len);
void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len);
void MD5_TEST(void);
void MD5_code(unsigned char * buf, unsigned char * outbuf, unsigned int len);
#endif

129
APP/Mem.c Normal file
View File

@@ -0,0 +1,129 @@
/*——————————————————————————
* 文 件 名Mem.c
* 文件说明:内存拷贝源文件
*
* 当前版本V8.0
* 作 者ZL
* 开始日期2013-12-30
*———————————————————————————*/
#include "Mem.h"
/************* 函数声明 *************/
/*——————————————————————————
* 函 数 名MemCpy
* 输入参数pSrc 源内存指针
len 数据长度
* 输出参数pDsc 目的内在指针
* 返 回 值:拷贝后的目的偏移地址
* 功能说明:拷贝一段内存内容
*——————————————————————————*/
u8 *MemCpy(void *pDsc, void*pSrc, u16 len)
{
u8 *pAddr1 = (u8 *)pDsc;
u8 *pAddr2 = (u8 *)pSrc;
while(len--)
{
*pAddr1++ = *pAddr2++;
}
return pAddr1;
}
/*——————————————————————————
* 函 数 名MemSet
* 输入参数pAddr 内存指针
value 需要设置的值
len 数据长度
* 输出参数None
* 返 回 值None
* 功能说明:设置某一段内容为某值
*——————————————————————————*/
void MemSet(void *pAddr, u8 value, u16 len)
{
u8 *pTmp = (u8 *)pAddr;
while(len--)
{
*pTmp++ = value;
}
}
/*——————————————————————————
* 函 数 名MemCmp
* 输入参数pDsc 目的地址
pSrc 源地址
Len 数据长度
* 输出参数None
* 返 回 值1 不一致
0 一致
* 功能说明:比较两个内存中的值
*——————————————————————————*/
u8 MemCmp(void *pDsc, void *pSrc, u16 len)
{
u8 *pAddr1 = (u8 *)pDsc;
u8 *pAddr2 = (u8 *)pSrc;
while(len--)
{
if (*pAddr1 != *pAddr2)
{
return 1;
}
pAddr1++;
pAddr2++;
}
return 0;
}
/*——————————————————————————
* 函 数 名MemCmpData
* 输入参数buf 数据区
data 比较数据
len 数据长度
* 输出参数None
* 返 回 值:>0 不一致
0 一致
* 功能说明:比较内存中的值与某个数据一致
*——————————————————————————*/
u8 MemCmpData(const u8 *buf,u8 data,u16 len)
{
while(len--)
{
if(buf[len] != data)
{
return buf[len]-data;
}
}
return 0;
}
void * w_memcpy( void *out, const void *in, size_t n)
{
uint8_t *src, *dest;
src = (uint8_t *) in;
dest = (uint8_t *) out;
while(n-- > 0) {
*dest++ = *src++;
}
return out;
}
void *w_memset(void *out, int value, size_t n)
{
uint8_t *dest;
dest = (uint8_t *) out;
while(n-- > 0) {
*dest++ = value & 0xff;
}
return out;
}

66
APP/Mem.h Normal file
View File

@@ -0,0 +1,66 @@
#ifndef _MEM_H
#define _MEM_H
/*——————————————————————————
* 文 件 名Mem.h
* 文件说明:内存拷贝头文件
*
* 当前版本V8.0
* 作 者ZL
* 开始日期2013-12-30
*———————————————————————————*/
#include "Basedefine.h"
/*——————————————————————————
* 函 数 名MemCpy
* 输入参数pSrc 源内存指针
len 数据长度
* 输出参数pDsc 目的内在指针
* 返 回 值:拷贝后的目的偏移地址
* 功能说明:拷贝一段内存内容
*——————————————————————————*/
u8 *MemCpy(void *pDsc, void*pSrc, u16 len);
/*——————————————————————————
* 函 数 名MemSet
* 输入参数pAddr 内存指针
value 需要设置的值
len 数据长度
* 输出参数None
* 返 回 值None
* 功能说明:设置某一段内容为某值
*——————————————————————————*/
void MemSet(void *pAddr, u8 value, u16 len);
/*——————————————————————————
* 函 数 名MemCmp
* 输入参数pDsc 目的地址
pSrc 源地址
len 数据长度
* 输出参数None
* 返 回 值1 不一致
0 一致
* 功能说明:比较两个内存中的值
*——————————————————————————*/
u8 MemCmp(void *pDsc, void*pSrc, u16 len);
/*——————————————————————————
* 函 数 名MemCmpData
* 输入参数buf 数据区
data 比较数据
len 数据长度
* 输出参数None
* 返 回 值:>0 不一致
0 一致
* 功能说明:比较内存中的值与某个数据一致
*——————————————————————————*/
u8 MemCmpData(const u8 *buf,u8 data,u16 len);
void * w_memcpy( void *out, const void *in, unsigned int n);
void *w_memset(void *out, int value, unsigned int n);
#define memcpy(dest, src, count) w_memcpy(dest, src, count)
#define memset(dest, value, count) w_memset(dest, value, count)
#endif

416
APP/PHY.c Normal file
View File

@@ -0,0 +1,416 @@
#include "PHY.h"
#include "uart.h"
#
extern st_RF_LoRa_DypeDef g_RF_LoRa;
extern SemaphoreHandle_t port_radio_Semaphore;
static QueueHandle_t radioQueue;
static TimerHandle_t radio_tx_handle;
static int8_t RxPacketSnr;
static double RxPacketRssiValue;
#define RADIO_TX_TIMEOUT 2000/portTICK_RATE_MS
u32 period = 1500;
void radio_tx_timeout_callback(TimerHandle_t xTimer)
{
hal_InitRF();
SX1276LoRa_Receive_Packet(0, false);
printf("RF tx timeout\r\n");
}
void read_radio_rssi(void)
{
RxPacketSnr = getPacketSnr();
RxPacketRssiValue = get_RxPacketRssi(RxPacketSnr);
printf("RSSI = %.2f, SNR = %d\r\n",RxPacketRssiValue, RxPacketSnr);
}
/*****************************************************************************
* Function : get_radio_bufPtr
* Description : none
* Input : void
* Output : None
* Return : u8
* Others :
* Record
* 1.Date : 20170419
* Author : barry
* Modification: Created function
*****************************************************************************/
u8 * get_RF_bufPtr(void)
{
return g_RF_LoRa.rf_DataBuffer;
}
/*****************************************************************************
* Function : get_radio_bufLen
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170419
* Author : barry
* Modification: Created function
*****************************************************************************/
u8 get_RF_bufLen(void)
{
return g_RF_LoRa.rf_RxPacketSize;
}
/*****************************************************************************
* Function : SX1276LoRa_NormalTx
* Description : none
* Input : u8 chl
u8 *PBuffer
u8 length
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170419
* Author : barry
* Modification: Created function
*****************************************************************************/
void SX1276LoRa_NormalTx(u8 chl, u8 *PBuffer,u8 length)
{
SX1276LoRa_Send_Packet(chl, false, PBuffer,length);
}
/*****************************************************************************
* Function : SX1276LoRa_WokeUpTx
* Description : none
* Input : u8 chl
u8 *PBuffer
u8 length
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170419
* Author : barry
* Modification: Created function
*****************************************************************************/
void SX1276LoRa_WokeUpTx(u8 chl, u8 *PBuffer,u8 length)
{
SX1276LoRa_Send_Packet(chl, true, PBuffer,length);
}
/*****************************************************************************
* Function : radio_idle
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170306
* Author : barry
* Modification: Created function
*****************************************************************************/
bool radio_idle(void)
{
#ifdef USE_LORA_MODE
if ( (g_RF_LoRa.rf_state != RFLR_STATE_TX_RUNNING) && (g_RF_LoRa.rf_state != RFLR_STATE_RX_RECEIVEING))
#else
if ( (g_fsk.states != RF_STATE_TX_RUNNING) && (g_fsk.states != RF_STATE_RX_SYNC) && (g_fsk.states != RF_STATE_RX_RUNNING))
#endif
{
return true;
}
else
{
return false;
}
}
/*****************************************************************************
* Function : mac_data_req
* Description : none
* Input : u8 *buf
u8 length
u32 timeout
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170419
* Author : barry
* Modification: Created function
*****************************************************************************/
void mac_data_req(u8 *buf, u8 length)
{
if (radio_idle())
{
SX1276LoRa_WokeUpTx(0 , buf, length);
xTimerReset(radio_tx_handle, 0);
}
else
{
printf("radio busy\r\n");
}
}
/*****************************************************************************
* Function : vtask_mac_data_process
* Description : none
* Input : void *ptr
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170419
* Author : barry
* Modification: Created function
*****************************************************************************/
void vtask_mac_data_process(void *ptr)
{
u16 flag;
radioQueue = xQueueCreate(1, 2);
u32 radio_rx_timeout = 4000/portTICK_RATE_MS;
radio_tx_handle = xTimerCreate( "radio tx timer", RADIO_TX_TIMEOUT, pdFALSE, 0, radio_tx_timeout_callback);
Lora_lowPower_Init(period);
hal_InitRF();
SX1276LoRa_Receive_Packet(0, false);
for (;;)
{
flag = 0;
if (xQueueReceive(radioQueue, &flag, DELAY_HOUR_TIME) == pdPASS)
{
if (flag == RF_VALID_HEAD)
{
printf("valid head\r\n");
if (xQueueReceive(radioQueue, &flag, radio_rx_timeout) == pdPASS)
{
printf("RSSI = %.2f, SNR = %d\r\n",RxPacketRssiValue, RxPacketSnr);
if (flag == RF_RX_SUCCESS)
{
printf("RF Rx:");
printf_buf(g_RF_LoRa.rf_DataBuffer, g_RF_LoRa.rf_RxPacketSize);
xSemaphoreGive(port_radio_Semaphore);
}
else if (flag == RF_RX_FAILED)
{
printf("crc err\r\n");
}
else
{
printf("RF RX timeout\r\n");
}
}
SX1276LoRa_Receive_Packet(0, false);
}
else if ( (flag == RF_RX_SUCCESS) || (flag == RF_RX_FAILED) || (flag == RF_TX_SUCCESS) )
{
if (flag == RF_TX_SUCCESS)
{
xTimerStop(radio_tx_handle,100);
printf("tx done\r\n");
}
else if (flag == RF_RX_SUCCESS)
{
printf("RF Rx:");
printf_buf(g_RF_LoRa.rf_DataBuffer, g_RF_LoRa.rf_RxPacketSize);
xSemaphoreGive(port_radio_Semaphore);
}
else
{
printf("rx crc err\r\n");
}
SX1276LoRa_Receive_Packet(0, false);
}
}
else
{
//此处可以做成绝对复位射频功能
hal_InitRF();
SX1276LoRa_Receive_Packet(0, false);
printf("reset RF\r\n");
}
}
}
/*****************************************************************************
* Function : get_lora_status
* Description : none
* Input : ST_irqFlag irq_flag
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170418
* Author : barry
* Modification: Created function
*****************************************************************************/
u8 get_lora_status(ST_irqFlag irq_flag)
{
u8 rf_status = RF_ERR;
u8 cur_chl;
if ( (irq_flag.RxDone == 1) || (irq_flag.TxDone == 1) || (irq_flag.CadDone == 1) || (irq_flag.RxTimeout == 1))
{
hal_DIOx_ITConfig(all,DISABLE);
hal_sRF_ClearAllRF_IT();
SX1276Write( REG_LR_IRQFLAGS, 0xFF);
}
if (irq_flag.RxDone == 1)
{
SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY);
RxPacketSnr = getPacketSnr();
RxPacketRssiValue = get_RxPacketRssi(RxPacketSnr);
if (irq_flag.PayloadCrcError == 0)
{
g_RF_LoRa.rf_state = RFLR_STATE_RX_DONE;
receiveRxData(g_RF_LoRa.rf_DataBuffer, &g_RF_LoRa.rf_RxPacketSize);
rf_status = RF_RX_SUCCESS;
}
else
{
g_RF_LoRa.rf_state = RFLR_STATE_RX_ERR;
rf_status = RF_RX_FAILED;
}
}
else if (irq_flag.TxDone == 1)
{
switch_Rx();
g_RF_LoRa.rf_state = RFLR_STATE_TX_DONE;
rf_status = RF_TX_SUCCESS;
}
else if (irq_flag.ValidHeader == 1)
{
hal_DIOx_ITConfig(3,DISABLE);
// SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_VALIDHEADER);
if (g_RF_LoRa.rf_state == RFLR_STATE_RX_RUNNING)
{
g_RF_LoRa.rf_state = RFLR_STATE_RX_RECEIVEING;
}
rf_status = RF_VALID_HEAD;
}
else if (irq_flag.CadDone == 1)
{
if (irq_flag.CadDetected == 1)
{
rf_status = RF_CAD_DETECT;
}
else
{
//SX1276StartSleep();
}
}
else if (irq_flag.RxTimeout == 1)
{
rf_status = RF_PREAMBLE_TIMEOUT;
}
else if (irq_flag.FhssChangeChannel == 1)
{
/* 此处表明在单次接收时是先收到头再跳频,在连续接收模式下是先跳频再收到头,需要验证 */
/* 在接收模式下,谁先发生就算接收开始了,并不是接收到头才算接收开始,
也可以处理为接收到头算接收开始,连续模式下可能头也是跳频发送的*/
/* 统一为接收到头才算接收开始 */
SX1276Write( REG_LR_IRQFLAGS, RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL );
SX1276Read( REG_LR_HOPCHANNEL, &cur_chl);
set_hop_Channel(cur_chl);
}
return rf_status;
}
#ifdef USE_LORA_MODE
/*****************************************************************************
Prototype : EXTI4_15_IRQHandler
Description : EXTI11 for valid header
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void EXTI15_10_IRQHandler(void)
{
BaseType_t pxHigherPriorityTaskWoken = pdFALSE;
ST_irqFlag irq_flag;
u16 rf_flag;
bool need_radio_process = FALSE;
/* tx done, rx done, cad done */
if(EXTI_GetITStatus(DIO0_IRQ) != RESET)
{
need_radio_process = TRUE;
EXTI_ClearITPendingBit(DIO0_IRQ);
}
else if (EXTI_GetITStatus(DIO1_IRQ) != RESET) /* Rx timeOut */
{
need_radio_process = TRUE;
EXTI_ClearITPendingBit(DIO1_IRQ);
}
if ( need_radio_process == TRUE)
{
SX1276Read( REG_LR_IRQFLAGS, (u8*)&irq_flag);
rf_flag = get_lora_status(irq_flag);
if (rf_flag != 0)
{
xQueueSendToBackFromISR( radioQueue, &rf_flag, &pxHigherPriorityTaskWoken);
portYIELD_FROM_ISR( pxHigherPriorityTaskWoken );
}
}
}
/*****************************************************************************
* Function : EXTI0_IRQHandler
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170419
* Author : barry
* Modification: Created function
*****************************************************************************/
void EXTI0_IRQHandler(void)
{
BaseType_t pxHigherPriorityTaskWoken = pdFALSE;
ST_irqFlag irq_flag;
u16 rf_flag;
bool need_radio_process = FALSE;
if (EXTI_GetITStatus(DIO3_IRQ) != RESET)
{
need_radio_process= TRUE;
EXTI_ClearITPendingBit(DIO3_IRQ);
}
if ( need_radio_process == TRUE)
{
SX1276Read( REG_LR_IRQFLAGS, (u8*)&irq_flag);
rf_flag = get_lora_status(irq_flag);
if (rf_flag != 0)
{
xQueueSendToBackFromISR( radioQueue, &rf_flag, &pxHigherPriorityTaskWoken);
portYIELD_FROM_ISR( pxHigherPriorityTaskWoken );
}
}
}
#endif

8
APP/PHY.h Normal file
View File

@@ -0,0 +1,8 @@
#include "include.h"
#include "hal_radio.h"
void vtask_mac_data_process(void *ptr);
void mac_data_req(u8 *buf, u8 length);
u8 * get_RF_bufPtr(void);
u8 get_RF_bufLen();
void read_radio_rssi(void);

223
APP/Rtc.c Normal file
View File

@@ -0,0 +1,223 @@
/**
******************************************************************************
* @file hal_timer.c
* @author William Liang
* @version V1.0.0
* @date 07/18/2013
* @brief This file contains the initialization and handle of the timer.
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "Rtc.h"
#include "uart.h"
#include "Mem.h"
#include "Led.h"
/** @addtogroup Timer
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static const u8 daysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
u32 g_SystickCounter = 0;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief Initialize the RTC.
* @param None.
* @retval None.
*/
void RTC_Init(void)
{
/* Enable PWR and BKP clocks */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
/* Allow access to BKP Domain */
PWR_BackupAccessCmd(ENABLE);
/* Select HSE as RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128);
//BKP_DeInit();
if (BKP_ReadBackupRegister(RTC_VALID_REG) != RTC_VALID_FLAG)
{
/* Enable RTC Clock */
RCC_RTCCLKCmd(ENABLE);
//RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128);
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set RTC prescaler: set RTC period to 1sec */
RTC_SetPrescaler(RTC_PRESCALER); /* RTC period = RTCCLK/RTC_PR = (8 MHz /128)/(RTC_PRESCALER+1) */
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set RTC Valid Flag in the BKP */
BKP_WriteBackupRegister(RTC_VALID_REG, RTC_VALID_FLAG);
/* Initialize current time to 2010/1/1 00:00:00 */
Time_Set(17, 8, 17, 8, 23, 42);
}
else
{
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
}
}
/**
* @brief convert current time format from the total seconds since 2010 to the time struct.
* @param utcTime: input variable, total seconds since 2010.
* @retval time: the struct of current time.
*/
sTime TimetoBCD(u32 utcTime)
{
sTime time;
u32 secondsSince2010 = (utcTime - START_OF_2010);
u16 daysSince2010 = (secondsSince2010 >> 2) / (u16)(SECS_IN_DAY >> 2);
u32 secondInDay = secondsSince2010 - ((u32)daysSince2010) * SECS_IN_DAY;
u8 yearsSince2000 = 0;
u16 daysRemaining = daysSince2010;
u16 accum = 10;//We start from 2010
u8 phase;
for (phase = 0; phase < 2; phase++)
{
while (1)
{
u16 tick;
if (phase == 0)
{
tick = ((accum & 0x03) == 0 ? 366 : 365);
}
else
{
tick = daysInMonth[accum];
if ((accum == 1) && ((yearsSince2000 & 0x03) == 0))
{
tick++;
}
}
if (tick <= daysRemaining)
{
daysRemaining -= tick;
accum++;
}
else
{
if (phase == 0)
{
yearsSince2000 = accum;
accum = 0;
}
break;
}
}
}
time.year = yearsSince2000;
time.month = accum + 1;
time.day = daysRemaining + 1;
time.hour = secondInDay / 3600;
time.minute = (secondInDay - time.hour * 3600) / 60;
time.second = (secondInDay - time.hour * 3600) % 60;
return time;
}
/**
* @brief Set the current time.
* @param year: input variable, the year of current time.
* @param month: input variable, the month of current time.
* @param day: input variable, the day of current time.
* @param hour: input variable, the hour of current time.
* @param min: input variable, the minute of current time.
* @param sec: input variable, the second of current time.
* @retval None.
*/
void Time_Set(u8 year, u8 month, u8 day, u8 hour, u8 min, u8 sec)
{
u32 secs = START_OF_2010 + (u32) hour * 3600 + (u32) min * 60 + (u32) sec;
u16 days = day - 1;
u8 i;
//printf("设置系统时间 %02d-%02d-%02d %02d:%02d:%02d\r\n", year, month, day, hour, min, sec);
for (i = 10; i < year; i++)
{
days += 365;
if ((i & 0x03) == 0)
{
days++;
}
}
for (i = 0; i < month - 1; i++)
{
days += daysInMonth[i];
}
if ((month > 2) && ((year & 0x03) == 0))
{
days++;
}
secs += ((u32) days) * SECS_IN_DAY;
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Change the current time */
RTC_SetCounter(secs);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
/**
* @brief Print the current time.
* @param None.
* @retval None.
*/
void Time_Get(void)
{
sTime CurrentTime;
CurrentTime = TimetoBCD(RTC_GetCounter());
printf("获取系统时间 %02d-%02d-%02d %02d:%02d:%02d %d\r\n",
CurrentTime.year,
CurrentTime.month,
CurrentTime.day,
CurrentTime.hour,
CurrentTime.minute,
CurrentTime.second,
RTC_GetCounter()
);
}
void get_timeBCD(sTime * CTime)
{
sTime CurrentTime = TimetoBCD(RTC_GetCounter());
MemCpy(CTime, &CurrentTime, sizeof(sTime));
}
/******************* (C) COPYRIGHT 2013 Robulink Technology Ltd.*****END OF FILE****/

47
APP/Rtc.h Normal file
View File

@@ -0,0 +1,47 @@
/**
******************************************************************************
* @file hal_rtc.h
* @author William Liang
* @version V1.0.0
* @date 05/05/2014
* @brief This file contains the headers of the rtc handlers.
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _RTC_H_
#define _RTC_H_
/* Includes ------------------------------------------------------------------*/
#include "Basedefine.h"
#define START_OF_2010 0
#define SECS_IN_DAY 86400 // 24*3600
#define RTC_PRESCALER (HSE_VALUE / 128 - 1)
#define RTC_VALID_REG BKP_DR1
#define RTC_VALID_FLAG 0xA5A5
#define GetRTCTime RTC_GetCounter
//ʱ¼ä
typedef struct
{
u8 year;
u8 month;
u8 day;
u8 hour;
u8 minute;
u8 second;
}sTime;
/* Exported functions ------------------------------------------------------- */
void RTC_Init(void);
sTime TimetoBCD(u32 utcTime);
void Time_Set(u8 year, u8 month, u8 day, u8 hour, u8 min, u8 sec);
void Time_Get(void);
void get_timeBCD(sTime * CTime);
#endif /* __HAL_TIMER_H__ */
/******************* (C) COPYRIGHT 2013 Robulink Technology Ltd.*****END OF FILE****/

415
APP/WaterMeterManager.c Normal file
View File

@@ -0,0 +1,415 @@
#include "WaterMetermanager.h"
#include "storage.h"
#include "bl24c512.h"
#include "include.h"
#include "sx1276-Fsk.h"
#include "rtc_ext.h"
u16 read_maintain_time_ram(void);
void Clear485PortINValidCount( void );
//QueueHandle_t RfSendTask;
//APP_OPER_COLLECT_MAN_UNIT_TYPE ManXTCollecterUnit; //转换器控制新天采集器数据以及任务单元
//extern u8 HNSJ_chl ;
static SJ_ADDRLIST_MANUNIT_TYPE SJManager = {0};
/*------------------------------------------------------------------------------
------------------------------------------------------------------------------
抄表数据以及水表档案存储读取管理任务
------------------------------------------------------------------------------
------------------------------------------------------------------------------
*/
//读取水表地址档案数量
bool ReadAddrListLength( u8* Length )
{
u8 TempBuff[5] = {0x00};
SP_SJ_ADDRLIST_MANUNIT_TYPE Pload = (SP_SJ_ADDRLIST_MANUNIT_TYPE)TempBuff;
if(Pload->ValidFlag == SHUANGJIA_MANAGERUNIT_VALID)
{
SJManager.ValidFlag = SHUANGJIA_MANAGERUNIT_VALID;
*Length = Pload->AddrSum;
return true;
}
else
{
*Length = 0;
return false;
}
}
//更新水表地址档案数量
bool WriteAddrListLength( u8 Length )
{
return true;
}
//更新水表地址地址和数据
bool WriteAddrListDataInfo( LPMETER_STRUCT_UNITTYPE Pload )
{
return true;
}
/*根据地址信息,获取某块水表的数据*/
//当数据链表内已经保存当前水表地址时检查该水表数据是否有效当无效时返回00表示从未监控到该水表数据
//当数据链表内未保存当前水表地址时需要保存当前水表地址并且标记数据区域无效且返回00方便集中器继续执行抄表动作。
//三种情况。1.没有水表地址2.有水表地址但是数据无效3.有水表地址,而且数据有效
//save :是否保留当前地址信息
RETURN_TYPE ReadAddrListDataInfo( LPMETER_STRUCT_UNITTYPE Pload ,bool Save)
{
u16 index = 0x00;
RETURN_TYPE ret = NKNOW;
if(SJManager.ValidFlag != SHUANGJIA_MANAGERUNIT_VALID)
{
return ret;
}
for(index = 0x00; index < SJManager.AddrSum; index ++)
{
if((SJManager.Info[index].Index == index) && (SJManager.Info[index].Addr.AddrValidFlag == VALID_FLAG))
if(MemCmp(Pload->Addr.Address,SJManager.Info[index].Addr.Address,ADDRESS_LENGTH) == 0x00)
{
if(SJManager.Info[index].Data.DataValidFlag == VALID_FLAG)
{
if(SJManager.Info[index].CRCV == GetCRC16(&SJManager.Info[index].Index, sizeof(METER_STRUCT_UNITTYPE) - sizeof(SJManager.Info[index].CRCV)))
{
ret = EXIST_ADDR_DATA_VALID;
Pload->Index = index;
Pload->Data.BCD_Decimal = SJManager.Info[index].Data.BCD_Decimal;
Pload->Data.BCD_Integer_L = SJManager.Info[index].Data.BCD_Integer_L;
Pload->Data.BCD_Integer_M = SJManager.Info[index].Data.BCD_Integer_M;
Pload->Data.BCD_Integer_H = SJManager.Info[index].Data.BCD_Integer_H;
Pload->Data.FailCount = SJManager.Info[index].Data.FailCount;
Pload->Data.StateFlag0 = SJManager.Info[index].Data.StateFlag0;
Pload->Data.StateFlag1 = SJManager.Info[index].Data.StateFlag1;
memcpy(&Pload->Index,&SJManager.Info[index].Index, sizeof(METER_STRUCT_UNITTYPE));
return ret;
}
else
{
Pload->Index = index;
Pload->Data.FailCount = SJManager.Info[index].Data.FailCount;
memcpy(&Pload->Index,&SJManager.Info[index].Index, sizeof(METER_STRUCT_UNITTYPE));
ret = EXIST_ADDR_CRC_ERROR;
return ret;
}
}
else
{
Pload->Index = index;
Pload->Data.FailCount = SJManager.Info[index].Data.FailCount;
memcpy(&Pload->Index,&SJManager.Info[index].Index, sizeof(METER_STRUCT_UNITTYPE));
ret = EXIST_ADDR_DATA_INVALID; //存在地址但是数据无效
return ret;
}
}
}
// u8 Index;
// METER_ADDR_UNITTYPE Addr;
// METER_DATA_UNITTYPE Data;
// u16 CRCV;
if( Save == false) return NO_EXIST_ADDR;
SJManager.AddrSum ++;
SJManager.Info[index].Index = index;
SJManager.Info[index].Addr.AddrValidFlag = VALID_FLAG;
MemCpy(SJManager.Info[index].Addr.Address,Pload->Addr.Address,ADDRESS_LENGTH);
SJManager.Info[index].Data.DataValidFlag = INVALID_FLAG;
SJManager.Info[index].Data.BCD_Decimal = 0x00;
SJManager.Info[index].Data.BCD_Integer_H = 0x00;
SJManager.Info[index].Data.BCD_Integer_L = 0x00;
SJManager.Info[index].Data.BCD_Integer_M = 0x00;
//当前地址不存在
SJManager.Info[index].Data.FailCount = 0x00;
Pload->Data.BCD_Decimal = SJManager.Info[index].Data.BCD_Decimal;
Pload->Data.BCD_Integer_L = SJManager.Info[index].Data.BCD_Integer_L;
Pload->Data.BCD_Integer_M = SJManager.Info[index].Data.BCD_Integer_M;
Pload->Data.BCD_Integer_H = SJManager.Info[index].Data.BCD_Integer_H;
SJManager.Info[index].CRCV = GetCRC16(&SJManager.Info[index].Index, sizeof(METER_STRUCT_UNITTYPE) - sizeof(SJManager.Info[index].CRCV));
WriteAddrListLength(SJManager.AddrSum);
WriteAddrListDataInfo(&SJManager.Info[index]);
return NO_EXIST_ADDR;
}
void ReadSystemMeterAddrList( void )
{
//u8 Length = 0x00;
u8 index = 0x00;
//if(ReadAddrListLength( &Length ) == false)
if(SJManager.AddrSum == 00)
{
printf("Water Meter SUM is 0\r\n");
return ;
}
else
{
printf("Water Meter SUM is %03d\r\n",SJManager.AddrSum);
}
printf("\r\n-序号---------地址-----------水表示数---------水表状态---------抄表时间\r\n");
for(index = 0x00 ; index < SJManager.AddrSum; index ++)
{
if(SJManager.Info[index].Addr.AddrValidFlag == VALID_FLAG)
{
printf(" %03d: %02X%02X%02X%02X%02X%02X%02X",index,SJManager.Info[index].Addr.Address[6],SJManager.Info[index].Addr.Address[5],SJManager.Info[index].Addr.Address[4],SJManager.Info[index].Addr.Address[3],SJManager.Info[index].Addr.Address[2],SJManager.Info[index].Addr.Address[1],SJManager.Info[index].Addr.Address[0]);
if(SJManager.Info[index].Data.DataValidFlag == VALID_FLAG)
{//新版本转换器使用的是内部时钟
printf(" %02X%02X%02X.%02X %02X%02X %02d.%02d.%02d %02d:%02d:%02d\r\n",
SJManager.Info[index].Data.BCD_Integer_H,SJManager.Info[index].Data.BCD_Integer_M,SJManager.Info[index].Data.BCD_Integer_L,SJManager.Info[index].Data.BCD_Decimal,SJManager.Info[index].Data.StateFlag0,SJManager.Info[index].Data.StateFlag1,SJManager.Info[index].Data.TYaer,SJManager.Info[index].Data.TMonth,SJManager.Info[index].Data.TDay,SJManager.Info[index].Data.THour,SJManager.Info[index].Data.TMin,SJManager.Info[index].Data.TSec);
}
else
{
printf(" --------\r\n");
}
vTaskDelay( 50 / portTICK_RATE_MS );
}
}
}
bool manager_get_data(u8 * addr,u8* data,u8* state,u8 * state2)
{
for(u8 i = 0;i<SJManager.AddrSum;i++)
{
// if(SJManager.Info[i].Addr.AddrValidFlag == VALID_FLAG)
{
if(0 == memcmp(addr,SJManager.Info[i].Addr.Address,6))
{
if(SJManager.Info[i].Data.DataValidFlag == VALID_FLAG)
{
data[0] = SJManager.Info[i].Data.BCD_Decimal;
data[1] = SJManager.Info[i].Data.BCD_Integer_L;
data[2] = SJManager.Info[i].Data.BCD_Integer_M;
data[3] = SJManager.Info[i].Data.BCD_Integer_H;
* state = SJManager.Info[i].Data.StateFlag0;
* state2 = SJManager.Info[i].Data.StateFlag1;
return true;
}
}
}
}
return false;
}
bool UpdateRFReceiveData(u8* addr,u8* data,u8* status)
{
RETURN_TYPE ret = NKNOW;
sTime Temp_Time;
bool Save = false;
u8 TempBuff[sizeof(METER_STRUCT_UNITTYPE)] = {0x00};
LPMETER_STRUCT_UNITTYPE Pstr = (LPMETER_STRUCT_UNITTYPE)TempBuff;
MemCpy(Pstr->Addr.Address,addr,ADDRESS_LENGTH);
//不能保存当前接收的地址,只做读取当前地址的水表数据检查
ret = ReadAddrListDataInfo( Pstr ,false);
if(EXIST_ADDR_DATA_VALID == ret)
{
if(MemCmp(&Pstr->Data.BCD_Decimal,data,METER_DATA_MAX_SIZE) == 0x00)
{
//return false;
Save = true;
}
else
{
Save = true;
}
}
else if((EXIST_ADDR_DATA_INVALID == ret) || (EXIST_ADDR_CRC_ERROR == ret))
{
Save = true;
}
else
{
return false;
}
if(true == Save)
{
Clear485PortINValidCount();
//GetExternClockTime(&Temp_Time);
get_timeBCD(&Temp_Time);
Pstr->Addr.AddrValidFlag = VALID_FLAG;
Pstr->Data.DataValidFlag = VALID_FLAG;
MemCpy(&Pstr->Data.BCD_Decimal,data,METER_DATA_MAX_SIZE);
Pstr->Data.FailCount = 0x00;
Pstr->Data.StateFlag0 = status[0];
Pstr->Data.StateFlag1 = status[1];
Pstr->Data.TYaer = Temp_Time.year;
Pstr->Data.TMonth= Temp_Time.month;
Pstr->Data.TDay = Temp_Time.day;
Pstr->Data.THour = Temp_Time.hour;
Pstr->Data.TMin = Temp_Time.minute;
Pstr->Data.TSec = Temp_Time.second;
Pstr->CRCV = GetCRC16(TempBuff, sizeof(METER_STRUCT_UNITTYPE) - sizeof(Pstr->CRCV));
MemCpy(&SJManager.Info[Pstr->Index].Index,&Pstr->Index,sizeof(METER_STRUCT_UNITTYPE));
WriteAddrListDataInfo( Pstr );
return true;
}
return false;
}
bool UpdataWMRMFailCounterProcess(u8* addr)
{
RETURN_TYPE ret = NKNOW;
//sTime Temp_Time;
bool Save = true;
u8 TempBuff[sizeof(METER_STRUCT_UNITTYPE)] = {0x00};
LPMETER_STRUCT_UNITTYPE Pstr = (LPMETER_STRUCT_UNITTYPE)TempBuff;
MemCpy(Pstr->Addr.Address,addr,ADDRESS_LENGTH);
//不能保存当前接收的地址,只做读取当前地址的水表数据检查
ret = ReadAddrListDataInfo( Pstr ,false);
if( (ret == EXIST_ADDR_DATA_VALID) || (ret == EXIST_ADDR_CRC_ERROR) || (ret == EXIST_ADDR_DATA_INVALID) )
{
Pstr->Data.FailCount ++;
if(true == Save)
{
//GetExternClockTime(&Temp_Time);
//get_timeBCD(&Temp_Time);
//Pstr->Addr.AddrValidFlag = VALID_FLAG;
Pstr->CRCV = GetCRC16(TempBuff, sizeof(METER_STRUCT_UNITTYPE) - sizeof(Pstr->CRCV));
MemCpy(&SJManager.Info[Pstr->Index].Index,&Pstr->Index,sizeof(METER_STRUCT_UNITTYPE));
//WriteAddrListDataInfo( Pstr );
return true;
}
}
return false;
}
void CopyEEPROMInfoToRAM( void )
{
}
void SJMeterInfoInit( void )
{
if(ReadAddrListLength( &SJManager.AddrSum ) == false)
{
SJManager.ValidFlag = SHUANGJIA_MANAGERUNIT_VALID;
WriteAddrListLength( 00 );
return ;
}
CopyEEPROMInfoToRAM( );
}
void ClearMeterInfo( void )
{
SJManager.AddrSum = 0x00;
WriteAddrListLength( 00 );
MemSet((u8*)&SJManager.Info[0].Index,0x00, sizeof(METER_STRUCT_UNITTYPE)*ADDR_LIST_LENGTH);
printf("Success !!\r\n");
}
void ClearMeterInfo_realdl( void )
{
SJManager.AddrSum = 0;
}
u8 GetCurrentAddrListLength( void )
{
return SJManager.AddrSum;
}
bool CheckDataStoreTime(u8* CurTim,u8* StoreTime,u32 MaxT)
{
sTime * curt = (sTime *)CurTim;
PLst_rtc_ext storet = (PLst_rtc_ext)StoreTime;
//u32 curt_hour = (BCDToHex(curt->year) * 365 * 24) + (BCDToHex(curt->month) * 30 * 24) + (BCDToHex(curt->day) * 24) + BCDToHex(curt->hour);
u32 curt_hour = ((curt->year) * 365 * 24) + ((curt->month) * 30 * 24) + ((curt->day) * 24) + (curt->hour);//当前时间使用的是内部RTC不是BCD码
//u32 storet_hour = (BCDToHex(storet->year) * 365 * 24) + (BCDToHex(storet->month) * 30 * 24) + (BCDToHex(storet->day) * 24) + BCDToHex(storet->hour);
u32 storet_hour = ((storet->year) * 365 * 24) + ((storet->month) * 30 * 24) + ((storet->day) * 24) + (storet->hour);
if(curt_hour > (storet_hour + MaxT))
{
return false;
}
else if(curt_hour < storet_hour)
{
return false;
}
else
{
return true;
}
}
void ClearMeterDataTimeOuttime( void )
{
u8 index = 0x00;
sTime Temp_Time;
//GetExternClockTime(&Temp_Time);
get_timeBCD(&Temp_Time);
for(index = 0x00 ; index < SJManager.AddrSum; index ++)
{
if( (SJManager.Info[index].Addr.AddrValidFlag == VALID_FLAG) && (SJManager.Info[index].Data.DataValidFlag == VALID_FLAG) )
{
if(CheckDataStoreTime((u8*)&Temp_Time.year,&SJManager.Info[index].Data.TSec,read_maintain_time_ram()) == false)
{
SJManager.Info[index].Data.DataValidFlag = INVALID_FLAG;
SJManager.Info[index].Data.FailCount = 0x00;
}
}
}
}

125
APP/WaterMetermanager.h Normal file
View File

@@ -0,0 +1,125 @@
#ifndef WATERMETER_MANAGER_H__
#define WATERMETER_MANAGER_H__
#include "include.h"
#define SHUANGJIA_MANAGERUNIT_VALID (0x12345679)
#define ADDRESS_LENGTH (7)
#define METER_DATA_MAX_SIZE (4)
#define ADDR_LIST_LENGTH (0xFF)
#define VALID_FLAG (0xAA)
#define INVALID_FLAG (0x55)
#pragma pack(1)
typedef struct
{
u8 AddrValidFlag;
u8 Address[ADDRESS_LENGTH];
}METER_ADDR_UNITTYPE,* LPMETER_ADDR_UNITTYPE;
typedef struct
{
//u8 Data[METER_DATA_MAX_SIZE];
u8 DataValidFlag;
u8 BCD_Decimal;
u8 BCD_Integer_L;
u8 BCD_Integer_M;
u8 BCD_Integer_H;
u8 FailCount;//抄表失败计数
u8 StateFlag0;
u8 StateFlag1;
u8 TSec;
u8 TMin;
u8 THour;
u8 TDay;
u8 TMonth;
u8 TYaer;
}METER_DATA_UNITTYPE,* LPMETER_DATA_UNITTYPE;
typedef struct
{
u8 Index;
METER_ADDR_UNITTYPE Addr;
METER_DATA_UNITTYPE Data;
u16 CRCV;
}METER_STRUCT_UNITTYPE, * LPMETER_STRUCT_UNITTYPE;
typedef enum
{
NKNOW = 0x00, //未知
EXIST_ADDR_DATA_INVALID, //存在地址但是数据无效
EXIST_ADDR_DATA_VALID, //存在地址但是数据有效
EXIST_ADDR_CRC_ERROR, //存在地址但数据CRC校验错误
ADDR_OVERFLOW,
NO_EXIST_ADDR, //不存在地址
}RETURN_TYPE;
//新天采集器地址档案数据管理单元
typedef struct
{
u32 ValidFlag;
u8 AddrSum; //地址总长度
METER_STRUCT_UNITTYPE Info[ADDR_LIST_LENGTH]; //当前数据存储信息
}SJ_ADDRLIST_MANUNIT_TYPE,* SP_SJ_ADDRLIST_MANUNIT_TYPE;
#pragma pack()
void SJMeterInfoInit( void );
bool UpdateRFReceiveData(u8* addr,u8* data,u8* status);
RETURN_TYPE ReadAddrListDataInfo( LPMETER_STRUCT_UNITTYPE Pload ,bool Save);
void ClearMeterDataTimeOuttime( void );
bool UpdataWMRMFailCounterProcess(u8* addr);
#endif //WATERMETER_MANAGER_H__

135
APP/addr.c Normal file
View File

@@ -0,0 +1,135 @@
#include "addr.h"
#include "Mem.h"
#include "General.h"
#include "Flash.h"
extern void addr_set(u8 * addr);
static u8 broadcast_addr[6] = {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
static u8 broadcast_addr_1[6] = {0x99, 0x99, 0x99, 0x99, 0x99, 0x99};
static u8 local_addr[6] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11};
u8 cmp_addr(u8 *addr)
{
if (cmp_datas(addr, local_addr, 6))
{
return ADDR_EQ;
}
else if (cmp_datas(addr, broadcast_addr, 6))
{
return BRODCAST_ADDRAA_EQ;
}
else if (cmp_datas(addr, broadcast_addr_1, 6))
{
return BRODCAST_ADDR99_EQ;
}
else
{
return ADDR_NEQ;
}
}
u8 * read_broadcast_addr(void)
{
return broadcast_addr;
}
/*****************************************************************************
Prototype : set_addr
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void set_addr(u8 *newaddr)
{
u8 local_temp[8];
u16 crc;
//ÊäÈëÊÇÕýÐò£¬´æ´¢·´Ðò
//memcpy(local_addr, newaddr, 6);
//memcpy(local_temp, newaddr, 6);
memset(local_temp,0,sizeof(local_temp));
memset(local_addr,0,sizeof(local_addr));
for (u8 i = 0; i < 6; i++)
{
local_addr[i] = newaddr[5 - i];
local_temp[i] = newaddr[5 - i];
}
// memmove(local_addr,&newaddr[1],5);
// memmove(local_temp,&newaddr[1],5);
// addr_set(&newaddr[1]);
crc = GetCRC16(local_addr, 6);
local_temp[6] = crc & 0xFF;
local_temp[7] = (u8)((crc >> 8) & 0xFF);
if (STM32_FlashPageErase(FLASH_LOCAL_ADDR_ADDRESS) == FLH_SUCCESS)
{
STM32_FlashWrite( FLASH_LOCAL_ADDR_ADDRESS, local_temp, 8);
}
}
/*****************************************************************************
Prototype : read_addr
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
bool read_addr(u8 *addrbuf )
{
u8 tempaddr[8];
u16 crc;
memcpy(&tempaddr, (u8*)FLASH_LOCAL_ADDR_ADDRESS, sizeof(tempaddr));
crc = GetCRC16(tempaddr, 6);
if (crc == (tempaddr[6] + tempaddr[7]*256) )
{
memcpy(addrbuf, tempaddr, 6);
return TRUE;
}
else
{
memcpy(addrbuf, local_addr, 6);
return FALSE;
}
}
void init_local_addr(void)
{
u8 temp[6];
if (read_addr(temp) )
{
memcpy(local_addr,temp, 6);
return;
}
}
u8 * addr_get()
{
return local_addr;
}

27
APP/addr.h Normal file
View File

@@ -0,0 +1,27 @@
#ifndef __ADDR_H__
#define __ADDR_H__
#include "Basedefine.h"
#define FLASH_LOCAL_ADDR_ADDRESS 0x08004c00
enum
{
ADDR_NEQ = 0,
ADDR_EQ,
BRODCAST_ADDRAA_EQ,
BRODCAST_ADDR99_EQ
};
bool cmp_datas(u8 * buf1, u8* buf2, u8 length);
u8 cmp_addr(u8 *addr);
void set_addr(u8 *newaddr);
bool read_addr(u8 *addrbuf);
u8 * read_broadcast_addr(void);
void init_local_addr(void);
bool read_unique_id(u8 * id);
#endif

59
APP/apl.c Normal file
View File

@@ -0,0 +1,59 @@
/**
******************************************************************************
* @file apl.c
* @author William Liang
* @version V1.0.0
* @date 07/26/2013
* @brief This file contains application layer task and the initializtion of the variable.
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "Basedefine.h"
#include "apl.h"
//应用层版本
// __root 保证没有使用的函数或者变量也能够包含在目标代码中
__root const Manufacturer_Version aplVersion =
{
{'H', 'T',},//厂商代码
{'T', 'X'},//芯片代码,表示全部所有共计8种转换器协议
0x14, 0x12, 0x21,//日月年
{0x09, 0x02}//版本
};
const Manufacturer_Version * get_apl_version_ptr(void)
{
return &aplVersion;
}
u8 * get_veryw()
{
return (u8 *)&aplVersion;
}
void ReadVersion(void)
{
u8 buf[sizeof(Manufacturer_Version)];
buf[0] = aplVersion.venderID[0];
buf[1] = aplVersion.venderID[1];
buf[2] = aplVersion.chipID[0];
buf[3] = aplVersion.chipID[1];
buf[4] = aplVersion.date;
buf[5] = aplVersion.month;
buf[6] = aplVersion.year;
buf[7] = aplVersion.version[0];
buf[8] = aplVersion.version[1];
printf("APL Version=%c%c%c%c-%02x%02x%02x-V%02x.%02x\r\n", \
buf[1], buf[0], buf[3], buf[2], buf[6], buf[5], buf[4], buf[8], buf[7]);
}
/************** (C) COPYRIGHT 2013 Robulink Technology Ltd.*****END OF FILE****/

33
APP/apl.h Normal file
View File

@@ -0,0 +1,33 @@
/**
******************************************************************************
* @file apl.h
* @author William Liang
* @version V1.0.0
* @date 07/26/2013
* @brief This file contains the headers of the application layer.
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __APL_H__
#define __APL_H__
#include "Basedefine.h"
typedef struct
{
u8 venderID[2];//const 厂商代码
u8 chipID[2];//const 芯片代码
u8 date;//const 日
u8 month;//const 月
u8 year;//const 年
u8 version[2];//const 版本
}Manufacturer_Version;
const Manufacturer_Version * get_apl_version_ptr(void);
void ReadVersion(void);
#endif /* __APL_H__ */
/******************* (C) COPYRIGHT 2013 Robulink Technology Ltd.*****END OF FILE****/

673
APP/bl24c512.c Normal file
View File

@@ -0,0 +1,673 @@
#include "bl24c512.h"
#include "include.h"
static u32 last_write_time;
bool I2C_eeprom_write_byte( u16 addr, u8 data);
bool I2C_eeprom_Read_byte(u16 addr, u8 *data);
void eeprom_da_mode(bool in_mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = SDA_PIN;
GPIO_InitStructure.GPIO_Mode = (in_mode == TRUE) ? GPIO_Mode_IN_FLOATING : GPIO_Mode_Out_OD;
GPIO_Init(SDA_PIN_PORT, &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = SCL_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(SCL_PIN_PORT , &GPIO_InitStructure );
}
/*************************************************************
函数功能:延时连个指令周期
函数名称delayedus
函数返回:无返回值。
函数参数:延时时间
**************************************************************/
void delayed_ms(u8 n)
{
u32 dy;
u8 i;
for(i=0;i<n;i++)
{
dy=3200;
while(dy!=0)
{dy--;}
}
}
void delayedus(u8 n)
{
u8 i;
for(i=0;i<n;i++);
}
/*************************************************************
函数功能I2C总线复位。
函数名称I2C_Reset。
函数返回:无返回值。
函数参数:无参数
**************************************************************/
void I2C_Reset(void)
{
eeprom_da_mode(SDA_MODE_IN);
while(1)
{
SCL_LOW();
delayedus(1);
SCL_HIGH();
if( GET_SDA() ==1 )
{
break;
}
delayedus(1);
}
eeprom_da_mode(SDA_MODE_OUT);
}
void bl24c512_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(SDA_PIN_CLK | SCL_PIN_CLK , ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = SDA_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(SDA_PIN_PORT , &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = SCL_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(SCL_PIN_PORT , &GPIO_InitStructure );
//I2C_Reset();
}
/*************************************************************
函数功能:产生起始位。
函数名称I2C_GenerateSTART。
函数返回:无返回值。
函数参数:无参数
**************************************************************/
void BL24C512I2C_GenerateSTART(void)
{
SDA_HIGH();//eeprom_da(1);
SCL_HIGH();//eeprom_clk(1);
delayedus(2);
SDA_LOW();//eeprom_da(0);
delayedus(2);
SCL_LOW();//eeprom_clk(0);
delayedus(2);
}
/*************************************************************
函数功能:产生停始位。
函数名称I2C_GenerateSTOP。
函数返回:无返回值。
函数参数:无参数
**************************************************************/
void BL24C512_I2C_GenerateSTOP(void)
{
SDA_LOW();//eeprom_da(0);
delayedus(2);
SCL_HIGH();//eeprom_clk(1);
SDA_LOW();//eeprom_da(0);
delayedus(2);
SDA_HIGH();//eeprom_da(1);
}
void self_test_eeprom(void)
{
char testBuf[] = "test eeprom";
char buf[15] = {0};
I2C_eeprom_write_buf(32896, (u8*)testBuf, sizeof(testBuf));
I2C_eeprom_read_buf( 32896, (u8*)buf, sizeof(testBuf));
if (cmp_datas((u8*)buf, (u8*)testBuf, sizeof(testBuf)))
{
printf("OK\r\n");
}
else
{
printf("ERROR\r\n");
}
}
/*************************************************************
函数功能:检测应答。
函数名称I2C_check_ack。
函数返回:返回值是应答状态。
函数参数:无参数。
**************************************************************/
unsigned char I2C_check_ack(void)
{
unsigned char ack=0;
eeprom_da_mode(SDA_MODE_IN);
SCL_HIGH();//eeprom_clk(1);
delayedus(1);
if(GET_SDA() ==1)
{
ack=0;
}
else
{
ack=1;
}
SCL_LOW();//eeprom_clk(0);
delayedus(1);
eeprom_da_mode(SDA_MODE_OUT);
return ack;
}
/*************************************************************
函数功能:发送一个应答位。
函数名称I2c_send_ack。
函数返回:无返回值。
函数参数:无。
**************************************************************/
void I2c_send_ack(void)
{
SDA_LOW();//eeprom_da(0);
delayedus(1);
SCL_LOW();//eeprom_clk(0);
delayedus(1);
SCL_HIGH();//eeprom_clk(1);
delayedus(1);
SCL_LOW();//eeprom_clk(0);
SDA_HIGH();//eeprom_da(1);
}
/*************************************************************
函数功能发送一个NO应答。
函数名称I2c_send_no_ack。
函数返回:无返回值。
函数参数:无。
*************************************************************/
void I2c_send_no_ack(void)
{
SDA_HIGH();//eeprom_da(1);
delayedus(1);
SCL_LOW();//eeprom_clk(0);
delayedus(1);
SCL_HIGH();//eeprom_clk(1);
delayedus(1);
SCL_LOW();//eeprom_clk(0);
}
/*************************************************************
函数功能I2C发送一个字节。
函数名称I2c_send_byte。
函数返回:无返回值。
函数参数:无。
*************************************************************/
void I2c_send_byte(unsigned char data )
{
unsigned char i;
SCL_LOW(); //eeprom_clk(0);//clk 0
for(i=0;i<8;i++)
{
if((data&0x80)==0x80)
{
SDA_HIGH();//eeprom_da(1);
}
else
{
SDA_LOW(); //eeprom_da(0);
}
SCL_HIGH(); //eeprom_clk(1);//clk 1
delayedus(1);
SCL_LOW(); //eeprom_clk(0);//clk 0
delayedus(1);
data<<=1;
}
delayedus(90);
}
/*************************************************************
函数功能I2C接收一个字节。
函数名称I2c_receive_byte。
函数返回:无返回值。
函数参数:无。
**************************************************************/
unsigned char I2c_receive_byte(void)
{
unsigned char i;
unsigned char rda=0;
eeprom_da_mode(SDA_MODE_IN);
SCL_LOW(); //eeprom_clk(0);//clk 0
delayedus(1);
for(i=0;i<8;i++)
{
rda<<=1;
SCL_HIGH(); //eeprom_clk(1);//clk 1
delayedus(1);
if(GET_SDA() ==1 )
{
rda|=0x01;
}
else
{
rda&=0xFE;
}
SCL_LOW(); //eeprom_clk(0);//clk 0
delayedus(1);
}
eeprom_da_mode(SDA_MODE_OUT);
return rda;
}
/*************************************************************
函数功能EEPROM检测EEPROM是否空闲可以进行读写
函数名称poll_busy。
函数返回:无返回值。
函数参数EEPROM的地址addr 对应写入数据data。
**************************************************************/
bool poll_busy(void)
{
BL24C512I2C_GenerateSTART();
I2c_send_byte(BL24C512ADDR);
if(I2C_check_ack()== 1)
{
BL24C512_I2C_GenerateSTOP();
return TRUE;
}
else
{
BL24C512_I2C_GenerateSTOP();
return FALSE;
}
}
void wait_eeprom_free(void)
{
while( last_write_time + 6/portTICK_RATE_MS > xTaskGetTickCount() );
while (1)
{
if (poll_busy())
{
break;
}
}
}
/*************************************************************
函数功能EEPROM任意地址写一字节。
函数名称I2C_eeprom_write_byte。
函数返回:无返回值。
函数参数EEPROM的地址addr 对应写入数据data。
**************************************************************/
bool I2C_eeprom_write_byte( u16 addr, u8 data)
{
unsigned char addrlow;
unsigned char addrhigh;
addrlow=(unsigned char)addr;
addrhigh=(unsigned char)(addr>>8);
wait_eeprom_free();
BL24C512I2C_GenerateSTART();
I2c_send_byte(BL24C512ADDR);
if(I2C_check_ack()==0)
{
return FALSE;
}
I2c_send_byte(addrhigh);
if(I2C_check_ack()==0)
{
return FALSE;
}
I2c_send_byte(addrlow);
if(I2C_check_ack()==0)
{
return FALSE;
}
I2c_send_byte(data);
if(I2C_check_ack()==0)
{
return FALSE;
}
BL24C512_I2C_GenerateSTOP();
last_write_time = xTaskGetTickCount();
return TRUE;
}
/*************************************************************
函数功能EEPROM任意地址读一字节。
函数名称I2C_eeprom_Read_byte。
函数返回:无返回值。
函数参数EEPROM的地址addr。
**************************************************************/
bool I2C_eeprom_Read_byte(u16 addr, u8 *data)
{
unsigned char devaddr=0;
unsigned char addrlow=0;
unsigned char addrhigh=0;
addrlow=(unsigned char)addr;
addrhigh=(unsigned char)(addr>>8);
wait_eeprom_free();
BL24C512I2C_GenerateSTART();
I2c_send_byte(BL24C512ADDR);
if(I2C_check_ack()==0)
{
return FALSE;
}
I2c_send_byte(addrhigh);
if(I2C_check_ack()==0)
{
return FALSE;
}
I2c_send_byte(addrlow);
if(I2C_check_ack()==0)
{
return FALSE;
}
devaddr=(BL24C512ADDR| 0X01);
BL24C512I2C_GenerateSTART();
I2c_send_byte(devaddr);
if(I2C_check_ack()==0)
{
return FALSE;
}
*data=I2c_receive_byte();
I2c_send_no_ack();
delayedus(1);
BL24C512_I2C_GenerateSTOP();
return TRUE;
}
/*************************************************************
函数功能EEPROM写入数组只能写入小于128byte数据并且不能超过页范围
函数名称I2C_eeprom_write_buf
函数返回:无返回值。
函数参数EEPROM的地址addr。
**************************************************************/
bool I2C_eeprom_write_page(u16 addr, u8 * buf, u8 length)
{
unsigned char addrlow;
unsigned char addrhigh;
addrlow=(unsigned char)addr;
addrhigh=(unsigned char)(addr>>8);
wait_eeprom_free();
BL24C512I2C_GenerateSTART();
I2c_send_byte(BL24C512ADDR);
if(I2C_check_ack()==0)
{
return FALSE;
}
I2c_send_byte(addrhigh);
if(I2C_check_ack()==0)
{
return FALSE;
}
I2c_send_byte(addrlow);
if(I2C_check_ack()==0)
{
return FALSE;
}
for (u8 i = 0; i < length; i++)
{
I2c_send_byte(buf[i]);
if(I2C_check_ack()==0)
{
return FALSE;
}
}
BL24C512_I2C_GenerateSTOP();
last_write_time = xTaskGetTickCount();
return TRUE;
}
/*************************************************************
函数功能EEPROM写入数组只能写入小于128byte数据并且不能超过页范围
函数名称I2C_eeprom_write_buf
函数返回:无返回值。
函数参数EEPROM的地址addr。
**************************************************************/
bool I2C_eeprom_write_buf(u16 startAddr, u8 * buf, u16 length)
{
bl24c512_init();
u16 current_startAddr = startAddr;
u8 first_page_byte = EEPROM_PAGE_SIZE - (startAddr % EEPROM_PAGE_SIZE);
u8 * current_data_ptr = buf;
u16 left_length = length;
u16 integrated_Pages;
u16 end_page_byte;
if (length > first_page_byte)
{
if (!I2C_eeprom_write_page(current_startAddr, current_data_ptr, first_page_byte))
{
return FALSE;
}
current_startAddr = current_startAddr + first_page_byte;
current_data_ptr += first_page_byte;
left_length = length - first_page_byte;
integrated_Pages = left_length / EEPROM_PAGE_SIZE;
end_page_byte = left_length % EEPROM_PAGE_SIZE;
for (u16 i = 0; i < integrated_Pages; i++)
{
if (!I2C_eeprom_write_page(current_startAddr, current_data_ptr, EEPROM_PAGE_SIZE))
{
return FALSE;
}
current_startAddr += EEPROM_PAGE_SIZE;
current_data_ptr += EEPROM_PAGE_SIZE;
}
if (end_page_byte > 0)
{
if (!I2C_eeprom_write_page(current_startAddr, current_data_ptr, end_page_byte))
{
return FALSE;
}
}
}
else
{
if(!I2C_eeprom_write_page(startAddr, buf, length))
{
return FALSE;
}
}
return TRUE;
}
/*************************************************************
函数功能EEPROM读出数组
函数名称I2C_eeprom_write_buf
函数返回:无返回值。
函数参数EEPROM的地址addr。
**************************************************************/
bool I2C_eeprom_read_buf(u16 addr, u8 * buf, u16 length)
{
unsigned char devaddr;
if (length == 0)
{
return FALSE;
}
wait_eeprom_free();
bl24c512_init();
if (I2C_eeprom_Read_byte(addr, buf) == FALSE)
{
return FALSE;
}
length--;
if (length > 0)
{
devaddr=(BL24C512ADDR| 0X01);
BL24C512I2C_GenerateSTART();
I2c_send_byte(devaddr);
if(I2C_check_ack()==0)
{
return FALSE;
}
for (u16 i = 0; i < length; i++)
{
buf[i+ 1] = I2c_receive_byte();
if (i < length - 1)
{
I2c_send_ack();
}
}
I2c_send_no_ack();
BL24C512_I2C_GenerateSTOP();
}
return TRUE;
}

46
APP/bl24c512.h Normal file
View File

@@ -0,0 +1,46 @@
#ifndef _BL24C512_H_
#define _BL24C512_H_
#include "stm32f10x.h"
#include "Basedefine.h"
#define SDA_MODE_IN TRUE
#define SDA_MODE_OUT FALSE
#define EEPROM_PAGE_SIZE 128
#define BL24C512ADDR 0xA0
#define ADDRMAX 65535
#define SDA_PIN GPIO_Pin_7
#define SDA_PIN_PORT GPIOB
#define SDA_PIN_CLK RCC_APB2Periph_GPIOB
#define SCL_PIN GPIO_Pin_6
#define SCL_PIN_PORT GPIOB
#define SCL_PIN_CLK RCC_APB2Periph_GPIOB
#define SDA_HIGH() GPIO_SetBits(SDA_PIN_PORT, SDA_PIN)
#define SDA_LOW() GPIO_ResetBits(SDA_PIN_PORT, SDA_PIN)
#define SCL_HIGH() GPIO_SetBits(SCL_PIN_PORT, SCL_PIN)
#define SCL_LOW() GPIO_ResetBits(SCL_PIN_PORT, SCL_PIN)
#define GET_SDA() GPIO_ReadInputDataBit(SDA_PIN_PORT, SDA_PIN)
void delayedus(u8 n);
void bl24c512_init(void);
bool I2C_eeprom_write_byte(u16 addr, u8 data);
bool I2C_eeprom_Read_byte(u16 addr, u8 *data);
bool I2C_eeprom_write_buf(u16 addr, u8 * buf, u16 length);
bool I2C_eeprom_read_buf(u16 addr, u8 * buf, u16 length);
void I2C_test(void);
void IIC_test_write(void);
void IIC_test_read(void);
void self_test_eeprom(void);
#endif

894
APP/debug_printf.c Normal file
View File

@@ -0,0 +1,894 @@
#include "include.h"
#include "uart.h"
#include <math.h>
#include "debug_printf.h"
#include "Cmd.h"
//信号量 队列 互斥信号量 定时器 进程同步 数据保护
void EdbugPrintProcess(u8* Pstr,u16 len);
#define PEINTFBUFF_LENGTH (800)
#define COM_DEBUG_BUF g_DebugRxBuffer
u8 g_DebugRxBuffer[COM_DEBUG_RX_BUFFER_SIZE];
struct st_uart_port COM_DEBUG_port = USART_PORT_PARAMS(COM_DEBUG, g_DebugRxBuffer,NULL);
//static QueueHandle_t printQueue;
static SemaphoreHandle_t xSemaphore;
static bool printf_switch_open = TRUE;
TaskHandle_t print_task_handle;
u16 head_index = 0;
u16 tail_index = 0;
u8 print_buf[Q_PRINT_LENGTH][Q_PRINT_SIZE + 1] = {0};
bool SendRuning = false;
u16 EdbugPrintBuffLength = 0x00;
u16 EdbugPrintBuffIndex = 0x00;
u16 EdbugPrintBuffRxLength = 0x00;
u16 EdbugPrintBuffRxIndex = 0x00;
u8 EdbugPrintBuff[PEINTFBUFF_LENGTH];
/*****************************************************************************
* Function : close_printf
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
void close_printf(void)
{
printf_switch_open = FALSE;
head_index = 0;
tail_index = 0;
}
/*****************************************************************************
* Function : open_printf
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
void open_printf(void)
{
printf_switch_open = TRUE;
head_index = 0;
tail_index = 0;
}
/*****************************************************************************
* Function : debug_Tx
* Description : none
* Input : u8 *buf
u8 len
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
void debug_Tx(u8 *buf, u8 len)
{
//hal_UartDMATx(&COM_DEBUG_port, buf, len);
EdbugPrintProcess(buf, len);
}
/*****************************************************************************
* Function : reset_debug_buf
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
void reset_debug_buf(void)
{
MemSet(COM_DEBUG_port.data.rxBuf, 0, sizeof(g_DebugRxBuffer));
COM_DEBUG_port.data.rx_len = 0;
}
/*****************************************************************************
* Function : get_debugBuf_len
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
u16 get_debugBuf_len(void)
{
return COM_DEBUG_port.data.rx_len;
}
/*****************************************************************************
* Function : get_debugBuf
* Description : none
* Input : void
* Output : None
* Return : u8
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
u8 * get_debugBuf(void)
{
return COM_DEBUG_port.data.rxBuf;
}
void add_print_buf(u8*buf, u8 length)
{
u8 print_size;
u8 index = 0;
u8 valid_blockNum;
u8 blockNum = (length % Q_PRINT_SIZE == 0)? (length / Q_PRINT_SIZE): (length/ Q_PRINT_SIZE + 1);
if (head_index >= tail_index)
{
if (head_index == tail_index)
{
head_index = 0;
tail_index = 0;
}
valid_blockNum = Q_PRINT_LENGTH - head_index + tail_index;
blockNum = (blockNum >= valid_blockNum) ? valid_blockNum : blockNum;
}
else
{
valid_blockNum = tail_index - head_index;
blockNum = (blockNum >= valid_blockNum) ? valid_blockNum : blockNum;
}
for (u8 i = 0; i < blockNum; i++)
{
if (i == blockNum - 1)
{
print_size = (length % Q_PRINT_SIZE == 0)? Q_PRINT_SIZE: (length % Q_PRINT_SIZE);
}
else
{
print_size = Q_PRINT_SIZE;
}
print_buf[head_index][0] = print_size;
MemCpy(&print_buf[head_index][1], buf + index, print_size);
index += print_size;
head_index = (head_index + 1) % Q_PRINT_LENGTH;
}
}
void UART5_IRQHandler(void)
{
if (USART_GetITStatus(COM_DEBUG_NO, USART_IT_TC) != RESET)
{
if( EdbugPrintBuffIndex >= EdbugPrintBuffLength)
{
USART_ITConfig(COM_DEBUG_NO, USART_IT_TC, DISABLE);
EdbugPrintBuffIndex = 0;
SendRuning = false;
}
else
{
USART_SendData(COM_DEBUG_NO, EdbugPrintBuff[EdbugPrintBuffIndex]);
EdbugPrintBuffIndex ++;
}
}
else if (USART_GetITStatus(COM_DEBUG_NO, USART_IT_RXNE) != RESET)
{
u8 transparent_cmd[] = "transparent 00 ";
u16 len;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if (USART_GetITStatus(COM_DEBUG_NO, USART_IT_RXNE) != RESET)
{
u8 receivedByte = USART_ReceiveData(COM_DEBUG_NO);
if ( COM_DEBUG_port.data.rx_index >= COM_DEBUG_RX_BUFFER_SIZE)
{
COM_DEBUG_port.data.rx_index = 0;
}
if (receivedByte == '\b')//Backspace
{
if ( cmp_datas(transparent_cmd, COM_DEBUG_port.data.rxBuf, 11) )
{
COM_DEBUG_port.data.rxBuf[COM_DEBUG_port.data.rx_index++] = receivedByte;
}
else
{
if (COM_DEBUG_port.data.rx_index > 0)
{
COM_DEBUG_port.data.rx_index--;
}
}
}
else
{
COM_DEBUG_port.data.rxBuf[COM_DEBUG_port.data.rx_index ++] = receivedByte;
if ((receivedByte == '\r') || (receivedByte == '\n'))//Enter
{
if ( cmp_datas(transparent_cmd, COM_DEBUG_port.data.rxBuf, 11) )
{
len = COM_DEBUG_port.data.rxBuf[12] + COM_DEBUG_port.data.rxBuf[13]*256 + sizeof(transparent_cmd) - 1;
if (COM_DEBUG_port.data.rx_index < len)
{
return;
}
}
COM_DEBUG_port.data.rx_len = COM_DEBUG_port.data.rx_index;
COM_DEBUG_port.data.rx_index = 0;
xSemaphoreGiveFromISR( COM_DEBUG_port.xSemaphore, &xHigherPriorityTaskWoken );
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
}
}
}
}
void WaitPrintfEnd( void )
{
if(SendRuning == true)
{
for(u8 tc = 0x0; ( tc < 20 ) & ( SendRuning == true) ; tc ++)
{
vTaskDelay(20 /portTICK_RATE_MS);
}
}
}
void EdbugPrintProcess(u8* Pstr,u16 len)
{
if(len > PEINTFBUFF_LENGTH) return ;
WaitPrintfEnd();
MemCpy(EdbugPrintBuff, Pstr, len);
EdbugPrintBuffLength = len;
EdbugPrintBuffIndex = 0x00;
while(USART_GetITStatus(COM_DEBUG_NO, USART_IT_TC) != RESET);
USART_ITConfig(COM_DEBUG_NO, USART_IT_TC, ENABLE);
}
/**
* @brief Retargets the C library printf function to the DEBUG_COM.
* @param None.
* @retval None.
*/
int printf(const char *format ,... )
{
u16 receData = 0;
// if (printf_switch_open)
// {
// va_list arg;
// u16 receNum = 0;
// static u8 buffer[100];
//
// va_start(arg, format);
// receNum = (u16)vsnprintf((char *)(buffer), sizeof(buffer), format, arg);
// va_end(arg);
//
// receData = receNum;
// if ((receNum > 0) && (receNum <= sizeof(buffer)))
// {
// add_print_buf(buffer, receNum);
//
// if (COM_DEBUG_port.data.tx_timeout == 0)
// {
// COM_DEBUG_port.data.tx_timeout = 1;
// hal_UartDMATx(&COM_DEBUG_port,&print_buf[tail_index][1], print_buf[tail_index][0]);
// }
// }
// }
if (printf_switch_open)
{
va_list arg;
u16 receNum = 0;
//static u8 buffer[100];
WaitPrintfEnd();
va_start(arg, format);
receNum = (u16)vsnprintf((char *)(EdbugPrintBuff), sizeof(EdbugPrintBuff), format, arg);
va_end(arg);
SendRuning = true;
EdbugPrintBuffLength = receNum;
EdbugPrintBuffIndex = 0x00;
while(USART_GetITStatus(COM_DEBUG_NO, USART_IT_TC) != RESET);
USART_ITConfig(COM_DEBUG_NO, USART_IT_TC, ENABLE);
}
return receData;
}
// memcpy(RS485_tx_buf, buf, length);
// COM_noDMA_tx_index = 0;
// COM_noDMA_len = length;
// COM_485_port.data.tx_timeout = xTaskGetTickCount() + (RS485_BAUD_COFF*length + 100)/portTICK_RATE_MS;;
// while(USART_GetITStatus(COM_RADIO_NO, USART_IT_TC) != RESET);
// USART_ITConfig(COM_RADIO_NO, USART_IT_TC, ENABLE);
/*****************************************************************************
* Function : printf_buf
* Description : none
* Input : u8* buf
u16 length
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170306
* Author : barry
* Modification: Created function
*****************************************************************************/
void printf_buf(u8* buf, u16 length)
{
// static u8 temp_buf[Q_PRINT_SIZE];
// u8 temp_count = 0;
//
// u8 max_pos = (sizeof(temp_buf) - 1) - (sizeof(temp_buf) - 1) % 3;
//
// if (Q_PRINT_SIZE < 4)
// {
// return;
// }
//
// MemSet(temp_buf, 0, Q_PRINT_SIZE);
//
// for (u8 i = 0; i < length; i++)
// {
// temp_buf[temp_count++] = ((buf[i] / 0x10) <= 9)? (buf[i] / 0x10) + '0': (buf[i] / 0x10) + 'A' - 10;
// temp_buf[temp_count++] = ((buf[i] % 0x10) <= 9)? (buf[i] % 0x10) + '0': (buf[i] % 0x10) + 'A' - 10;
// temp_buf[temp_count++] = ' ';
//
// if ( (temp_count >= max_pos ) || (i == length - 1))
// {
// add_print_buf(temp_buf, temp_count);
// temp_count = 0;
// MemSet(temp_buf, 0, Q_PRINT_SIZE);
// }
// }
//
// if (head_index != tail_index)
// {
// printf("\r\n");
// }
if(length >= 255 ) return ;
u16 index = 0x00;
u16 Printflength = 0x00;
//printf("%s"," ");
WaitPrintfEnd();
for(index = 0x00; index < length; index ++)
{
Printflength += sprintf((char*)&EdbugPrintBuff[Printflength],"%02X ",buf[index]);
}
Printflength += sprintf((char*)&EdbugPrintBuff[Printflength],"%s ","\r\n");
// EdbugPrintBuffLength = Printflength;
//
// EdbugPrintBuffIndex = 0x00;
//
// while(USART_GetITStatus(COM_DEBUG_NO, USART_IT_TC) != RESET);
//
// USART_ITConfig(COM_DEBUG_NO, USART_IT_TC, ENABLE);
printf("%s",EdbugPrintBuff);
}
/*****************************************************************************
* Function : vPrintf_task
* Description : none
* Input : void * ptr
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
void vPrintf_task(void * ptr)
{
for (;;)
{
vTaskDelay(pdMS_TO_TICKS(100));
while (SendRuning == true)
{
if (xSemaphoreTake( xSemaphore, 1000 ) == pdFALSE)
{
hal_InitCOM(&COM_DEBUG_port);
// COM_DEBUG_port.data.rx_index = 0;
// COM_DEBUG_port.data.rx_len = 0;
// COM_DEBUG_port.data.tx_timeout = 0;
//
SendRuning = false;
EdbugPrintBuffLength = 0x00;
EdbugPrintBuffIndex = 0x00;
}
}
}
}
/*****************************************************************************
* Function : vPrintf_rx_task
* Description : none
* Input : void * ptr
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
void vPrintf_rx_task(void * ptr)
{
for (;;)
{
if (xSemaphoreTake( COM_DEBUG_port.xSemaphore, portMAX_DELAY ) == pdPASS)
{
Cmd_Proc();
reset_debug_buf();
}
}
}
/*****************************************************************************
* Function : task_print_start
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
void task_print_start(void)
{
vSemaphoreCreateBinary( xSemaphore );
xQueueReset( (QueueHandle_t)xSemaphore);
init_uart_port(&COM_DEBUG_port);
xTaskCreate( vPrintf_task, "Task printf", 150, NULL, 4, &print_task_handle );
xTaskCreate( vPrintf_rx_task, "Task rx printf", 150, NULL, 2, NULL );
printf("hb app start 2021-12-14\r\n");
}
#if 0
///*****************************************************************************
// * Function : printf
// * Description : none
// * Input : const char *format
// ...
// * Output : None
// * Return :
// * Others :
// * Record
// * 1.Date : 20170314
// * Author : barry
// * Modification: Created function
//
//*****************************************************************************/
//int printf(const char *format ,... )
//{
// static va_list arg;
// static u16 receNum = 0;
// static u16 receData = 0;
// static u8 blockNum = 0;
// static u8 buffer[PRINT_MAX_BUF];
// static u8 print_buf[ Q_PRINT_SIZE + 1];
// static u8 index = 0;
// static u8 print_size;
//
// if (printf_switch_open)
// {
// MemSet(buffer, 0, sizeof(buffer));
// va_start(arg, format);
// receNum = (u16)vsnprintf((char *)(buffer), sizeof(buffer), format, arg);
// va_end(arg);
//
// index = 0;
//
// if ((receNum > 0) && (receNum <= PRINT_MAX_BUF))
// {
// blockNum = (receNum % Q_PRINT_SIZE == 0)? (receNum / Q_PRINT_SIZE): (receNum / Q_PRINT_SIZE + 1);
//
// taskENTER_CRITICAL(); //保护临界区代码,不被其他的任务在数据打印过程中调用
//
// for (u8 i = 0; i < blockNum; i++)
// {
// if (i == blockNum - 1)
// {
// print_size = (receNum % Q_PRINT_SIZE == 0)? Q_PRINT_SIZE: receNum % Q_PRINT_SIZE;
// }
// else
// {
// print_size = Q_PRINT_SIZE;
// }
// print_buf[0] = print_size;
// MemCpy(print_buf + 1, buffer + index, Q_PRINT_SIZE);
// index += print_size;
// xQueueSendToBack( printQueue, print_buf, 0 );
// }
//
// taskEXIT_CRITICAL();
// }
// }
//
// return receData;
// }
//
///*****************************************************************************
// * Function : printf_buf
// * Description : none
// * Input : u8* buf
// u16 length
// * Output : None
// * Return :
// * Others :
// * Record
// * 1.Date : 20170314
// * Author : barry
// * Modification: Created function
//
//*****************************************************************************/
//void printf_buf(u8* buf, u16 length)
//{
// static u8 temp_buf[Q_PRINT_SIZE];
// u8 temp_count = 0;
//
// u8 max_pos = (sizeof(temp_buf) - 1) - (sizeof(temp_buf) - 1) % 3;
//
// if (Q_PRINT_SIZE < 4)
// {
// return;
// }
//
// MemSet(temp_buf, 0, Q_PRINT_SIZE);
//
// taskENTER_CRITICAL();
//
// for (u8 i = 0; i < length; i++)
// {
// temp_buf[temp_count++] = ((buf[i] / 0x10) <= 9)? (buf[i] / 0x10) + '0': (buf[i] / 0x10) + 'a' - 10;
// temp_buf[temp_count++] = ((buf[i] % 0x10) <= 9)? (buf[i] % 0x10) + '0': (buf[i] % 0x10) + 'a' - 10;
// temp_buf[temp_count++] = ' ';
//
// if ( (temp_count >= max_pos ) || (i == length - 1))
// {
// temp_count = 0;
// printf("%s", temp_buf);
// MemSet(temp_buf, 0, Q_PRINT_SIZE);
// }
// }
//
// printf("\r\n");
//
// taskEXIT_CRITICAL();
//}
//
///*****************************************************************************
// * Function : vPrintf_task
// * Description : none
// * Input : void * ptr
// * Output : None
// * Return :
// * Others :
// * Record
// * 1.Date : 20170314
// * Author : barry
// * Modification: Created function
//
//*****************************************************************************/
//void vPrintf_task(void * ptr)
//{
// u8 buf[Q_PRINT_SIZE+ 1];
//
// for (;;)
// {
// if( xQueueReceive( printQueue, buf, portMAX_DELAY ) == pdPASS )
// {
// hal_UartDMATx(&COM_DEBUG_port, buf + 1, buf[0]);
// if (xSemaphoreTake( xSemaphore, 1000 ) == pdFALSE)
// {
// hal_InitCOM(&COM_DEBUG_port);
// COM_DEBUG_port.data.rx_index = 0;
// COM_DEBUG_port.data.rx_len = 0;
// }
// }
// }
//}
//
// /*****************************************************************************
// * Function : vPrintf_rx_task
// * Description : none
// * Input : void * ptr
// * Output : None
// * Return :
// * Others :
// * Record
// * 1.Date : 20170314
// * Author : barry
// * Modification: Created function
//
//*****************************************************************************/
//void vPrintf_rx_task(void * ptr)
//{
// for (;;)
// {
// if (xSemaphoreTake( COM_DEBUG_port.xSemaphore, portMAX_DELAY ) == pdPASS)
// {
// Cmd_Proc();
// reset_debug_buf();
// }
// }
//}
// /*****************************************************************************
// * Function : task_print_start
// * Description : none
// * Input : void
// * Output : None
// * Return :
// * Others :
// * Record
// * 1.Date : 20170314
// * Author : barry
// * Modification: Created function
//
// *****************************************************************************/
// void task_print_start(void)
// {
// hal_InitCOM(&COM_DEBUG_port);
//
// printQueue = xQueueCreate(Q_PRINT_LENGTH, Q_PRINT_SIZE + 1); // Q_PRINT_LENGTH 队列的条目数 Q_PRINT_SIZE 每个条目占多少字节
// vSemaphoreCreateBinary( xSemaphore );
// xQueueReset( (QueueHandle_t)xSemaphore);
//
// init_uart_port(&COM_DEBUG_port);
// xTaskCreate( vPrintf_task, "Task printf", 150, NULL, 4, &print_task_handle );
// xTaskCreate( vPrintf_rx_task, "Task rx printf", 150, NULL, 2, NULL );
//
// printf("app start\r\n");
// }
#endif
/*****************************************************************************
* Function : COM_DEBUG_TX_IRQHandler
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
//
//void COM_DEBUG_TX_IRQHandler(void)
//{
// BaseType_t xHigherPriorityTaskWoken = pdFALSE;
//
// if (DMA_GetITStatus(COM_DEBUG_TX_DMA_COMPLETE) != RESET)
// {
// DMA_ClearITPendingBit(COM_DEBUG_TX_DMA_COMPLETE);
//
// tail_index = (tail_index + 1) % Q_PRINT_LENGTH;
// if (tail_index != head_index)
// {
// hal_UartDMATx(&COM_DEBUG_port,&print_buf[tail_index][1], print_buf[tail_index][0]);
// }
// else
// {
// COM_DEBUG_port.data.tx_timeout = 0;
// }
// xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
// portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
// }
// else if (DMA_GetITStatus(COM_DEBUG_TX_DMA_ERROR) != RESET)
// {
// DMA_ClearITPendingBit(COM_DEBUG_TX_DMA_ERROR);
// }
//}
/*****************************************************************************
* Function : COM_DEBUG_RX_IRQHandler
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
//void COM_DEBUG_RX_IRQHandler(void)
//{
// u8 transparent_cmd[] = "transparent 00 ";
//
// u16 len;
//
// BaseType_t xHigherPriorityTaskWoken = pdFALSE;
//
// if (USART_GetITStatus(COM_DEBUG_NO, USART_IT_RXNE) != RESET)
// {
// u8 receivedByte = USART_ReceiveData(COM_DEBUG_NO);
//
// if ( COM_DEBUG_port.data.rx_index >= COM_DEBUG_RX_BUFFER_SIZE)
// {
// COM_DEBUG_port.data.rx_index = 0;
// }
//
// if (receivedByte == '\b')//Backspace
// {
// if ( cmp_datas(transparent_cmd, COM_DEBUG_port.data.rxBuf, 11) )
// {
// COM_DEBUG_port.data.rxBuf[COM_DEBUG_port.data.rx_index++] = receivedByte;
// }
// else
// {
// if (COM_DEBUG_port.data.rx_index > 0)
// {
// COM_DEBUG_port.data.rx_index--;
// }
// }
// }
// else
// {
// COM_DEBUG_port.data.rxBuf[COM_DEBUG_port.data.rx_index ++] = receivedByte;
//
// if ((receivedByte == '\r') || (receivedByte == '\n'))//Enter
// {
// if ( cmp_datas(transparent_cmd, COM_DEBUG_port.data.rxBuf, 11) )
// {
// len = COM_DEBUG_port.data.rxBuf[12] + COM_DEBUG_port.data.rxBuf[13]*256 + sizeof(transparent_cmd) - 1;
//
// if (COM_DEBUG_port.data.rx_index < len)
// {
// return;
// }
// }
//
// COM_DEBUG_port.data.rx_len = COM_DEBUG_port.data.rx_index;
// COM_DEBUG_port.data.rx_index = 0;
//
// xSemaphoreGiveFromISR( COM_DEBUG_port.xSemaphore, &xHigherPriorityTaskWoken );
// portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
// }
// }
// }
//}

163
APP/debug_printf.h Normal file
View File

@@ -0,0 +1,163 @@
#ifndef __DEBUG_PRINTF_H__
#define __DEBUG_PRINTF_H__
#include "Basedefine.h"
#include "Rtc.h"
//define COM_DEBUG infomation
//#define COM_DEBUG_NO UART4 // DEBUG
//#define COM_DEBUG_BAUD 9600
//#define COM_DEBUG_CHECK USART_Parity_Even
//#define COM_DEBUG_CLK RCC_APB1Periph_UART4
//
//#define COM_DEBUG_TX_PIN GPIO_Pin_10
//#define COM_DEBUG_TX_PORT GPIOC
//#define COM_DEBUG_TX_PORT_CLK RCC_APB2Periph_GPIOC
//
//#define COM_DEBUG_RX_PIN GPIO_Pin_11
//#define COM_DEBUG_RX_PORT GPIOC
//#define COM_DEBUG_RX_PORT_CLK RCC_APB2Periph_GPIOC
//
//#define COM_DEBUG_IRQn UART4_IRQn
//
//#define COM_DEBUG_DMA_CLK RCC_AHBPeriph_DMA2
//#define COM_DEBUG_TX_DMA_CHANNEL DMA2_Channel5
//#define COM_DEBUG_DR_BASE (UART4_BASE + 4)
//#define COM_DEBUG_TX_IRQHandler DMA2_Channel4_5_IRQHandler
//#define COM_DEBUG_RX_IRQHandler UART4_IRQHandler
//#define COM_DEBUG_TX_DMA_COMPLETE DMA2_IT_TC5
//#define COM_DEBUG_TX_DMA_ERROR DMA2_IT_TE5
//#define COM_DEBUG_DMA_IRQn DMA2_Channel4_5_IRQn
//#define COM_DEBUG_TX_BUFFER_SIZE 255
//#define COM_DEBUG_RX_BUFFER_SIZE 255
//#define COM_DEBUG_STR "DEBUG"
#define COM_DEBUG_NO UART5 // DEBUG
//#define COM_DEBUG_BAUD 115200
//#define COM_DEBUG_CHECK USART_Parity_Even
#define COM_DEBUG_BAUD 9600
#define COM_DEBUG_CHECK USART_Parity_No
#define COM_DEBUG_CLK RCC_APB1Periph_UART5
#define COM_DEBUG_TX_PIN GPIO_Pin_12
#define COM_DEBUG_TX_PORT GPIOC
#define COM_DEBUG_TX_PORT_CLK RCC_APB2Periph_GPIOC
#define COM_DEBUG_RX_PIN GPIO_Pin_2
#define COM_DEBUG_RX_PORT GPIOD
#define COM_DEBUG_RX_PORT_CLK RCC_APB2Periph_GPIOD
#define COM_DEBUG_IRQn UART5_IRQn
#define COM_DEBUG_DMA_CLK 0
#define COM_DEBUG_TX_DMA_CHANNEL 0
#define COM_DEBUG_DR_BASE 0
#define COM_DEBUG_TX_IRQHandler 0
#define COM_DEBUG_RX_IRQHandler 0
#define COM_DEBUG_TX_DMA_COMPLETE 0
#define COM_DEBUG_TX_DMA_ERROR 0
#define COM_DEBUG_DMA_IRQn 0
#define COM_DEBUG_TX_BUFFER_SIZE 255
#define COM_DEBUG_RX_BUFFER_SIZE 255
#define COM_DEBUG_STR "DEBUG"
//define COM LORA moudule infomation
//#define COM_RADIO_NO UART5
//#define COM_RADIO_BAUD 9600 //8,e,1
//#define COM_RADIO_CHECK USART_Parity_Even
//#define COM_RADIO_CLK RCC_APB1Periph_UART5
//
//#define COM_RADIO_TX_PIN GPIO_Pin_12
//#define COM_RADIO_TX_PORT GPIOC
//#define COM_RADIO_TX_PORT_CLK RCC_APB2Periph_GPIOC
//
//#define COM_RADIO_RX_PIN GPIO_Pin_2
//#define COM_RADIO_RX_PORT GPIOD
//#define COM_RADIO_RX_PORT_CLK RCC_APB2Periph_GPIOD
//
//#define COM_RADIO_IRQn UART5_IRQn
//
//#define COM_RADIO_DMA_CLK 0
//
//#define COM_RADIO_TX_DMA_CHANNEL 0
//#define COM_RADIO_DR_BASE 0
//#define COM_RADIO_TX_IRQHandler 0
//#define COM_RADIO_RX_IRQHandler 0
//#define COM_RADIO_TX_DMA_COMPLETE 0
//#define COM_RADIO_TX_DMA_ERROR 0
//#define COM_RADIO_DMA_IRQn 0
//
//
//#define COM_RADIO_TX_BUFFER_SIZE 255
//#define COM_RADIO_RX_BUFFER_SIZE 255
//#define COM_RADIO_STR "radio"
/*
#define COM_DEBUG_NO USART3 // DEBUG
#define COM_DEBUG_BAUD 9600
#define COM_DEBUG_CHECK USART_Parity_Even
#define COM_DEBUG_CLK RCC_APB1Periph_USART3
#define COM_DEBUG_TX_PIN GPIO_Pin_10
#define COM_DEBUG_TX_PORT GPIOB
#define COM_DEBUG_TX_PORT_CLK RCC_APB2Periph_GPIOB
#define COM_DEBUG_RX_PIN GPIO_Pin_11
#define COM_DEBUG_RX_PORT GPIOB
#define COM_DEBUG_RX_PORT_CLK RCC_APB2Periph_GPIOB
#define COM_DEBUG_IRQn USART3_IRQn
#define COM_DEBUG_DMA_CLK RCC_AHBPeriph_DMA1
#define COM_DEBUG_TX_DMA_CHANNEL DMA1_Channel2
#define COM_DEBUG_DR_BASE (USART3_BASE + 4)
#define COM_DEBUG_TX_IRQHandler DMA1_Channel2_IRQHandler
#define COM_DEBUG_RX_IRQHandler USART3_IRQHandler
#define COM_DEBUG_TX_DMA_COMPLETE DMA1_IT_TC2
#define COM_DEBUG_TX_DMA_ERROR DMA1_IT_TE2
#define COM_DEBUG_DMA_IRQn DMA1_Channel2_IRQn
#define COM_DEBUG_TX_BUFFER_SIZE 255
#define COM_DEBUG_RX_BUFFER_SIZE 255
*/
#define PRINT_TIME_OUT(bytes) (((bytes * 11000) / COM_DEBUG_BAUD) + 100) //ms
#define Q_PRINT_LENGTH 128
#define Q_PRINT_SIZE 16
#define PRINT_BUFFER_SIZE (Q_PRINT_LENGTH * Q_PRINT_SIZE)
#define PRINT_MAX_BUF 255
#define PRINT(CODE) do\
{\
sTime time;\
time = TimetoBCD(RTC_GetCounter());\
printf("%02d:%02d:%02d->", time.hour, time.minute, time.second);\
CODE\
} while (0)
#define __DISPLAY
#ifdef __DISPLAY
#define DISP(CODE) PRINT(CODE)
#define LIST(CODE) do{CODE}while(0)
#else
#define DISP(CODE)
#define LIST(CODE)
#endif
void debug_Tx(u8 *buf, u8 len);
void task_print_start(void);
void reset_debug_buf(void);
void printf_buf(u8* buf, u16 length);
u16 get_debugBuf_len(void);
u8 * get_debugBuf(void);
void close_printf(void);
void open_printf(void);
#endif

885
APP/hal_radio.c Normal file
View File

@@ -0,0 +1,885 @@
/**
******************************************************************************
* @file hal_radio.c
* @author William Liang
* @version V1.0.0
* @date 09/10/2013
* @brief This file contains the initialization and handle of the radio frequency.
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include <string.h>
#include <stdlib.h>
#include "hal_radio.h"
#include "uart.h"
#include "Rtc.h"
#include "sx1276-LoRa.h"
#include "sx1276-Fsk.h"
#include "apl.h"
/*****************************************************************************
Prototype : spiReadWriteByte
Description : spi basic function
Input : u8 data
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
u8 spiReadWriteByte(u8 data)
{
while(SPI_I2S_GetFlagStatus(sRF_SPI,SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(sRF_SPI, data);
while(SPI_I2S_GetFlagStatus(sRF_SPI,SPI_I2S_FLAG_RXNE)==RESET);
return (u8)(SPI_I2S_ReceiveData(sRF_SPI));
}
/*****************************************************************************
Prototype : SX1276WriteBuffer
Description : spi write buffer
Input : uint8_t addr
uint8_t *buffer
uint8_t size
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
sRF_CS_LOW();
spiReadWriteByte(addr|0x80);
for(u8 i = 0;i < size; i++)
{
spiReadWriteByte(buffer[i]);
}
sRF_CS_HIGH();
}
/*****************************************************************************
Prototype : SX1276ReadBuffer
Description : none
Input : uint8_t addr
uint8_t *buffer
uint8_t size
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
sRF_CS_LOW();
spiReadWriteByte(addr);
for(u8 i = 0;i < size; i++)
{
buffer[i] = spiReadWriteByte(0xFF);
}
sRF_CS_HIGH();
}
/*****************************************************************************
Prototype : SX1276Write
Description : 1276 write Reg
Input : uint8_t addr
uint8_t data
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276Write( uint8_t addr, uint8_t data )
{
SX1276WriteBuffer( addr, &data, 1 );
}
/*****************************************************************************
Prototype : SX1276Read
Description : 1276 read Reg
Input : uint8_t addr
uint8_t *data
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276Read( uint8_t addr, uint8_t *data )
{
SX1276ReadBuffer( addr, data, 1 );
}
/*****************************************************************************
Prototype : SX1276WriteFifo
Description : none
Input : uint8_t *buffer
uint8_t size
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276WriteFifo( uint8_t *buffer, uint8_t size )
{
SX1276WriteBuffer( sRF_FIFO_ARRD, buffer, size );
}
/*****************************************************************************
Prototype : SX1276ReadFifo
Description : none
Input : uint8_t *buffer
uint8_t size
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276ReadFifo( uint8_t *buffer, uint8_t size )
{
SX1276ReadBuffer( sRF_FIFO_ARRD, buffer, size );
}
/*****************************************************************************
* Function : SX1276Reset
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170307
* Author : barry
* Modification: Created function
*****************************************************************************/
#define get_sys_time() xTaskGetTickCount()*portTICK_RATE_MS
void SX1276Reset(void)
{
u32 startTick;
GPIO_InitTypeDef GPIO_InitStructure;
hal_DIOx_ITConfig(all, DISABLE);
RCC_APB2PeriphClockCmd(sRF_RESET_SCK, ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = sRF_RESET_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init( sRF_RESET_PORT, &GPIO_InitStructure );
GPIO_ResetBits( sRF_RESET_PORT, sRF_RESET_PIN);
startTick = get_sys_time( );
while( get_sys_time( ) < ( startTick + 2 ));
GPIO_SetBits( sRF_RESET_PORT, sRF_RESET_PIN );
startTick = get_sys_time( );
while( get_sys_time( ) < ( startTick + 6 ));
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = sRF_RESET_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( sRF_RESET_PORT, &GPIO_InitStructure );
hal_sRF_ClearAllRF_IT();
}
/*****************************************************************************
Prototype : hal_sRF_ITConfig
Description : none
Input : en_GDOx_IrqLine irqLine
FunctionalState NewState
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void hal_sRF_ITConfig(uint32_t irqLine, FunctionalState NewState)
{
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = irqLine;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = NewState;
EXTI_Init(&EXTI_InitStructure);
}
/*****************************************************************************
* Function : hal_sRF_FSK_ITConfig
* Description : none
* Input : uint32_t irqLine
FunctionalState NewState
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170418
* Author : barry
* Modification: Created function
*****************************************************************************/
void hal_sRF_FSK_ITConfig( uint32_t irqLine, FunctionalState NewState)
{
EXTI_InitTypeDef EXTI_InitStructure;
if (NewState == ENABLE)
{
EXTI_ClearITPendingBit(irqLine);
}
EXTI_InitStructure.EXTI_Line = irqLine;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = NewState;
EXTI_Init(&EXTI_InitStructure);
if (NewState == DISABLE)
{
EXTI_ClearITPendingBit(irqLine);
}
}
/*****************************************************************************
* Function : hal_sRF_ClearAllRF_IT
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170418
* Author : barry
* Modification: Created function
*****************************************************************************/
void hal_sRF_ClearAllRF_IT(void)
{
EXTI_ClearITPendingBit(DIO0_IRQ);
EXTI_ClearITPendingBit(DIO1_IRQ);
EXTI_ClearITPendingBit(DIO2_IRQ);
EXTI_ClearITPendingBit(DIO3_IRQ);
}
/*****************************************************************************
Prototype : hal_Init_RF_pins
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void hal_Init_RF_pins(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(sRF_CS_GPIO_CLK | sRF_SPI_MOSI_GPIO_CLK | sRF_SPI_MISO_GPIO_CLK |
sRF_SPI_SCK_GPIO_CLK | sRF_DIOx_SCK | sRF_RESET_SCK | sRF_DIO4_SCK, ENABLE);
hal_DIOx_ITConfig(all,DISABLE);
hal_sRF_ClearAllRF_IT();
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = sRF_RESET_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init( sRF_RESET_PORT, &GPIO_InitStructure );
/*!< Configure sRF_SPI pins: SCK */
GPIO_InitStructure.GPIO_Pin = sRF_SPI_SCK_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(sRF_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);
/*!< Configure sRF_SPI pins: MOSI */
GPIO_InitStructure.GPIO_Pin = sRF_SPI_MOSI_PIN;
GPIO_Init(sRF_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);
/*!< Configure sRF_SPI pins: MISO */
GPIO_InitStructure.GPIO_Pin = sRF_SPI_MISO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(sRF_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);
/*!< Configure sRF_CS_PIN pin: sRF CS pin */
GPIO_InitStructure.GPIO_Pin = sRF_CS_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(sRF_CS_GPIO_PORT, &GPIO_InitStructure);
/*!< Configure sRF_IRQ_PINs pin: DDO0~GDO5 */
GPIO_InitStructure.GPIO_Pin = sRF_DIO0_PIN | sRF_DIO1_PIN | sRF_DIO3_PIN;// | sRF_DIO2_PIN ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(sRF_DIOx_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = sRF_DIO4_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(sRF_DIO4_PORT, &GPIO_InitStructure);
/*TX LED pin*/
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = sRF_TX_CTRL_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init( sRF_TX_CTRL_PORT, &GPIO_InitStructure );
}
void hal_Init_RF_int(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Disable sRF_IRQ_EXTI clock */
RCC_APB2PeriphResetCmd(RCC_APB2Periph_AFIO, DISABLE);
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
GPIO_EXTILineConfig(sRF_DIOx_PORT_SOURCE, sRF_DIO0_PIN_SOURCE);
GPIO_EXTILineConfig(sRF_DIOx_PORT_SOURCE, sRF_DIO1_PIN_SOURCE);
//GPIO_EXTILineConfig(sRF_DIOx_PORT_SOURCE, sRF_DIO2_PIN_SOURCE);
GPIO_EXTILineConfig(sRF_DIOx_PORT_SOURCE, sRF_DIO3_PIN_SOURCE);
GPIO_EXTILineConfig(sRF_DIO4_PORT_SOURCE, sRF_DIO4_PIN_SOURCE);
/* Enable AFIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
}
/*****************************************************************************
Prototype : hal_sRF_SPI_Config
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void hal_Init_RF_SPI(void)
{
SPI_InitTypeDef SPI_InitStructure;
if (sRF_SPI == SPI1)
{
RCC_APB2PeriphClockCmd(sRF_SPI_CLK, ENABLE);
}
else
{
RCC_APB1PeriphClockCmd(sRF_SPI_CLK, ENABLE);
}
/* Enable sRF SPI DMA clock */
RCC_AHBPeriphClockCmd(sRF_SPI_DMA_CLK, ENABLE);
/*!< Deselect the RF: Chip Select high */
sRF_CS_HIGH();
/* Disable sRF_SPI */
SPI_Cmd(sRF_SPI, DISABLE);
/*!< SPI configuration */
SPI_I2S_DeInit(sRF_SPI);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(sRF_SPI, &SPI_InitStructure);
/*!< Enable the sRF_SPI */
SPI_Cmd(sRF_SPI, ENABLE);
}
/*****************************************************************************
Prototype : hal_sRF_InitSPI
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void hal_sRF_InitSPI(void)
{
hal_Init_RF_pins();
hal_Init_RF_int();
hal_Init_RF_SPI();
#ifdef SPI_DMA_FIFO
init_SPI_DMA();
#endif
}
/*****************************************************************************
* Function : SX1276_lora_init
* Description : none
* Input : bool lora
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170320
* Author : barry
* Modification: Created function
*****************************************************************************/
void SX1276_init(bool lora)
{
SX1276Reset();
if (lora)
{
SX1276LoRaInit();
}
else
{
#ifndef USE_LORA_MODE
SX1276FskInit();
#endif
}
}
/*****************************************************************************
Prototype : hal_InitRF
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void hal_InitRF(void)
{
hal_sRF_InitSPI();
#ifdef USE_LORA_MODE
SX1276_init(true);
#else
SX1276_init(false);
#endif
}
#if 0
/*****************************************************************************
Prototype : init_SPI_DMA
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void init_SPI_DMA(void)
{
DMA_InitTypeDef DMA_InitStructure;
/* Enable SPI Rx and Tx request */
SPI_I2S_DMACmd(sRF_SPI, SPI_I2S_DMAReq_Rx | SPI_I2S_DMAReq_Tx, ENABLE);
/* sRF_SPI_DMA_RX_Channel configuration ---------------------------------------------*/
DMA_DeInit(sRF_SPI_DMA_RX_Channel);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)sRF_SPI_DR_Base;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)0;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 0;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(sRF_SPI_DMA_RX_Channel, &DMA_InitStructure);
/* sRF_SPI_DMA_TX_Channel configuration ---------------------------------------------*/
DMA_DeInit(sRF_SPI_DMA_TX_Channel);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)sRF_SPI_DR_Base;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)0;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 0;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(sRF_SPI_DMA_TX_Channel, &DMA_InitStructure);
}
/*****************************************************************************
Prototype : hal_sRF_ReadRegister
Description : none
Input : u8 reg
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
u8 hal_sRF_ReadRegister(u8 reg)
{
if (reg > TOTAL_REGISTER_NUMBER)
{
printf("regsiter input error\r\n");
return 0;
}
/*!< Deselect the Radio: Chip Select high */
sRF_CS_HIGH();
/*!< Select the radio by pulling low the nSEL pin */
sRF_CS_LOW();
/*!< Loop while DR register in not emplty */
while (SPI_I2S_GetFlagStatus(sRF_SPI, SPI_I2S_FLAG_TXE) == RESET);
/*!< Send byte through the SPI1 peripheral */
SPI_I2S_SendData(sRF_SPI, reg);
/*!< Wait to receive a byte */
while (SPI_I2S_GetFlagStatus(sRF_SPI, SPI_I2S_FLAG_RXNE) == RESET);
/* read from the SPI bus */
SPI_I2S_ReceiveData(sRF_SPI);
/*!< Loop while DR register in not emplty */
while (SPI_I2S_GetFlagStatus(sRF_SPI, SPI_I2S_FLAG_TXE) == RESET);
/*!< Send byte through the SPI1 peripheral */
SPI_I2S_SendData(sRF_SPI, sRF_DUMMY_BYTE);
/*!< Wait to receive a byte */
while (SPI_I2S_GetFlagStatus(sRF_SPI, SPI_I2S_FLAG_RXNE) == RESET);
/*!< Return the byte read from the SPI bus */
reg = SPI_I2S_ReceiveData(sRF_SPI);
/*!< Deselect the radio by pulling high the nSEL pin */
sRF_CS_HIGH();
return reg;
}
/*****************************************************************************
Prototype : hal_sRF_WriteRegister
Description : none
Input : u8 reg
u8 val
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void hal_sRF_WriteRegister(u8 reg, u8 val)
{
reg |= 0x80;
/*!< Deselect the Radio: Chip Select high */
sRF_CS_HIGH();
/*!< Select the radio by pulling low the nSEL pin */
sRF_CS_LOW();
/*!< Loop while DR register in not emplty */
while (SPI_I2S_GetFlagStatus(sRF_SPI, SPI_I2S_FLAG_TXE) == RESET);
/*!< Send byte through the SPI1 peripheral */
SPI_I2S_SendData(sRF_SPI, reg);
/*!< Wait to receive a byte */
while (SPI_I2S_GetFlagStatus(sRF_SPI, SPI_I2S_FLAG_RXNE) == RESET);
/* read from the SPI bus */
SPI_I2S_ReceiveData(sRF_SPI);
/*!< Loop while DR register in not emplty */
while (SPI_I2S_GetFlagStatus(sRF_SPI, SPI_I2S_FLAG_TXE) == RESET);
/*!< Send byte through the SPI1 peripheral */
SPI_I2S_SendData(sRF_SPI, val);
/*!< Wait to receive a byte */
while (SPI_I2S_GetFlagStatus(sRF_SPI, SPI_I2S_FLAG_RXNE) == RESET);
/* read from the SPI bus */
SPI_I2S_ReceiveData(sRF_SPI);
/*!< Deselect the radio by pulling high the nSEL pin */
sRF_CS_HIGH();
}
/*****************************************************************************
Prototype : hal_sRF_DMA_Read
Description : none
Input : u8 startReg
u8 *pBuffer
u8 length
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void hal_sRF_DMA_Read(u8 startReg, u8 *pBuffer, u8 length)
{
/* Allocate storage for CPU status register */
#if OS_CRITICAL_METHOD == 3u
OS_CPU_SR cpu_sr = 0u;
#endif
if (startReg > TOTAL_REGISTER_NUMBER)
{
return;
}
if (length > 0)
{
/*!< Deselect the Radio: Chip Select high */
sRF_CS_HIGH();
/*!< Select the radio by pulling low the nSEL pin */
sRF_CS_LOW();
/*!< Loop while DR register in not emplty */
while (SPI_I2S_GetFlagStatus(sRF_SPI, SPI_I2S_FLAG_TXE) == RESET);
/*!< Send byte through the SPI1 peripheral */
SPI_I2S_SendData(sRF_SPI, startReg);
/*!< Wait to receive a byte */
while (SPI_I2S_GetFlagStatus(sRF_SPI, SPI_I2S_FLAG_RXNE) == RESET);
/* read from the SPI bus */
SPI_I2S_ReceiveData(sRF_SPI);
OS_ENTER_CRITICAL();
sRF_SPI->CR1 |= SPI_Direction_2Lines_RxOnly;
/* sRF_SPI_DMA_RX_Channel configuration ---------------------------------------------*/
sRF_SPI_DMA_RX_Channel->CMAR = (u32)pBuffer;
sRF_SPI_DMA_RX_Channel->CNDTR = (u32)length;
/* Enable sRF_SPI_DMA_RX_Channel and TC interrupt*/
sRF_SPI_DMA_RX_Channel->CCR |= DMA_CCR1_EN | DMA_CCR1_TCIE;
OS_EXIT_CRITICAL();
}
}
/*****************************************************************************
Prototype : hal_sRF_DMA_Write
Description : none
Input : u8 *pBuffer
u8 length
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void hal_sRF_DMA_Write(u8 *pBuffer, u8 length)
{
if (length > 0)
{
/*!< Deselect the Radio: Chip Select high */
sRF_CS_HIGH();
/*!< Select the radio by pulling low the nSEL pin */
sRF_CS_LOW();
/* sRF_SPI_DMA_TX_Channel configuration ---------------------------------------------*/
sRF_SPI_DMA_TX_Channel->CMAR = (u32)pBuffer;
sRF_SPI_DMA_TX_Channel->CNDTR = (u32)length;
/* Enable sRF_SPI_DMA_TX_Channel */
sRF_SPI_DMA_TX_Channel->CCR |= DMA_CCR1_EN | DMA_CCR1_TCIE;
}
else
{
printf("length input error\r\n");
}
}
/*****************************************************************************
Prototype : hal_sRF_Config
Description : none
Input : u8 startReg
u8 *pBuffer
u8 length
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void hal_sRF_Config(u8 startReg, u8 *pBuffer, u8 length)
{
if (startReg >= TOTAL_REGISTER_NUMBER)
{
printf("startReg input error\r\n");
return;
}
if (length > 0)
{
hal_sRF_InitSPI();
*pBuffer = startReg | 0x80;
hal_sRF_DMA_Write(pBuffer, length + 1);
}
}
/*****************************************************************************
Prototype : hal_sRF_Read
Description : DMA read FIFO
Input : u8 startReg
u8 *pBuffer
u8 length
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void hal_sRF_Read(u8 startReg, u8 *pBuffer, u8 length)
{
if (length > 0)
{
hal_sRF_InitSPI();
hal_sRF_DMA_Read(startReg,pBuffer,length);
}
}
/*****************************************************************************
Prototype : hal_sRF_readFIFO_DMA
Description : none
Input : u8 * pBuffer指向接收数组数组的第一个字节为长度字节
u8 length
Output : None
Return Value :
Date : 2014/3/21
Author : Barry
*****************************************************************************/
void hal_sRF_readFIFO_DMA(u8 * pBuffer, u8 length)
{
hal_sRF_DMA_Read(0,pBuffer+1,length);
}
/*****************************************************************************
Prototype : hal_sRF_writeFIFO_DMA
Description : none
Input : u8 * pBuffer 指向开始发送的数组数组的第一个字节为FIFO地址
u8 length 实际发送的字节数
Output : None
Return Value :
Date : 2014/3/21
Author : Barry
*****************************************************************************/
void hal_sRF_writeFIFO_DMA(u8 * pBuffer, u8 length)
{
hal_sRF_Config(0,pBuffer,length);
}
/******************************************************************************/
/* STM32F10x Peripherals Interrupt Handlers */
/******************************************************************************/
/*****************************************************************************
Prototype : DMA1_Channel2_IRQHandler
Description : This function handles SPI1 Rx Transfer Complete interrupt
and Transfer Error interrupt.
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void DMA1_Channel2_IRQHandler(void)
{
if (DMA_GetITStatus(DMA1_IT_TC2) != RESET)
{
/* hal_sRF_InitSPI();初始化放在主循环中去 */
RxEndProcess(TRUE);
}
/*!< Deselect the RADIO: Chip Select high */
//sRF_CS_HIGH();
/* Disable the selected SPI peripheral */
//sRF_SPI->CR1 &= 0xFFBF;
/* Clear the DMA1 interrupt pending bits */
DMA1->IFCR = DMA1_IT_TC2 | DMA1_IT_HT2 | DMA1_IT_TE2;
/* Disable the selected DMA1_Channel2 */
DMA1_Channel2->CCR &= (u16)(~DMA_CCR1_EN);
}
/*****************************************************************************
Prototype : DMA1_Channel3_IRQHandler
Description : This function handles SPI1 Tx Transfer Complete interrupt
and Transfer Error interrupt.
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void DMA1_Channel3_IRQHandler(void)
{
if (DMA_GetITStatus(DMA1_IT_TC3) != RESET)
{
SX1276LoRaStartTransmit();
}
/* Clear the DMA1 interrupt pending bits */
DMA1->IFCR = DMA1_IT_TC3 | DMA1_IT_HT3 | DMA1_IT_TE3;
/* Disable the selected DMA1_Channel3 */
DMA1_Channel3->CCR &= (u16)(~DMA_CCR1_EN);
}
/*****************************************************************************
Prototype : hal_sRF_Transmit
Description : PHY send
Input : u8 *pBuffer
u8 length
u8 channel
Output : None
Return Value :
Calls :
Called By :
History :
1.Date : 2014/10/29
Author : liwei
Modification : Created function
*****************************************************************************/
void hal_sRF_Transmit(u8 *pBuffer, u8 length, u8 channel)
{
SX1276LoRa_NormalTx(pBuffer,length);
}
#endif
/******************* (C) COPYRIGHT 2013 Robulink Technology Ltd.*****END OF FILE****/

240
APP/hal_radio.h Normal file
View File

@@ -0,0 +1,240 @@
/**
******************************************************************************
* @file hal_radio.h
* @author William Liang
* @version V1.0.0
* @date 09/10/2013
* @brief This file contains the headers of the radio frequency handlers.
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __HAL_sRF_H__
#define __HAL_sRF_H__
/* Includes ------------------------------------------------------------------*/
#include "include.h"
#include "stm32f10x.h"
#include "sx1276-LoRa.h"
/* Exported constants --------------------------------------------------------*/
/**
* @brief SPI sRF Frequency Chip Interface pins
*/
#define sRF_SPI SPI1
#define sRF_SPI_CLK RCC_APB2Periph_SPI1
#define sRF_CS_PIN GPIO_Pin_4 /* PA.4 */
#define sRF_CS_GPIO_PORT GPIOA /* GPIOA */
#define sRF_CS_GPIO_CLK RCC_APB2Periph_GPIOA
#define sRF_SPI_SCK_PIN GPIO_Pin_5 /* PB.5 */
#define sRF_SPI_SCK_GPIO_PORT GPIOA /* GPIOA */
#define sRF_SPI_SCK_GPIO_CLK RCC_APB2Periph_GPIOA
#define sRF_SPI_MISO_PIN GPIO_Pin_6 /* PB.6 */
#define sRF_SPI_MISO_GPIO_PORT GPIOA /* GPIOA */
#define sRF_SPI_MISO_GPIO_CLK RCC_APB2Periph_GPIOA
#define sRF_SPI_MOSI_PIN GPIO_Pin_7 /* PB.7 */
#define sRF_SPI_MOSI_GPIO_PORT GPIOA /* GPIOA */
#define sRF_SPI_MOSI_GPIO_CLK RCC_APB2Periph_GPIOA
#define sRF_SPI_DR_Base (SPI1_BASE + 0x0C)
#define sRF_SPI_DMA DMA1
#define sRF_SPI_DMA_CLK RCC_AHBPeriph_DMA1
#define sRF_SPI_DMA_RX_Channel DMA1_Channel4
#define sRF_SPI_DMA_TX_Channel DMA1_Channel5
#define sRF_SPI_DMA_RX_FLAG DMA1_FLAG_TC4
#define sRF_SPI_DMA_TX_FLAG DMA1_FLAG_TC5
/* BEGIN: Added by Barry, 2014/3/4 */
#define sRF_RESET_PORT GPIOA
#define sRF_RESET_SCK RCC_APB2Periph_GPIOA
#define sRF_RESET_PIN GPIO_Pin_1
#define sRF_DIOx_PORT GPIOB
#define sRF_DIOx_SCK RCC_APB2Periph_GPIOB
#define sRF_DIO0_PIN GPIO_Pin_13
#define sRF_DIO1_PIN GPIO_Pin_12
//#define sRF_DIO2_PIN GPIO_Pin_1
#define sRF_DIO3_PIN GPIO_Pin_0
//#define sRF_DIO4_PIN GPIO_Pin_4
//#define sRF_DIO5_PIN GPIO_Pin_5
#define sRF_DIO4_PORT GPIOC
#define sRF_DIO4_PIN GPIO_Pin_5 //PC5
#define sRF_DIO4_SCK RCC_APB2Periph_GPIOC
#define sRF_DIO4_PORT_SOURCE GPIO_PortSourceGPIOC
#define sRF_DIO4_PIN_SOURCE GPIO_PinSource5
#define sRF_DIOx_PORT_SOURCE GPIO_PortSourceGPIOB
#define sRF_DIO0_PIN_SOURCE GPIO_PinSource13
#define sRF_DIO1_PIN_SOURCE GPIO_PinSource12
#define sRF_DIO2_PIN_SOURCE GPIO_PinSource1
#define sRF_DIO3_PIN_SOURCE GPIO_PinSource0
#define DIO0_IRQ EXTI_Line13
#define DIO1_IRQ EXTI_Line12
#define DIO2_IRQ EXTI_Line1
#define DIO3_IRQ EXTI_Line0
#define DIO4_IRQ EXTI_Line5
#define DIOall_IRQ (DIO0_IRQ | DIO1_IRQ | DIO2_IRQ | DIO3_IRQ | DIO4_IRQ)
#define hal_DIOx_ITConfig(n,NewState) hal_sRF_ITConfig(DIO##n##_IRQ,NewState)
#define sRF_TX_CTRL_PORT GPIOC
#define sRF_TX_CTRL_PIN GPIO_Pin_4
#define sRF_FIFO_ARRD 0
/* END: Added by Barry, 2014/3/4 */
/* Select sRF: Chip Select pin low */
#define sRF_CS_LOW() GPIO_ResetBits(sRF_CS_GPIO_PORT, sRF_CS_PIN)
/* Deselect sRF: Chip Select pin high */
#define sRF_CS_HIGH() GPIO_SetBits(sRF_CS_GPIO_PORT, sRF_CS_PIN)
#define RFTX_ENABLE GPIO_SetBits(sRF_TX_CTRL_PORT, sRF_TX_CTRL_PIN)
#define RFRX_ENABLE GPIO_ResetBits(sRF_TX_CTRL_PORT, sRF_TX_CTRL_PIN)
#define switch_Tx() GPIO_SetBits(sRF_TX_CTRL_PORT, sRF_TX_CTRL_PIN)
#define switch_Rx() GPIO_ResetBits(sRF_TX_CTRL_PORT, sRF_TX_CTRL_PIN)
/* Disable PA */
#define sRF_PA_DISABLE() GPIO_ResetBits(sRF_PA_CTRL_PORT, sRF_PA_CTRL_PIN)
/* Enable PA */
#define sRF_PA_ENABLE() GPIO_SetBits(sRF_PA_CTRL_PORT, sRF_PA_CTRL_PIN)
#define sRF_DUMMY_BYTE 0xAA
#define sRF_CRYSTALCAP_EEPROM_ADDR 0xFFC1
#define sRF_CHANNEL_NUMBER 66u
#define sRF_PREAMBLE_LENGTH 80u //bytes
#define sRF_SYNCWORD_LENGTH 2u //bytes
#define sRF_FREQ_HOP_TIMEOUT 30u//ms
#define sRF_CHECK_SYNCWORD_TIMEOUT 85u //(((sRF_PREAMBLE_LENGTH + sRF_SYNCWORD_LENGTH) * 8) / 10 + 20) //ms
#define sRF_FIRST_TX_TIMEOUT 136u //(((sRF_PREAMBLE_LENGTH + sRF_SYNCWORD_LENGTH + FIFO_SIZE) * 8) / 10 + 20) //ms
#define sRF_FIFO_TRX_TIMEOUT 71u //((FIFO_SIZE * 8) / 10 + 20) //ms
#define sRF_FIFO_DMA_TIMEOUT 20u //ms
#define sRF_PACKET_SIZE (aMaxPHYPayloadSize + 6) //258u
#define sRF_RSSI_SAMPLE_NUMBER 9u
#define sRF_RSSI_SAMPLE_INTERVAL 2u //ms
#define sRF_TEST_INTERVAL 1000u //ms
#define TOTAL_REGISTER_NUMBER 0x70
#define FIFO_SIZE 255u
#define RF_TIMEOUT 3000
#define RXTX( txEnable ) SX1276WriteRxTx( txEnable )
#define TICK_RATE_MS( ms ) ( ms )
#define true TRUE
#define false FALSE
typedef struct
{
u16 version;
u16 lastBytes;
u16 total_packets;
u16 current_packet_No;
u16 total_bytes;
u8 packet_length;
}ST_update_slave_info;
typedef struct
{
u8 CadDetected:1;
u8 FhssChangeChannel:1;
u8 CadDone:1;
u8 TxDone:1;
u8 ValidHeader:1;
u8 PayloadCrcError:1;
u8 RxDone:1;
u8 RxTimeout:1;
}ST_irqFlag;
enum
{
RF_ERR = 0x0000,
RF_CAD_DETECT = 0x0001,
RF_TX_START = 0x0002,
RF_TX_SUCCESS = 0x0004,
RF_RX_SUCCESS = 0x0008,
RF_RX_FAILED = 0x0010,
RF_VALID_HEAD = 0x0020,
RF_SET_PARAMS = 0x0040,
RF_PREAMBLE_TIMEOUT = 0x0080,
};
#endif
/* Exported macro ------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void hal_InitRFVariable(void);
void hal_InitRF(void);
void hal_sRF_InitSPI(void);
void hal_sRF_ITConfig(uint32_t irqLine, FunctionalState NewState);
u8 hal_sRF_ReadRegister(u8 reg);
void hal_sRF_WriteRegister(u8 reg, u8 val);
void hal_sRF_DMA_Read(u8 startReg, u8 *pBuffer, u8 length);
void hal_sRF_DMA_Write(u8 *pBuffer, u8 length);
void hal_sRF_Config(u8 startReg, u8 *pBuffer, u8 length);
void hal_sRF_Read(u8 startReg, u8 *pBuffer, u8 length);
void hal_sRF_Receive(void);
void hal_sRF_Transmit(u8 *pBuffer, u8 length, u8 channel);
void hal_sRF_ReadRssi(void);
u8 hal_sRF_GetLinkQuality(void);
u8 hal_sRF_RssiToLinkQuality(u8 rssi);
void hal_sRF_FrequencyHopping(void);
void hal_sRF_WhiteningBuffer(u8 *pBuffer, u16 length);
bool hal_sRF_CheckPacketValid(u8 *pBuffer, u16 length);
void hal_sRF_Sync_Handle(void);
void hal_sRF_TRX_Handle(void);
u8 spiReadWriteByte(u8 data);
void SX1276WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size );
void SX1276ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size );
void SX1276Write( uint8_t addr, uint8_t data );
void SX1276Read( uint8_t addr, uint8_t *data );
void SX1276WriteFifo( uint8_t *buffer, uint8_t size );
void SX1276ReadFifo( uint8_t *buffer, uint8_t size );
void SX1276SetReset( uint8_t state );
u8 cmp(u8 * buf1, u8* buf2, u8 length);
void SX1276WriteRxTx( bool txEnable );
void hal_sRF_SPI_Config(void);
void sRFTransmitHandle(void);
void TimeOutHandle(void);
void hal_sRF_writeFIFO_DMA(u8 * pBuffer, u8 length);
void hal_sRF_readFIFO_DMA(u8 * pBuffer, u8 length);
void hal_sRF_Transmit(u8 *pBuffer, u8 length, u8 channel);
void hal_sRF_FSK_ITConfig( uint32_t irqLine, FunctionalState NewState);
void hal_sRF_ITConfig(uint32_t irqLine, FunctionalState NewState);
void hal_sRF_ClearAllRF_IT();
#define hal_fsk_eit_failing(n,NewState) hal_sRF_FSK_ITConfig(DIO##n##_IRQ,NewState)
/*!
* DIO state read functions mapping
*/
#define DIO(n) GPIO_ReadInputDataBit( sRF_DIOx_PORT, sRF_DIO##n##_PIN )
#define DIO0 DIO(0)
#define DIO1 DIO(1)
#define DIO2 DIO(2)
#define DIO3 DIO(3)
#define DIO4 DIO(4)
#define DIO5 DIO(5)
#define DEBUG
/******************* (C) COPYRIGHT 2013 Robulink Technology Ltd.*****END OF FILE****/

41
APP/include.h Normal file
View File

@@ -0,0 +1,41 @@
#ifndef _INCLUDE_H_
#define _INCLUDE_H_
/************FreeRTOS include*********************/
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include "timers.h"
#include "event_groups.h"
/************standard include************************/
#include "string.h"
/**************user include***********************/
#include "Mem.h"
#include "Basedefine.h"
#include "General.h"
#include "debug_printf.h"
#include "uart.h"
#include "Init.h"
#define METER_ADDR_LEN (7)
#define METERTABLE_NUM_MAX (300)
#define METER_CLOSE (1)
#define METER_OPEN (2)
#define COMMON_VER
#define ONE_UNIT_LEN (16) //一个单元的数据长度
//#define AMT_VER
//#define ONE_UNIT_LEN (17) //一个单元的数据长度
#endif

181
APP/keywd.c Normal file
View File

@@ -0,0 +1,181 @@
#include "keywd.h"
#include "MD5.h"
#include "Flash.h"
extern const u16 CRC16_Table[256];
/*****************************************************************************
* Function : create_keywd
* Description : none
* Input : u8* keyid
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
bool create_keywd(u8* keyid)
{
u8 un_id[12];
u8 md5_id[16];
u16 crc = 0;
u8 index = 0;
if (!read_unique_id(un_id))
{
return FALSE;
}
MD5_code(un_id, md5_id, sizeof(un_id));
for (u16 i = 0; i < KEY_LEN; i++)
{
keyid[i] = rand()%255;
}
for (u32 i = 0; i < KEY_LEN; i++)
{
if ((i % 32) == 0)
{
keyid[i] = md5_id[index++];
if (index >= 16)
{
break;
}
}
}
crc = GetCRC16(keyid, KEY_LEN -2);
keyid[KEY_LEN -2] = (u8)(crc %256);
keyid[KEY_LEN -1] = (u8)(crc /256);
return TRUE;
}
/*****************************************************************************
* Function : set_key_word
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
bool set_key_word(void)
{
u8 keyid[KEY_LEN];
for (u32 i = 0; i < KEY_LEN; i++)
{
if (*((u8*)(FLASH_KEY_ADDRESS + i)) != 0xFF)
{
return FALSE;
}
}
if ( create_keywd(keyid))
{
if (STM32_FlashPageErase(FLASH_KEY_ADDRESS) == FLH_SUCCESS)
{
if (STM32_FlashWrite( FLASH_KEY_ADDRESS, keyid, KEY_LEN) == FLH_SUCCESS)
{
return TRUE;
}
}
return FALSE;
}
else
{
return FALSE;
}
}
/*****************************************************************************
* Function : check_passwd
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
bool check_passwd(void)
{
u8 unid[12];
u8 MD5_ID[16];
u8 passwd[16];
u8 temp;
u8 index = 0;
u16 crc16 = 0xFFFF;
u16 crc_read = 0;
bool new_flash_area = TRUE;
if ( read_unique_id(unid))
{
MD5_code(unid, MD5_ID, sizeof(unid));
}
else
{
return FALSE;
}
for (u16 i = 0; i < KEY_LEN -2; i++)
{
temp = *((u8*)(FLASH_KEY_ADDRESS + i));
if (temp != 0xFF)
{
new_flash_area = FALSE;
}
crc16 = (crc16 >> 8 ) ^ CRC16_Table[(crc16 ^ temp) & 0xFF];
if ( (i % 32) == 0)
{
if (index < sizeof(passwd))
{
passwd[index++] = temp;
}
}
}
crc16 ^= 0xFFFF;
crc_read = *((u8*)(FLASH_KEY_ADDRESS + KEY_LEN - 2)) + *((u8*)(FLASH_KEY_ADDRESS + KEY_LEN - 1))*256;
if (new_flash_area == TRUE)
{
return set_key_word();
}
else
{
if (crc_read == crc16)
{
if (cmp_datas(passwd, MD5_ID, 16))
{
return TRUE;
}
}
return FALSE;
}
}

13
APP/keywd.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef _HEYWD_H_
#define _HEYWD_H_
#include "include.h"
#define KEY_LEN 1024
bool create_keywd(u8* keyid);
bool set_key_word(void);
bool check_passwd(void);
#endif

319
APP/main.c Normal file
View File

@@ -0,0 +1,319 @@
/*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
***************************************************************************
>>! NOTE: The modification to the GPL is included to allow you to !<<
>>! distribute a combined work that includes FreeRTOS without being !<<
>>! obliged to provide the source code for proprietary components !<<
>>! outside of the FreeRTOS kernel. !<<
***************************************************************************
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. Full license text is available on the following
link: http://www.freertos.org/a00114.html
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that is more than just the market leader, it *
* is the industry's de facto standard. *
* *
* Help yourself get started quickly while simultaneously helping *
* to support the FreeRTOS project by purchasing a FreeRTOS *
* tutorial book, reference manual, or both: *
* http://www.FreeRTOS.org/Documentation *
* *
***************************************************************************
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
the FAQ page "My application does not run, what could be wrong?". Have you
defined configASSERT()?
http://www.FreeRTOS.org/support - In return for receiving this top quality
embedded software for free we request you assist our global community by
participating in the support forum.
http://www.FreeRTOS.org/training - Investing in training allows your team to
be as productive as possible as early as possible. Now you can receive
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
Ltd, and the world's leading authority on the world's leading RTOS.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and commercial middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/
/******************************************************************************
* This project provides two demo applications. A low power project that
* demonstrates the FreeRTOS tickless mode, and a more comprehensive test and
* demo application. The configCREATE_LOW_POWER_DEMO setting (defined at the
* top of FreeRTOSConfig.h) is used to select between the two. The low power
* demo is implemented and described in main_low_power.c. The more
* comprehensive test and demo application is implemented and described in
* main_full.c.
*
* This file implements the code that is not demo specific, including the
* hardware setup and FreeRTOS hook functions.
*/
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
/* ST library functions. */
#include "stm32f10x.h"
#include "Led.h"
#include "debug_printf.h"
#include "uart.h"
#include "Init.h"
#include "addr.h"
#include "bl24c512.h"
#include "update.h"
#include "PHY.h"
#include "IRDA.h"
#include "rtc_ext.h"
#include "file.h"
//#include "file.h"
extern u32 time_cur;
extern void dl_task();
extern void rp_task();
/*-----------------------------------------------------------*/
/*
* Set up the hardware ready to run this demo.
*/
static void prvSetupHardware( void );
/*
* main_low_power() is used when configCREATE_LOW_POWER_DEMO is set to 1.
* main_full() is used when configCREATE_LOW_POWER_DEMO is set to 0.
* configCREATE_LOW_POWER_DEMO is defined at the top of main.c.
*/
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
within this file. */
void vApplicationMallocFailedHook( void );
void vApplicationIdleHook( void );
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
void vApplicationTickHook( void );
extern void task_gprs(void *pParam);
extern void frame3762_task(void *pParam);
extern void GDflash_init(void);
extern void sj_up_process();
extern void ctl_task();
extern void sj_ctl_process();
extern void send_to_mbus(void *ptr);
extern void upgrade_task();
extern void send_to_485(void *ptr);
u8 tedtbuf[100];
void vTask_bilnk_led(void * led)
{
//test_led();
//if (self_test_eeprom())
//{
// printf("eeprom test OK\r\n");
//}
//else
//{
// printf("eeprom test err\r\n");
//}
for(;;)
{
COM_led_on(0);
vTaskDelay( 1000 / portTICK_RATE_MS );
COM_led_off(0);
vTaskDelay( 1000 / portTICK_RATE_MS );
}
}
void vTask_wtg(void *ptr)
{
Iwdg_Init(10);
for (;;)
{
FEED_WDG;
vTaskDelay( 2000 / portTICK_RATE_MS );
time_cur = time_cur + 2;
//sj_ctl_process();
}
}
TaskHandle_t vTask_mac_handle;
/*-----------------------------------------------------------*/
void main( void )
{
for (u8 i = 0; i < 255; i++)
{
tedtbuf[i] = i+1;
}
/* Prepare the hardware to run this demo. */
prvSetupHardware();
GDflash_init();
file_read();
//test_crc();
xTaskCreate( vTask_bilnk_led, NULL, 100, NULL, 1, NULL);
xTaskCreate( vTask_wtg, NULL, 70, NULL, 2, NULL);
xTaskCreate( uarts_process_task, NULL, 400, NULL, 3, NULL);
xTaskCreate( ExtRTC_Process_Task, "Extern RTC", 200, NULL, 4, NULL);
xTaskCreate( task_gprs, NULL, 200, NULL, 5, NULL);
xTaskCreate( send_to_485, NULL, 700, NULL, 6, NULL);
xTaskCreate( rp_task, NULL, 400, NULL, 7, NULL);
xTaskCreate( upgrade_task, NULL, 100, NULL, 10, NULL);
task_print_start();
// create_update_task();
vTaskStartScheduler();
/* The configCREATE_LOW_POWER_DEMO setting is described at the top of
this file. */
while(1){};
/* This line will never be reached. */
}
/*-----------------------------------------------------------*/
static void prvSetupHardware( void )
{
void SystemCoreClockUpdate( void ); //在函数内部声明外部函数
RCC_Init();
Nvic_Init();
/* System function that updates the SystemCoreClock variable. */
SystemCoreClockUpdate();
/* Systick is fed from HCLK */
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
/* Essential on STM32 Cortex-M devices. */
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4);
init_all_led();
init_local_addr();
bl24c512_init();
RTC_Init();
}
/*-----------------------------------------------------------*/
void vApplicationMallocFailedHook( void )
{
/* vApplicationMallocFailedHook() will only be called if
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
function that will get called if a call to pvPortMalloc() fails.
pvPortMalloc() is called internally by the kernel whenever a task, queue,
timer or semaphore is created. It is also called by various parts of the
demo application. If heap_1.c or heap_2.c are used, then the size of the
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
to query the size of free heap space that remains (although it does not
provide information on how the remaining heap might be fragmented). */
taskDISABLE_INTERRUPTS();
for( ;; );
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
task. It is essential that code added to this hook function never attempts
to block in any way (for example, call xQueueReceive() with a block time
specified, or call vTaskDelay()). If the application makes use of the
vTaskDelete() API function (as this demo application does) then it is also
important that vApplicationIdleHook() is permitted to return to its calling
function, because it is the responsibility of the idle task to clean up
memory allocated by the kernel to any task that has since been deleted. */
//u32 free_byte = xPortGetFreeHeapSize();
//free_byte += 1;
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
for( ;; );
}
/*-----------------------------------------------------------*/
void vApplicationTickHook( void )
{
/* This function will be called by each tick interrupt if
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
added here, but the tick hook is called from an interrupt context, so
code must not attempt to block, and only the interrupt safe FreeRTOS API
functions can be used (those that end in FromISR()). */
}
/*-----------------------------------------------------------*/
void vAssertCalled( unsigned long ulLine, const char * const pcFileName )
{
volatile unsigned long ulSetToNonZeroInDebuggerToContinue = 0;
/* Parameters are not used. */
( void ) ulLine;
( void ) pcFileName;
taskENTER_CRITICAL();
{
while( ulSetToNonZeroInDebuggerToContinue == 0 )
{
/* Use the debugger to set ulSetToNonZeroInDebuggerToContinue to a
non zero value to step out of this function to the point that raised
this assert(). */
__asm volatile( "NOP" );
__asm volatile( "NOP" );
}
}
taskEXIT_CRITICAL();
}

2209
APP/protocol.c Normal file

File diff suppressed because it is too large Load Diff

693
APP/protocol.h Normal file
View File

@@ -0,0 +1,693 @@
#ifndef __PROTOCOL_H__
#define __PROTOCOL_H__
#include "Basedefine.h"
/************************************************************************
J188 read meter struct
************************************************************************/
typedef struct
{
u8 start68;
u8 type;
u8 id[7];
u8 ctrl;
u8 len;
u8 DI[2];
}ST_J188_head;
typedef struct
{
ST_J188_head head;
u8 SER;
u8 cs;
u8 end;
}ST_J188_read,* PLST_J188_read;
typedef struct
{
u8 current_sum[5];
u8 day_sum[5];
u8 current_time[7];
u8 status[2];
}ST_woter_data_block;
typedef struct
{
ST_J188_head head;
u8 SER;
ST_woter_data_block data_block;
u8 cs;
u8 end;
}ST_J188_read_woter_ack,* PLST_J188_read_woter_ack;
typedef struct
{
ST_J188_head head;
u8 SER;
u8 Data[4];
u8 ST0;
u8 ST1;
u8 cs;
u8 end;
}ST_XYJ188_read_woter_ack,* PLST_XYJ188_read_woter_ack;
typedef struct
{
u8 start68;
u8 type;
u8 id[7];
u8 ctrl;
u8 len;
u8 SER;
u8 status[2];
u8 cs;
u8 end;
}ST_J188_err_ack;
typedef struct
{
ST_J188_head head;
u8 SER;
u8 status[2];
u8 cs;
u8 end;
}ST_J188_ctrl_ack;
typedef struct
{
ST_J188_head head;
u8 cmd;
u8 SER;
u8 cs;
u8 end;
}ST_J188_ctrl;
/************************************************************************
yzsj read meter struct
************************************************************************/
typedef struct
{
u8 start68;
u8 id[6];
u8 end68;
u8 ctrl;
u8 len;
u8 DI0;
u8 DI1;
u8 cs;
u8 end;
}ST_yzsj_read;
typedef struct
{
u8 start68;
u8 data[3];
u8 sum;
}ST_yzsj_ack;
/************************************************************************
HHCQ read meter struct
************************************************************************/
typedef struct
{
u8 start68;
u8 MSA;
u8 SSA;
u8 WMA;
u8 type;
u8 key;
u8 ctrl;
u8 lenH;
u8 lenL;
}ST_HHCQ_head;
typedef struct
{
u8 start68;
u8 MSA;
u8 SSA;
u8 WMA;
u8 type;
u8 key;
u8 ctrl;
u8 lenH;
u8 lenL;
u8 data[4];
u8 crc8;
u8 end16;
}ST_HHCQ_read;
typedef struct
{
u8 start68;
u8 MSA;
u8 SSA;
u8 WMA;
u8 type;
u8 key;
u8 ctrl;
u8 lenH;
u8 lenL;
u8 id[4];
u8 status;
u8 data[4];
u8 crc8;
u8 end16;
}ST_HHCQ_read_woter_ack;
/************************************************************************
CS485 read meter struct
************************************************************************/
typedef struct
{
u8 start68;
u8 default80;
u8 center_addr[6];
u8 ctrl;
u8 dataLen[2];
u8 default70;
u8 DI[2];
}st_CS485_head;
typedef struct
{
st_CS485_head head;
u8 meterCount;
u8 meterID[5];
u8 day;
u8 month;
u8 year;
u8 crc16[2];
u8 end16;
}st_CS485_read;
typedef struct
{
st_CS485_head head;
u8 meterCount;
u8 meterID[5];
u8 min;
u8 hour;
u8 day;
u8 month;
u8 year;
u8 meter_data[4];
u8 status[2];
u8 reserved[2];
u8 crc16[2];
u8 end16;
}st_CS485_ack_ok;
typedef struct
{
st_CS485_head head;
u8 data[3];
u8 crc16[2];
u8 endi6;
}st_CS485_ack_err;
/************************************************************************
NJSM read meter struct
************************************************************************/
typedef struct
{
u8 startEB;
u8 cmd80;
u8 id[4];
u8 len;
u8 cs;
}st_NJSM485_read;
typedef struct
{
u8 startEB;
u8 cmd90;
u8 id[4];
u8 len0F;
u8 data[4];
u8 period[2];
u8 stop[2];
u8 status;
u8 saved[2];
u8 volt[2];
u8 temp[2];
u8 cs;
}st_NJSM485_ack;
/************************************************************************
HZJD read meter struct
************************************************************************/
typedef struct
{
u8 start68;
u8 id[6];
u8 end68;
u8 ctrl;
u8 len;
u8 DI[2];
u8 cs;
u8 end16;
}st_HZJD_read;
typedef struct
{
u8 start68;
u8 id[6];
u8 end68;
u8 ctrl;
u8 len;
u8 DI[2];
u8 data[4];
u8 cs;
u8 end16;
}st_HZJD_ack;
typedef struct
{
u8 start68;
u8 addr[6];
u8 end68;
u8 ctrl;
u8 len;
u8 DI[4];
}ST_645_head;
typedef struct
{
u8 start68;
u8 addr[6];
u8 end68;
u8 ctrl;
u8 len;
u8 id[6];
u8 cs;
u8 end;
}ST_645_read_ADDR;
typedef struct
{
u8 start68;
u8 addr[6];
u8 end68;
u8 ctrl;
u8 len;
u8 defaultAF;
u8 defoult02;
u8 id[6];
u8 cs;
u8 end;
}ST_645_read_ADDR99;
typedef struct
{
u8 start68;
u8 addr[6];
u8 end68;
u8 ctrl;
u8 len;
u8 DI[4];
u8 type;
u8 meter_id[7];
u8 cs;
u8 end;
}ST_645_read_meter;
typedef struct
{
u8 saved5[5];
u8 type_data;
u8 current_sum[5];
u8 day_sum[5];
u8 kpa[2];
u8 current[3];
u8 saved16[16];
u8 time_sum[3];
u8 current_time[7];
u8 status[2];
}ST_645_woter_data_block;
typedef struct
{
u8 frozen_time_flag[3];
u8 teminal_read_time[5];
u8 meter_type;
u8 current_sum[5];
u8 check_day_sum[5];
u8 saved[21];
u8 time_sum[3];
u8 current_time[7];
u8 status[2];
}ST_day_frozen_data_block;
typedef struct
{
u8 start68;
u8 id[6];
u8 end68;
u8 ctrl;
u8 len;
u8 DI[4];
ST_645_woter_data_block data_block;
u8 type;
u8 meter_id[7];
u8 cs;
u8 end;
}ST_645_read_worter_ack;
typedef struct
{
u8 start68;
u8 id[6];
u8 end68;
u8 ctrl;
u8 len;
u8 DI[4];
ST_day_frozen_data_block data_block;
u8 type;
u8 meter_id[7];
u8 cs;
u8 end;
}ST_645_read_frozen_woter_ack;
typedef struct
{
u8 start68;
u8 addr[6];
u8 end68;
u8 ctrl;
u8 len;
u8 DI[2];
u8 MSB;
u8 type;
u8 saved[2];
}ST_645_SFDX_read_meter;
typedef struct
{
u8 start68;
u8 addr[6];
u8 end68;
u8 ctrl;
u8 len;
u8 DI[2];
u8 MSB;
u8 type;
u8 current_sum[5];
u8 day_sum[5];
u8 current_time[7];
u8 status[2];
u8 cs;
u8 end;
}ST_645_SFDX_read_ack;
typedef struct
{
u8 com_databits:2;
u8 com_checkbit:1;
u8 com_checkbit_mask:1;
u8 com_stopbit:1;
u8 com_baud:3;
}ST_comConf;
typedef struct
{
u8 start68;
u8 id[6];
u8 end68;
u8 ctrl;
u8 len;
u8 DI[4];
u8 port;
u8 meter_config;
u8 meter_type;
u8 meter_id[7];
}ST_E5E50000_packet;//E5E50000 E5E50001
typedef struct
{
u8 start68;
u8 id[6];
u8 end68;
u8 ctrl;
u8 len;
u8 DI[4];
}ST_E5E50000_ack;//E5E50000 ack
typedef struct
{
u8 start68;
u8 id[6];
u8 end68;
u8 ctrl;
u8 len;
u8 DI[4];
u8 port;
u8 port_config;
u8 meter_type;
u8 meter_id[7];
ST_J188_read packet188;
u8 cs;
u8 end16;
}ST_E5E50001_packet;//E5E50001
typedef struct
{
u8 start68;
u8 id[6];
u8 end68;
u8 ctrl;
u8 len;
u8 DI[4];
ST_J188_read_woter_ack packet188;
u8 cs;
u8 end16;
}ST_E5E50001_ack; //E5E50001 ack
typedef union
{
ST_645_read_meter * com_upPacket_ptr;
ST_645_SFDX_read_meter * whsf_upPacket_ptr;
ST_E5E50000_packet * e5e50000_upPacket_ptr;
ST_E5E50001_packet * e5e50001_upPacket_ptr;
}un_upPaket;
/*********************************************/
typedef union
{
ST_J188_read * J188_read_ptr;
ST_yzsj_read * yzsj_read_ptr;
ST_HHCQ_read * hhcq_read_ptr;
st_CS485_read * CS485_read_ptr;
st_NJSM485_read * NJSM485_read_ptr;
st_HZJD_read * HZJD_read_ptr;
}un_down_read_Packet;
typedef struct
{
u8 up_protol;
u8 meter_type;
u8 meter_protl;
u8 meter_port;
u8 meter_config;
u8 meter_addr[7];
u8 plc_DI[4];
u8 data[5];
u8 status[2];
u8 j188DI[2];
u8 j188SER;
u8 e5e5dat[200];
u8 e5e5datLen;
}st_params;
#pragma pack(1)
//福建赛达水表集中器抄表协议
typedef struct
{
u8 FIXED_FE1;
u8 FIXED_FE2;
u8 FIXED_FE3;
u8 StartSymbol; //0x68
u8 MeterType;
u8 GPRSAddr[7];
u8 ControlWord;
u8 FrameSum;
u8 FrameSn;
u16 FrameLength;
//Data Area
u8 DataFlag[3];
//u8 DataSn;
u8 MAddr[7];
u8 CS;
u8 ENDSymbol;
}ST_FUJIAN_SDPROTOCOL_READWGDATA,*LPST_FUJIAN_SDPROTOCOL_READWGDATA;
//福建赛达水表集中器抄表返回帧协议
typedef struct
{
u8 StartSymbol; //0x68
u8 MeterType;
u8 GPRSAddr[7];
u8 ControlWord;
u8 FrameSum;
u8 FrameSn;
u16 FrameLength;
//Data Area
u8 DataFlag[3];
//u8 DataSn;
u8 MAddr[7];
u8 DataBuff[6];
u8 CS;
u8 ENDSymbol;
}ST_FUJIAN_SDPROTOCOL_READWGACKDATA,*LPST_FUJIAN_SDPROTOCOL_READWGACKDATA;
typedef struct
{
u8 StartSymbol; //0x68
u8 CAddr[6];
u8 StartaSymbol; //0x68
u8 ControlWord;
u8 DataLength;
//Data Area
u8 MAddr[7];
u8 Data[4];
u8 Status[2];
u8 CS;
u8 ENDSymbol;
}ST_RADIO_MONITOR_DATA_TYPE,*PLST_RADIO_MONITOR_DATA_TYPE;
typedef struct _readmf
{
u8 frameh; //0xAA
u8 companyflag[2];//00 00
u8 ctrl[2];// 06 01
u8 addr[4];// hex => dec
u8 rm_year;//dec
u8 rm_month;//dec
u8 rm_day;//dec
u8 standy[6];//00
u8 cs;//
u8 frameend;//16
}ST_CDRS232_READ_MONTH_DATA_FRAME_TYPE,*PLST_CDRS232_READ_MONTH_DATA_FRAME_TYPE;
#pragma pack()
extern u8 calcrc_1byte(u8 abyte);
extern u8 calcrc_bytes(u8 *p, u16 len);
extern bool check_645_protocol(u8 *buf, u8 length);
extern u8 check_HHQQ_protocol(u8 *buf, u8 length);
extern bool check_j188_protocol(u8 *buf, u8 length);
extern bool check_yzsj_ack_protocol(u8 *buf, u16 len);
extern void code_HHCQ_buf(u8 *buf, u8 len);
extern void create_read_CS485_Meter(u8* id, u8 *outBuf, u16 *outLen);
extern void create_read_HHCQ_Meter(u8 *id, u8 *outBuf, u16 *outLen);
extern void create_read_HYgas_Meter(u8 *id, u8 *outBuf, u16 *outLen);
extern void create_read_HZJD_Meter(u8 *id, u8 *outBuf, u16 *outLen);
extern void create_read_J188_Meter(u8 type, u8 *id, bool j901f, u8 *outBuf, u16 *outLen);
extern void create_read_NJSM485_Meter( u8 *id, u8 *outBuf, u16 *outLen);
extern void create_read_YZSJ_Meter( u8 *id, u8 *outBuf, u16 *outLen);
extern bool CS485_ackPacket_analyse(u8 *inbuf, u16 len, u8 *inID, u8 *out_datas, u8 *out_status);
extern void decode_HHCQ_buf(u8* buf);
extern u8 get_645_packet_length(u8* buf);
extern u8 get_HHCQ_length(u8* buf);
extern u8 get_j188_length(u8 *buf);
extern bool HHCQ_ackPacket_analyse(u8 *inbuf, u16 len, u8 *inID, u8 *out_datas, u8 *out_status);
extern bool HZJD_ackPacket_analyse(u8 *inbuf, u16 len, u8 *inID, u8 *out_datas, u8 *out_status);
extern bool J188_ackPacket_analyse(u8 *inbuf, u16 len, u8 *inID, u8 *out_datas, u8 *out_status);
extern bool NJSM485_ackPacket_analyse(u8 *inbuf, u16 len, u8 *inID, u8 *out_datas, u8 *out_status);
extern u8 * search_645_packet(u8 *buf, u16 length);
extern u8 * search_HHCQ_packet(u8* buf, u8 length);
extern u8 * search_j188_packet(u8 *buf, u16 length);
extern u8 * search_yzsj_packet(u8 *buf, u16 length);
extern u8 transparent_tx(u8 *buf, u8 inlen);
extern bool YZSJ_ackPacket_analyse(u8 *inbuf, u16 len, u8 *inID, u8 *out_datas, u8 *out_status);
extern struct st_meter_temp_value * process_recevied_id(u8 *id);
extern bool check_188_read_meter_packet(u8 *buf, u16 length, u8 *type, u8 *id, u8 *j188DI, u8 *j188SER);
extern void E5E50001_uplinkPacket_create(st_params * ptr, u8* outBuf);
extern void E5E50000_uplinkPacket_create(st_params * ptr, u8 *inbuf, u8 inLen, u8* outBuf);
void CreatFuJian_Protocol_ReadWaterGasMeterDataBlockFrame( u8* str,u8* len,u8* Addr);
u8* CheckFuJian_Protocol_ReadWaterGasMeterDataBlockAckFrame( u8* str,u8 len,u8* Addr);
void CreatFuJian_Protocol_WaterGasMeter645DataACKFrame( u8* Pstr,u8* len,u8* Addr,u8* Data,u8* Ftime);
void CreatFuJian_Protocol_WaterGasMeter645DataERRORACKFrame( u8* Pstr,u8* len,u8* Addr);
u8* CheckFuJian_Protocol_ReadXYWaterMeterDataBlockAckFrame( u8* str,u8 len,u8* Addr);
void CreatFuJian_Protocol_ReadXYWaterMeterDataBlockFrame( u8* str,u8* len,u8* Addr);
void CreatHubei_Protocol_ReadXYWaterMeterDataFrame( u8* str,u16* len,u8* Addr);
u8* CheckHubei_Protocol_ReadXYWaterMeterAckDataFrame( u8* str,u8 len,u8* Addr,u8* outaddr);
void AnalyzeXYDXAckDataFrameProcess(u8* pData,st_params * pstr);
void DLT645_07_watermetertype_ack(u8 *buf);
void CreatXinTian_Protocol_ControlONOFFKey(u8* Pstr,u8* Len,u8* Addr,u8 key);
void CreatChenDianGuoJi_Protocol_ControlWaterGasMeterKeyAckFrame( u8* Pstr,u8* len,st_params * pstr,u16 key);
void CreatChenDianGuoJI_Protocol_WaterGasMeter645DataERRORACKFrame( u8* Pstr,u8* len,st_params * pstr);
void CreatReadChangDeConcentratorData(u8* meter_id,u8* outBuf, u16* outLen);
void CreatReadChangDeConcentratorDate(u8* outBuf, u16* outLen);
//void CreatReadChangDeConcentratorDate(u8* outBuf, u16* outLen);
#endif

506
APP/rtc_ext.c Normal file
View File

@@ -0,0 +1,506 @@
#include "rtc_ext.h"
#include "bl24c512.h"
#include "include.h"
extern void dl_start();
extern void rp_start();
extern bool is_report_time();
extern bool is_dl_time();
extern void hb_timeproc();
st_rtc_ext ERtctime;
void RTC_EXT_da_mode(bool in_mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = RTC_SDA_PIN;
if (in_mode)
{
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
}
else
{
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
}
GPIO_Init(RTC_SDA_PIN_PORT, &GPIO_InitStructure );
}
/*************************************************************
函数功能I2C总线复位。
函数名称I2C_Reset。
函数返回:无返回值。
函数参数:无参数
**************************************************************/
void RTC_EXT_Reset(void)
{
RTC_EXT_da_mode(SDA_MODE_IN);
while(1)
{
RTC_SCL_LOW();
delayedus(1);
RTC_SCL_HIGH();
if( RTC_GET_SDA() ==1 )
{
break;
}
delayedus(1);
}
RTC_EXT_da_mode(SDA_MODE_OUT);
}
void RTC_EXT_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RTC_SDA_PIN_CLK | RTC_SCL_PIN_CLK , ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = RTC_SDA_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(RTC_SDA_PIN_PORT , &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = RTC_SCL_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(RTC_SCL_PIN_PORT , &GPIO_InitStructure );
RTC_EXT_Reset();
}
/*************************************************************
函数功能:产生起始位。
函数名称I2C_GenerateSTART。
函数返回:无返回值。
函数参数:无参数
**************************************************************/
void RTC_EXT_GenerateSTART(void)
{
RTC_SDA_HIGH();//eeprom_da(1);
RTC_SCL_HIGH();//eeprom_clk(1);
delayedus(2);
RTC_SDA_LOW();//eeprom_da(0);
delayedus(2);
RTC_SCL_LOW();//eeprom_clk(0);
delayedus(2);
}
/*************************************************************
函数功能:产生停始位。
函数名称I2C_GenerateSTOP。
函数返回:无返回值。
函数参数:无参数
**************************************************************/
void RTC_EXT_I2C_GenerateSTOP(void)
{
RTC_SDA_LOW();//eeprom_da(0);
delayedus(2);
RTC_SCL_HIGH();//eeprom_clk(1);
RTC_SDA_LOW();//eeprom_da(0);
delayedus(2);
RTC_SDA_HIGH();//eeprom_da(1);
}
/*************************************************************
函数功能:检测应答。
函数名称I2C_check_ack。
函数返回:返回值是应答状态。
函数参数:无参数。
**************************************************************/
unsigned char RTC_EXT_check_ack(void)
{
unsigned char ack=0;
RTC_EXT_da_mode(SDA_MODE_IN);
RTC_SCL_HIGH();//eeprom_clk(1);
//delayedus(1);
if(RTC_GET_SDA() ==1)
{
ack=0;
}
else
{
ack=1;
}
RTC_SCL_LOW();//eeprom_clk(0);
//delayedus(1);
RTC_EXT_da_mode(SDA_MODE_OUT);
return ack;
}
/*************************************************************
函数功能:发送一个应答位。
函数名称I2c_send_ack。
函数返回:无返回值。
函数参数:无。
**************************************************************/
void RTC_EXT_send_ack(void)
{
RTC_SDA_LOW();//eeprom_da(0);
//delayedus(1);
RTC_SCL_LOW();//eeprom_clk(0);
//delayedus(1);
RTC_SCL_HIGH();//eeprom_clk(1);
//delayedus(1);
RTC_SCL_LOW();//eeprom_clk(0);
RTC_SDA_HIGH();//eeprom_da(1);
}
/*************************************************************
函数功能发送一个NO应答。
函数名称I2c_send_no_ack。
函数返回:无返回值。
函数参数:无。
**************************************************************/
void RTC_EXT_send_no_ack(void)
{
RTC_SDA_HIGH();//eeprom_da(1);
//delayedus(1);
RTC_SCL_LOW();//eeprom_clk(0);
//delayedus(1);
RTC_SCL_HIGH();//eeprom_clk(1);
//delayedus(1);
RTC_SCL_LOW();//eeprom_clk(0);
}
/*************************************************************
函数功能I2C发送一个字节。
函数名称I2c_send_byte。
函数返回:无返回值。
函数参数:无。
**************************************************************/
void RTC_EXT_send_byte(unsigned char data )
{
unsigned char i;
RTC_SCL_LOW(); //eeprom_clk(0);//clk 0
for(i=0;i<8;i++)
{
if((data&0x80)==0x80)
{
RTC_SDA_HIGH();//eeprom_da(1);
}
else
{
RTC_SDA_LOW(); //eeprom_da(0);
}
RTC_SCL_HIGH(); //eeprom_clk(1);//clk 1
//delayedus(1);
RTC_SCL_LOW(); //eeprom_clk(0);//clk 0
//delayedus(1);
data<<=1;
}
delayedus(90);
}
/*************************************************************
函数功能I2C接收一个字节。
函数名称I2c_receive_byte。
函数返回:无返回值。
函数参数:无。
**************************************************************/
unsigned char RTC_EXT_receive_byte(void)
{
unsigned char i;
unsigned char rda=0;
RTC_EXT_da_mode(SDA_MODE_IN);
RTC_SCL_LOW(); //eeprom_clk(0);//clk 0
//delayedus(1);
for(i=0;i<8;i++)
{
rda<<=1;
RTC_SCL_HIGH(); //eeprom_clk(1);//clk 1
//delayedus(1);
if(RTC_GET_SDA() ==1 )
{
rda|=0x01;
}
else
{
rda&=0xFE;
}
RTC_SCL_LOW(); //eeprom_clk(0);//clk
//delayedus(1);
}
RTC_EXT_da_mode(SDA_MODE_OUT);
return rda;
}
/*************************************************************
函数功能RTC8025T读reg
函数名称RTC_read_reg。
函数返回:
函数参数:
**************************************************************/
bool RTC_read_reg(u8 reg, u8 *dat)
{
RTC_EXT_GenerateSTART();
RTC_EXT_send_byte(RTC_WRIT_ADDR);
if(RTC_EXT_check_ack()==0)
{
return FALSE;
}
RTC_EXT_send_byte(reg);
if(RTC_EXT_check_ack()==0)
{
return FALSE;
}
RTC_EXT_GenerateSTART();
RTC_EXT_send_byte(RTC_READ_ADDR);
if(RTC_EXT_check_ack()==0)
{
return FALSE;
}
*dat = RTC_EXT_receive_byte();
RTC_EXT_send_no_ack();
delayedus(1);
RTC_EXT_I2C_GenerateSTOP();
return TRUE;
}
/*************************************************************
函数功能RTC8025T写reg
函数名称RTC_write_reg。
函数返回:
函数参数:
**************************************************************/
bool RTC_write_reg(u8 reg, u8 dat)
{
RTC_EXT_GenerateSTART();
RTC_EXT_send_byte(RTC_WRIT_ADDR);
if(RTC_EXT_check_ack()==0)
{
return FALSE;
}
RTC_EXT_send_byte(reg);
if(RTC_EXT_check_ack()==0)
{
return FALSE;
}
RTC_EXT_send_byte(dat);
if(RTC_EXT_check_ack()==0)
{
return FALSE;
}
RTC_EXT_I2C_GenerateSTOP();
return TRUE;
}
/*************************************************************
函数功能EEPROM任意地址读一字节。
函数名称RTC_test
函数返回:
函数参数:
**************************************************************/
void RTC_test(void)
{
u8 dat_year;
u8 dat_mon;
u8 dat_day;
RTC_EXT_init();
RTC_read_reg(RTC_REG_MONTH, &dat_mon);
RTC_read_reg(RTC_REG_YEAR, &dat_year);
RTC_read_reg(RTC_REG_DAY , &dat_day);
RTC_write_reg(RTC_REG_YEAR, 16);
RTC_write_reg(RTC_REG_MONTH, 6);
RTC_write_reg(RTC_REG_DAY, 14);
RTC_read_reg(RTC_REG_YEAR, &dat_year);
RTC_read_reg(RTC_REG_MONTH, &dat_mon);
RTC_read_reg(RTC_REG_DAY , &dat_day);
printf("%d/%d/%d\r\n", dat_year, dat_mon, dat_day);
}
void set_rtc_time(st_rtc_ext rtc_dat)
{
RTC_EXT_init();
RTC_write_reg(RTC_REG_SEC, rtc_dat.sec);
RTC_write_reg(RTC_REG_MIN, rtc_dat.min);
RTC_write_reg(RTC_REG_HOUR, rtc_dat.hour);
RTC_write_reg(RTC_REG_WEEK, rtc_dat.week);
RTC_write_reg(RTC_REG_DAY, rtc_dat.day);
RTC_write_reg(RTC_REG_MONTH, rtc_dat.month);
RTC_write_reg(RTC_REG_YEAR, rtc_dat.year);
}
void read_rtc_time(st_rtc_ext * rtc_dat)
{
RTC_EXT_init();
st_rtc_ext TempTime1,TempTime2;
/*
RTC_read_reg(RTC_REG_SEC, &rtc_dat->sec);
RTC_read_reg(RTC_REG_MIN, &rtc_dat->min);
RTC_read_reg(RTC_REG_HOUR, &rtc_dat->hour);
RTC_read_reg(RTC_REG_WEEK, &rtc_dat->week);
RTC_read_reg(RTC_REG_DAY, &rtc_dat->day);
RTC_read_reg(RTC_REG_MONTH, &rtc_dat->month);
RTC_read_reg(RTC_REG_YEAR, &rtc_dat->year);
*/
for(u8 n=0 ;n<3; n++)
{
RTC_read_reg(RTC_REG_SEC, &TempTime1.sec);
RTC_read_reg(RTC_REG_MIN, &TempTime1.min);
RTC_read_reg(RTC_REG_HOUR, &TempTime1.hour);
RTC_read_reg(RTC_REG_WEEK, &TempTime1.week);
RTC_read_reg(RTC_REG_DAY, &TempTime1.day);
RTC_read_reg(RTC_REG_MONTH, &TempTime1.month);
RTC_read_reg(RTC_REG_YEAR, &TempTime1.year);
RTC_read_reg(RTC_REG_SEC, &TempTime2.sec);
RTC_read_reg(RTC_REG_MIN, &TempTime2.min);
RTC_read_reg(RTC_REG_HOUR, &TempTime2.hour);
RTC_read_reg(RTC_REG_WEEK, &TempTime2.week);
RTC_read_reg(RTC_REG_DAY, &TempTime2.day);
RTC_read_reg(RTC_REG_MONTH, &TempTime2.month);
RTC_read_reg(RTC_REG_YEAR, &TempTime2.year);
if((TempTime1.sec == TempTime2.sec) &&
(TempTime1.min == TempTime2.min) &&
(TempTime1.hour == TempTime2.hour) &&
(TempTime1.week == TempTime2.week) &&
(TempTime1.day == TempTime2.day) &&
(TempTime1.month == TempTime2.month) &&
(TempTime1.year == TempTime2.year)
)
{
rtc_dat->sec = TempTime1.sec;
rtc_dat->min = TempTime1.min;
rtc_dat->hour = TempTime1.hour;
rtc_dat->week = TempTime1.week;
rtc_dat->day = TempTime1.day;
rtc_dat->month = TempTime1.month;
rtc_dat->year = TempTime1.year;
return;
}
}
RTC_read_reg(RTC_REG_SEC, &rtc_dat->sec);
RTC_read_reg(RTC_REG_MIN, &rtc_dat->min);
RTC_read_reg(RTC_REG_HOUR, &rtc_dat->hour);
RTC_read_reg(RTC_REG_WEEK, &rtc_dat->week);
RTC_read_reg(RTC_REG_DAY, &rtc_dat->day);
RTC_read_reg(RTC_REG_MONTH, &rtc_dat->month);
RTC_read_reg(RTC_REG_YEAR, &rtc_dat->year);
}
void read_rtc_stime(sTime *time_dat)
{
RTC_EXT_init();
RTC_read_reg(RTC_REG_SEC, &time_dat->second);
RTC_read_reg(RTC_REG_MIN, &time_dat->minute);
RTC_read_reg(RTC_REG_HOUR, &time_dat->hour);
RTC_read_reg(RTC_REG_DAY, &time_dat->day);
RTC_read_reg(RTC_REG_MONTH, &time_dat->month);
RTC_read_reg(RTC_REG_YEAR, &time_dat->year);
}
u8* GetCurrentTime( void )
{
return (u8*)&ERtctime;
}
void GetExternClockTime(st_rtc_ext * rtc_dat)
{
MemCpy((u8*)rtc_dat,(u8*)&ERtctime,sizeof(st_rtc_ext));
}
bool CheckTimeDate( st_rtc_ext * rtc_dat )
{
if(rtc_dat->year < 0x17) return FALSE;
if((rtc_dat->month > 0x12) || (rtc_dat->month == 0x00) )return FALSE;
if((rtc_dat->day > 0x31) || (rtc_dat->day == 0x00) ) return FALSE;
if(rtc_dat->hour > 0x24) return FALSE;
if(rtc_dat->min > 0x60) return FALSE;
if(rtc_dat->sec > 0x60) return FALSE;
if(rtc_dat->week > 0x06) return FALSE;
return TRUE;
}
static bool is_reset = false;
static u32 reset_count = 0;
void ExtRTC_Process_Task(void *ptr)
{
RTC_EXT_init();
read_rtc_time(&ERtctime);
// if( ( CheckBCDFormat( (u8*)&ERtctime, sizeof(&ERtctime) ) == FALSE ) || (CheckTimeDate(&ERtctime) == FALSE) )
// {
// ERtctime.year = 0x17;
// ERtctime.month = 0x07;
// ERtctime.day = 0x01;
// ERtctime.hour = 0x10;
// ERtctime.min = 0x23;
// ERtctime.sec = 0x45;
// ERtctime.week = 0x06;
//
// set_rtc_time(ERtctime);
// }
for (;;)
{
read_rtc_time(&ERtctime);
vTaskDelay( 2000 / portTICK_RATE_MS );
hb_timeproc();
if(ERtctime.hour==0x09 && ERtctime.min == 0x30)
{
is_reset = true;
}
if(is_reset)
{
reset_count ++ ;
if(reset_count>60)
{
SysReset();
}
}
}
}

72
APP/rtc_ext.h Normal file
View File

@@ -0,0 +1,72 @@
#ifndef _RTC_EXT_H_
#define _RTC_EXT_H_
#include "Basedefine.h"
#include "stm32f10x.h"
#include "Rtc.h"
typedef struct
{
u8 sec;
u8 min;
u8 hour;
u8 day;
u8 month;
u8 year;
u8 week;
}st_rtc_ext,*PLst_rtc_ext;
#define RTC_WRIT_ADDR 0x64
#define RTC_READ_ADDR 0x65
#define RTC_REG_SEC 0x00
#define RTC_REG_MIN 0x01
#define RTC_REG_HOUR 0x02
#define RTC_REG_WEEK 0x03
#define RTC_REG_DAY 0x04
#define RTC_REG_MONTH 0x05
#define RTC_REG_YEAR 0x06
#define RTC_REG_RAM 0x07
#define RTC_REG_MIN_Alarm 0x08
#define RTC_REG_WEEK_Alarm 0x09
#define RTC_REG_DAY_Alarm 0x0A
#define RTC_REG_COUNT0 0x0B
#define RTC_REG_COUNT1 0x0C
#define RTC_REG_EXT 0x0D
#define RTC_REG_FLAG 0x0E
#define RTC_REG_CTRL 0x0F
#define RTC_SDA_PIN GPIO_Pin_9
#define RTC_SDA_PIN_PORT GPIOB
#define RTC_SDA_PIN_CLK RCC_APB2Periph_GPIOB
#define RTC_SCL_PIN GPIO_Pin_8
#define RTC_SCL_PIN_PORT GPIOB
#define RTC_SCL_PIN_CLK RCC_APB2Periph_GPIOB
#define RTC_SDA_HIGH() GPIO_SetBits(RTC_SDA_PIN_PORT, RTC_SDA_PIN)
#define RTC_SDA_LOW() GPIO_ResetBits(RTC_SDA_PIN_PORT, RTC_SDA_PIN)
#define RTC_SCL_HIGH() GPIO_SetBits(RTC_SCL_PIN_PORT, RTC_SCL_PIN)
#define RTC_SCL_LOW() GPIO_ResetBits(RTC_SCL_PIN_PORT, RTC_SCL_PIN)
#define RTC_GET_SDA() GPIO_ReadInputDataBit( RTC_SDA_PIN_PORT, RTC_SDA_PIN)
void set_rtc_time(st_rtc_ext rtc_dat);
void read_rtc_time(st_rtc_ext * rtc_dat);
void read_rtc_stime(sTime *time_dat);
void read_rtc_stime(sTime *time_dat);
void RTC_test(void);
void ExtRTC_Process_Task(void *ptr);
void GetExternClockTime(st_rtc_ext * rtc_dat);
void set_rtc_time(st_rtc_ext rtc_dat);
u8* GetCurrentTime( void );
#endif

32
APP/storage.c Normal file
View File

@@ -0,0 +1,32 @@
/********************************************************************************
**** Copyright (C), 2017, xx xx xx xx info&tech Co., Ltd. ****
********************************************************************************
* File Name : storage.c
* Author : barry
* Date : 2017-02-21
* Description : .C file function description
* Version : 1.0
* Function List :
*
* Record :
* 1.Date : 2017-02-21
* Author : barry
* Modification: Created file
*************************************************************************************************************/
#include "storage.h"
#include "protocol.h"
#include "General.h"
#include "debug_printf.h"
#include "bl24c512.h"
#include "Mem.h"
#include "update.h"
#include "Flash.h"
#include "uart.h"
// I2C_eeprom_write_buf(WM_ADDR_MANAGER_UNIT_ADDR +5 + (Pload->Index * sizeof(METER_STRUCT_UNITTYPE)), (u8*)Pload, sizeof(METER_STRUCT_UNITTYPE));
// I2C_eeprom_read_buf(WM_ADDR_MANAGER_UNIT_ADDR +5 , (u8*)&SJManager.Info[0].Index, sizeof(METER_STRUCT_UNITTYPE)*SJManager.AddrSum);

32
APP/storage.h Normal file
View File

@@ -0,0 +1,32 @@
#ifndef _STORAGE_H_
#define _STORAGE_H_
#include "Basedefine.h"
#define SLAVE_NODE_SIZE 64
#define SLAVE_NODE_MAX 10
#define INVALID_POS_FLAG 0xFFFF
#define VALID_NODE_FLAG 0x8899
#define INVALID_NODE_FLAG 0xAABB
#define EEPROM_METER_CONFIG 0
#define SLAVE_NODE_LEN_ADDR EEPROM_PAGE_SIZE*2 //档案长度存储位置
#define SLAVE_NODE_DOC_ADDR EEPROM_PAGE_SIZE*3 //档案数据存储位置
#define WM_ADDR_MANAGER_UNIT_ADDR (EEPROM_PAGE_SIZE*5) //存储水表地址数据以及管理单元
#define XYDX_WATERMETER_MONITOR EEPROM_PAGE_SIZE*165 //档案数据存储位置
#define DEFAULT_MAINTAIN_TIME 1
#define FRALED_COUNT 3
#define INNER_FLASH_PAGE_SIZE 2048
#endif

638
APP/sx1276-Fsk.c Normal file
View File

@@ -0,0 +1,638 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) SEMTECH S.A.
*/
/*!
* \file sx1276.c
* \brief SX1276 RF chip driver
*
* \version 2.0.0
* \date May 6 2013
* \author Gregory Cristian
*
* Last modified by Miguel Luis on Jun 19 2013
*/
#include <string.h>
#include <math.h>
#include "include.h"
#include "sx1276-Fsk.h"
#include "sx1276-FskMisc.h"
#include "hal_radio.h"
// Default settings
tFskSettings FskSettings =
{
492000000, // RFFrequency
10000, // Bitrate
20000, // Fdev
0, // Power
40000, // RxBw
150000, // RxBwAfc
true, // CrcOn
true, // AfcOn
255 // PayloadLength (set payload size to the maximum for variable mode, else set the exact payload length)
};
extern struct etimer timer_rf;
sRF_FSK g_fsk = {
.states = RF_STATE_IDLE,
.index = 0,
.packetLenth = 0,
.rssi = 0.0,
.sync_timeout = 1000,
.plyloadtimeout = 1000
};
void SX1276Fsk_recrive_Packet(void);
/*!
* SX1276 FSK registers variable
*/
extern uint8_t SX1276Regs[];
tSX1276* SX1276 = ( tSX1276* )SX1276Regs;;
/*!
* Local RF buffer for communication support
*/
static uint8_t RFBuffer[RF_BUFFER_SIZE];
/*!
* Chunk size of data write in buffer
*/
//static uint8_t DataChunkSize = 32;
/*!
* RF state machine variable
*/
static uint8_t RFState = RF_STATE_IDLE;
/*!
* Rx management support variables
*/
/*!
* PacketTimeout holds the RF packet timeout
* SyncSize = [0..8]
* VariableSize = [0;1]
* AddressSize = [0;1]
* PayloadSize = [0..RF_BUFFER_SIZE]
* CrcSize = [0;2]
* PacketTimeout = ( ( 8 * ( VariableSize + AddressSize + PayloadSize + CrcSize ) / BR ) * 1000.0 ) + 1
* Computed timeout is in miliseconds
*/
//static uint32_t PacketTimeout;
/*!
* Preamble2SyncTimeout
* Preamble2SyncTimeout = ( ( 8 * ( PremableSize + SyncSize ) / RFBitrate ) * 1000.0 ) + 1
* Computed timeout is in miliseconds
*/
//static uint32_t Preamble2SyncTimeout;
//static bool PreambleDetected = false;
//static bool SyncWordDetected = false;
//static bool PacketDetected = false;
static uint16_t RxPacketSize = 0;
//static uint8_t RxBytesRead = 0;
//static uint8_t TxBytesSent = 0;
static double RxPacketRssiValue;
static uint32_t RxPacketAfcValue;
static uint8_t RxGain = 1;
//static uint32_t RxTimeoutTimer = 0;
//static uint32_t Preamble2SyncTimer = 0;
//static bool firstReceiveByte = true;
/*!
* Tx management support variables
*/
static uint16_t TxPacketSize = 0;
//static uint32_t TxTimeoutTimer = 0;
void SX1276FskInit( void )
{
SX1276FskSetOpMode( RF_OPMODE_SLEEP );
SX1276->RegOpMode = ( SX1276->RegOpMode & 0x7F ) | 0x00;
SX1276Write( REG_OPMODE, SX1276->RegOpMode );
SX1276FskSetOpMode( RF_OPMODE_STANDBY );
SX1276FskSetDefaults( );
SX1276ReadBuffer( REG_OPMODE, SX1276Regs + 1, 0x70 - 1 );
// Set the device in FSK mode and Sleep Mode
SX1276->RegOpMode = RF_OPMODE_MODULATIONTYPE_FSK | RF_OPMODE_SLEEP;
SX1276Write( REG_OPMODE, SX1276->RegOpMode );
SX1276->RegPaRamp = RF_PARAMP_MODULATIONSHAPING_01;
SX1276Write( REG_PARAMP, SX1276->RegPaRamp );
SX1276->RegLna = RF_LNA_GAIN_G1;
SX1276Write( REG_LNA, SX1276->RegLna );
SX1276->RegRxConfig = ( FskSettings.AfcOn == true ) ? RF_RXCONFIG_AFCAUTO_ON: RF_RXCONFIG_AFCAUTO_OFF;
SX1276->RegRxConfig |= RF_RXCONFIG_RESTARTRXONCOLLISION_OFF | RF_RXCONFIG_AGCAUTO_ON;// |RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT;
if( FskSettings.AfcOn == true )
{
SX1276->RegRxConfig = RF_RXCONFIG_RESTARTRXONCOLLISION_OFF | RF_RXCONFIG_AFCAUTO_ON |
RF_RXCONFIG_AGCAUTO_ON;// |RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT;
}
else
{
SX1276->RegRxConfig = RF_RXCONFIG_RESTARTRXONCOLLISION_OFF | RF_RXCONFIG_AFCAUTO_OFF |
RF_RXCONFIG_AGCAUTO_ON;// | RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT;
}
SX1276->RegPreambleLsb = 30;
SX1276->RegPreambleDetect = RF_PREAMBLEDETECT_DETECTOR_ON | RF_PREAMBLEDETECT_DETECTORSIZE_3 |
RF_PREAMBLEDETECT_DETECTORTOL_10;
SX1276->RegRssiThresh = 0xFF;
SX1276->RegSyncConfig = RF_SYNCCONFIG_AUTORESTARTRXMODE_OFF | RF_SYNCCONFIG_PREAMBLEPOLARITY_AA |
RF_SYNCCONFIG_SYNC_ON |
RF_SYNCCONFIG_SYNCSIZE_4;
SX1276->RegSyncValue1 = 0x69;
SX1276->RegSyncValue2 = 0x81;
SX1276->RegSyncValue3 = 0x7E;
SX1276->RegSyncValue4 = 0x96;
SX1276->RegPacketConfig1 = RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE | RF_PACKETCONFIG1_DCFREE_OFF |
( FskSettings.CrcOn << 4 ) | RF_PACKETCONFIG1_CRCAUTOCLEAR_OFF |
RF_PACKETCONFIG1_ADDRSFILTERING_OFF | RF_PACKETCONFIG1_CRCWHITENINGTYPE_CCITT;
SX1276FskGetPacketCrcOn( ); // Update CrcOn on FskSettings
SX1276->RegPayloadLength = FskSettings.PayloadLength;
// we can now update the registers with our configuration
SX1276WriteBuffer( REG_OPMODE, SX1276Regs + 1, 0x70 - 1 );
// then we need to set the RF settings
SX1276FskSetRFFrequency( FskSettings.RFFrequency );
SX1276FskSetBitrate( FskSettings.Bitrate );
SX1276FskSetFdev( FskSettings.Fdev );
SX1276FskSetDccBw( &SX1276->RegRxBw, 0, FskSettings.RxBw );
SX1276FskSetDccBw( &SX1276->RegAfcBw, 0, FskSettings.RxBwAfc );
SX1276FskSetRssiOffset( 0 );
SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_RFO );
//SX1276FskSetPAOutput( RF_PACONFIG_PASELECT_PABOOST );
SX1276FskSetPa20dBm( false );
SX1276FskSetRFPower( FskSettings.Power );
SX1276FskSetOpMode( RF_OPMODE_STANDBY );
// Calibrate the HF
SX1276FskRxCalibrate( );
g_fsk.sync_timeout = (u16)(8*8*1000/FskSettings.Bitrate) + 5;
g_fsk.plyloadtimeout = (u16)(255*2*8*1000/FskSettings.Bitrate) + 5;
SX1276Fsk_recrive_Packet();
}
void SX1276FskSetDefaults( void )
{
// REMARK: See SX1276 datasheet for modified default values.
SX1276Read( REG_VERSION, &SX1276->RegVersion );
}
void SX1276FskSetOpMode( uint8_t opMode )
{
static uint8_t opModePrev = RF_OPMODE_STANDBY;
static bool antennaSwitchTxOnPrev = true;
bool antennaSwitchTxOn = false;
opModePrev = SX1276->RegOpMode & ~RF_OPMODE_MASK;
if( opMode != opModePrev )
{
if( opMode == RF_OPMODE_TRANSMITTER )
{
antennaSwitchTxOn = true;
}
else
{
antennaSwitchTxOn = false;
}
if( antennaSwitchTxOn != antennaSwitchTxOnPrev )
{
antennaSwitchTxOnPrev = antennaSwitchTxOn;
//RXTX( antennaSwitchTxOn ); // Antenna switch control
}
SX1276->RegOpMode = ( SX1276->RegOpMode & RF_OPMODE_MASK ) | opMode;
SX1276Write( REG_OPMODE, SX1276->RegOpMode );
}
}
uint8_t SX1276FskGetOpMode( void )
{
SX1276Read( REG_OPMODE, &SX1276->RegOpMode );
return SX1276->RegOpMode & ~RF_OPMODE_MASK;
}
int32_t SX1276FskReadFei( void )
{
SX1276ReadBuffer( REG_FEIMSB, &SX1276->RegFeiMsb, 2 ); // Reads the FEI value
return ( int32_t )(( double )( ( ( uint16_t )SX1276->RegFeiMsb << 8 ) | ( uint16_t )SX1276->RegFeiLsb ) * ( double )FREQ_STEP);
}
int32_t SX1276FskReadAfc( void )
{
SX1276ReadBuffer( REG_AFCMSB, &SX1276->RegAfcMsb, 2 ); // Reads the AFC value
return ( int32_t )(( double )( ( ( uint16_t )SX1276->RegAfcMsb << 8 ) | ( uint16_t )SX1276->RegAfcLsb ) * ( double )FREQ_STEP);
}
uint8_t SX1276FskReadRxGain( void )
{
SX1276Read( REG_LNA, &SX1276->RegLna );
return( SX1276->RegLna >> 5 ) & 0x07;
}
double SX1276FskReadRssi( void )
{
SX1276Read( REG_RSSIVALUE, &SX1276->RegRssiValue ); // Reads the RSSI value
return -( double )( ( double )SX1276->RegRssiValue / 2.0 );
}
uint8_t SX1276FskGetPacketRxGain( void )
{
return RxGain;
}
double SX1276FskGetPacketRssi( void )
{
return RxPacketRssiValue;
}
uint32_t SX1276FskGetPacketAfc( void )
{
return RxPacketAfcValue;
}
/*
void SX1276FskStartRx( void )
{
SX1276FskSetRFState( RF_STATE_RX_INIT );
}
*/
void SX1276FskGetRxPacket( void *buffer, uint16_t *size )
{
*size = RxPacketSize;
RxPacketSize = 0;
memcpy( ( void * )buffer, ( void * )RFBuffer, ( size_t )*size );
}
void SX1276FskSetTxPacket( const void *buffer, uint16_t size )
{
TxPacketSize = size;
memcpy( ( void * )RFBuffer, buffer, ( size_t )TxPacketSize );
RFState = RF_STATE_TX_INIT;
}
// Remark: SX1276 must be fully initialized before calling this function
uint16_t SX1276FskGetPacketPayloadSize( void )
{
uint16_t syncSize;
uint16_t variableSize;
uint16_t addressSize;
uint16_t payloadSize;
uint16_t crcSize;
syncSize = ( SX1276->RegSyncConfig & 0x07 ) + 1;
variableSize = ( ( SX1276->RegPacketConfig1 & 0x80 ) == 0x80 ) ? 1 : 0;
addressSize = ( ( SX1276->RegPacketConfig1 & 0x06 ) != 0x00 ) ? 1 : 0;
payloadSize = SX1276->RegPayloadLength;
crcSize = ( ( SX1276->RegPacketConfig1 & 0x10 ) == 0x10 ) ? 2 : 0;
return syncSize + variableSize + addressSize + payloadSize + crcSize;
}
// Remark: SX1276 must be fully initialized before calling this function
uint16_t SX1276FskGetPacketHeaderSize( void )
{
uint16_t preambleSize;
uint16_t syncSize;
preambleSize = ( ( uint16_t )SX1276->RegPreambleMsb << 8 ) | ( uint16_t )SX1276->RegPreambleLsb;
syncSize = ( SX1276->RegSyncConfig & 0x07 ) + 1;
return preambleSize + syncSize;
}
uint8_t SX1276FskGetRFState( void )
{
return RFState;
}
void SX1276FskSetRFState( uint8_t state )
{
RFState = state;
}
void start_continuous_mode(void)
{
//4、BitSyncOn
//5、continuous mode
//6、RX
u8 RegDioMapping[2];
u8 temp = 0;;
SX1276FskSetOpMode(RF_OPMODE_STANDBY);
switch_Rx();
RegDioMapping[0] = RF_DIOMAPPING1_DIO0_11 | RF_DIOMAPPING1_DIO1_00 | RF_DIOMAPPING1_DIO2_11 | RF_DIOMAPPING1_DIO3_10;
RegDioMapping[1] = RF_DIOMAPPING2_DIO4_00 | RF_DIOMAPPING2_DIO5_11 | RF_DIOMAPPING2_MAP_PREAMBLEDETECT;
SX1276WriteBuffer( REG_DIOMAPPING1, RegDioMapping, 2 );
SX1276Read(REG_OOKPEAK, &temp);
temp |= (0x20);
SX1276Write(REG_OOKPEAK, temp);
SX1276Read(REG_PACKETCONFIG2, &temp);
temp &= (~0x40);
SX1276Write(REG_PACKETCONFIG2, temp);
SX1276FskSetOpMode(RF_OPMODE_RECEIVER);
}
void packet_tx_data(u8 *PBuffer,u8 length)
{
g_fsk.buffer[0] = length;
memcpy( ( void * )(g_fsk.buffer+1), PBuffer, length);
g_fsk.packetLenth = length + 1;
g_fsk.index = 0;
}
void fill_fifo(void)
{
u8 sendLenth;
u8 leftlength = g_fsk.packetLenth - g_fsk.index;
if (g_fsk.index == 0)
{
if (leftlength <= 64)
{
SX1276WriteFifo(g_fsk.buffer, leftlength);
g_fsk.index += leftlength;
hal_DIOx_ITConfig(1,DISABLE);
}
else
{
SX1276WriteFifo(g_fsk.buffer, 64);
g_fsk.index += 64;
}
}
else if (g_fsk.index < g_fsk.packetLenth)
{
sendLenth = ( leftlength > (FIFO_LENGTH - TX_FIFO_THRESHOLD) ? (FIFO_LENGTH - TX_FIFO_THRESHOLD) : leftlength);
SX1276WriteFifo(g_fsk.buffer+g_fsk.index, sendLenth);
g_fsk.index += sendLenth;
}
}
void contious_tx(void)
{
SX1276->RegFifoThresh = RF_FIFOTHRESH_TXSTARTCONDITION_FIFOTHRESH | TX_FIFO_THRESHOLD; // 24 bytes of data
SX1276Write( REG_FIFOTHRESH, SX1276->RegFifoThresh );
switch_Tx();
SX1276FskSetOpMode( RF_OPMODE_TRANSMITTER );
}
void read_fifo(bool rxdone)
{
u8 leftlength;
if (g_fsk.index == 0)
{
SX1276ReadFifo(&g_fsk.packetLenth , 1);
}
leftlength = g_fsk.packetLenth - g_fsk.index;
if (rxdone)
{
if (leftlength <= FIFO_LENGTH)
{
//hal_DIOx_ITConfig(all,DISABLE);
SX1276ReadFifo(g_fsk.buffer+g_fsk.index, leftlength);
}
}
else
{
if (g_fsk.index < (g_fsk.packetLenth -1) )
{
SX1276ReadFifo(g_fsk.buffer+g_fsk.index, RX_FIFO_THRESHOLD);
g_fsk.index += RX_FIFO_THRESHOLD;
}
leftlength = g_fsk.packetLenth - g_fsk.index;
if (leftlength <= FIFO_LENGTH)
{
hal_DIOx_ITConfig(1,DISABLE);
}
}
}
void SX1276Fsk_Send_Packet(u8 *PBuffer,u8 length)
{
hal_DIOx_ITConfig(all, DISABLE);
SX1276FskSetOpMode( RF_OPMODE_STANDBY );
// PacketSent, FifoLevel, FifoFull, TxReady
SX1276->RegDioMapping1 = packet_DIO0_packetSend | packet_DIO1_fifoLevel | packet_DIO2_fifoFull | packet_DIO3_TxReady;
// LowBat, Data
SX1276->RegDioMapping2 = packet_DIO4_TimeOut | packet_DIO5_Data ;
SX1276WriteBuffer( REG_DIOMAPPING1, &SX1276->RegDioMapping1, 2 );
SX1276->RegFifoThresh = RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY | TX_FIFO_THRESHOLD; // 24 bytes of data
SX1276Write( REG_FIFOTHRESH, SX1276->RegFifoThresh );
packet_tx_data(PBuffer, length);
hal_DIOx_ITConfig(0,ENABLE);
hal_DIOx_ITConfig(1,ENABLE);
fill_fifo();
switch_Tx();
g_fsk.states = RF_STATE_TX_RUNNING;
SX1276FskSetOpMode( RF_OPMODE_TRANSMITTER );
}
void SX1276Fsk_recrive_Packet(void)
{
SX1276FskSetOpMode( RF_OPMODE_STANDBY );
hal_DIOx_ITConfig(all, DISABLE);
SX1276->RegDioMapping1 = packet_DIO0_RxpayloadReady | packet_DIO1_fifoLevel | packet_DIO2_SyncAddress | packet_DIO3_fifoEmpty;
// LowBat, Data
SX1276->RegDioMapping2 = packet_DIO4_Rssi_PreambleDetect | packet_DIO5_Data | RF_DIOMAPPING2_MAP_PREAMBLEDETECT;
SX1276WriteBuffer( REG_DIOMAPPING1, &SX1276->RegDioMapping1, 2 );
SX1276->RegFifoThresh = RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY | RX_FIFO_THRESHOLD; // 24 bytes of data
SX1276Write( REG_FIFOTHRESH, SX1276->RegFifoThresh );
g_fsk.states = RF_STATE_RX_INIT;
g_fsk.index = 0;
hal_DIOx_ITConfig(4,ENABLE);
hal_DIOx_ITConfig(0,ENABLE);
hal_DIOx_ITConfig(1,ENABLE);
hal_DIOx_ITConfig(2,ENABLE);
hal_DIOx_ITConfig(3,ENABLE);
switch_Rx();
SX1276FskSetOpMode( RF_OPMODE_RECEIVER );
}
#if 0
/*****************************************************************************
Prototype : GPIO_EVEN_IRQHandler
Description :
Input : void
Output : None
Return Value :
Date : 2016/08/15
Author : Barry
*****************************************************************************/
void GPIO_EVEN_IRQHandler(void)
{
u32 flags = GPIO->IF;
GPIO->IFC = flags;
if(flags & (1 << sRF_DIO0_PIN) )
{
hal_DIOx_ITConfig(all, DISABLE);
hal_sRF_ClearAllRF_IT();
if(g_fsk.states == RF_STATE_TX_RUNNING)
{
// Tx done
SX1276FskSetOpMode( RF_OPMODE_STANDBY );
g_fsk.states = RF_STATE_TX_DONE;
process_post(&hal_RF_process, PROCESS_EVENT_MSG, (void *)(&g_fsk.states));
}
if(g_fsk.states == RF_STATE_RX_SYNC)
{
// Rx done
SX1276FskSetOpMode( RF_OPMODE_STANDBY );
read_fifo(true);
etimer_stop(&timer_rf);
g_fsk.states = RF_STATE_RX_DONE;
process_post(&hal_RF_process, PROCESS_EVENT_MSG, (void *)(&g_fsk.states));
}
}
else if (flags & (1 << sRF_DIO2_PIN) )
{
if(g_fsk.states == RF_STATE_TX_RUNNING)
{
hal_DIOx_ITConfig(all,DISABLE);
SX1276FskSetOpMode( RF_OPMODE_STANDBY );
}
//sync detect
if(g_fsk.states == RF_STATE_RX_PREAMBLE)
{
hal_DIOx_ITConfig(2,DISABLE);
etimer_remodify(&timer_rf, g_fsk.plyloadtimeout);
printf("sync det\r\n");
g_fsk.states = RF_STATE_RX_SYNC;
g_fsk.rssi = SX1276FskReadRssi( );
}
}
else if (flags & (1 << sRF_DIO3_PIN) )
{
hal_DIOx_ITConfig(all,DISABLE);
SX1276FskSetOpMode( RF_OPMODE_STANDBY );
}
}
void GPIO_ODD_IRQHandler(void)
{
u32 flags = GPIO->IF;
GPIO->IFC = flags;
if (flags & (1 << sRF_DIO1_PIN) )
{
if(g_fsk.states == RF_STATE_TX_RUNNING)
{
fill_fifo();
}
if(g_fsk.states == RF_STATE_RX_SYNC)
{
read_fifo(false);
}
}
else if (flags & (1 << sRF_DIO4_PIN) )
{
if(g_fsk.states == RF_STATE_RX_INIT)
{
hal_DIOx_ITConfig(4,DISABLE);
etimer_remodify(&timer_rf, g_fsk.sync_timeout); //不执行这个的话,中断函数少点时间,执行的话,可快速判断超时
printf("preamble det\r\n");
g_fsk.states = RF_STATE_RX_PREAMBLE;
process_post(&hal_RF_process, PROCESS_EVENT_MSG, (void *)(&g_fsk.states));
}
}
}
#endif

1500
APP/sx1276-Fsk.h Normal file

File diff suppressed because it is too large Load Diff

515
APP/sx1276-FskMisc.c Normal file
View File

@@ -0,0 +1,515 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) SEMTECH S.A.
*/
/*!
* \file sx1276-FskMisc.c
* \brief SX1276 RF chip high level functions driver
*
* \remark Optional support functions.
* These functions are defined only to easy the change of the
* parameters.
* For a final firmware the radio parameters will be known so
* there is no need to support all possible parameters.
* Removing these functions will greatly reduce the final firmware
* size.
*
* \version 2.0.0
* \date May 6 2013
* \author Gregory Cristian
*
* Last modified by Miguel Luis on Jun 19 2013
*/
#include <math.h>
#include "hal_radio.h"
#include "sx1276-Fsk.h"
#include "sx1276-FskMisc.h"
extern tFskSettings FskSettings;
void SX1276FskSetRFFrequency( uint32_t freq )
{
FskSettings.RFFrequency = freq;
freq = ( uint32_t )( ( double )freq / ( double )FREQ_STEP );
SX1276->RegFrfMsb = ( uint8_t )( ( freq >> 16 ) & 0xFF );
SX1276->RegFrfMid = ( uint8_t )( ( freq >> 8 ) & 0xFF );
SX1276->RegFrfLsb = ( uint8_t )( freq & 0xFF );
SX1276WriteBuffer( REG_FRFMSB, &SX1276->RegFrfMsb, 3 );
}
uint32_t SX1276FskGetRFFrequency( void )
{
SX1276ReadBuffer( REG_FRFMSB, &SX1276->RegFrfMsb, 3 );
FskSettings.RFFrequency = ( ( uint32_t )SX1276->RegFrfMsb << 16 ) | ( ( uint32_t )SX1276->RegFrfMid << 8 ) | ( ( uint32_t )SX1276->RegFrfLsb );
FskSettings.RFFrequency = ( uint32_t )( ( double )FskSettings.RFFrequency * ( double )FREQ_STEP );
return FskSettings.RFFrequency;
}
void SX1276FskRxCalibrate( void )
{
// the function RadioRxCalibrate is called just after the reset so all register are at their default values
uint8_t regPaConfigInitVal;
uint32_t initialFreq;
// save register values;
SX1276Read( REG_PACONFIG, &regPaConfigInitVal );
initialFreq = SX1276FskGetRFFrequency( );
// Cut the PA just in case
SX1276->RegPaConfig = 0x00; // RFO output, power = -1 dBm
SX1276Write( REG_PACONFIG, SX1276->RegPaConfig );
// Set Frequency in HF band
SX1276FskSetRFFrequency( 860000000 );
// Rx chain re-calibration workaround
SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal );
SX1276->RegImageCal = ( SX1276->RegImageCal & RF_IMAGECAL_IMAGECAL_MASK ) | RF_IMAGECAL_IMAGECAL_START;
SX1276Write( REG_IMAGECAL, SX1276->RegImageCal );
SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal );
// rx_cal_run goes low when calibration in finished
while( ( SX1276->RegImageCal & RF_IMAGECAL_IMAGECAL_RUNNING ) == RF_IMAGECAL_IMAGECAL_RUNNING )
{
SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal );
}
// reload saved values into the registers
SX1276->RegPaConfig = regPaConfigInitVal;
SX1276Write( REG_PACONFIG, SX1276->RegPaConfig );
SX1276FskSetRFFrequency( initialFreq );
}
void SX1276FskSetBitrate( uint32_t bitrate )
{
FskSettings.Bitrate = bitrate;
bitrate = ( uint16_t )( ( double )XTAL_FREQ / ( double )bitrate );
SX1276->RegBitrateMsb = ( uint8_t )( bitrate >> 8 );
SX1276->RegBitrateLsb = ( uint8_t )( bitrate & 0xFF );
SX1276WriteBuffer( REG_BITRATEMSB, &SX1276->RegBitrateMsb, 2 );
}
uint32_t SX1276FskGetBitrate( void )
{
SX1276ReadBuffer( REG_BITRATEMSB, &SX1276->RegBitrateMsb, 2 );
FskSettings.Bitrate = ( ( ( uint32_t )SX1276->RegBitrateMsb << 8 ) | ( ( uint32_t )SX1276->RegBitrateLsb ) );
FskSettings.Bitrate = ( uint16_t )( ( double )XTAL_FREQ / ( double )FskSettings.Bitrate );
return FskSettings.Bitrate;
}
void SX1276FskSetFdev( uint32_t fdev )
{
FskSettings.Fdev = fdev;
SX1276Read( REG_FDEVMSB, &SX1276->RegFdevMsb );
fdev = ( uint16_t )( ( double )fdev / ( double )FREQ_STEP );
SX1276->RegFdevMsb = ( ( SX1276->RegFdevMsb & RF_FDEVMSB_FDEV_MASK ) | ( ( ( uint8_t )( fdev >> 8 ) ) & ~RF_FDEVMSB_FDEV_MASK ) );
SX1276->RegFdevLsb = ( uint8_t )( fdev & 0xFF );
SX1276WriteBuffer( REG_FDEVMSB, &SX1276->RegFdevMsb, 2 );
}
uint32_t SX1276FskGetFdev( void )
{
SX1276ReadBuffer( REG_FDEVMSB, &SX1276->RegFdevMsb, 2 );
FskSettings.Fdev = ( ( ( uint32_t )( ( SX1276->RegFdevMsb << 8 ) & ~RF_FDEVMSB_FDEV_MASK ) ) | ( ( uint32_t )SX1276->RegFdevLsb ) );
FskSettings.Fdev = ( uint16_t )( ( double )FskSettings.Fdev * ( double )FREQ_STEP );
return FskSettings.Fdev;
}
void SX1276FskSetRFPower( int8_t power )
{
SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig );
SX1276Read( REG_PADAC, &SX1276->RegPaDac );
if( ( SX1276->RegPaConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
{
if( ( SX1276->RegPaDac & 0x87 ) == 0x87 )
{
if( power < 5 )
{
power = 5;
}
if( power > 20 )
{
power = 20;
}
SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70;
SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F );
}
else
{
if( power < 2 )
{
power = 2;
}
if( power > 17 )
{
power = 17;
}
SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70;
SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F );
}
}
else
{
if( power < -1 )
{
power = -1;
}
if( power > 14 )
{
power = 14;
}
SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70;
SX1276->RegPaConfig = ( SX1276->RegPaConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F );
}
SX1276Write( REG_PACONFIG, SX1276->RegPaConfig );
FskSettings.Power = power;
}
int8_t SX1276FskGetRFPower( void )
{
SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig );
SX1276Read( REG_PADAC, &SX1276->RegPaDac );
if( ( SX1276->RegPaConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
{
if( ( SX1276->RegPaDac & 0x07 ) == 0x07 )
{
FskSettings.Power = 5 + ( SX1276->RegPaConfig & ~RF_PACONFIG_OUTPUTPOWER_MASK );
}
else
{
FskSettings.Power = 2 + ( SX1276->RegPaConfig & ~RF_PACONFIG_OUTPUTPOWER_MASK );
}
}
else
{
FskSettings.Power = -1 + ( SX1276->RegPaConfig & ~RF_PACONFIG_OUTPUTPOWER_MASK );
}
return FskSettings.Power;
}
/*!
* \brief Computes the Rx bandwidth with the mantisse and exponent
*
* \param [IN] mantisse Mantisse of the bandwidth value
* \param [IN] exponent Exponent of the bandwidth value
* \retval bandwidth Computed bandwidth
*/
static uint32_t SX1276FskComputeRxBw( uint8_t mantisse, uint8_t exponent )
{
// rxBw
if( ( SX1276->RegOpMode & RF_OPMODE_MODULATIONTYPE_FSK ) == RF_OPMODE_MODULATIONTYPE_FSK )
{
return ( uint32_t )( ( double )XTAL_FREQ / ( mantisse * ( double )pow( 2, exponent + 2 ) ) );
}
else
{
return ( uint32_t )( ( double )XTAL_FREQ / ( mantisse * ( double )pow( 2, exponent + 3 ) ) );
}
}
/*!
* \brief Computes the mantisse and exponent from the bandwitdh value
*
* \param [IN] rxBwValue Bandwidth value
* \param [OUT] mantisse Mantisse of the bandwidth value
* \param [OUT] exponent Exponent of the bandwidth value
*/
static void SX1276FskComputeRxBwMantExp( uint32_t rxBwValue, uint8_t* mantisse, uint8_t* exponent )
{
uint8_t tmpExp = 0;
uint8_t tmpMant = 0;
double tmpRxBw = 0;
double rxBwMin = 10e6;
for( tmpExp = 0; tmpExp < 8; tmpExp++ )
{
for( tmpMant = 16; tmpMant <= 24; tmpMant += 4 )
{
if( ( SX1276->RegOpMode & RF_OPMODE_MODULATIONTYPE_FSK ) == RF_OPMODE_MODULATIONTYPE_FSK )
{
tmpRxBw = ( double )XTAL_FREQ / ( tmpMant * ( double )pow( 2, tmpExp + 2 ) );
}
else
{
tmpRxBw = ( double )XTAL_FREQ / ( tmpMant * ( double )pow( 2, tmpExp + 3 ) );
}
if( fabs( tmpRxBw - rxBwValue ) < rxBwMin )
{
rxBwMin = fabs( tmpRxBw - rxBwValue );
*mantisse = tmpMant;
*exponent = tmpExp;
}
}
}
}
void SX1276FskSetDccBw( uint8_t* reg, uint32_t dccValue, uint32_t rxBwValue )
{
uint8_t mantisse = 0;
uint8_t exponent = 0;
if( reg == &SX1276->RegRxBw )
{
*reg = ( uint8_t )dccValue & 0x60;
}
else
{
*reg = 0;
}
SX1276FskComputeRxBwMantExp( rxBwValue, &mantisse, &exponent );
switch( mantisse )
{
case 16:
*reg |= ( uint8_t )( 0x00 | ( exponent & 0x07 ) );
break;
case 20:
*reg |= ( uint8_t )( 0x08 | ( exponent & 0x07 ) );
break;
case 24:
*reg |= ( uint8_t )( 0x10 | ( exponent & 0x07 ) );
break;
default:
// Something went terribely wrong
break;
}
if( reg == &SX1276->RegRxBw )
{
SX1276Write( REG_RXBW, *reg );
FskSettings.RxBw = rxBwValue;
}
else
{
SX1276Write( REG_AFCBW, *reg );
FskSettings.RxBwAfc = rxBwValue;
}
}
uint32_t SX1276FskGetBw( uint8_t* reg )
{
uint32_t rxBwValue = 0;
uint8_t mantisse = 0;
switch( ( *reg & 0x18 ) >> 3 )
{
case 0:
mantisse = 16;
break;
case 1:
mantisse = 20;
break;
case 2:
mantisse = 24;
break;
default:
break;
}
rxBwValue = SX1276FskComputeRxBw( mantisse, ( uint8_t )*reg & 0x07 );
if( reg == &SX1276->RegRxBw )
{
return FskSettings.RxBw = rxBwValue;
}
else
{
return FskSettings.RxBwAfc = rxBwValue;
}
}
void SX1276FskSetPacketCrcOn( bool enable )
{
SX1276Read( REG_PACKETCONFIG1, &SX1276->RegPacketConfig1 );
SX1276->RegPacketConfig1 = ( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_CRC_MASK ) | ( enable << 4 );
SX1276Write( REG_PACKETCONFIG1, SX1276->RegPacketConfig1 );
FskSettings.CrcOn = enable;
}
bool SX1276FskGetPacketCrcOn( void )
{
SX1276Read( REG_PACKETCONFIG1, &SX1276->RegPacketConfig1 );
FskSettings.CrcOn = (bool)(( SX1276->RegPacketConfig1 & RF_PACKETCONFIG1_CRC_ON ) >> 4);
return FskSettings.CrcOn;
}
void SX1276FskSetAfcOn( bool enable )
{
SX1276Read( REG_RXCONFIG, &SX1276->RegRxConfig );
SX1276->RegRxConfig = ( SX1276->RegRxConfig & RF_RXCONFIG_AFCAUTO_MASK ) | ( enable << 4 );
SX1276Write( REG_RXCONFIG, SX1276->RegRxConfig );
FskSettings.AfcOn = enable;
}
bool SX1276FskGetAfcOn( void )
{
SX1276Read( REG_RXCONFIG, &SX1276->RegRxConfig );
FskSettings.AfcOn = (bool)(( SX1276->RegRxConfig & RF_RXCONFIG_AFCAUTO_ON ) >> 4);
return FskSettings.AfcOn;
}
void SX1276FskSetPayloadLength( uint8_t value )
{
SX1276->RegPayloadLength = value;
SX1276Write( REG_PAYLOADLENGTH, SX1276->RegPayloadLength );
FskSettings.PayloadLength = value;
}
uint8_t SX1276FskGetPayloadLength( void )
{
SX1276Read( REG_PAYLOADLENGTH, &SX1276->RegPayloadLength );
FskSettings.PayloadLength = SX1276->RegPayloadLength;
return FskSettings.PayloadLength;
}
void SX1276FskSetPa20dBm( bool enale )
{
SX1276Read( REG_PADAC, &SX1276->RegPaDac );
SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig );
if( ( SX1276->RegPaConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
{
if( enale == true )
{
SX1276->RegPaDac = 0x87;
}
}
else
{
SX1276->RegPaDac = 0x84;
}
SX1276Write( REG_PADAC, SX1276->RegPaDac );
}
bool SX1276FskGetPa20dBm( void )
{
SX1276Read( REG_PADAC, &SX1276->RegPaDac );
return ( ( SX1276->RegPaDac & 0x07 ) == 0x07 ) ? true : false;
}
void SX1276FskSetPAOutput( uint8_t outputPin )
{
SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig );
SX1276->RegPaConfig = (SX1276->RegPaConfig & RF_PACONFIG_PASELECT_MASK ) | outputPin;
SX1276Write( REG_PACONFIG, SX1276->RegPaConfig );
}
uint8_t SX1276FskGetPAOutput( void )
{
SX1276Read( REG_PACONFIG, &SX1276->RegPaConfig );
return SX1276->RegPaConfig & ~RF_PACONFIG_PASELECT_MASK;
}
void SX1276FskSetPaRamp( uint8_t value )
{
SX1276Read( REG_PARAMP, &SX1276->RegPaRamp );
SX1276->RegPaRamp = ( SX1276->RegPaRamp & RF_PARAMP_MASK ) | ( value & ~RF_PARAMP_MASK );
SX1276Write( REG_PARAMP, SX1276->RegPaRamp );
}
uint8_t SX1276FskGetPaRamp( void )
{
SX1276Read( REG_PARAMP, &SX1276->RegPaRamp );
return SX1276->RegPaRamp & ~RF_PARAMP_MASK;
}
void SX1276FskSetRssiOffset( int8_t offset )
{
SX1276Read( REG_RSSICONFIG, &SX1276->RegRssiConfig );
if( offset < 0 )
{
offset = ( ~offset & 0x1F );
offset += 1;
offset = -offset;
}
SX1276->RegRssiConfig |= ( uint8_t )( ( offset & 0x1F ) << 3 );
SX1276Write( REG_RSSICONFIG, SX1276->RegRssiConfig );
}
int8_t SX1276FskGetRssiOffset( void )
{
SX1276Read( REG_RSSICONFIG, &SX1276->RegRssiConfig );
int8_t offset = SX1276->RegRssiConfig >> 3;
if( ( offset & 0x10 ) == 0x10 )
{
offset = ( ~offset & 0x1F );
offset += 1;
offset = -offset;
}
return offset;
}
int8_t SX1276FskGetRawTemp( void )
{
int8_t temp = 0;
uint8_t previousOpMode;
//uint32_t startTick;
// Enable Temperature reading
SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal );
SX1276->RegImageCal = ( SX1276->RegImageCal & RF_IMAGECAL_TEMPMONITOR_MASK ) | RF_IMAGECAL_TEMPMONITOR_ON;
SX1276Write( REG_IMAGECAL, SX1276->RegImageCal );
// save current Op Mode
SX1276Read( REG_OPMODE, &SX1276->RegOpMode );
previousOpMode = SX1276->RegOpMode;
// put device in FSK RxSynth
SX1276->RegOpMode = RF_OPMODE_SYNTHESIZER_RX;
SX1276Write( REG_OPMODE, SX1276->RegOpMode );
// Wait 1ms
//startTick = GET_TICK_COUNT( );
//while( ( GET_TICK_COUNT( ) - startTick ) < TICK_RATE_MS( 1 ) );
// Disable Temperature reading
SX1276Read( REG_IMAGECAL, &SX1276->RegImageCal );
SX1276->RegImageCal = ( SX1276->RegImageCal & RF_IMAGECAL_TEMPMONITOR_MASK ) | RF_IMAGECAL_TEMPMONITOR_OFF;
SX1276Write( REG_IMAGECAL, SX1276->RegImageCal );
// Read temperature
SX1276Read( REG_TEMP, &SX1276->RegTemp );
temp = SX1276->RegTemp & 0x7F;
if( ( SX1276->RegTemp & 0x80 ) == 0x80 )
{
temp *= -1;
}
// Reload previous Op Mode
SX1276Write( REG_OPMODE, previousOpMode );
return temp;
}
int8_t SX1276FskCalibreateTemp( int8_t actualTemp )
{
return actualTemp - SX1276FskGetRawTemp( );
}
int8_t SX1276FskGetTemp( int8_t compensationFactor )
{
return SX1276FskGetRawTemp( ) + compensationFactor;
}

241
APP/sx1276-FskMisc.h Normal file
View File

@@ -0,0 +1,241 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) SEMTECH S.A.
*/
/*!
* \file sx1276-FskMisc.h
* \brief SX1276 RF chip high level functions driver
*
* \remark Optional support functions.
* These functions are defined only to easy the change of the
* parameters.
* For a final firmware the radio parameters will be known so
* there is no need to support all possible parameters.
* Removing these functions will greatly reduce the final firmware
* size.
*
* \version 2.0.B2
* \date May 6 2013
* \author Gregory Cristian
*
* Last modified by Miguel Luis on Jun 19 2013
*/
#ifndef __SX1276_FSK_MISC_H__
#define __SX1276_FSK_MISC_H__
/*!
* \brief Writes the new RF frequency value
*
* \param [IN] freq New RF frequency value in [Hz]
*/
void SX1276FskSetRFFrequency( uint32_t freq );
/*!
* \brief Reads the current RF frequency value
*
* \retval freq Current RF frequency value in [Hz]
*/
uint32_t SX1276FskGetRFFrequency( void );
/*!
* \brief Calibrate RSSI and I/Q mismatch for HF
*
* \retval none
*/
void SX1276FskRxCalibrate( void );
/*!
* \brief Writes the new bitrate value
*
* \param [IN] bitrate New bitrate value in [bps]
*/
void SX1276FskSetBitrate( uint32_t bitrate );
/*!
* \brief Reads the current bitrate value
*
* \retval bitrate Current bitrate value in [bps]
*/
uint32_t SX1276FskGetBitrate( void );
/*!
* \brief Writes the new frequency deviation value
*
* \param [IN] fdev New frequency deviation value in [Hz]
*/
void SX1276FskSetFdev( uint32_t fdev );
/*!
* \brief Reads the current frequency deviation value
*
* \retval fdev Current frequency deviation value in [Hz]
*/
uint32_t SX1276FskGetFdev( void );
/*!
* \brief Writes the new RF output power value
*
* \param [IN] power New output power value in [dBm]
*/
void SX1276FskSetRFPower( int8_t power );
/*!
* \brief Reads the current RF output power value
*
* \retval power Current output power value in [dBm]
*/
int8_t SX1276FskGetRFPower( void );
/*!
* \brief Writes the DC offset canceller and Rx bandwidth values
*
* \remark For SX1276 there is no DCC setting. dccValue should be 0
* ie: SX1276SetDccBw( &SX1276.RegRxBw, 0, 62500 );
*
* \param [IN] reg Register pointer to either SX1231.RegRxBw or SX1231.RegAfcBw
* \param [IN] dccValue New DC offset canceller value in [Hz] ( SX1231 only )
* \param [IN] rxBwValue New Rx bandwidth value in [Hz]
*/
void SX1276FskSetDccBw( uint8_t* reg, uint32_t dccValue, uint32_t rxBwValue );
/*!
* \brief Reads the current bandwidth setting
*
* \param [IN] reg Register pointer to either SX1231.RegRxBw or SX1231.RegAfcBw
*
* \retval bandwidth Bandwidth value
*/
uint32_t SX1276FskGetBw( uint8_t* reg );
/*!
* \brief Enables/Disables CRC
*
* \param [IN] enable CRC enable/disable
*/
void SX1276FskSetPacketCrcOn( bool enable );
/*!
* \brief Reads the current CRC Enable/Disbale value
*
* \retval enable Current CRC Enable/Disbale value
*/
bool SX1276FskGetPacketCrcOn( void );
/*!
* \brief Enables/Disables AFC
*
* \param [IN] enable AFC enable/disable
*/
void SX1276FskSetAfcOn( bool enable );
/*!
* \brief Reads the current AFC Enable/Disbale value
*
* \retval enable Current AFC Enable/Disbale value
*/
bool SX1276FskGetAfcOn( void );
/*!
* \brief Writes the new payload length value
*
* \param [IN] value New payload length value
*/
void SX1276FskSetPayloadLength( uint8_t value );
/*!
* \brief Reads the current payload length value
*
* \retval value Current payload length value
*/
uint8_t SX1276FskGetPayloadLength( void );
/*!
* \brief Enables/Disables the 20 dBm PA
*
* \param [IN] enable [true, false]
*/
void SX1276FskSetPa20dBm( bool enale );
/*!
* \brief Gets the current 20 dBm PA status
*
* \retval enable [true, false]
*/
bool SX1276FskGetPa20dBm( void );
/*!
* \brief Set the RF Output pin
*
* \param [IN] RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO
*/
void SX1276FskSetPAOutput( uint8_t outputPin );
/*!
* \brief Gets the used RF Ouptu pin
*
* \retval RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO
*/
uint8_t SX1276FskGetPAOutput( void );
/*!
* \brief Writes the new PA rise/fall time of ramp up/down value
*
* \param [IN] value New PaRamp value
*/
void SX1276FskSetPaRamp( uint8_t value );
/*!
* \brief Reads the current PA rise/fall time of ramp up/down value
*
* \retval value Current PaRamp value
*/
uint8_t SX1276FskGetPaRamp( void );
/*!
* \brief Applies an offset to the RSSI. Compensates board components
*
* \param [IN] offset Offset to be applied (+/-)
*/
void SX1276FskSetRssiOffset( int8_t offset );
/*!
* \brief Gets the current RSSI offset.
*
* \retval offset Current offset (+/-)
*/
int8_t SX1276FskGetRssiOffset( void );
/*!
* \brief Writes the new value for the preamble size
*
* \param [IN] size New value of pramble size
*/
void SX1276FskSetPreambleSize( uint16_t size );
/*!
* Reads the raw temperature
* \retval temperature New raw temperature reading in 2's complement format
*/
int8_t SX1276FskGetRawTemp( void );
/*!
* Computes the temperature compensation factor
* \param [IN] actualTemp Actual temperature measured by an external device
* \retval compensationFactor Computed compensation factor
*/
int8_t SX1276FskCalibreateTemp( int8_t actualTemp );
/*!
* Gets the actual compensated temperature
* \param [IN] compensationFactor Return value of the calibration function
* \retval New compensated temperature value
*/
int8_t SX1276FskGetTemp( int8_t compensationFactor );
#endif //__SX1276_FSK_MISC_H__

832
APP/sx1276-LoRa.c Normal file
View File

@@ -0,0 +1,832 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) SEMTECH S.A.
*/
/*!
* \file sx1276-LoRa.c
* \brief SX1276 RF chip driver mode LoRa
*
* \version 2.0.0
* \date May 6 2013
* \author Gregory Cristian
*
* Last modified by Miguel Luis on Jun 19 2013
*/
#include <math.h>
#include "hal_radio.h"
#include "sx1276-Fsk.h"
#include "sx1276-LoRaMisc.h"
#include "sx1276-LoRa.h"
/*!
* Frequency hopping frequencies table
*/
#if defined (HIGH_FREQUENCY)
const int32_t HoppingFrequencies[] =
{
916500000,
923500000,
906500000,
917500000,
917500000,
909000000,
903000000,
916000000,
912500000,
926000000,
925000000,
909500000,
913000000,
918500000,
918500000,
902500000,
911500000,
926500000,
902500000,
922000000,
924000000,
903500000,
913000000,
922000000,
926000000,
910000000,
920000000,
922500000,
911000000,
922000000,
909500000,
926000000,
922000000,
918000000,
925500000,
908000000,
917500000,
926500000,
908500000,
916000000,
905500000,
916000000,
903000000,
905000000,
915000000,
913000000,
907000000,
910000000,
926500000,
925500000,
911000000,
};
#else
const int32_t HoppingFrequencies[] =
{
#if 0
479000000,
484700000,
471500000,
479300000,
471700000,
479500000,
471900000,
479700000,
472100000,
479900000,
472300000,
480100000,
472500000,
480300000,
472700000,
480500000,
472900000,
480700000,
473100000,
480900000,
473300000,
481100000,
473500000,
481300000,
473700000,
481500000,
473900000,
481700000,
474100000,
481900000,
474300000,
482100000,
474500000,
482300000,
474700000,
482500000,
474900000,
482700000,
475100000,
482900000,
475300000,
483100000,
475500000,
483300000,
475700000,
483500000,
475900000,
483700000,
476100000,
483900000,
476500000,
484100000,
476700000,
484300000,
476900000,
484500000,
477100000,
484900000,
477300000,
485100000,
477500000,
485300000,
477700000,
485500000,
477900000,
485700000,
#endif
492000000,
492100000,
492200000,
492300000,
492400000,
492500000,
492600000,
492700000,
492800000,
492900000,
493000000,
493100000,
493200000,
493300000,
493400000,
493500000,
493600000,
493700000,
493800000,
493900000,
494000000,
494100000,
494200000,
494300000,
494400000,
494500000,
494600000,
494700000,
494800000,
494900000,
495000000,
495100000,
495200000,
495300000,
495400000,
495500000,
495600000,
495700000,
495800000,
495900000,
496000000,
496100000,
496200000,
496300000,
496400000,
496500000,
496600000,
496700000,
496800000,
496900000,
};
#endif
#define NO_HOP_LOW_FREQUENCY 479000000
#ifdef HOP_CHSS
#define HOP_CHANNELS 50
#endif
static u8 g_hopChannel = 0;
static u32 LoraSymbolTs;
static u32 loraWokePreambleLenth;
u8 SX1276Regs[0x70];
tSX1276LR* SX1276LR = (tSX1276LR*)SX1276Regs;
u32 g_SignalBw[10] = {7800, 10400, 15600, 20800, 31200, 41600, 62500, 125000, 250000, 500000};
tLoRaSettings LoRaSettings =
{
#ifdef HIGH_FREQUENCY
.RFFrequency = 920000000, // RFFrequency
#else
.RFFrequency = NO_HOP_LOW_FREQUENCY,
#endif
.Power = 0, // Power
.SignalBw = 6, // SignalBw [0: 7.8kHz, 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]
.SpreadingFactor = 7, // SpreadingFactor [6: 64, 7: 128, 8: 256, 9: 512, 10: 1024, 11: 2048, 12: 4096 chips]
.ErrorCoding = 2, // ErrorCoding [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
.CrcOn = true, // CrcOn [0: OFF, 1: ON]
.ImplicitHeaderOn = false, // ImplicitHeaderOn [0: OFF, 1: ON]
.RxSingleOn = false, // RxSingleOn [0: Continuous, 1 Single]
.FreqHopOn = false, // FreqHopOn [0: OFF, 1: ON]
.HopPeriod = 7, // HopPeriod Hops every frequency hopping period symbols
.TxPacketTimeout = 800, // TxPacketTimeout
.RxPacketTimeout = 800, // RxPacketTimeout
.PayloadLength = 254, // PayloadLength (used for implicit header mode)
.LowDatarateOptimize = false, // LowDatarateOptimize option
.PreambleLen = NORMALSYMBOLSLENGTH, // Preamble length
};
st_RF_LoRa_DypeDef g_RF_LoRa =
{
.rf_DataBufferValid = false,
.rf_state = RFLR_STATE_IDLE,
.rf_RxPacketSize = 0,
.rf_TxPacketSize = 0,
.rf_HeaderValid = false,
};
/*
typedef struct
{
u32 loraWokePreambleLenth;
uint8_t LoraChl;
st_RF_LoRa_DypeDef data;
u32 (*readLoraSymbolTs)(void);
int8_t (*getPacketSnr)(void);
u8 (*getRxPacketRssi)();
void (*LoRa_NormalTx)(u8 channel, u8 *PBuffer, u8 length);
void (*LoRa_WakeUpTx)(u8 channel, u8 *PBuffer, u8 length);
void (*LoRa_Receive_Packet)(u8 channel, bool wakeUp);
}st_Lora_port;
u32 readLoraSymbolTs(void)
{
return set_LoraSymbolTs(LoRaSettings.SignalBw, LoRaSettings.SpreadingFactor);
}
*/
/*****************************************************************************
* Function : set_LoraSymbolTs
* Description : none
* Input : uint8_t BwFlag
uint8_t SF
* Output : None
* Return : unit ms
* Others :
* Record
* 1.Date : 20170320
* Author : barry
* Modification: Created function
*****************************************************************************/
u32 set_LoraSymbolTs(uint8_t BwFlag ,uint8_t SF)
{
return (1 << SF)*1000/g_SignalBw[BwFlag];
}
u32 get_LoraSymbolTs(void)
{
return LoraSymbolTs;
}
/*****************************************************************************
* Function : set_LoRaWokeUpPreambleLenth
* Description : none
* Input : u32 period
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170320
* Author : barry
* Modification: Created function
*****************************************************************************/
u32 set_LoRaWokeUpPreambleLenth(u32 period, uint8_t BwFlag ,uint8_t SF)
{
return (u32)(period * g_SignalBw[BwFlag] / ((1 << SF) *1000)) + 6;
}
u32 get_LoRaWokeUpPreambleLenth(void)
{
return loraWokePreambleLenth;
}
/*****************************************************************************
Prototype : SX1276LoRaSetDefaults
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276LoRaSetDefaults( void )
{
/* REMARK: See SX1276 datasheet for modified default values */
SX1276Read( REG_LR_VERSION, &SX1276LR->RegVersion );
}
/*****************************************************************************
Prototype : SX1276LoRaSetOpMode
Description : none
Input : uint8_t opMode
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276LoRaSetOpMode( uint8_t opMode )
{
SX1276LR->RegOpMode = ( SX1276LR->RegOpMode & RFLR_OPMODE_MASK ) | opMode;
/* BEGIN: Added by Barry, 2014/3/14 */
#ifdef HIGH_FREQUENCY
SX1276LR->RegOpMode = ( SX1276LR->RegOpMode & RFLR_OPMODE_FREQMODE_ACCESS_MASK ) | RFLR_OPMODE_FREQMODE_ACCESS_HF; //Elvis
#endif
/* END: Added by Barry, 2014/3/14 */
SX1276Write( REG_LR_OPMODE, SX1276LR->RegOpMode );
}
/*****************************************************************************
Prototype : SX1276LoRaGetOpMode
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
uint8_t SX1276LoRaGetOpMode( void )
{
SX1276Read( REG_LR_OPMODE, &SX1276LR->RegOpMode );
return SX1276LR->RegOpMode & ~RFLR_OPMODE_MASK;
}
/*****************************************************************************
Prototype : SX1276LoRaReadRxGain
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
uint8_t SX1276LoRaReadRxGain( void )
{
SX1276Read( REG_LR_LNA, &SX1276LR->RegLna );
return( SX1276LR->RegLna >> 5 ) & 0x07;
}
/*****************************************************************************
Prototype : config_GDOx_Map
Description : none
Input : st_GDOx_Config GDOx_Map
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void config_GDOx_Map(st_GDOx_Config GDOx_Map)
{
SX1276LR->RegDioMapping1 = GDOx_Map.GDO0Config|
GDOx_Map.GDO1Config|
GDOx_Map.GDO2Config|
GDOx_Map.GDO3Config;
SX1276LR->RegDioMapping2 = GDOx_Map.GDO4Config|
GDOx_Map.GDO5Config;
SX1276WriteBuffer( REG_LR_DIOMAPPING1, &SX1276LR->RegDioMapping1, 2 );
}
/*****************************************************************************
Prototype : getPacketSnr
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
int8_t getPacketSnr(void)
{
uint8_t rxSnrEstimate;
int8_t RxPacketSnrEstimate;
SX1276Read( REG_LR_PKTSNRVALUE, &rxSnrEstimate );
/* The SNR sign bit is 1 */
if( rxSnrEstimate & 0x80 )
{
/* Invert and divide by 4 */
RxPacketSnrEstimate = ( ( ~rxSnrEstimate + 1 ) & 0xFF ) >> 2;
RxPacketSnrEstimate = -RxPacketSnrEstimate;
}
else
{
/* Divide by 4 */
RxPacketSnrEstimate = ( rxSnrEstimate & 0xFF ) >> 2;
}
return RxPacketSnrEstimate;
}
/*****************************************************************************
Prototype : get_RxPacketRssi
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
double get_RxPacketRssi(int8_t RxPacketSnr)
{
#define RSSI_OFFSET_LF -164.0
#define RSSI_OFFSET_HF -157.0
double RxPacketRssi;
SX1276Read( REG_LR_PKTRSSIVALUE, &SX1276LR->RegPktRssiValue );
if( LoRaSettings.RFFrequency < 860000000 ) // LF
{
if( RxPacketSnr < 0 )
{
RxPacketRssi = RSSI_OFFSET_LF + ((double)SX1276LR->RegPktRssiValue) + RxPacketSnr;
}
else
{
RxPacketRssi = RSSI_OFFSET_LF + ( 1.0666 * ((double)SX1276LR->RegPktRssiValue) );
}
}
else // HF
{
if( RxPacketSnr < 0 )
{
RxPacketRssi = RSSI_OFFSET_HF + ( ( double )SX1276LR->RegPktRssiValue ) + RxPacketSnr;
}
else
{
RxPacketRssi = RSSI_OFFSET_HF + ( 1.0666 * ((double)SX1276LR->RegPktRssiValue) );
}
}
return RxPacketRssi;
}
/*****************************************************************************
Prototype : read_Lora_Rssi
Description : none
Input : tRFLRStates state
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
u8 read_Lora_Rssi(void)
{
int8_t pSnr = getPacketSnr();
u8 rssi = (u8)get_RxPacketRssi(pSnr);
if (rssi & 0x80)
{
rssi = (~rssi + 1);
}
return rssi;
}
/*****************************************************************************
Prototype : SX1276LoRaInit
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276LoRaInit( void )
{
SX1276LoRaSetOpMode( RFLR_OPMODE_SLEEP );
SX1276LR->RegOpMode = ( SX1276LR->RegOpMode & RFLR_OPMODE_LONGRANGEMODE_MASK ) | RFLR_OPMODE_LONGRANGEMODE_ON;
SX1276Write( REG_LR_OPMODE, SX1276LR->RegOpMode );
SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );
SX1276LoRaSetDefaults( );
SX1276ReadBuffer( REG_LR_OPMODE, SX1276Regs + 1, 0x70 - 1 );
SX1276LR->RegLna = RFLR_LNA_GAIN_G1;
SX1276Write( REG_LR_LNA, SX1276LR->RegLna );
/* Set the device in Sleep Mode */
SX1276LoRaSetOpMode( RFLR_OPMODE_SLEEP );
SX1276LoRaSetRFFrequency( LoRaSettings.RFFrequency );
SX1276LoRaSetSpreadingFactor( LoRaSettings.SpreadingFactor ); // SF6 only operates in implicit header mode.
SX1276LoRaSetErrorCoding( LoRaSettings.ErrorCoding );
SX1276LoRaSetPacketCrcOn( LoRaSettings.CrcOn );
SX1276LoRaSetSignalBandwidth( LoRaSettings.SignalBw );
SX1276LoRaSetImplicitHeaderOn( LoRaSettings.ImplicitHeaderOn );
SX1276LoRaSetSymbTimeout( 0x3FF );
SX1276LoRaSetPayloadLength( LoRaSettings.PayloadLength );
SX1276LoRaSetPreambleLength(LoRaSettings.PreambleLen);
/* seted true when a symble time over 16ms */
if (get_LoraSymbolTs() >= 16)
{
SX1276LoRaSetLowDatarateOptimize(true);
}
else
{
SX1276LoRaSetLowDatarateOptimize(false);
}
SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_RFO );
//SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_PABOOST );
/* set max power 17DBm */
SX1276LoRaSetPa20dBm( false );
/* set power */
SX1276LoRaSetRFPower( LoRaSettings.Power );
SX1276StartSleep();
}
/*****************************************************************************
* Function : Lora_lowPower_Init
* Description : none
* Input : u32 period
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170526
* Author : barry
* Modification: Created function
*****************************************************************************/
void Lora_lowPower_Init(u32 period)
{
LoraSymbolTs = set_LoraSymbolTs(LoRaSettings.SignalBw, LoRaSettings.SpreadingFactor);
loraWokePreambleLenth = set_LoRaWokeUpPreambleLenth(period, LoRaSettings.SignalBw, LoRaSettings.SpreadingFactor);
}
u32 get_LoraWokeUpPreambleT(void)
{
return LoraSymbolTs*loraWokePreambleLenth;
}
/*****************************************************************************
Prototype : receiveRxData
Description : none
Input : bool spiDMA
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void receiveRxData(u8 *buf, u8 *length)
{
if( LoRaSettings.RxSingleOn == true )
{
SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxBaseAddr;
}
else
{
SX1276Read( REG_LR_FIFORXCURRENTADDR, &SX1276LR->RegFifoRxCurrentAddr );
SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoRxCurrentAddr;
}
if( LoRaSettings.ImplicitHeaderOn == true )
{
*length = SX1276LR->RegPayloadLength;
}
else
{
SX1276Read( REG_LR_NBRXBYTES, &SX1276LR->RegNbRxBytes );
*length = SX1276LR->RegNbRxBytes;
}
SX1276Write( REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr );
SX1276ReadFifo(buf, *length);
}
/*****************************************************************************
* Function : SX1276LoRa_hopTx_config
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170320
* Author : barry
* Modification: Created function
*****************************************************************************/
void SX1276LoRa_hopTx_config(st_GDOx_Config *DIO_map_ptr)
{
SX1276LR->RegIrqFlagsMask &= (~RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL);
SX1276LR->RegHopPeriod = LoRaSettings.HopPeriod;
DIO_map_ptr->GDO1Config = DIO1_FhssCC;
hal_DIOx_ITConfig(1,ENABLE);
}
/*****************************************************************************
Prototype : SX1276LoRa_Send_Packet
Description : none
Input : u8 *PBuffer
u8 length
bool FreqHop
bool spiDMA
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276LoRa_Send_Packet(u8 channel, bool wakeUp, u8 *PBuffer,u8 length)
{
st_GDOx_Config DIO_map_conf = DEFAULT_DIO_config;
SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );
hal_DIOx_ITConfig(all, DISABLE);
switch_Tx();
DIO_map_conf.GDO0Config = DIO0_TxDone;
SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_ALL_MASK & (~RFLR_IRQFLAGS_TXDONE);
SX1276LoRaSetOpMode( RFLR_OPMODE_SYNTHESIZER_TX );
SX1276LR->RegHopPeriod = 0;
#ifdef HOP_CHSS
SX1276LoRa_hopTx_config(DIO_map_conf);
#endif
LoRaSettings.PreambleLen = wakeUp? get_LoRaWokeUpPreambleLenth():NORMALSYMBOLSLENGTH;
SX1276LoRaSetPreambleLength(LoRaSettings.PreambleLen);
config_GDOx_Map(DIO_map_conf);
SX1276Write( REG_LR_HOPPERIOD, SX1276LR->RegHopPeriod );
SX1276Write( REG_LR_IRQFLAGSMASK, SX1276LR->RegIrqFlagsMask );
SX1276LoRaSetRFFrequency(HoppingFrequencies[channel]);
SX1276LR->RegPayloadLength = length;
SX1276Write( REG_LR_PAYLOADLENGTH, SX1276LR->RegPayloadLength);
SX1276LR->RegFifoTxBaseAddr = 0x00;
SX1276Write( REG_LR_FIFOTXBASEADDR, SX1276LR->RegFifoTxBaseAddr );
SX1276LR->RegFifoAddrPtr = SX1276LR->RegFifoTxBaseAddr;
SX1276Write(REG_LR_FIFOADDRPTR, SX1276LR->RegFifoAddrPtr);
g_RF_LoRa.rf_state = RFLR_STATE_TX_RUNNING;
MemCpy(g_RF_LoRa.rf_DataBuffer, PBuffer, length);
g_RF_LoRa.rf_TxPacketSize = length;
SX1276WriteFifo(g_RF_LoRa.rf_DataBuffer,length);
SX1276LoRaSetOpMode(RFLR_OPMODE_TRANSMITTER);
hal_DIOx_ITConfig(0,ENABLE);
}
/*****************************************************************************
Prototype : SX1276LoRa_Receive_Packet
Description : none
Input : bool FreqHop
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276LoRa_Receive_Packet(u8 channel, bool wakeUp)
{
st_GDOx_Config DIO_map_conf = DEFAULT_DIO_config;
SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );
SX1276LR->RegIrqFlagsMask = RFLR_IRQFLAGS_ALL_MASK;
SX1276LR->RegIrqFlagsMask &= (~(RFLR_IRQFLAGS_RXDONE |
RFLR_IRQFLAGS_PAYLOADCRCERROR|
RFLR_IRQFLAGS_VALIDHEADER
/*|RFLR_IRQFLAGS_RXTIMEOUT*/
));
DIO_map_conf.GDO0Config = DIO0_RxDone;
DIO_map_conf.GDO3Config = DIO3_ValidHeader;
SX1276LR->RegHopPeriod = 0;
switch_Rx();
#ifdef HOP_CHSS
SX1276LoRa_hopTx_config(DIO_map_conf);
#endif
LoRaSettings.PreambleLen = wakeUp? get_LoRaWokeUpPreambleLenth():NORMALSYMBOLSLENGTH;
SX1276LoRaSetPreambleLength(LoRaSettings.PreambleLen);
SX1276LoRaSetSymbTimeout(0x3FF);
config_GDOx_Map(DIO_map_conf);
SX1276Write( REG_LR_HOPPERIOD, SX1276LR->RegHopPeriod );
SX1276Write( REG_LR_IRQFLAGSMASK, SX1276LR->RegIrqFlagsMask );
SX1276LoRaSetRFFrequency(HoppingFrequencies[channel]);
if (wakeUp)
{
SX1276LoRaSetOpMode( RFLR_OPMODE_RECEIVER_SINGLE );
}
else
{
SX1276LoRaSetOpMode( RFLR_OPMODE_RECEIVER );
}
g_RF_LoRa.rf_state = RFLR_STATE_RX_RUNNING;
hal_DIOx_ITConfig(0,ENABLE);
hal_DIOx_ITConfig(3,ENABLE);
}
/*****************************************************************************
Prototype : SX1276StartSleep
Description : none
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276StartSleep(void)
{
switch_Rx();
hal_DIOx_ITConfig(all, DISABLE);
hal_sRF_ClearAllRF_IT();
SX1276LoRaSetOpMode( RFLR_OPMODE_SLEEP );
g_RF_LoRa.rf_state = RFLR_STATE_SLEEP;
}
/*****************************************************************************
Prototype : SX1276LoRa_CAD_Scan
Description : none
Input : void
Output : None
Return Value :
Date : 2014/3/15
Author : Barry
*****************************************************************************/
void SX1276LoRa_CAD_Scan(u8 channel)
{
st_GDOx_Config DIO_map_conf = DEFAULT_DIO_config;
switch_Rx();
SX1276LoRaSetOpMode( RFLR_OPMODE_STANDBY );
SX1276LR->RegIrqFlagsMask |= RFLR_IRQFLAGS_ALL_MASK;
SX1276LR->RegIrqFlagsMask &= (~(RFLR_IRQFLAGS_CADDETECTED | RFLR_IRQFLAGS_CADDONE));
SX1276Write( REG_LR_IRQFLAGSMASK, SX1276LR->RegIrqFlagsMask );
SX1276LoRaSetRFFrequency(HoppingFrequencies[channel]);
DIO_map_conf.GDO0Config = DIO0_CadDone;
DIO_map_conf.GDO1Config = DIO1_CadDetected;
config_GDOx_Map(DIO_map_conf);
hal_DIOx_ITConfig(0,ENABLE);
SX1276LoRaSetOpMode( RFLR_OPMODE_CAD );
g_RF_LoRa.rf_state = RFLR_STATE_CAD_RUNNING;
}
/*****************************************************************************
* Function : set_hop_Channel
* Description : none
* Input : u8 channel
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170320
* Author : barry
* Modification: Created function
*****************************************************************************/
void set_hop_Channel(u8 channel)
{
SX1276LoRaSetRFFrequency( HoppingFrequencies[ (g_hopChannel + channel&RFLR_HOPCHANNEL_CHANNEL_MASK)%HOP_CHANNELS] );
}

1071
APP/sx1276-LoRa.h Normal file

File diff suppressed because it is too large Load Diff

414
APP/sx1276-LoRaMisc.c Normal file
View File

@@ -0,0 +1,414 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) SEMTECH S.A.
*/
/*!
* \file sx1276-LoRaMisc.c
* \brief SX1276 RF chip high level functions driver
*
* \remark Optional support functions.
* These functions are defined only to easy the change of the
* parameters.
* For a final firmware the radio parameters will be known so
* there is no need to support all possible parameters.
* Removing these functions will greatly reduce the final firmware
* size.
*
* \version 2.0.0
* \date May 6 2013
* \author Gregory Cristian
*
* Last modified by Miguel Luis on Jun 19 2013
*/
//#include "platform.h"
//#if defined( USE_SX1276_RADIO )
//#if defined(SX1276_LORA)
#include "hal_radio.h"
//#include "sx1276.h"
#include "sx1276-LoRa.h"
/*!
* SX1276 definitions
*/
#define XTAL_FREQ 32000000
#define FREQ_STEP 61.03515625
extern tLoRaSettings LoRaSettings;
void SX1276LoRaSetRFFrequency( uint32_t freq )
{
LoRaSettings.RFFrequency = freq;
freq = ( uint32_t )( ( double )freq / ( double )FREQ_STEP );
SX1276LR->RegFrfMsb = ( uint8_t )( ( freq >> 16 ) & 0xFF );
SX1276LR->RegFrfMid = ( uint8_t )( ( freq >> 8 ) & 0xFF );
SX1276LR->RegFrfLsb = ( uint8_t )( freq & 0xFF );
SX1276WriteBuffer( REG_LR_FRFMSB, &SX1276LR->RegFrfMsb, 3 );
}
uint32_t SX1276LoRaGetRFFrequency( void )
{
SX1276ReadBuffer( REG_LR_FRFMSB, &SX1276LR->RegFrfMsb, 3 );
LoRaSettings.RFFrequency = ( ( uint32_t )SX1276LR->RegFrfMsb << 16 ) | ( ( uint32_t )SX1276LR->RegFrfMid << 8 ) | ( ( uint32_t )SX1276LR->RegFrfLsb );
LoRaSettings.RFFrequency = ( uint32_t )( ( double )LoRaSettings.RFFrequency * ( double )FREQ_STEP );
return LoRaSettings.RFFrequency;
}
void SX1276LoRaSetRFPower( int8_t power )
{
SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig );
SX1276Read( REG_LR_PADAC, &SX1276LR->RegPaDac );
/* is used PA boost pin*/
if( ( SX1276LR->RegPaConfig & RFLR_PACONFIG_PASELECT_PABOOST ) == RFLR_PACONFIG_PASELECT_PABOOST )
{ /* is max 20dbm output enable */
if( ( SX1276LR->RegPaDac & 0x87 ) == 0x87 )
{
if( power < 5 )
{
power = 5;
}
if( power > 20 )
{
power = 20;
}
/* set RegPaConfig MaxPower x111xxxx MaxPower over 14dbm */
SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_MAX_POWER_MASK ) | 0x70;
SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F );
}
/* max PA 17 dbm */
else
{
if( power < 2 )
{
power = 2;
}
if( power > 17 )
{
power = 17;
}
SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_MAX_POWER_MASK ) | 0x70;
SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F );
}
}
else
{
if( power < -1 )
{
power = -1;
}
if( power > 14 )
{
power = 14;
}
SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_MAX_POWER_MASK ) | 0x70;
SX1276LR->RegPaConfig = ( SX1276LR->RegPaConfig & RFLR_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F );
}
SX1276Write( REG_LR_PACONFIG, SX1276LR->RegPaConfig );
LoRaSettings.Power = power;
}
int8_t SX1276LoRaGetRFPower( void )
{
SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig );
SX1276Read( REG_LR_PADAC, &SX1276LR->RegPaDac );
if( ( SX1276LR->RegPaConfig & RFLR_PACONFIG_PASELECT_PABOOST ) == RFLR_PACONFIG_PASELECT_PABOOST )
{
if( ( SX1276LR->RegPaDac & 0x07 ) == 0x07 )
{
LoRaSettings.Power = 5 + ( SX1276LR->RegPaConfig & ~RFLR_PACONFIG_OUTPUTPOWER_MASK );
}
else
{
LoRaSettings.Power = 2 + ( SX1276LR->RegPaConfig & ~RFLR_PACONFIG_OUTPUTPOWER_MASK );
}
}
else
{
LoRaSettings.Power = -1 + ( SX1276LR->RegPaConfig & ~RFLR_PACONFIG_OUTPUTPOWER_MASK );
}
return LoRaSettings.Power;
}
void SX1276LoRaSetSignalBandwidth( uint8_t bw )
{
SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 );
SX1276LR->RegModemConfig1 = ( SX1276LR->RegModemConfig1 & RFLR_MODEMCONFIG1_BW_MASK ) | ( bw << 4 );
SX1276Write( REG_LR_MODEMCONFIG1, SX1276LR->RegModemConfig1 );
LoRaSettings.SignalBw = bw;
}
uint8_t SX1276LoRaGetSignalBandwidth( void )
{
SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 );
LoRaSettings.SignalBw = ( SX1276LR->RegModemConfig1 & ~RFLR_MODEMCONFIG1_BW_MASK ) >> 4;
return LoRaSettings.SignalBw;
}
void SX1276LoRaSetSpreadingFactor( uint8_t factor )
{
if( factor > 12 )
{
factor = 12;
}
else if( factor < 6 )
{
factor = 6;
}
if( factor == 6 )
{
SX1276LoRaSetNbTrigPeaks( 5 );
}
else
{
SX1276LoRaSetNbTrigPeaks( 3 );
}
SX1276Read( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2 );
SX1276LR->RegModemConfig2 = ( SX1276LR->RegModemConfig2 & RFLR_MODEMCONFIG2_SF_MASK ) | ( factor << 4 );
SX1276Write( REG_LR_MODEMCONFIG2, SX1276LR->RegModemConfig2 );
LoRaSettings.SpreadingFactor = factor;
}
uint8_t SX1276LoRaGetSpreadingFactor( void )
{
SX1276Read( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2 );
LoRaSettings.SpreadingFactor = ( SX1276LR->RegModemConfig2 & ~RFLR_MODEMCONFIG2_SF_MASK ) >> 4;
return LoRaSettings.SpreadingFactor;
}
void SX1276LoRaSetErrorCoding( uint8_t value )
{
SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 );
SX1276LR->RegModemConfig1 = ( SX1276LR->RegModemConfig1 & RFLR_MODEMCONFIG1_CODINGRATE_MASK ) | ( value << 1 );
SX1276Write( REG_LR_MODEMCONFIG1, SX1276LR->RegModemConfig1 );
LoRaSettings.ErrorCoding = value;
}
uint8_t SX1276LoRaGetErrorCoding( void )
{
SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 );
LoRaSettings.ErrorCoding = ( SX1276LR->RegModemConfig1 & ~RFLR_MODEMCONFIG1_CODINGRATE_MASK ) >> 1;
return LoRaSettings.ErrorCoding;
}
void SX1276LoRaSetPacketCrcOn( bool enable )
{
SX1276Read( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2 );
SX1276LR->RegModemConfig2 = ( SX1276LR->RegModemConfig2 & RFLR_MODEMCONFIG2_RXPAYLOADCRC_MASK ) | ( enable << 2 );
SX1276Write( REG_LR_MODEMCONFIG2, SX1276LR->RegModemConfig2 );
LoRaSettings.CrcOn = enable;
}
void SX1276LoRaSetPreambleLength( uint16_t value )
{
SX1276ReadBuffer( REG_LR_PREAMBLEMSB, &SX1276LR->RegPreambleMsb, 2 );
SX1276LR->RegPreambleMsb = ( value >> 8 ) & 0x00FF;
SX1276LR->RegPreambleLsb = value & 0xFF;
SX1276WriteBuffer( REG_LR_PREAMBLEMSB, &SX1276LR->RegPreambleMsb, 2 );
}
uint16_t SX1276LoRaGetPreambleLength( void )
{
SX1276ReadBuffer( REG_LR_PREAMBLEMSB, &SX1276LR->RegPreambleMsb, 2 );
return ( ( SX1276LR->RegPreambleMsb & 0x00FF ) << 8 ) | SX1276LR->RegPreambleLsb;
}
bool SX1276LoRaGetPacketCrcOn( void )
{
SX1276Read( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2 );
LoRaSettings.CrcOn =(bool) (( SX1276LR->RegModemConfig2 & RFLR_MODEMCONFIG2_RXPAYLOADCRC_ON ) >> 1);
return LoRaSettings.CrcOn;
}
void SX1276LoRaSetImplicitHeaderOn( bool enable )
{
SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 );
SX1276LR->RegModemConfig1 = ( SX1276LR->RegModemConfig1 & RFLR_MODEMCONFIG1_IMPLICITHEADER_MASK ) | ( enable );
SX1276Write( REG_LR_MODEMCONFIG1, SX1276LR->RegModemConfig1 );
LoRaSettings.ImplicitHeaderOn = enable;
}
bool SX1276LoRaGetImplicitHeaderOn( void )
{
SX1276Read( REG_LR_MODEMCONFIG1, &SX1276LR->RegModemConfig1 );
LoRaSettings.ImplicitHeaderOn =(bool) (( SX1276LR->RegModemConfig1 & RFLR_MODEMCONFIG1_IMPLICITHEADER_ON ));
return LoRaSettings.ImplicitHeaderOn;
}
void SX1276LoRaSetRxSingleOn( bool enable )
{
LoRaSettings.RxSingleOn = enable;
}
bool SX1276LoRaGetRxSingleOn( void )
{
return LoRaSettings.RxSingleOn;
}
void SX1276LoRaSetFreqHopOn( bool enable )
{
LoRaSettings.FreqHopOn = enable;
}
bool SX1276LoRaGetFreqHopOn( void )
{
return LoRaSettings.FreqHopOn;
}
void SX1276LoRaSetHopPeriod( uint8_t value )
{
SX1276LR->RegHopPeriod = value;
SX1276Write( REG_LR_HOPPERIOD, SX1276LR->RegHopPeriod );
LoRaSettings.HopPeriod = value;
}
uint8_t SX1276LoRaGetHopPeriod( void )
{
SX1276Read( REG_LR_HOPPERIOD, &SX1276LR->RegHopPeriod );
LoRaSettings.HopPeriod = SX1276LR->RegHopPeriod;
return LoRaSettings.HopPeriod;
}
void SX1276LoRaSetTxPacketTimeout( uint32_t value )
{
LoRaSettings.TxPacketTimeout = value;
}
uint32_t SX1276LoRaGetTxPacketTimeout( void )
{
return LoRaSettings.TxPacketTimeout;
}
void SX1276LoRaSetRxPacketTimeout( uint32_t value )
{
LoRaSettings.RxPacketTimeout = value;
}
uint32_t SX1276LoRaGetRxPacketTimeout( void )
{
return LoRaSettings.RxPacketTimeout;
}
void SX1276LoRaSetPayloadLength( uint8_t value )
{
SX1276LR->RegPayloadLength = value;
SX1276Write( REG_LR_PAYLOADLENGTH, SX1276LR->RegPayloadLength );
LoRaSettings.PayloadLength = value;
}
uint8_t SX1276LoRaGetPayloadLength( void )
{
SX1276Read( REG_LR_PAYLOADLENGTH, &SX1276LR->RegPayloadLength );
LoRaSettings.PayloadLength = SX1276LR->RegPayloadLength;
return LoRaSettings.PayloadLength;
}
void SX1276LoRaSetPa20dBm( bool enale )
{
SX1276Read( REG_LR_PADAC, &SX1276LR->RegPaDac );
SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig );
if( ( SX1276LR->RegPaConfig & RFLR_PACONFIG_PASELECT_PABOOST ) == RFLR_PACONFIG_PASELECT_PABOOST )
{
if( enale == true )
{
SX1276LR->RegPaDac = 0x87;
}
}
else
{
SX1276LR->RegPaDac = 0x84;
}
SX1276Write( REG_LR_PADAC, SX1276LR->RegPaDac );
}
bool SX1276LoRaGetPa20dBm( void )
{
SX1276Read( REG_LR_PADAC, &SX1276LR->RegPaDac );
return ( ( SX1276LR->RegPaDac & 0x07 ) == 0x07 ) ? true : false;
}
void SX1276LoRaSetPAOutput( uint8_t outputPin )
{
SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig );
SX1276LR->RegPaConfig = (SX1276LR->RegPaConfig & RFLR_PACONFIG_PASELECT_MASK ) | outputPin;
SX1276Write( REG_LR_PACONFIG, SX1276LR->RegPaConfig );
}
uint8_t SX1276LoRaGetPAOutput( void )
{
SX1276Read( REG_LR_PACONFIG, &SX1276LR->RegPaConfig );
return SX1276LR->RegPaConfig & ~RFLR_PACONFIG_PASELECT_MASK;
}
void SX1276LoRaSetPaRamp( uint8_t value )
{
SX1276Read( REG_LR_PARAMP, &SX1276LR->RegPaRamp );
SX1276LR->RegPaRamp = ( SX1276LR->RegPaRamp & RFLR_PARAMP_MASK ) | ( value & ~RFLR_PARAMP_MASK );
SX1276Write( REG_LR_PARAMP, SX1276LR->RegPaRamp );
}
uint8_t SX1276LoRaGetPaRamp( void )
{
SX1276Read( REG_LR_PARAMP, &SX1276LR->RegPaRamp );
return SX1276LR->RegPaRamp & ~RFLR_PARAMP_MASK;
}
void SX1276LoRaSetSymbTimeout( uint16_t value )
{
SX1276ReadBuffer( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2, 2 );
SX1276LR->RegModemConfig2 = ( SX1276LR->RegModemConfig2 & RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) | ( ( value >> 8 ) & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK );
SX1276LR->RegSymbTimeoutLsb = value & 0xFF;
SX1276WriteBuffer( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2, 2 );
}
uint16_t SX1276LoRaGetSymbTimeout( void )
{
SX1276ReadBuffer( REG_LR_MODEMCONFIG2, &SX1276LR->RegModemConfig2, 2 );
return ( ( SX1276LR->RegModemConfig2 & ~RFLR_MODEMCONFIG2_SYMBTIMEOUTMSB_MASK ) << 8 ) | SX1276LR->RegSymbTimeoutLsb;
}
void SX1276LoRaSetLowDatarateOptimize( bool enable )
{
SX1276Read( REG_LR_MODEMCONFIG3, &SX1276LR->RegModemConfig3 );
SX1276LR->RegModemConfig3 = ( SX1276LR->RegModemConfig3 & RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_MASK ) | ( enable << 3 );
SX1276Write( REG_LR_MODEMCONFIG3, SX1276LR->RegModemConfig3 );
}
bool SX1276LoRaGetLowDatarateOptimize( void )
{
SX1276Read( REG_LR_MODEMCONFIG3, &SX1276LR->RegModemConfig3 );
return (bool)(( ( SX1276LR->RegModemConfig3 & RFLR_MODEMCONFIG3_LOWDATARATEOPTIMIZE_ON ) >> 3 ));
}
void SX1276LoRaSetNbTrigPeaks( uint8_t value )
{
SX1276Read( 0x31, &SX1276LR->RegTestReserved31 );
SX1276LR->RegTestReserved31 = ( SX1276LR->RegTestReserved31 & 0xF8 ) | value;
SX1276Write( 0x31, SX1276LR->RegTestReserved31 );
}
uint8_t SX1276LoRaGetNbTrigPeaks( void )
{
SX1276Read( 0x31, &SX1276LR->RegTestReserved31 );
return ( SX1276LR->RegTestReserved31 & 0x07 );
}
//#endif // (SX1276_LORA)
//#endif // USE_SX1276_RADIO

315
APP/sx1276-LoRaMisc.h Normal file
View File

@@ -0,0 +1,315 @@
/*
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
* CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* Copyright (C) SEMTECH S.A.
*/
/*!
* \file sx1276-LoRaMisc.h
* \brief SX1276 RF chip high level functions driver
*
* \remark Optional support functions.
* These functions are defined only to easy the change of the
* parameters.
* For a final firmware the radio parameters will be known so
* there is no need to support all possible parameters.
* Removing these functions will greatly reduce the final firmware
* size.
*
* \version 2.0.B2
* \date May 6 2013
* \author Gregory Cristian
*
* Last modified by Miguel Luis on Jun 19 2013
*/
#ifndef __SX1276_LORA_MISC_H__
#define __SX1276_LORA_MISC_H__
/*!
* \brief Writes the new RF frequency value
*
* \param [IN] freq New RF frequency value in [Hz]
*/
void SX1276LoRaSetRFFrequency( uint32_t freq );
/*!
* \brief Reads the current RF frequency value
*
* \retval freq Current RF frequency value in [Hz]
*/
uint32_t SX1276LoRaGetRFFrequency( void );
/*!
* \brief Writes the new RF output power value
*
* \param [IN] power New output power value in [dBm]
*/
void SX1276LoRaSetRFPower( int8_t power );
/*!
* \brief Reads the current RF output power value
*
* \retval power Current output power value in [dBm]
*/
int8_t SX1276LoRaGetRFPower( void );
/*!
* \brief Writes the new Signal Bandwidth value
*
* \remark This function sets the IF frequency according to the datasheet
*
* \param [IN] factor New Signal Bandwidth value [0: 125 kHz, 1: 250 kHz, 2: 500 kHz]
*/
void SX1276LoRaSetSignalBandwidth( uint8_t bw );
/*!
* \brief Reads the current Signal Bandwidth value
*
* \retval factor Current Signal Bandwidth value [0: 125 kHz, 1: 250 kHz, 2: 500 kHz]
*/
uint8_t SX1276LoRaGetSignalBandwidth( void );
/*!
* \brief Writes the new Spreading Factor value
*
* \param [IN] factor New Spreading Factor value [7, 8, 9, 10, 11, 12]
*/
void SX1276LoRaSetSpreadingFactor( uint8_t factor );
/*!
* \brief Reads the current Spreading Factor value
*
* \retval factor Current Spreading Factor value [7, 8, 9, 10, 11, 12]
*/
uint8_t SX1276LoRaGetSpreadingFactor( void );
/*!
* \brief Writes the new Error Coding value
*
* \param [IN] value New Error Coding value [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
*/
void SX1276LoRaSetErrorCoding( uint8_t value );
/*!
* \brief Reads the current Error Coding value
*
* \retval value Current Error Coding value [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
*/
uint8_t SX1276LoRaGetErrorCoding( void );
/*!
* \brief Enables/Disables the packet CRC generation
*
* \param [IN] enaable [true, false]
*/
void SX1276LoRaSetPacketCrcOn( bool enable );
/*!
* \brief Reads the current packet CRC generation status
*
* \retval enable [true, false]
*/
bool SX1276LoRaGetPacketCrcOn( void );
/*!
* \brief Enables/Disables the Implicit Header mode in LoRa
*
* \param [IN] enable [true, false]
*/
void SX1276LoRaSetImplicitHeaderOn( bool enable );
/*!
* \brief Check if implicit header mode in LoRa in enabled or disabled
*
* \retval enable [true, false]
*/
bool SX1276LoRaGetImplicitHeaderOn( void );
/*!
* \brief Enables/Disables Rx single instead of Rx continuous
*
* \param [IN] enable [true, false]
*/
void SX1276LoRaSetRxSingleOn( bool enable );
/*!
* \brief Check if LoRa is in Rx Single mode
*
* \retval enable [true, false]
*/
bool SX1276LoRaGetRxSingleOn( void );
/*!
* \brief Enables/Disables the frequency hopping
*
* \param [IN] enable [true, false]
*/
void SX1276LoRaSetFreqHopOn( bool enable );
/*!
* \brief Get the frequency hopping status
*
* \param [IN] enable [true, false]
*/
bool SX1276LoRaGetFreqHopOn( void );
/*!
* \brief Set symbol period between frequency hops
*
* \param [IN] value
*/
void SX1276LoRaSetHopPeriod( uint8_t value );
/*!
* \brief Get symbol period between frequency hops
*
* \retval value symbol period between frequency hops
*/
uint8_t SX1276LoRaGetHopPeriod( void );
/*!
* \brief Set timeout Tx packet (based on MCU timer, timeout between Tx Mode entry Tx Done IRQ)
*
* \param [IN] value timeout (ms)
*/
void SX1276LoRaSetTxPacketTimeout( uint32_t value );
/*!
* \brief Get timeout between Tx packet (based on MCU timer, timeout between Tx Mode entry Tx Done IRQ)
*
* \retval value timeout (ms)
*/
uint32_t SX1276LoRaGetTxPacketTimeout( void );
/*!
* \brief Set timeout Rx packet (based on MCU timer, timeout between Rx Mode entry and Rx Done IRQ)
*
* \param [IN] value timeout (ms)
*/
void SX1276LoRaSetRxPacketTimeout( uint32_t value );
/*!
* \brief Get timeout Rx packet (based on MCU timer, timeout between Rx Mode entry and Rx Done IRQ)
*
* \retval value timeout (ms)
*/
uint32_t SX1276LoRaGetRxPacketTimeout( void );
/*!
* \brief Set payload length
*
* \param [IN] value payload length
*/
void SX1276LoRaSetPayloadLength( uint8_t value );
/*!
* \brief Get payload length
*
* \retval value payload length
*/
uint8_t SX1276LoRaGetPayloadLength( void );
/*!
* \brief Enables/Disables the 20 dBm PA
*
* \param [IN] enable [true, false]
*/
void SX1276LoRaSetPa20dBm( bool enale );
/*!
* \brief Gets the current 20 dBm PA status
*
* \retval enable [true, false]
*/
bool SX1276LoRaGetPa20dBm( void );
/*!
* \brief Set the RF Output pin
*
* \param [IN] RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO
*/
void SX1276LoRaSetPAOutput( uint8_t outputPin );
/*!
* \brief Gets the used RF Ouptut pin
*
* \retval RF_PACONFIG_PASELECT_PABOOST or RF_PACONFIG_PASELECT_RFO
*/
uint8_t SX1276LoRaGetPAOutput( void );
/*!
* \brief Writes the new PA rise/fall time of ramp up/down value
*
* \param [IN] value New PaRamp value
*/
void SX1276LoRaSetPaRamp( uint8_t value );
/*!
* \brief Reads the current PA rise/fall time of ramp up/down value
*
* \retval freq Current PaRamp value
*/
uint8_t SX1276LoRaGetPaRamp( void );
/*!
* \brief Set Symbol Timeout based on symbol length
*
* \param [IN] value number of symbol
*/
void SX1276LoRaSetSymbTimeout( uint16_t value );
/*!
* \brief Get Symbol Timeout based on symbol length
*
* \retval value number of symbol
*/
uint16_t SX1276LoRaGetSymbTimeout( void );
/*!
* \brief Configure the device to optimize low datarate transfers
*
* \param [IN] enable Enables/Disables the low datarate optimization
*/
void SX1276LoRaSetLowDatarateOptimize( bool enable );
/*!
* \brief Get the status of optimize low datarate transfers
*
* \retval LowDatarateOptimize enable or disable
*/
bool SX1276LoRaGetLowDatarateOptimize( void );
/*!
* \brief Get the preamble length
*
* \retval value preamble length
*/
uint16_t SX1276LoRaGetPreambleLength( void );
/*!
* \brief Set the preamble length
*
* \param [IN] value preamble length
*/
void SX1276LoRaSetPreambleLength( uint16_t value );
/*!
* \brief Set the number or rolling preamble symbol needed for detection
*
* \param [IN] value number of preamble symbol
*/
void SX1276LoRaSetNbTrigPeaks( uint8_t value );
/*!
* \brief Get the number or rolling preamble symbol needed for detection
*
* \retval value number of preamble symbol
*/
uint8_t SX1276LoRaGetNbTrigPeaks( void );
#endif //__SX1276_LORA_MISC_H__

3089
APP/uart.c Normal file

File diff suppressed because it is too large Load Diff

751
APP/uart.h Normal file
View File

@@ -0,0 +1,751 @@
/**
******************************************************************************
* @file hal_uart.h
* @author William Liang
* @version V1.0.0
* @date 07/22/2013
* @brief This file contains the headers of the uart handlers.
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _UART_H_
#define _UART_H_
/* Includes ------------------------------------------------------------------*/
#include "include.h"
#include "protocol.h"
#include "storage.h"
#define USART_BUF_SIXE 255
//define COM MBUS master infomation
#define COM_MBUS_MASTER_NO USART1
#ifdef COMMON_VER
#define COM_MBUS_MASTER_BAUD 2400
#endif
#ifdef AMT_VER
#define COM_MBUS_MASTER_BAUD 1200
#endif
#define COM_MBUS_MASTER_CHECK USART_Parity_Even
#define COM_MBUS_MASTER_CLK RCC_APB2Periph_USART1
#define COM_MBUS_MASTER_TX_PIN GPIO_Pin_9
#define COM_MBUS_MASTER_TX_PORT GPIOA
#define COM_MBUS_MASTER_TX_PORT_CLK RCC_APB2Periph_GPIOA
#define COM_MBUS_MASTER_RX_PIN GPIO_Pin_10
#define COM_MBUS_MASTER_RX_PORT GPIOA
#define COM_MBUS_MASTER_RX_PORT_CLK RCC_APB2Periph_GPIOA
#define COM_MBUS_MASTER_IRQn USART1_IRQn
#define COM_MBUS_MASTER_DMA_CLK RCC_AHBPeriph_DMA1
#define COM_MBUS_MASTER_TX_DMA_CHANNEL DMA1_Channel4
#define COM_MBUS_MASTER_DR_BASE (USART1_BASE + 4)
#define COM_MBUS_MASTER_TX_IRQHandler DMA1_Channel4_IRQHandler
#define COM_MBUS_MASTER_RX_IRQHandler USART1_IRQHandler
#define COM_MBUS_MASTER_TX_DMA_COMPLETE DMA1_IT_TC4
#define COM_MBUS_MASTER_TX_DMA_ERROR DMA1_IT_TE4
#define COM_MBUS_MASTER_DMA_IRQn DMA1_Channel4_IRQn
#define COM_MBUS_MASTER_TX_BUFFER_SIZE 200
#define COM_MBUS_MASTER_RX_BUFFER_SIZE 512
#define COM_MBUS_MASTER_STR "MBUS master"
//define COM LORA moudule infomation
//#define COM_RADIO_NO UART5
//#define COM_RADIO_BAUD 9600 //8,e,1
//#define COM_RADIO_CHECK USART_Parity_Even
//#define COM_RADIO_CLK RCC_APB1Periph_UART5
//
//#define COM_RADIO_TX_PIN GPIO_Pin_12
//#define COM_RADIO_TX_PORT GPIOC
//#define COM_RADIO_TX_PORT_CLK RCC_APB2Periph_GPIOC
//
//#define COM_RADIO_RX_PIN GPIO_Pin_2
//#define COM_RADIO_RX_PORT GPIOD
//#define COM_RADIO_RX_PORT_CLK RCC_APB2Periph_GPIOD
//
//#define COM_RADIO_IRQn UART5_IRQn
//
//#define COM_RADIO_DMA_CLK 0
//
//#define COM_RADIO_TX_DMA_CHANNEL 0
//#define COM_RADIO_DR_BASE 0
//#define COM_RADIO_TX_IRQHandler 0
//#define COM_RADIO_RX_IRQHandler 0
//#define COM_RADIO_TX_DMA_COMPLETE 0
//#define COM_RADIO_TX_DMA_ERROR 0
//#define COM_RADIO_DMA_IRQn 0
//
//
//#define COM_RADIO_TX_BUFFER_SIZE 255
//#define COM_RADIO_RX_BUFFER_SIZE 255
//#define COM_RADIO_STR "radio"
#define COM_RADIO_NO UART4
#define COM_RADIO_BAUD 2400 //8,e,1
#define COM_RADIO_CHECK USART_Parity_Even
#define COM_RADIO_CLK RCC_APB1Periph_UART4
#define COM_RADIO_TX_PIN GPIO_Pin_10
#define COM_RADIO_TX_PORT GPIOC
#define COM_RADIO_TX_PORT_CLK RCC_APB2Periph_GPIOC
#define COM_RADIO_RX_PIN GPIO_Pin_11
#define COM_RADIO_RX_PORT GPIOC
#define COM_RADIO_RX_PORT_CLK RCC_APB2Periph_GPIOC
#define COM_RADIO_IRQn UART4_IRQn
#define COM_RADIO_DMA_CLK RCC_AHBPeriph_DMA2
#define COM_RADIO_TX_DMA_CHANNEL DMA2_Channel5
#define COM_RADIO_DR_BASE (UART4_BASE + 4)
#define COM_RADIO_TX_IRQHandler DMA2_Channel4_5_IRQHandler
#define COM_RADIO_RX_IRQHandler UART4_IRQHandler
#define COM_RADIO_TX_DMA_COMPLETE DMA2_IT_TC5
#define COM_RADIO_TX_DMA_ERROR DMA2_IT_TE5
#define COM_RADIO_DMA_IRQn DMA2_Channel4_5_IRQn
//#define COM_RADIO_TX_BUFFER_SIZE 255
//#define COM_RADIO_RX_BUFFER_SIZE 255
#define COM_RADIO_TX_BUFFER_SIZE 10
#define COM_RADIO_RX_BUFFER_SIZE 10
#define COM_RADIO_STR "radio"
//
//#define COM_DEBUG_NO UART4 // DEBUG
//#define COM_DEBUG_BAUD 9600
//#define COM_DEBUG_CHECK USART_Parity_Even
//#define COM_DEBUG_CLK RCC_APB1Periph_UART4
//
//#define COM_DEBUG_TX_PIN GPIO_Pin_10
//#define COM_DEBUG_TX_PORT GPIOC
//#define COM_DEBUG_TX_PORT_CLK RCC_APB2Periph_GPIOC
//
//#define COM_DEBUG_RX_PIN GPIO_Pin_11
//#define COM_DEBUG_RX_PORT GPIOC
//#define COM_DEBUG_RX_PORT_CLK RCC_APB2Periph_GPIOC
//
//#define COM_DEBUG_IRQn UART4_IRQn
//
//#define COM_DEBUG_DMA_CLK RCC_AHBPeriph_DMA2
//#define COM_DEBUG_TX_DMA_CHANNEL DMA2_Channel5
//#define COM_DEBUG_DR_BASE (UART4_BASE + 4)
//#define COM_DEBUG_TX_IRQHandler DMA2_Channel4_5_IRQHandler
//#define COM_DEBUG_RX_IRQHandler UART4_IRQHandler
//#define COM_DEBUG_TX_DMA_COMPLETE DMA2_IT_TC5
//#define COM_DEBUG_TX_DMA_ERROR DMA2_IT_TE5
//#define COM_DEBUG_DMA_IRQn DMA2_Channel4_5_IRQn
//#define COM_DEBUG_TX_BUFFER_SIZE 255
//#define COM_DEBUG_RX_BUFFER_SIZE 255
//#define COM_DEBUG_STR "DEBUG"
//define COM PLC module infomation
#define COM_PLC_NO USART3
#define COM_PLC_BAUD 115200
#define COM_PLC_CHECK USART_Parity_No
//#define COM_PLC_BAUD 2400
//#define COM_PLC_CHECK USART_Parity_Even
#define COM_PLC_CLK RCC_APB1Periph_USART3
#define COM_PLC_TX_PIN GPIO_Pin_10
#define COM_PLC_TX_PORT GPIOB
#define COM_PLC_TX_PORT_CLK RCC_APB2Periph_GPIOB
#define COM_PLC_RX_PIN GPIO_Pin_11
#define COM_PLC_RX_PORT GPIOB
#define COM_PLC_RX_PORT_CLK RCC_APB2Periph_GPIOB
#define COM_PLC_IRQn USART3_IRQn
#define COM_PLC_DMA_CLK RCC_AHBPeriph_DMA1
#define COM_PLC_TX_DMA_CHANNEL DMA1_Channel2
#define COM_PLC_DR_BASE (USART3_BASE + 4)
#define COM_PLC_TX_IRQHandler DMA1_Channel2_IRQHandler
#define COM_PLC_RX_IRQHandler USART3_IRQHandler
#define COM_PLC_TX_DMA_COMPLETE DMA1_IT_TC2
#define COM_PLC_TX_DMA_ERROR DMA1_IT_TE2
#define COM_PLC_DMA_IRQn DMA1_Channel2_IRQn
#define COM_PLC_TX_BUFFER_SIZE 512
#define COM_PLC_RX_BUFFER_SIZE 512
#define COM_PLC_STR "PLC"
//define COM LORA moudule infomation
#define COM_485_NO USART2
#define COM_485_BAUD 2400 //8,e,1
#define COM_485_CHECK USART_Parity_Even//USART_Parity_No
#define COM_485_CLK RCC_APB1Periph_USART2
#define COM_485_TX_PIN GPIO_Pin_2
#define COM_485_TX_PORT GPIOA
#define COM_485_TX_PORT_CLK RCC_APB2Periph_GPIOA
#define COM_485_RX_PIN GPIO_Pin_3
#define COM_485_RX_PORT GPIOA
#define COM_485_RX_PORT_CLK RCC_APB2Periph_GPIOA
#define COM_485_IRQn USART2_IRQn
#define COM_485_DMA_CLK RCC_AHBPeriph_DMA1
#define COM_485_TX_DMA_CHANNEL DMA1_Channel7
#define COM_485_DR_BASE (USART2_BASE + 4)
#define COM_485_TX_IRQHandler DMA1_Channel7_IRQHandler
#define COM_485_RX_IRQHandler USART2_IRQHandler
#define COM_485_TX_DMA_COMPLETE DMA1_IT_TC7
#define COM_485_TX_DMA_ERROR DMA1_IT_TE7
#define COM_485_DMA_IRQn DMA1_Channel7_IRQn
#define COM_485_TX_BUFFER_SIZE 255
#define COM_485_RX_BUFFER_SIZE 255
//#define COM_485_TX_BUFFER_SIZE 20
//#define COM_485_RX_BUFFER_SIZE 10
#define COM_485_STR "485"
#define COM_4852_NO NULL//USART2
#define COM_4852_BAUD 600 //8,e,1
#define COM_4852_CHECK USART_Parity_Even
#define COM_4852_CLK NULL//RCC_APB1Periph_USART2
#define COM_4852_TX_PIN GPIO_Pin_4
#define COM_4852_TX_PORT GPIOA
#define COM_4852_TX_PORT_CLK RCC_APB2Periph_GPIOA
#define COM_4852_RX_PIN GPIO_Pin_5
#define COM_4852_RX_PORT GPIOA
#define COM_4852_RX_PORT_CLK RCC_APB2Periph_GPIOA
#define COM_4852_TX_BIT0 GPIO_ResetBits(COM_4852_TX_PORT, COM_4852_TX_PIN);
#define COM_4852_TX_BIT1 GPIO_SetBits(COM_4852_TX_PORT, COM_4852_TX_PIN);
#define COM_4852_RX_BIT GPIO_ReadInputDataBit(COM_4852_RX_PORT, COM_4852_RX_PIN)
//接收管脚中断
#define COM_4852_RX_LINE EXTI_Line5
#define COM_4852_RX_PORT_SOURCE GPIO_PortSourceGPIOA
#define COM_4852_RX_PIN_SOURCE GPIO_PinSource5
#define COM_4852_IRQn EXTI9_5_IRQn//USART2_IRQn
//数据波特率定时器
#define COM_4852_BAUD_TIMER TIM4
#define COM_4852_BAUD_TIMER_CLK RCC_APB1Periph_TIM4
#define COM_4852_BAUD_PRESC 100
#define COM_4852_BAUD_TIMER_PERIOD (SystemCoreClock/COM_4852_BAUD_PRESC/COM_4852_BAUD)
#define COM_4852_BAUD_IRQn TIM4_IRQn
#define COM_4852_BAUD_IRQHandler TIM4_IRQHandler
#define COM_4852_DMA_CLK 0//RCC_AHBPeriph_DMA1
#define COM_4852_TX_DMA_CHANNEL 0//DMA1_Channel7
#define COM_4852_DR_BASE 0//(USART2_BASE + 4)
#define COM_4852_TX_IRQHandler 0//DMA1_Channel7_IRQHandler
#define COM_4852_RX_IRQHandler EXTI9_5_IRQHandler//USART2_IRQHandler
#define COM_4852_TX_DMA_COMPLETE 0//DMA1_IT_TC7
#define COM_4852_TX_DMA_ERROR 0//DMA1_IT_TE7
#define COM_4852_DMA_IRQn 0//DMA1_Channel7_IRQn
#define COM_4852_TX_BUFFER_SIZE 255
#define COM_4852_RX_BUFFER_SIZE 255
#define COM_4852_STR "4852"
/*
//define COM module end
#define MBUS_OVERLOAD_FLAG_PIN GPIO_Pin_3
#define MBUS_OVERLOAD_FLAG_PIN_PORT GPIOC
#define MBUS_OVERLOAD_FLAG_PORT_CLK RCC_APB2Periph_GPIOC
#define MBUS_OVERLOAD_FLAG_PORT_SOURCE GPIO_PortSourceGPIOC
#define MBUS_OVERLOAD_FLAG_PIN_SOURCE GPIO_PinSource3
#define MBUS_OVERLOAD_FLAG_LINE EXTI_Line3
#define MBUS_OVERLOAD_FLAG_IRQHandler EXTI3_IRQHandler
*/
#define MBUSM_BAUD_COFF (11 * 1000 / COM_MBUS_MASTER_BAUD)
#define PLC_BAUD_COFF (11 * 1000 / COM_PLC_BAUD)
#define RS485_BAUD_COFF (11 * 1000 / COM_485_BAUD)
#define PRINT_BAUD_COFF (11 * 1000 / COM_DEBUG_BAUD)
//#define MBUS_SWITCH_TIMEOUT (10000 /portTICK_RATE_MS)
#define MBUS_SWITCH_TIMEOUT (60000 /portTICK_RATE_MS)
#define PORT_RX_TIMEOUT (70 /portTICK_RATE_MS)//设置串口的超时接收时间,此值需设置为最低波特率的最少两个字节时间
#define SCAN_PORT_RERIOD (5 /portTICK_RATE_MS)//扫描串口超时的周期
#define MBUS_TIMEOUT (1200 /portTICK_RATE_MS)
#define CS485_TIMEOUT (2000 /portTICK_RATE_MS)
#define PLC_TIMEOUT (2500 /portTICK_RATE_MS)
#define XIMEI_TIMEOUT (10000 /portTICK_RATE_MS)
#define MUT_TIMEOUT (2000 /portTICK_RATE_MS)
#define OPEN_SWITCN_DELAY (2000 /portTICK_RATE_MS)
#define DELAY_HOUR_TIME (3600000 /portTICK_RATE_MS)
#define DELAY_MIN_TIME (60000 /portTICK_RATE_MS)
typedef struct
{
USART_TypeDef * com;
USART_InitTypeDef uart_param;
uint32_t com_clk;
uint16_t com_tx_pin;
GPIO_TypeDef * com_tx_port;
uint32_t com_tx_port_clk;
uint16_t com_rx_pin;
GPIO_TypeDef * com_rx_port;
uint32_t xom_rx_port_clk;
uint32_t com_DMA_CLK;
uint8_t com_IRQn;
uint8_t com_DMA_IRQn;
}st_uart_int;
typedef struct
{
USART_TypeDef * com;
DMA_Channel_TypeDef * com_TX_DMA_CHANNEL;
uint32_t com_DR_BASE;
u16 txbufLength;
}st_uart_channel_cfg;
#define COMM_BUF_SIZE 512
typedef struct
{
u8 *rxBuf;
u8 *txBuf;
u16 tx_index;
u16 rx_index;
u16 rx_len;
u16 tx_len;
u32 rx_timeout;
u32 tx_timeout;
}st_uart_buf_cfg;
struct st_uart_port
{
EventBits_t port_No;
SemaphoreHandle_t xSemaphore;
st_uart_int init;
st_uart_channel_cfg chl;
st_uart_buf_cfg data;
char * string;
};
#define DEFAULT_USART_CFG(baud, check) { baud,USART_WordLength_9b,USART_StopBits_1,\
check, (USART_Mode_Rx | USART_Mode_Tx),\
USART_HardwareFlowControl_None\
}
#define USART_INIT(name) { name##_NO,\
DEFAULT_USART_CFG(name##_BAUD, name##_CHECK),\
name##_CLK,name##_TX_PIN,\
name##_TX_PORT,name##_TX_PORT_CLK,\
name##_RX_PIN,\
name##_RX_PORT,\
name##_RX_PORT_CLK,\
name##_DMA_CLK,\
name##_IRQn,\
name##_DMA_IRQn\
}
#define USART_DMA_config(name) {name##_NO, name##_TX_DMA_CHANNEL, (uint32_t)name##_DR_BASE, name##_TX_BUFFER_SIZE}
#define USART_PORT_PARAMS(name, rxbuf, txbuf) {name##_PORT_NO, NULL, USART_INIT(name),USART_DMA_config(name),{rxbuf,txbuf,0,0,0,0,0,0}, name##_STR}
#define USART_RX_INT_HANDLE(name) void name##_RX_IRQHandler(void) \
{ \
if (USART_GetITStatus(name##_NO, USART_IT_RXNE) != RESET) \
{ \
uart_int_rx_frame(&(name##_port)); \
} \
} \
#define USART_TX_INT_HANDLE(name) void name##_TX_IRQHandler(void) \
{ \
if (DMA_GetITStatus(name##_TX_DMA_COMPLETE) != RESET) \
{ \
DMA_ClearITPendingBit(name##_TX_DMA_COMPLETE); \
uart_dma_tx_callback(&(name##_port)); \
} \
if (DMA_GetITStatus(name##_TX_DMA_ERROR) != RESET) \
{ \
DMA_ClearITPendingBit(name##_TX_DMA_ERROR); \
} \
}
#define create_uart_port(name, rxbuf, txbuf) struct st_uart_port name##_port = USART_PORT_PARAMS(name, rxbuf, txbuf);\
USART_TX_INT_HANDLE(name) \
USART_RX_INT_HANDLE(name) \
enum
{
UP_VER_OF_COMMON = 0,
UP_VER_OF_ON_KEY,
UP_VER_OF_OFF_KEY,
UP_VER_OF_WHSF,
UP_VER_OF_E5E50000,
UP_VER_OF_E5E50001,
UP_VER_OF_FJWGDATA,
UP_VER_OF_standard,
UP_VER_OF_MAX
};
enum
{
PORT_NONE = 0,
PORT_MBUS_MASTER,
PORT_RADIO,
PORT_PLC,
PORT_485,
PORT_MUT,
POET_DEBUG,
POET_4852,
PORT_MAX,
};
enum
{
COM_MBUS_MASTER_PORT_NO = (1UL << PORT_MBUS_MASTER),
COM_RADIO_PORT_NO = (1UL << PORT_RADIO),
COM_PLC_PORT_NO = (1UL << PORT_PLC),
COM_485_PORT_NO = (1UL << PORT_485),
COM_MUT_PORT_NO = (1UL << PORT_MUT),
COM_DEBUG_PORT_NO = (1UL << POET_DEBUG),
COM_4852_PORT_NO = (1UL << POET_4852),
PORT_AUTO = (COM_MBUS_MASTER_PORT_NO | COM_485_PORT_NO | COM_MUT_PORT_NO)
};
enum
{
PROTCL_AUTO = 0,
PROTCL_E5E50000,
MBUS_METER_START,
MBUS_901F_2400_E,
MBUS_1F90_2400_E,
MBUS_HHCQ_2400_N,
MBUS_YZSJ_1200_E,
MBUS_HZJD_1200_E,
MBUS_METER_MAX,
RS485_METER_START,
RS485_NJSM_1200_N,
RS485_CS485_2400_E,
RS485_XYDX_2400_8N2,
RS485_METER_MAX,
MUT_METER_START,
MUT_RS232_CD_115200_N,
//MUT_CQXM_LORA,
MUT_SPI_LORA,
MUT_METER_MAX,
};
/* Baud bps 07 依次表示:
自适应, 1200 2400 4800 9600 19200
38400 57600 */
enum
{
BAUD_auto = 0,
BAUD_1200,
BAUD_2400,
BAUD_4800,
BAUD_9600,
BAUD_19200,
BAUD_38400,
BAUD_57600,
};
/* 0/1
1/2 停止位 */
enum
{
STOP_1bits = 0,
STOP_2bits,
};
/* 0/1
无/有校验 */
enum
{
PARITY_NONE = 0,
PARITY_TRUE,
};
/* 0/1
偶/奇校验 */
enum
{
PARITY_EVEN = 0,
PARITY_ODD,
};
/* 03
5-8 位数 */
enum
{
DATABITS_5 = 0,
DATABITS_6,
DATABITS_7,
DATABITS_8,
};
enum
{
UP_PORT_PLC,
UP_PORT_485,
UP_PORT_MAX,
};
enum
{
MBUS_MODE_MASTER = 0,
MBUS_MODE_SLAVE,
};
/********************define MBUS power contrl pin******************************/
//MBUS继电器控制
#define MBUS_POWER_CTRL_PIN GPIO_Pin_1
#define MBUS_POWER_CTRL_PIN_PORT GPIOB
#define MBUS_POWER_CTRL_PORT_CLK RCC_APB2Periph_GPIOB
#define open_mbus_switch() GPIO_ResetBits(MBUS_POWER_CTRL_PIN_PORT, MBUS_POWER_CTRL_PIN)
//#define close_mbus_switch() GPIO_SetBits(MBUS_POWER_CTRL_PIN_PORT, MBUS_POWER_CTRL_PIN)
#define mbus_switch_state() GPIO_ReadOutputDataBit(MBUS_POWER_CTRL_PIN_PORT, MBUS_POWER_CTRL_PIN)
/********************define MBUS in pin*******************************/
#define MBUS_EXTIN_PIN GPIO_Pin_4
#define MBUS_EXTIN_PORT GPIOC
#define MBUS_EXTIN_CLK RCC_APB2Periph_GPIOC
#define MBUS_in_state() GPIO_ReadInputDataBit(MBUS_EXTIN_PORT, MBUS_EXTIN_PIN)
#define MBUS_EXT_FLAG_PORT_SOURCE GPIO_PortSourceGPIOC
#define MBUS_EXT_FLAG_PIN_SOURCE GPIO_PinSource4
#define MBUS_EXT_FLAG_LINE EXTI_Line4
#define MBUS_EXT_IRQHandler EXTI4_IRQHandler
/********************define MBUS overload *******************************/
#define MBUS_OVERLOAD_PIN GPIO_Pin_12
#define MBUS_OVERLOAD_PORT GPIOB
#define MBUS_OVERLOAD_CLK RCC_APB2Periph_GPIOB
#define MBUS_OVERLOAD_in_state() GPIO_ReadInputDataBit(MBUS_OVERLOAD_PORT, MBUS_OVERLOAD_PIN)
#define MBUS_OVERLOAD_FLAG_PORT_SOURCE GPIO_PortSourceGPIOB
#define MBUS_OVERLOAD_FLAG_PIN_SOURCE GPIO_PinSource12
#define MBUS_OVERLOAD_FLAG_LINE EXTI_Line12
#define MBUS_OVERLOAD_FLAG_IRQHandler EXTI15_10_IRQHandler
/********************define power level pin*******************************/
#define POWER_LEVEL_PIN GPIO_Pin_13
#define POWER_LEVEL_PORT GPIOB
#define POWER_LEVEL_PORT_CLK RCC_APB2Periph_GPIOB
#define SET_POWER_LEVEL_HIGH() GPIO_SetBits(POWER_LEVEL_PORT, POWER_LEVEL_PIN);
#define SET_POWER_LEVEL_LOW() GPIO_ResetBits(POWER_LEVEL_PORT, POWER_LEVEL_PIN);
#define power_level_state() GPIO_ReadOutputDataBit(POWER_LEVEL_PORT, POWER_LEVEL_PIN)
/********************define 485 power contrl pin******************************/
#define RS485_CTRL_PIN GPIO_Pin_5
#define RS485_CTRL_PIN_PORT GPIOC
#define RS485_CTRL_PORT_CLK RCC_APB2Periph_GPIOC
#define open_RS485_switch() GPIO_ResetBits(RS485_CTRL_PIN_PORT, RS485_CTRL_PIN);hal_sRF_ITConfig(RS485_OVERLOAD_FLAG_LINE, ENABLE)
#define close_RS485_switch() GPIO_SetBits(RS485_CTRL_PIN_PORT, RS485_CTRL_PIN); hal_sRF_ITConfig(RS485_OVERLOAD_FLAG_LINE, DISABLE)
#define RS485_switch_state() GPIO_ReadOutputDataBit(RS485_CTRL_PIN_PORT, RS485_CTRL_PIN)
/********************define 485 in pin*******************************/
#define RS485_EXTIN_PIN GPIO_Pin_6
#define RS485_EXTIN_PORT GPIOA
#define RS485_EXTIN_CLK RCC_APB2Periph_GPIOA
#define RS485_in_state() GPIO_ReadInputDataBit(RS485_EXTIN_PORT, RS485_EXTIN_PIN)
/********************define MBUS overload *******************************/
#define RS485_OVERLOAD_PIN GPIO_Pin_7
#define RS485_OVERLOAD_PORT GPIOA
#define RS485_OVERLOAD_CLK RCC_APB2Periph_GPIOA
#define RS485_OVERLOAD_in_state() GPIO_ReadInputDataBit(RS485_OVERLOAD_PORT, RS485_OVERLOAD_PIN)
#define RS485_OVERLOAD_FLAG_PORT_SOURCE GPIO_PortSourceGPIOA
#define RS485_OVERLOAD_FLAG_PIN_SOURCE GPIO_PinSource7
#define RS485_OVERLOAD_FLAG_LINE EXTI_Line7
#define RS485_OVERLOAD_IRQn EXTI9_5_IRQn
#define RS485_OVERLOAD_FLAG_IRQHandler EXTI9_5_IRQHandler
/********************define PLC reset pin*******************************/
#define PLC_RESET_PIN GPIO_Pin_0
#define PLC_RESET_PIN_PORT GPIOB
#define PLC_RESET_PIN_CLK RCC_APB2Periph_GPIOB
#define PLC_RESET_HIGH() GPIO_SetBits(PLC_RESET_PIN_PORT, PLC_RESET_PIN)
#define PLC_RESET_LOW() GPIO_ResetBits(PLC_RESET_PIN_PORT, PLC_RESET_PIN)
/********************define overload current pin*******************************/
#define MUT_RESET_PIN GPIO_Pin_14
#define MUT_RESET_PIN_PORT GPIOB
#define MUT_RESET_PIN_CLK RCC_APB2Periph_GPIOB
#define MUT_RESET_HIGH() GPIO_SetBits(PLC_RESET_PIN_PORT, PLC_RESET_PIN)
#define MUT_RESET_LOW() GPIO_ResetBits(PLC_RESET_PIN_PORT, PLC_RESET_PIN)
//#define IRDA_TPIN_CFG {GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_0, GPIO_Mode_AF_OD} //PA0
//#define IRDA_RPIN_CFG {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_1, GPIO_Mode_IPU} //PC1
//#define RF_DOWN_TPIN_CFG {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_12, GPIO_Mode_IN_FLOATING} //PC12
//#define RF_DOWN_RPIN_CFG {GPIOD, RCC_APB2Periph_GPIOD, GPIO_Pin_2, GPIO_Mode_IN_FLOATING} //PD2
//#define RS485_UP_TPIN_CFG {GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_4, GPIO_Mode_IN_FLOATING} //PA4
//#define RS485_UP_RPIN_CFG {GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_5, GPIO_Mode_IN_FLOATING} //PA5
#define PLC_RESET_CFG {GPIOB, RCC_APB2Periph_GPIOB, GPIO_Pin_0, GPIO_Mode_Out_OD} //PB0
#define MBUS_SWITCH_CFG {GPIOB, RCC_APB2Periph_GPIOB, GPIO_Pin_1, GPIO_Mode_IN_FLOATING} //PB1
#define MBUS_EXT_CFG {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_4, GPIO_Mode_IN_FLOATING} //PC4
#define MBUS_OVERLOAD_CFG {GPIOB, RCC_APB2Periph_GPIOB, GPIO_Pin_12, GPIO_Mode_IN_FLOATING} //PB12
#define RS485_CTRL_CFG {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_5, GPIO_Mode_IN_FLOATING} //PC5
#define RS485_OVERLOAD_CFG {GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_7, GPIO_Mode_IN_FLOATING} //PA7
#define RS485_EXT_CFG {GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_6, GPIO_Mode_IN_FLOATING} //PA6
#define MBUS_POW_LEVEL_CFG {GPIOB, RCC_APB2Periph_GPIOB, GPIO_Pin_13, GPIO_Mode_IN_FLOATING} //PB13
#define OFF_KEY 0xAA
#define ON_KEY 0x55
extern void add_one_list_node(st_params* params);
extern void COM_frozen_uplinkPacket_create(st_params * ptr, u8* outBuf);
extern void COM_uplinkPacket_create(st_params * ptr, u8* outBuf);
extern u16 create_queue_send_packet(u8 * buf, u16 length);
extern void DLT645_07_addr_ack(u8 *buf);
extern void DLT645_97_1F_addr_ack(u8 *buf);
extern void E5E5_uplinkPacket_create(st_params * ptr, u8* outBuf);
extern u8 get_protocl_inRAM(void);
extern bool get_readMeter_params(u8 *buf, st_params * ptr);
extern bool get_read_meter_packet(u16 meter_protcl, u8 type, u8 *meter_id, u8 *outBuf, u16 *outLen);
extern void hal_InitCOM(struct st_uart_port * port);
extern void hal_UartDMATx(struct st_uart_port* uart_port, u8 *pBuf, u16 length);
//extern void hal_UartIntTx(u8 *pBuf, u16 length);
extern void init_uart_port(struct st_uart_port * port);
extern void init_uart_tasks(void);
extern void led_process_task(void * ptr);
extern void mbus_gpio_init(void);
extern void MBUS_master_process_task(void * ptr);
extern void MBUS_mater_Tx(u8 *pBuf, u16 length);
extern void MBUS_OVERLOAD_FLAG_IRQHandler(void);
extern void MBUS_slave_process_task(void *ptr);
extern void mbus_switch_timeOut_callback_function(TimerHandle_t xTimer);
extern bool meter_ack_packet_process(u16 meter_protl, u8 *inbuf, u16 inLen, st_params * ptr, u8* outBuf);
extern void PLC_process_task(void *ptr);
extern void plc_uart_Tx(u8 *buf, u16 length);
extern void port_send(struct st_uart_port* port, u8 *buf, u16 length);
extern bool read_meter_process(u8 meter_protcl);
extern bool read_power_level(void);
extern void read_standard_elcMeter(u8 *buf, u8 length);
extern void saved_meter_process(bool success, struct st_meter_temp_value *saved_ptr, st_params * ptr);
extern void set_curent_protocl(u8 config,u8 MBUSpower);
extern void set_mbus_master_params(u32 baud, u16 check);
extern void set_PLC_UART_baud(u32 baud);
extern void set_port_prams(u16 meter_protcl);
extern void set_power_level(bool high);
extern void simulate_mbus_plc_rx(u8 *buf, u16 len);
extern void temp_saved_task(void *ptr);
extern void UART5_IRQHandler(void);
extern void uarts_process_task(void * ptr);
extern void uart_dma_tx_callback(struct st_uart_port* uartPort);
extern void uart_int_rx_frame(struct st_uart_port* uartPort);
extern void uplinkPacket_create(st_params * ptr, u8* outBuf);
extern void uplink_ack_send(u8 uplink, u8 *buf, u16 length);
extern void WHSF_uplinkPacket_create(st_params * ptr, u8* outBuf);
extern void auto_sync_list_meters(void);
extern void RS485_gpio_init(void);
void RS4852_SendDataPacket(u8 *buf, u16 length);
void up_485_Tx(u8 *buf, u16 length);
void AnalogUartInit(struct st_uart_port * port);
void RS485DataRequenstReady( void );
bool ReadRS232ConcentratorDate(u8* year,u8* month);
#endif

588
APP/uart.h~RF183f36a.TMP Normal file
View File

@@ -0,0 +1,588 @@
/**
******************************************************************************
* @file hal_uart.h
* @author William Liang
* @version V1.0.0
* @date 07/22/2013
* @brief This file contains the headers of the uart handlers.
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _UART_H_
#define _UART_H_
/* Includes ------------------------------------------------------------------*/
#include "include.h"
#include "protocol.h"
#include "storage.h"
#define USART_BUF_SIXE 255
//define COM MBUS master infomation
#define COM_MBUS_MASTER_NO USART1
#define COM_MBUS_MASTER_BAUD 2400
#define COM_MBUS_MASTER_CHECK USART_Parity_Even
#define COM_MBUS_MASTER_CLK RCC_APB2Periph_USART1
#define COM_MBUS_MASTER_TX_PIN GPIO_Pin_9
#define COM_MBUS_MASTER_TX_PORT GPIOA
#define COM_MBUS_MASTER_TX_PORT_CLK RCC_APB2Periph_GPIOA
#define COM_MBUS_MASTER_RX_PIN GPIO_Pin_10
#define COM_MBUS_MASTER_RX_PORT GPIOA
#define COM_MBUS_MASTER_RX_PORT_CLK RCC_APB2Periph_GPIOA
#define COM_MBUS_MASTER_IRQn USART1_IRQn
#define COM_MBUS_MASTER_DMA_CLK RCC_AHBPeriph_DMA1
#define COM_MBUS_MASTER_TX_DMA_CHANNEL DMA1_Channel4
#define COM_MBUS_MASTER_DR_BASE (USART1_BASE + 4)
#define COM_MBUS_MASTER_TX_IRQHandler DMA1_Channel4_IRQHandler
#define COM_MBUS_MASTER_RX_IRQHandler USART1_IRQHandler
#define COM_MBUS_MASTER_TX_DMA_COMPLETE DMA1_IT_TC4
#define COM_MBUS_MASTER_TX_DMA_ERROR DMA1_IT_TE4
#define COM_MBUS_MASTER_DMA_IRQn DMA1_Channel4_IRQn
#define COM_MBUS_MASTER_TX_BUFFER_SIZE 200
#define COM_MBUS_MASTER_RX_BUFFER_SIZE 255
#define COM_MBUS_MASTER_STR "MBUS master"
//define COM LORA moudule infomation
#define COM_RADIO_NO UART5
#define COM_RADIO_BAUD 9600 //8,e,1
#define COM_RADIO_CHECK USART_Parity_Even
#define COM_RADIO_CLK RCC_APB1Periph_UART5
#define COM_RADIO_TX_PIN GPIO_Pin_12
#define COM_RADIO_TX_PORT GPIOC
#define COM_RADIO_TX_PORT_CLK RCC_APB2Periph_GPIOC
#define COM_RADIO_RX_PIN GPIO_Pin_2
#define COM_RADIO_RX_PORT GPIOD
#define COM_RADIO_RX_PORT_CLK RCC_APB2Periph_GPIOD
#define COM_RADIO_IRQn UART5_IRQn
#define COM_RADIO_DMA_CLK 0
#define COM_RADIO_TX_DMA_CHANNEL 0
#define COM_RADIO_DR_BASE 0
#define COM_RADIO_TX_IRQHandler 0
#define COM_RADIO_RX_IRQHandler 0
#define COM_RADIO_TX_DMA_COMPLETE 0
#define COM_RADIO_TX_DMA_ERROR 0
#define COM_RADIO_DMA_IRQn 0
#define COM_RADIO_TX_BUFFER_SIZE 255
#define COM_RADIO_RX_BUFFER_SIZE 255
#define COM_RADIO_STR "radio"
//define COM PLC module infomation
#define COM_PLC_NO USART3
#define COM_PLC_BAUD 2400
#define COM_PLC_CHECK USART_Parity_Even
#define COM_PLC_CLK RCC_APB1Periph_USART3
#define COM_PLC_TX_PIN GPIO_Pin_10
#define COM_PLC_TX_PORT GPIOB
#define COM_PLC_TX_PORT_CLK RCC_APB2Periph_GPIOB
#define COM_PLC_RX_PIN GPIO_Pin_11
#define COM_PLC_RX_PORT GPIOA
#define COM_PLC_RX_PORT_CLK RCC_APB2Periph_GPIOB
#define COM_PLC_IRQn USART3_IRQn
#define COM_PLC_DMA_CLK RCC_AHBPeriph_DMA1
#define COM_PLC_TX_DMA_CHANNEL DMA1_Channel2
#define COM_PLC_DR_BASE (USART3_BASE + 4)
#define COM_PLC_TX_IRQHandler DMA1_Channel2_IRQHandler
#define COM_PLC_RX_IRQHandler USART3_IRQHandler
#define COM_PLC_TX_DMA_COMPLETE DMA1_IT_TC2
#define COM_PLC_TX_DMA_ERROR DMA1_IT_TE2
#define COM_PLC_DMA_IRQn DMA1_Channel2_IRQn
#define COM_PLC_TX_BUFFER_SIZE 255
#define COM_PLC_RX_BUFFER_SIZE 255
#define COM_PLC_STR "PLC"
//define COM LORA moudule infomation
#define COM_485_NO USART2
#define COM_485_BAUD 2400 //8,e,1
#define COM_485_CHECK USART_Parity_Even
#define COM_485_CLK RCC_APB1Periph_USART2
#define COM_485_TX_PIN GPIO_Pin_2
#define COM_485_TX_PORT GPIOA
#define COM_485_TX_PORT_CLK RCC_APB2Periph_GPIOA
#define COM_485_RX_PIN GPIO_Pin_3
#define COM_485_RX_PORT GPIOA
#define COM_485_RX_PORT_CLK RCC_APB2Periph_GPIOA
#define COM_485_IRQn USART2_IRQn
#define COM_485_DMA_CLK RCC_AHBPeriph_DMA1
#define COM_485_TX_DMA_CHANNEL DMA1_Channel7
#define COM_485_DR_BASE (USART2_BASE + 4)
#define COM_485_TX_IRQHandler DMA1_Channel7_IRQHandler
#define COM_485_RX_IRQHandler USART2_IRQHandler
#define COM_485_TX_DMA_COMPLETE DMA1_IT_TC7
#define COM_485_TX_DMA_ERROR DMA1_IT_TE7
#define COM_485_DMA_IRQn DMA1_Channel7_IRQn
#define COM_485_TX_BUFFER_SIZE 255
#define COM_485_RX_BUFFER_SIZE 255
#define COM_485_STR "485"
/*
//define COM module end
#define MBUS_OVERLOAD_FLAG_PIN GPIO_Pin_3
#define MBUS_OVERLOAD_FLAG_PIN_PORT GPIOC
#define MBUS_OVERLOAD_FLAG_PORT_CLK RCC_APB2Periph_GPIOC
#define MBUS_OVERLOAD_FLAG_PORT_SOURCE GPIO_PortSourceGPIOC
#define MBUS_OVERLOAD_FLAG_PIN_SOURCE GPIO_PinSource3
#define MBUS_OVERLOAD_FLAG_LINE EXTI_Line3
#define MBUS_OVERLOAD_FLAG_IRQHandler EXTI3_IRQHandler
*/
#define MBUSM_BAUD_COFF (11 * 1000 / COM_MBUS_MASTER_BAUD)
#define PLC_BAUD_COFF (11 * 1000 / COM_PLC_BAUD)
#define RS485_BAUD_COFF (11 * 1000 / COM_485_BAUD)
#define PRINT_BAUD_COFF (11 * 1000 / COM_DEBUG_BAUD)
#define MBUS_SWITCH_TIMEOUT (10000 /portTICK_RATE_MS)
#define PORT_RX_TIMEOUT (15 /portTICK_RATE_MS)//设置串口的超时接收时间,此值需设置为最低波特率的最少两个字节时间
#define SCAN_PORT_RERIOD (5 /portTICK_RATE_MS)//扫描串口超时的周期
#define MBUS_TIMEOUT (1200 /portTICK_RATE_MS)
#define CS485_TIMEOUT (2000 /portTICK_RATE_MS)
#define PLC_TIMEOUT (2500 /portTICK_RATE_MS)
#define XIMEI_TIMEOUT (10000 /portTICK_RATE_MS)
#define MUT_TIMEOUT (2000 /portTICK_RATE_MS)
#define OPEN_SWITCN_DELAY (2000 /portTICK_RATE_MS)
#define DELAY_HOUR_TIME (3600000 /portTICK_RATE_MS)
#define DELAY_MIN_TIME (60000 /portTICK_RATE_MS)
typedef struct
{
USART_TypeDef * com;
USART_InitTypeDef uart_param;
uint32_t com_clk;
uint16_t com_tx_pin;
GPIO_TypeDef * com_tx_port;
uint32_t com_tx_port_clk;
uint16_t com_rx_pin;
GPIO_TypeDef * com_rx_port;
uint32_t xom_rx_port_clk;
uint32_t com_DMA_CLK;
uint8_t com_IRQn;
uint8_t com_DMA_IRQn;
}st_uart_int;
typedef struct
{
USART_TypeDef * com;
DMA_Channel_TypeDef * com_TX_DMA_CHANNEL;
uint32_t com_DR_BASE;
u16 txbufLength;
}st_uart_channel_cfg;
#define COMM_BUF_SIZE 300
typedef struct
{
u8 *rxBuf;
u8 *txBuf;
u16 rx_index;
u16 rx_len;
u32 rx_timeout;
u32 tx_timeout;
}st_uart_buf_cfg;
struct st_uart_port
{
EventBits_t port_No;
SemaphoreHandle_t xSemaphore;
st_uart_int init;
st_uart_channel_cfg chl;
st_uart_buf_cfg data;
char * string;
};
#define DEFAULT_USART_CFG(baud, check) { baud,USART_WordLength_9b,USART_StopBits_1,\
check, (USART_Mode_Rx | USART_Mode_Tx),\
USART_HardwareFlowControl_None\
}
#define USART_INIT(name) { name##_NO,\
DEFAULT_USART_CFG(name##_BAUD, name##_CHECK),\
name##_CLK,name##_TX_PIN,\
name##_TX_PORT,name##_TX_PORT_CLK,\
name##_RX_PIN,\
name##_RX_PORT,\
name##_RX_PORT_CLK,\
name##_DMA_CLK,\
name##_IRQn,\
name##_DMA_IRQn\
}
#define USART_DMA_config(name) {name##_NO, name##_TX_DMA_CHANNEL, (uint32_t)name##_DR_BASE, name##_TX_BUFFER_SIZE}
#define USART_PORT_PARAMS(name, rxbuf, txbuf) {name##_PORT_NO, NULL, USART_INIT(name),USART_DMA_config(name),{rxbuf,txbuf,0,0,0,0}, name##_STR}
#define USART_RX_INT_HANDLE(name) void name##_RX_IRQHandler(void) \
{ \
if (USART_GetITStatus(name##_NO, USART_IT_RXNE) != RESET) \
{ \
uart_int_rx_frame(&(name##_port)); \
} \
} \
#define USART_TX_INT_HANDLE(name) void name##_TX_IRQHandler(void) \
{ \
if (DMA_GetITStatus(name##_TX_DMA_COMPLETE) != RESET) \
{ \
DMA_ClearITPendingBit(name##_TX_DMA_COMPLETE); \
uart_dma_tx_callback(&(name##_port)); \
} \
if (DMA_GetITStatus(name##_TX_DMA_ERROR) != RESET) \
{ \
DMA_ClearITPendingBit(name##_TX_DMA_ERROR); \
} \
}
#define create_uart_port(name, rxbuf, txbuf) struct st_uart_port name##_port = USART_PORT_PARAMS(name, rxbuf, txbuf);\
USART_TX_INT_HANDLE(name) \
USART_RX_INT_HANDLE(name) \
enum
{
UP_VER_OF_COMMON = 0,
UP_VER_OF_WHSF,
UP_VER_OF_E5E50000,
UP_VER_OF_E5E50001,
UP_VER_OF_FJWGDATA,
UP_VER_OF_standard,
UP_VER_OF_MAX
};
enum
{
PORT_NONE = 0,
PORT_MBUS_MASTER,
PORT_RADIO,
PORT_PLC,
PORT_485,
PORT_MUT,
POET_DEBUG,
PORT_MAX,
};
enum
{
COM_MBUS_MASTER_PORT_NO = (1UL << PORT_MBUS_MASTER),
COM_RADIO_PORT_NO = (1UL << PORT_RADIO),
COM_PLC_PORT_NO = (1UL << PORT_PLC),
COM_485_PORT_NO = (1UL << PORT_485),
COM_MUT_PORT_NO = (1UL << PORT_MUT),
COM_DEBUG_PORT_NO = (1UL << POET_DEBUG),
PORT_AUTO = (COM_MBUS_MASTER_PORT_NO | COM_485_PORT_NO | COM_MUT_PORT_NO)
};
enum
{
PROTCL_AUTO = 0,
PROTCL_E5E50000,
MBUS_METER_START,
MBUS_901F_2400_E,
MBUS_1F90_2400_E,
MBUS_HHCQ_2400_N,
MBUS_YZSJ_1200_E,
MBUS_HZJD_1200_E,
MBUS_METER_MAX,
RS485_METER_START,
RS485_NJSM_1200_N,
RS485_CS485_2400_E,
RS485_METER_MAX,
MUT_METER_START,
//MUT_CQXM_LORA,
MUT_SPI_LORA,
MUT_METER_MAX,
};
/* Baud bps 07 依次表示:
自适应, 1200 2400 4800 9600 19200
38400 57600 */
enum
{
BAUD_auto = 0,
BAUD_1200,
BAUD_2400,
BAUD_4800,
BAUD_9600,
BAUD_19200,
BAUD_38400,
BAUD_57600,
};
/* 0/1
1/2 停止位 */
enum
{
STOP_1bits = 0,
STOP_2bits,
};
/* 0/1
无/有校验 */
enum
{
PARITY_NONE = 0,
PARITY_TRUE,
};
/* 0/1
偶/奇校验 */
enum
{
PARITY_EVEN = 0,
PARITY_ODD,
};
/* 03
5-8 位数 */
enum
{
DATABITS_5 = 0,
DATABITS_6,
DATABITS_7,
DATABITS_8,
};
enum
{
UP_PORT_PLC,
UP_PORT_485,
UP_PORT_MAX,
};
enum
{
MBUS_MODE_MASTER = 0,
MBUS_MODE_SLAVE,
};
/********************define MBUS power contrl pin******************************/
#define MBUS_POWER_CTRL_PIN GPIO_Pin_1
#define MBUS_POWER_CTRL_PIN_PORT GPIOB
#define MBUS_POWER_CTRL_PORT_CLK RCC_APB2Periph_GPIOB
#define open_mbus_switch() GPIO_ResetBits(MBUS_POWER_CTRL_PIN_PORT, MBUS_POWER_CTRL_PIN)
#define close_mbus_switch() GPIO_SetBits(MBUS_POWER_CTRL_PIN_PORT, MBUS_POWER_CTRL_PIN)
#define mbus_switch_state() GPIO_ReadOutputDataBit(MBUS_POWER_CTRL_PIN_PORT, MBUS_POWER_CTRL_PIN)
/********************define MBUS in pin*******************************/
#define MBUS_EXTIN_PIN GPIO_Pin_4
#define MBUS_EXTIN_PORT GPIOC
#define MBUS_EXTIN_CLK RCC_APB2Periph_GPIOC
#define MBUS_in_state() GPIO_ReadInputDataBit(MBUS_EXTIN_PORT, MBUS_EXTIN_PIN)
#define MBUS_EXT_FLAG_PORT_SOURCE GPIO_PortSourceGPIOC
#define MBUS_EXT_FLAG_PIN_SOURCE GPIO_PinSource4
#define MBUS_EXT_FLAG_LINE EXTI_Line4
#define MBUS_EXT_IRQHandler EXTI4_IRQHandler
/********************define MBUS overload *******************************/
#define MBUS_OVERLOAD_PIN GPIO_Pin_12
#define MBUS_OVERLOAD_PORT GPIOB
#define MBUS_OVERLOAD_CLK RCC_APB2Periph_GPIOB
#define MBUS_OVERLOAD_in_state() GPIO_ReadInputDataBit(MBUS_OVERLOAD_PORT, MBUS_OVERLOAD_PIN)
#define MBUS_OVERLOAD_FLAG_PORT_SOURCE GPIO_PortSourceGPIOB
#define MBUS_OVERLOAD_FLAG_PIN_SOURCE GPIO_PinSource12
#define MBUS_OVERLOAD_FLAG_LINE EXTI_Line12
#define MBUS_OVERLOAD_FLAG_IRQHandler EXTI15_10_IRQHandler
/********************define power level pin*******************************/
#define POWER_LEVEL_PIN GPIO_Pin_13
#define POWER_LEVEL_PORT GPIOB
#define POWER_LEVEL_PORT_CLK RCC_APB2Periph_GPIOB
#define SET_POWER_LEVEL_HIGH() GPIO_SetBits(POWER_LEVEL_PORT, POWER_LEVEL_PIN);
#define SET_POWER_LEVEL_LOW() GPIO_ResetBits(POWER_LEVEL_PORT, POWER_LEVEL_PIN);
#define power_level_state() GPIO_ReadOutputDataBit(POWER_LEVEL_PORT, POWER_LEVEL_PIN)
/********************define 485 power contrl pin******************************/
#define RS485_CTRL_PIN GPIO_Pin_5
#define RS485_CTRL_PIN_PORT GPIOC
#define RS485_CTRL_PORT_CLK RCC_APB2Periph_GPIOC
#define open_RS485_switch() GPIO_ResetBits(RS485_CTRL_PIN_PORT, RS485_CTRL_PIN);hal_sRF_ITConfig(RS485_OVERLOAD_FLAG_LINE, ENABLE)
#define close_RS485_switch() GPIO_SetBits(RS485_CTRL_PIN_PORT, RS485_CTRL_PIN); hal_sRF_ITConfig(RS485_OVERLOAD_FLAG_LINE, DISABLE)
#define RS485_switch_state() GPIO_ReadOutputDataBit(RS485_CTRL_PIN_PORT, RS485_CTRL_PIN)
/********************define 485 in pin*******************************/
#define RS485_EXTIN_PIN GPIO_Pin_6
#define RS485_EXTIN_PORT GPIOA
#define RS485_EXTIN_CLK RCC_APB2Periph_GPIOA
#define RS485_in_state() GPIO_ReadOutputDataBit(RS485_EXTIN_PORT, RS485_EXTIN_PIN)
/********************define MBUS overload *******************************/
#define RS485_OVERLOAD_PIN GPIO_Pin_7
#define RS485_OVERLOAD_PORT GPIOA
#define RS485_OVERLOAD_CLK RCC_APB2Periph_GPIOA
#define RS485_OVERLOAD_in_state() GPIO_ReadOutputDataBit(RS485_OVERLOAD_PORT, RS485_OVERLOAD_PIN)
#define RS485_OVERLOAD_FLAG_PORT_SOURCE GPIO_PortSourceGPIOA
#define RS485_OVERLOAD_FLAG_PIN_SOURCE GPIO_PinSource7
#define RS485_OVERLOAD_FLAG_LINE EXTI_Line7
#define RS485_OVERLOAD_IRQn EXTI9_5_IRQn
#define RS485_OVERLOAD_FLAG_IRQHandler EXTI9_5_IRQHandler
/********************define PLC reset pin*******************************/
#define PLC_RESET_PIN GPIO_Pin_0
#define PLC_RESET_PIN_PORT GPIOB
#define PLC_RESET_PIN_CLK RCC_APB2Periph_GPIOB
#define PLC_RESET_HIGH() GPIO_SetBits(PLC_RESET_PIN_PORT, PLC_RESET_PIN)
#define PLC_RESET_LOW() GPIO_ResetBits(PLC_RESET_PIN_PORT, PLC_RESET_PIN)
/********************define overload current pin*******************************/
#define MUT_RESET_PIN GPIO_Pin_14
#define MUT_RESET_PIN_PORT GPIOB
#define MUT_RESET_PIN_CLK RCC_APB2Periph_GPIOB
#define MUT_RESET_HIGH() GPIO_SetBits(PLC_RESET_PIN_PORT, PLC_RESET_PIN)
#define MUT_RESET_LOW() GPIO_ResetBits(PLC_RESET_PIN_PORT, PLC_RESET_PIN)
#define IRDA_TPIN_CFG {GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_0, GPIO_Mode_IN_FLOATING} //PA0
#define IRDA_RPIN_CFG {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_1, GPIO_Mode_IN_FLOATING} //PC1
#define RF_DOWN_TPIN_CFG {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_12, GPIO_Mode_IN_FLOATING} //PC12
#define RF_DOWN_RPIN_CFG {GPIOD, RCC_APB2Periph_GPIOD, GPIO_Pin_2, GPIO_Mode_IN_FLOATING} //PD2
#define RS485_UP_TPIN_CFG {GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_4, GPIO_Mode_IN_FLOATING} //PA4
#define RS485_UP_RPIN_CFG {GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_5, GPIO_Mode_IN_FLOATING} //PA5
#define PLC_RESET_CFG {GPIOB, RCC_APB2Periph_GPIOB, GPIO_Pin_0, GPIO_Mode_IPU} //PB0
#define MBUS_SWITCH_CFG {GPIOB, RCC_APB2Periph_GPIOB, GPIO_Pin_1, GPIO_Mode_IN_FLOATING} //PB1
#define MBUS_EXT_CFG {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_4, GPIO_Mode_IN_FLOATING} //PC4
#define MBUS_OVERLOAD_CFG {GPIOB, RCC_APB2Periph_GPIOB, GPIO_Pin_12, GPIO_Mode_IN_FLOATING} //PB12
#define RS485_CTRL_CFG {GPIOC, RCC_APB2Periph_GPIOC, GPIO_Pin_5, GPIO_Mode_IN_FLOATING} //PC5
#define RS485_OVERLOAD_CFG {GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_7, GPIO_Mode_IN_FLOATING} //PA7
#define RS485_EXT_CFG {GPIOA, RCC_APB2Periph_GPIOA, GPIO_Pin_6, GPIO_Mode_IN_FLOATING} //PA6
#define MBUS_POW_LEVEL_CFG {GPIOB, RCC_APB2Periph_GPIOB, GPIO_Pin_13, GPIO_Mode_IN_FLOATING} //PB13
extern void add_one_list_node(st_params* params);
extern void COM_frozen_uplinkPacket_create(st_params * ptr, u8* outBuf);
extern void COM_uplinkPacket_create(st_params * ptr, u8* outBuf);
extern u16 create_queue_send_packet(u8 * buf, u16 length);
extern void DLT645_07_addr_ack(u8 *buf);
extern void DLT645_97_1F_addr_ack(u8 *buf);
extern void E5E5_uplinkPacket_create(st_params * ptr, u8* outBuf);
extern u8 get_protocl_inRAM(void);
extern bool get_readMeter_params(u8 *buf, st_params * ptr);
extern bool get_read_meter_packet(u16 meter_protcl, u8 type, u8 *meter_id, u8 *outBuf, u16 *outLen);
extern void hal_InitCOM(struct st_uart_port * port);
extern void hal_UartDMATx(struct st_uart_port* uart_port, u8 *pBuf, u16 length);
//extern void hal_UartIntTx(u8 *pBuf, u16 length);
extern void init_uart_port(struct st_uart_port * port);
extern void init_uart_tasks(void);
extern void led_process_task(void * ptr);
extern void mbus_gpio_init(void);
extern void MBUS_master_process_task(void * ptr);
extern void MBUS_mater_Tx(u8 *pBuf, u16 length);
extern void MBUS_OVERLOAD_FLAG_IRQHandler(void);
extern void MBUS_slave_process_task(void *ptr);
extern void mbus_switch_timeOut_callback_function(TimerHandle_t xTimer);
extern bool meter_ack_packet_process(u16 meter_protl, u8 *inbuf, u8 inLen, st_params * ptr, u8* outBuf);
extern void PLC_process_task(void *ptr);
extern void plc_uart_Tx(u8 *buf, u16 length);
extern void port_send(struct st_uart_port* port, u8 *buf, u16 length);
extern bool read_meter_process(u8 meter_protcl, st_params *read_params, u8 *outbuf);
extern bool read_power_level(void);
extern void read_standard_elcMeter(u8 *buf, u8 length);
extern void saved_meter_process(bool success, struct st_meter_temp_value *saved_ptr, st_params * ptr);
extern void set_curent_protocl(u8 config);
extern void set_mbus_master_params(u32 baud, u16 check);
extern void set_PLC_UART_baud(u32 baud);
extern void set_port_prams(u16 meter_protcl);
extern void set_power_level(bool high);
extern void simulate_mbus_plc_rx(u8 *buf, u8 len);
extern void temp_saved_task(void *ptr);
extern void UART5_IRQHandler(void);
extern void uarts_process_task(void * ptr);
extern void uart_dma_tx_callback(struct st_uart_port* uartPort);
extern void uart_int_rx_frame(struct st_uart_port* uartPort);
extern void uplinkPacket_create(st_params * ptr, u8* outBuf);
extern void uplink_ack_send(u8 uplink, u8 *buf, u16 length);
extern void WHSF_uplinkPacket_create(st_params * ptr, u8* outBuf);
extern void auto_sync_list_meters(void);
extern void RS485_gpio_init(void);
void RS4852_SendDataPacket(u8 *buf, u16 length);
void up_485_Tx(u8 *buf, u16 length);
#endif

916
APP/update.c Normal file
View File

@@ -0,0 +1,916 @@
/******************************************************************************************
update Function
STM32F103RCT6 256K flash 48K RAM
flash : 0-15k API API : 0x0800,0000-0x0800,3FFF
: 16-17, params : 0x0800,4000-0x0800,47FF
: 18-19k key : 0x0800,4800-0x0800,4FFF
: 20K - 137K app : 0x0800,5000-0x0802,27FF
: 138K- 255K update app: 0x0802,2800-0x0803,FFFF
typedef struct
{
u8 file_indication;
u8 file_property;
u8 file_instr;
u16 total_packets;
u32 current_packet_No;
u16 packet_length;
u8 * data;
}st_update_packet;
typedef enum
{
UPDATE_END = 0,
UPDATE_RUNNING,
UPDATE_FINISH,
UPDATE_SUCCESS,
UPDATE_FAILED,
UPDATE_SALVE,
}EM_UPDATE_STATUS;
******************************************************************************/
#include "apl.h"
#include "update.h"
#include "Flash.h"
#include "uart.h"
#include "Mem.h"
#include "addr.h"
#include "General.h"
#include "MD5.h"
#include "Led.h"
st_update_params st_update;
static u8 packet_nnmber;
extern const u16 CRC16_Table[];
static u8 g_update_ctrl = UPDATE_NONE;
static QueueHandle_t updateQueue;
#define UPDATE_BUF_LEN 255
/*****************************************************************************
* Function : write_update_ctrlner
* Description : none
* Input : u8 ctrlner
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
void write_update_ctrlner(u8 ctrlner)
{
if (ctrlner < UPDATE_MAX)
{
g_update_ctrl = ctrlner;
}
}
/*****************************************************************************
* Function : read_update_ctrlner
* Description : none
* Input : void
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
u8 read_update_ctrlner(void)
{
return g_update_ctrl;
}
/*****************************************************************************
* Function : set_update_packetState
* Description : none
* Input : u16 packetNo
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
void set_update_packetState(u16 packetNo)
{
st_update.packetsState[packetNo/8] |= (1<<(packetNo%8));
}
/*****************************************************************************
* Function : check_update_packect_state
* Description : none
* Input : u16 packetNo
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170314
* Author : barry
* Modification: Created function
*****************************************************************************/
bool check_update_packect_state(u16 packetNo)
{
if (st_update.packetsState[packetNo/8] & (1<<(packetNo%8)) )
{
return TRUE;
}
else
{
return FALSE;
}
}
/*****************************************************************************
*
check if all packet reserved
*
*****************************************************************************/
bool check_update_state(u16 total_packets)
{
for (u16 j = 0; j < total_packets; j++)
{
if (check_update_packect_state(j) == FALSE)
{
return FALSE;
}
}
return TRUE;
}
/*****************************************************************************
*
check if update data reserved right
*
*****************************************************************************/
bool update_software_check(u32 totalBytes)
{
u16 temp;
u16 crc16 = 0xFFFF;
u32 count = totalBytes -2;
u8 flash_temp;
u32 current_flash_addr = FLASH_APP_BACK_ADDRESS;
if (totalBytes <= 2)
{
return FALSE;
}
while (count--)
{
//GDflash_read(current_flash_addr, &flash_temp, 1);
flash_temp = *((u8*)current_flash_addr);
current_flash_addr++;
crc16 = (crc16 >> 8 ) ^ CRC16_Table[(crc16 ^ flash_temp) & 0xFF];
}
crc16 ^= 0xFFFF;
//GDflash_read(current_flash_addr, &flash_temp, 1);
flash_temp = *((u8*)current_flash_addr);
current_flash_addr++;
temp = (u16)flash_temp*256;
//GDflash_read(current_flash_addr, &flash_temp, 1);
flash_temp = *((u8*)current_flash_addr);
current_flash_addr++;
temp += flash_temp;
if (crc16 == temp)
{
return TRUE;
}
else
{
return FALSE;
}
}
/*****************************************************************************
*
write update packet in flash
*
*****************************************************************************/
void FLASH_Write_update_page(u16 packetNo, u8 * Data, u8 length)
{
u32 packet_start_addr = FLASH_APP_BACK_ADDRESS + packetNo * UPDATE_DEFAULT_PACKET_SIZE;
u8 buf[128];
MemCpy(buf, Data, length);
__disable_irq();
STM32_FlashWrite(packet_start_addr, Data, length);
__enable_irq();
}
/********************************************************************************
*
read update params from flash
*
*********************************************************************************/
bool read_update_flash(st_update_params *st_update_Structure)
{
memcpy(st_update_Structure, (u8*)FLASH_UPDATE_PARAMS_ADDRESS,sizeof(st_update_params));
if ( GetCRC16((u8*)st_update_Structure, sizeof(st_update_params) -2) == (st_update_Structure->crc) )
{
return TRUE;
}
else
{
return FALSE;
}
}
/********************************************************************************
*
write update params in flash
*
*********************************************************************************/
void write_update_flash(st_update_params *st_update_Structure )
{
st_update_Structure->crc = GetCRC16((u8*)st_update_Structure, sizeof(st_update_params) - 2);
if (STM32_FlashPageErase(FLASH_UPDATE_PARAMS_ADDRESS) == FLH_SUCCESS)
{
STM32_FlashWrite( FLASH_UPDATE_PARAMS_ADDRESS, (u8*)st_update_Structure, sizeof(st_update_params));
}
}
/*****************************************************************************
*
*
*****************************************************************************/
void reset_update_params(void)
{
memset(&st_update, 0 , sizeof(st_update));
write_update_flash(&st_update);
}
void update_ack(u8 number, u32 current_packet_No, u8 ctrl, u8 ctrlner)
{
static st_AFN15_ack afn15ack;
afn15ack.head.start = 0x68;
afn15ack.head.len = 0x13;
afn15ack.head.ctrl = ctrl | 0xc0;
afn15ack.head.info_route = 0;
afn15ack.head.info_slave = 0;
afn15ack.head.info_com_module = 0;
afn15ack.head.info_conflict = 0;
afn15ack.head.info_relay = 0;
afn15ack.head.info[0] = 0;
afn15ack.head.info[1] = 0;
afn15ack.head.info[2] = 0;
afn15ack.head.info[3] = 0;
afn15ack.head.number = number;
afn15ack.afn = 0x15;
afn15ack.dt1 = 0x01;
afn15ack.dt2 = 0x00;
afn15ack.current_packet_No = current_packet_No;
afn15ack.cs = GetSum((u8*)(&afn15ack)+ 3, 14);
afn15ack.end = 0x16;
if (ctrlner == UPDATE_485)
{
debug_Tx( (u8*)&afn15ack, sizeof(st_AFN15_ack));
}
else
{
plc_uart_Tx( (u8*)&afn15ack, sizeof(st_AFN15_ack));
}
}
u16 get_DT(u8 DT1, u8 DT2)
{
u16 temp = 0;
for (u8 i = 0; i < 8; i++)
{
temp += ((DT1 >> i) & 0x01);
}
if (temp != 1)
{
return 0xFF;
}
temp = 0;
do{
DT1 = DT1 >> 1;
if (DT1 == 0)
{
break;
}
temp++;
}while(1);
return (0xF1 + DT2*8 + temp);
}
void decode_dt(u16 DT, u8 *dt1, u8 *dt2)
{
*dt2 = (DT - 0xF1)/ 8;
*dt1 = (1 << (DT - 0xF1) % 8);
}
void defaut_13762head_ack_write(st_13762_head * head, u8 length, bool com_module_exist, u8 ctrl)
{
head->start = 0x68;
head->len = length;
head->ctrl = ctrl | 0x80;
head->info_route = 0;
head->info_slave = 0;
head->info_com_module = (u8)com_module_exist;
head->info_conflict = 0;
head->info_relay = 0;
MemSet(head->info, 0, 4);
head->number = packet_nnmber;
}
void apl_process_1372(u8 * ptr1372, u8 ctrlner)
{
static st_13762 temp_1372_frame;
static st_13762 *ptr_1372 = &temp_1372_frame;
static st_13762_03F1_ack ack_ptr_13762_03f1;
u8 *current_ptr = NULL;
u16 DT;
memcpy(ptr_1372, ptr1372, 10);
u16 length = temp_1372_frame.lenL + temp_1372_frame.lenH *256;
ptr_1372->cs = ptr1372[length - 2];
ptr_1372->end = ptr1372[length - 1];
if ((ptr_1372->ctrl & 0x08) == 1)
{
return ;
}
current_ptr = &ptr1372[10];
packet_nnmber = ptr_1372->number;
if (ptr_1372->info_com_module)
{
ptr_1372->source_addr = current_ptr;
current_ptr += 6;
if (cmp_addr(ptr_1372->source_addr) == ADDR_NEQ)
{
return;
}
if (ptr_1372->info_relay)
{
ptr_1372->relay_addr = current_ptr;
current_ptr += ptr_1372->info_relay*6;
}
ptr_1372->desc_addr = current_ptr;
current_ptr += 6;
}
ptr_1372->AFN = *current_ptr;
ptr_1372->DT1 = *(current_ptr + 1);
ptr_1372->DT2 = *(current_ptr + 2);
current_ptr += 3;
DT = get_DT(ptr_1372->DT1, ptr_1372->DT2);
ptr_1372->data = current_ptr;
if (!(ptr_1372->info_com_module))
{
switch (ptr_1372->AFN)
{
case 0x03:
if (DT == 0xF1)
{
if (ctrlner == UPDATE_PLC)
{
defaut_13762head_ack_write(&ack_ptr_13762_03f1.head, sizeof(st_13762_03F1_ack), FALSE, ptr_1372->ctrl);
ack_ptr_13762_03f1.AFN = 0x03;
ack_ptr_13762_03f1.DT1 = 0x01;
ack_ptr_13762_03f1.DT2 = 0x00;
MemCpy(ack_ptr_13762_03f1.Manu_code, (u8*)get_apl_version_ptr(), sizeof(Manufacturer_Version));
ack_ptr_13762_03f1.cs = GetSum( (u8*)&ack_ptr_13762_03f1 + 3, sizeof(st_13762_03F1_ack) - 5);
ack_ptr_13762_03f1.end = 0x16;
plc_uart_Tx((u8*)&ack_ptr_13762_03f1, sizeof(st_13762_03F1_ack));
}
}
break;
case 0x15:
if (DT == 0xF1)
{
if (read_update_ctrlner() == UPDATE_NONE)
{
write_update_ctrlner(ctrlner);
xQueueSendToBack( updateQueue, (u8*)ptr_1372->data, 10);
}
else if (read_update_ctrlner() == ctrlner)
{
xQueueSendToBack( updateQueue, (u8*)ptr_1372->data, 10);
}
}
break;
default:
break;
}
}
}
bool check_13762_packet(u8 *buf)
{
u8 len = buf[1] + buf[2]*256;
if ( (buf[0] == 0x68) && (buf[len -1] == 0x16) )
{
if (buf[len -2] == GetSum(buf + 3, len - 5))
{
return TRUE;
}
}
return FALSE;
}
void transparent_Proc(void)
{
//transparent xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
u8 *start_pos = NULL;
// u8 transparent_cmd[] = "transparent 00 ";
start_pos = get_debugBuf() + sizeof("transparent 00 ") - 1;
if (check_13762_packet(start_pos))
{
apl_process_1372(start_pos, UPDATE_485);
}
}
uint16_t get_packets(uint32_t totalBytes )
{
uint16_t packet;
packet = totalBytes /FLASH_PAGE_SIZE;
if (totalBytes % FLASH_PAGE_SIZE )
{
packet += 1;
}
return packet;
}
/*****************************************************************************
* Function : update_iap
* Description : none
* Input : u32 totalBytes
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170425
* Author : barry
* Modification: Created function
此处还需要修改不要使用1页的内存来存储用小内存或者直接用半字的方式来处理
*****************************************************************************/
bool update_iap(u32 totalBytes)
{
//static u8 updateBuf[FLASH_PAGE_SIZE];
u16 iap_flash_pages = get_packets(totalBytes);
for (u32 j = 0; j < iap_flash_pages; j++)
{
// memcpy(updateBuf, (u8*)(FLASH_APP_BACK_ADDRESS + j*FLASH_PAGE_SIZE), FLASH_PAGE_SIZE);
if (STM32_FlashPageErase(FLASH_API_ADDRESS + FLASH_PAGE_SIZE*j) == FLH_SUCCESS)
{
if (STM32_FlashWrite(FLASH_API_ADDRESS + FLASH_PAGE_SIZE*j, (u8*)(FLASH_APP_BACK_ADDRESS + j*FLASH_PAGE_SIZE) , FLASH_PAGE_SIZE) != FLH_SUCCESS)
{
return FALSE;
}
}
else
{
return FALSE;
}
}
return TRUE;
}
bool proceess_packet(st_update_packet * current_ptr, st_update_params * flash_ptr)
{
if (check_update_packect_state( current_ptr->current_packet_No))
{
printf("the same packet\r\n");
return FALSE;
}
printf("write packet %d in flash\r\n", current_ptr->current_packet_No);
FLASH_Write_update_page(current_ptr->current_packet_No, current_ptr->data, current_ptr->packet_length);
set_update_packetState(current_ptr->current_packet_No);
flash_ptr->received_packets++;
flash_ptr->current_packets = current_ptr->current_packet_No;
if (current_ptr->current_packet_No >= (current_ptr->total_packets - 1))
{
if (check_update_state(flash_ptr->total_packets) == TRUE)
{
printf("all packet received\r\n");
printf("total updte bytes = %d\r\n", flash_ptr->totalBytes );
flash_ptr->totalBytes = (current_ptr->total_packets - 1)*UPDATE_DEFAULT_PACKET_SIZE + current_ptr->packet_length;
if (current_ptr->file_indication == 0x03)
{
flash_ptr->status = UPDATE_FINISH;
write_update_flash(flash_ptr);
return TRUE;
}
else if (current_ptr->file_indication == 0xFD )
{
return TRUE;
}
else
{
reset_update_params();
printf("update file indication err\r\n");
return FALSE;
}
}
else
{
reset_update_params();
printf("update file err\r\n");
return FALSE;
}
}
else
{
return FALSE;
}
}
void erase_128k(void)
{
for (u32 i = 0; i < FLASH_APPL_BACK_PAGES; i++)
{
STM32_FlashPageErase(FLASH_APP_BACK_ADDRESS + i*2048);
}
}
static bool is_update_process = false;
bool get_update_process()
{
return is_update_process;
}
void set_update_process()
{
is_update_process = true;
}
void update_process_task(void *ptr)
{
static st_update_packet update_packet;
static bool update_finish_state = FALSE;
static u8 tempBuf[UPDATE_BUF_LEN];
static u32 last_packet_No = 0;
updateQueue = xQueueCreate(1, UPDATE_BUF_LEN);
for (;;)
{
xQueueReceive(updateQueue, tempBuf, portMAX_DELAY );
memcpy(&update_packet, tempBuf, sizeof(st_update_packet) - 4);
update_packet.data = tempBuf + sizeof(st_update_packet) -4;
if (update_packet.current_packet_No != 0)
{
continue;
}
printf("update start\r\n");
set_update_process();
vTaskDelay(1000/portTICK_RATE_MS);
close_printf();
memset(&st_update, 0 , sizeof(st_update));
erase_128k();
vTaskDelay(1000/portTICK_RATE_MS);
st_update.status = UPDATE_RUNNING;
st_update.total_packets = update_packet.total_packets;
printf("update_totalPackets = %d\r\n", st_update.total_packets);
last_packet_No = 0;
update_finish_state = proceess_packet(&update_packet, &st_update);
update_ack(packet_nnmber, update_packet.current_packet_No, 0x0A, g_update_ctrl);
if ( g_update_ctrl == UPDATE_PLC)
{
vTaskDelay(100/portTICK_RATE_MS);
set_PLC_UART_baud(57600);
}
while(1)
{
if( xQueueReceive(updateQueue, tempBuf, 3000/portTICK_RATE_MS ) == pdPASS)
{
memcpy(&update_packet, tempBuf, sizeof(st_update_packet) - 4);
update_packet.data = tempBuf + sizeof(st_update_packet) -4;
if (update_packet.current_packet_No != (last_packet_No + 1))
{
reset_update_params();
open_printf();
if ( g_update_ctrl == UPDATE_PLC)
{
set_PLC_UART_baud(COM_PLC_BAUD);
}
break;
}
else
{
last_packet_No += 1;
update_finish_state = proceess_packet(&update_packet, &st_update);
update_ack(packet_nnmber, update_packet.current_packet_No, 0x0A, g_update_ctrl);
if (update_finish_state)
{
update_finish_state = FALSE;
if (update_packet.file_indication == 0x03 ) //升级自身
{
vTaskDelay(300/portTICK_RATE_MS);
SysReset();
}
else if (update_packet.file_indication == 0xFD ) //升级IAP
{
if (update_software_check(st_update.totalBytes))
{
bool iap_result = update_iap(st_update.totalBytes);
if (iap_result)
{
SysReset();
}
}
set_PLC_UART_baud(COM_PLC_BAUD);
reset_update_params();
}
else //升级标志错误
{
set_PLC_UART_baud(COM_PLC_BAUD);
reset_update_params();
}
}
}
}
else
{
if ( g_update_ctrl == UPDATE_PLC)
{
set_PLC_UART_baud(COM_PLC_BAUD);
}
memset(&st_update, 0 , sizeof(st_update));
break;
}
}
}
}
void create_update_task(void)
{
xTaskCreate( update_process_task, NULL, 200, NULL, 3, NULL);
}
void updata_finish(u32 total_packets)
{
reset_update_params();
st_update.status = UPDATE_FINISH;
st_update.totalBytes = total_packets;
write_update_flash(&st_update);
}
/*
#define ONE_HOUR_TIME 3600000
#define HALF_HOUR_TIME 1800000
PROCESS(apl_update_process, "update_process ");
PROCESS_THREAD(apl_update_process, ev, data)
{
static st_update_packet update_packet;
static bool update_finish_state = FALSE;
static struct etimer update_timer;
static struct etimer timeout_timer;
static u8 tempBuf[255];
static u8 buf[12];
PROCESS_BEGIN();
if (ev == PROCESS_EVENT_INIT)
{
read_update_flash(&st_update);
if (st_update.status == UPDATE_SUCCESS)
{
all_light_delay();
reset_update_params();
}
memset(&st_update, 0 , sizeof(st_update));
}
while (1)
{
PROCESS_WAIT_EVENT();
if (ev == PROCESS_EVENT_MSG)
{
memcpy(tempBuf, (u8*)data, COM_PLC_RX_BUFFER_SIZE);
memcpy(&update_packet, tempBuf, sizeof(st_update_packet) - 4);
update_packet.data = tempBuf + sizeof(st_update_packet) -4;
if (update_packet.current_packet_No >= update_packet.total_packets )
{
printf("packet no error\r\n");
continue;
}
if (update_packet.current_packet_No == 0)
{
close_printf();
printf("update start\r\n");
memset(&st_update, 0 , sizeof(st_update));
erase_128k();
etimer_set(&update_timer, 1000);
PROCESS_WAIT_EVENT_UNTIL((ev == PROCESS_EVENT_TIMER) && ((struct etimer *)data == &update_timer));
etimer_set(&update_timer, HALF_HOUR_TIME);
st_update.status = UPDATE_RUNNING;
st_update.total_packets = update_packet.total_packets;
printf("update_totalPackets = %d\r\n", st_update.total_packets);
}
else
{
if (st_update.status != UPDATE_RUNNING)
{
reset_update_params();
open_printf();
continue;
}
}
update_finish_state = proceess_packet(&update_packet, &st_update);
update_ack(packet_nnmber, update_packet.current_packet_No, 0x0A, g_update_ctrl);
if ((update_packet.current_packet_No == 0) && (g_update_ctrl == UPDATE_PLC))
{
etimer_set(&update_timer, 100);
PROCESS_WAIT_EVENT_UNTIL((ev == PROCESS_EVENT_TIMER) && ((struct etimer *)data == &update_timer));
set_PLC_UART_baud(57600);
}
if (update_packet.current_packet_No == update_packet.total_packets -1)
{
etimer_stop(&timeout_timer);
}
if (update_finish_state)
{
update_finish_state = FALSE;
if (update_packet.file_indication == 0x03 )
{
etimer_set(&update_timer, 300);
PROCESS_WAIT_EVENT_UNTIL((ev == PROCESS_EVENT_TIMER) && ((struct etimer *)data == &update_timer));
SysReset();
}
else if (update_packet.file_indication == 0xFD )
{
if (update_software_check(st_update.totalBytes))
{
if (!update_iap(st_update.totalBytes))
{
SysReset();
}
set_PLC_UART_baud(9600);
}
}
else
{
reset_update_params();
}
}
}
else if ((ev == PROCESS_EVENT_TIMER) && ((struct etimer *)data == &timeout_timer))
{
reset_update_params();
set_PLC_UART_baud(9600);
open_printf();
}
}
PROCESS_END();
}
*/
/******************* (C) COPYRIGHT 2013 Robulink Technology Ltd.*****END OF FILE****/

147
APP/update.h Normal file
View File

@@ -0,0 +1,147 @@
#ifndef _UPDATE_H_
#define _UPDATE_H_
#include "Basedefine.h"
#define FLASH_API_ADDRESS 0x08000000
#define FLASH_MAINTAINTIME_ADDRESS 0x08003000
#define FLASH_KEY_ADDRESS 0x08003800
#define FLASH_UPDATE_PARAMS_ADDRESS 0x08004000
#define FLASH_LOCAL_ADDR_ADDRESS 0x08004c00 // ÔÚAPPµÄÇ°ÃæÒ»¸ö1KλÖÃ
#define FLASH_APP_ADDRESS 0x08005000
#define FLASH_APP_BACK_ADDRESS 0x08022800
#define FLASH_SLAVE_NODE_COUNT_ADDRESS 0x0803F800
#define FLASH_API_PAGES 8
#define FLASH_PARAMS_PAGES 2
#define FLASH_APP_PAGES 59
#define FLASH_APPL_BACK_PAGES 59
#define UPDATE_DEFAULT_PACKET_SIZE 128
#define FLASH_PAGE_SIZE 2048
typedef enum
{
UPDATE_END = 0,
UPDATE_RUNNING,
UPDATE_FINISH,
UPDATE_SUCCESS,
UPDATE_FAILED,
UPDATE_SALVE,
}EM_UPDATE_STATUS;
enum
{
UPDATE_NONE,
UPDATE_PLC,
UPDATE_485,
UPDATE_MAX,
};
#pragma pack(push)
#pragma pack(1)
typedef struct
{
u32 totalBytes;
u16 version;
u16 total_packets;
u16 current_packets;
u16 received_packets;
u8 status;
u8 packetsState[127];
u16 crc;
}st_update_params;
typedef struct
{
u8 file_indication;
u8 file_property;
u8 file_instr;
u16 total_packets;
u32 current_packet_No;
u16 packet_length;
u8 * data;
}st_update_packet;
typedef struct
{
u8 start;
u16 len;
u8 ctrl;
u8 info_route:1;
u8 info_slave:1;
u8 info_com_module:1;
u8 info_conflict:1;
u8 info_relay:4;
u8 info[4];
u8 number;
}st_13762_head;
typedef struct
{
st_13762_head head;
u8 afn;
u8 dt1;
u8 dt2;
u32 current_packet_No;
u8 cs;
u8 end;
}st_AFN15_ack;
typedef struct
{
u8 start;
u8 lenL;
u8 lenH;
u8 ctrl;
u8 info_route:1;
u8 info_slave:1;
u8 info_com_module:1;
u8 info_conflict:1;
u8 info_relay:4;
u8 info[4];
u8 number;
u8 *source_addr;
u8 *relay_addr;
u8 *desc_addr;
u8 AFN;
u8 DT1;
u8 DT2;
u8 *data;
u8 cs;
u8 end;
}st_13762;
typedef struct
{
st_13762_head head;
u8 AFN;
u8 DT1;
u8 DT2;
u8 Manu_code[2];
u8 chip_code[2];
u8 day;
u8 month;
u8 year;
u8 version;
u8 cs;
u8 end;
}st_13762_03F1_ack;
#pragma pack(pop)
void transparent_Proc(void);
void write_update_contrlner(u8 ctrlner);
void apl_process_1372(u8 * ptr1372, u8 ctrlner);
bool check_13762_packet(u8 *buf);
void create_update_task(void);
#endif

53
APP/wdg.c Normal file
View File

@@ -0,0 +1,53 @@
#include "wdg.h"
/*****************************************************************************
* Function : Iwdg_Init
* Description : none
* Input : u8 timeout 为以秒为单位的看门狗超时时间不得低于1s,看门狗定时器的数据不能超过u16的大小65536
* Output : None
* Return :
* Others :
* Record
* 1.Date : 20170412
* Author : barry
* Modification: Created function
*****************************************************************************/
void Iwdg_Init(u8 timeout)
{
#define WDG_PRE 256
#define WDG_PER_COUNT (40000/WDG_PRE)
#define IWDG_Prescaler IWDG_Prescaler_256
u8 max_timeout = 0xFFF / WDG_PER_COUNT;
u16 reloadCount = 0;
timeout = (timeout == 0)? 1:timeout;
timeout = (timeout >= max_timeout)? max_timeout: timeout;
reloadCount = timeout* WDG_PER_COUNT;
/* Check if the system has resumed from IWDG reset */
if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET)
{
RCC_ClearFlag();
}
/* IWDG timeout equal to 280 ms (the timeout may varies due to LSI frequency
dispersion) */
/* Enable write access to IWDG_PR and IWDG_RLR registers */
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
/* IWDG counter clock: 40KHz(LSI) / 32 = 1.25 KHz */
IWDG_SetPrescaler(IWDG_Prescaler);
/* Set counter reload value to 1250, 1s timeout */
IWDG_SetReload(reloadCount);
/* Reload IWDG counter */
IWDG_ReloadCounter();
/* Enable IWDG (the LSI oscillator will be enabled by hardware) */
IWDG_Enable();
}

42
APP/wdg.h Normal file
View File

@@ -0,0 +1,42 @@
/********************************************************************************
**** Copyright (C), 2017, xx xx xx xx info&tech Co., Ltd. ****
********************************************************************************
* File Name : wdg.h
* Author : barry
* Date : 2017-04-12
* Description : wdg.c header file
* Version : 1.0
* Function List :
*
* Record :
* 1.Date : 2017-04-12
* Author : barry
* Modification: Created file
*************************************************************************************************************/
#ifndef __WDG_H__
#define __WDG_H__
#include "include.h"
#ifdef __cplusplus
#if __cplusplus
extern "C"{
#endif
#endif /* __cplusplus */
#define FEED_WDG do{IWDG_ReloadCounter();}while(0)
extern void Iwdg_Init(uint8_t timeout);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif /* __WDG_H__ */