📄 beacon.c
字号:
/* *****************************************************************************
Becaon send and process module. Used for system debug and test
*******************************************************************************/
#include "absacc.h"
#include "stdlib.h"
#include "beacon.h"
#include "timer.h"
#include "plc.h"
#include "sart.h"
#include "wr_flash.h"
#define uint unsigned int
#define uchar unsigned char
#define BUFFER_WR_TXBUF 0x7F
#define BEACON_FRAME 0xFF
#define BEACON_TABLE_NM 15
#define BEACON_FRAME_COUNT 10
#define BEACON_RX_FRAME_COUNT 10
#define BEACON_INTERVAL 100 // * 10ms
#define BEACON_RX_INTERVAL 230 // * 10ms
extern code uchar METER_ADDR[6];
uchar code reg_setting[2]; // reg_setting[0]: Gain, reg_setting[1]: amplitue
//#define self_address_R 0x00
//#define self_address_L 0x01
uchar tm1_count, count1_reload;
uchar inter1;
void (*beacon_timer_proc)(); // Agilent beacon timer
idata uchar beacon_timer_count;
idata uchar beacon_timer_val;
bit beacon_timer_enable;
void (*beacon_rx_timer_proc)(); // Agilent beacon timer
idata uchar beacon_rx_timer_count;
idata uchar beacon_rx_timer_val;
bit beacon_rx_timer_enable;
void delay(uint cnt);
/* transmit beacon contiously from beacon mode PLM, beacon sequence number increase from 0 to beacon_num
beacon_interval is the timer to control interval between two beacon */
extern idata uchar plc_frame[18];
idata char beacon_frame_count,beacon_rx_frame_count;
code struct link_status link_status_1[15];
extern idata uchar thres_ea;
void plc_tx_beacon();
void beacon_time_out();
void enable_beacon_timer();
void disable_beacon_timer(void);
void beacon_rx_time_out();
void enable_beacon_rx_timer();
void disable_beacon_rx_timer(void);
//void write_table(unsigned char i, unsigned char ave_ea, unsigned char ave_eb);
void write_table(uchar i, uchar add_R, uchar add_L, uchar ave_ea, uchar ave_eb,uchar succ_rate);
// beacon_interval * 10ms is the real interval between beacon
void send_beacon()
{
uchar i, k;
setup_beacon_timer(BEACON_INTERVAL, beacon_time_out);
beacon_frame_count = 0;
enable_beacon_timer();
while(beacon_frame_count < BEACON_FRAME_COUNT){;}
disable_beacon_timer();
// after finish tx beacon, keep on flashing RXOK to indicate this node has finish beacon transmission
while(1)
{
for (k=1; k<=5; k++)
{
// clr_wdt();
delay (50000);
delay (50000);
//brightening
for (i=1; i<=100; i++) // define 100 steps
{
// clr_wdt();
Rxok = 0;
delay (i*100);
Rxok = 1;
delay (10100-i*100);
}
for (i=1; i<=50; i++)
{
// clr_wdt();
Rxok = 0;
delay (10200-i*200);
Rxok = 1;
delay (i*200);
}
}
}
}
void delay (uint cnt)
{
while (--cnt);
}
void beacon_time_out()
{
// clr_wdt();
disable_beacon_timer();
plc_tx_beacon();
beacon_frame_count++;
/* set up timer seconds again. */
enable_beacon_timer();
}
void enable_beacon_timer(void)
{
beacon_timer_count = 0;
beacon_timer_enable = 1;
}
void disable_beacon_timer(void)
{
beacon_timer_count = 0;
beacon_timer_enable = 0;
}
/**************************************************************************************
Beacon
**************************************************************************************/
void plc_tx_beacon(void)
{
uchar i;
uchar self_address_R,self_address_L;
self_address_R = METER_ADDR[0];
self_address_L = METER_ADDR[1];
plc_frame[0] = self_address_R; // local address high byte
plc_frame[1] = self_address_L; // local address low byte
plc_frame[2] = self_address_R; // local address high byte
plc_frame[3] = self_address_L; // local address low byte
plc_frame[4] = 0xcc; // beacon command
plc_frame[5] = 0xBC; // padding
plc_frame[6] = beacon_frame_count;
for(i=7;i<18;i++)
{plc_frame[i] = 0xBC;}
sync_sendchar(BUFFER_WR_TXBUF);
send_block(plc_frame, 18);
send();
while (TX_BUSY == 0); // wait tx finish
}
/**************************************************************************************
Receive Beacon Frame and process, record Ea and Eb, Save to Flash
**************************************************************************************/
void beacon_rx_process()
{
unsigned char local_address_R, local_address_L;
unsigned char average_ea , average_eb;
unsigned char i,j,min_ea, wr_ea_index;
bit flag_first_frame; // when the first frame come in, = 1, average_ea and average_eb do not average
// after that, each frame come in, average Ea and Eb with last value.
unsigned char success_received_frame;
// unsigned char beacon_reply_frame[18];
local_address_R = METER_ADDR[0];
local_address_L = METER_ADDR[1];
average_ea = 0;
average_eb = 0;
beacon_rx_frame_count = 0;
setup_beacon_rx_timer(BEACON_RX_INTERVAL, beacon_rx_time_out);
disable_beacon_rx_timer();
// for debug only
uart_sendchar(0XFF);
uart_sendchar(0XFF);
uart_sendchar(0XFF);
uart_sendchar(0XFF);
for(i=0;i<BEACON_TABLE_NM;i++)
{
uart_sendchar(link_status_1[i].address_R);
uart_sendchar(link_status_1[i].address_L);
uart_sendchar(link_status_1[i].average_ea);
uart_sendchar(link_status_1[i].average_eb);
uart_sendchar(link_status_1[i].success_rate);
}
uart_sendchar(reg_setting[0]);
uart_sendchar(reg_setting[1]);
// end of for debug
while(1)
{
if (plc_recved())
{
plc_getframe(plc_frame); //* read the frame in
if(!read_crc())
{
RXOK = 0;
// PROCESS BEACON FRAME
// source address = destination address, 0xCC means beacon beacon frame
if ((plc_frame[0]==plc_frame[2])&&(plc_frame[1]==plc_frame[3])&& (plc_frame[4]==0xcc))
{
// clear the rx_timer, start it once process finished
disable_beacon_rx_timer();
if(flag_first_frame == 0)
{
average_ea = read_reg(0XEA);
average_eb = read_reg(0xEB);
flag_first_frame = 1; // clear first frame flag
}
else
{
average_ea = (average_ea + read_reg(0XEA))>>1;
average_eb = (average_eb + read_reg(0xEB))>>1;
}
success_received_frame++;
// Synchrnize the rx_count with tx_count
beacon_rx_frame_count = plc_frame[6];
uart_sendchar(0x99);
for(i=0;i<18;i++)
{
uart_sendchar(plc_frame[i]);
}
uart_sendchar(average_ea);
uart_sendchar(average_eb);
uart_sendchar(success_received_frame);
// once successfully receive a frame, start up rx timer, if tx timer out
// still not receive another frame, excute beacon_rx_time_out()
if (beacon_rx_frame_count!= BEACON_RX_FRAME_COUNT-1)
{
enable_beacon_rx_timer();
}
}
// read out link table. 00 00 is source address.
// to read out the table, FF as read command
if ((plc_frame[0]==0x00)&&(plc_frame[1]==0x00)&&(plc_frame[2]==local_address_R)&&(plc_frame[3]==local_address_L)&&(plc_frame[4]==0xFF))
{
send_table();
}
// clear the table, C0 as clear table command. When finish clear table
// use C1 to reply
if ((plc_frame[0]==0x00)&&(plc_frame[1]==0x00)&&(plc_frame[2]==local_address_R)&&(plc_frame[3]==local_address_L)&&(plc_frame[4]==0xC0))
{
clear_table();
// send back the ACK to confirm table is cleared. CMD 0xC1
plc_frame[0] = local_address_R;
plc_frame[1] = local_address_L;
plc_frame[2] = 0x00;
plc_frame[3] = 0x00;
plc_frame[4] = 0xC1;
sync_sendchar(BUFFER_WR_TXBUF);
send_block(plc_frame, 18);
send();
while (TX_BUSY == 0); // wait tx finish
}
// change register value through power line
// the command is 0xC2, repeat the command three times to gerantee no mistakes happen
if ((plc_frame[0]==0x00)&&(plc_frame[1]==0x00)&&(plc_frame[2]==local_address_R)&&(plc_frame[3]==local_address_L)&&(plc_frame[4]==0xc2)&&(plc_frame[8]==0xc2)&&(plc_frame[12]==0xc2))
{
// check whether the repeated 3 times value are the same.
if((plc_frame[5]==plc_frame[9])&&(plc_frame[5]==plc_frame[13])&&(plc_frame[6]==plc_frame[10])&&(plc_frame[6]==plc_frame[14]))
{
EA = 0; // disable all interrupt when writing flash
FLASH_WriteByte((int code *)®_setting[0], plc_frame[5]);
FLASH_WriteByte((int code *)®_setting[1], plc_frame[6]);
EA = 1; // enable all interrupt after finishing writing flash
// send back the ACK to confirm the register write is finished. CMD 0xC3
plc_frame[0] = local_address_R;
plc_frame[1] = local_address_L;
plc_frame[2] = 0x00;
plc_frame[3] = 0x00;
plc_frame[4] = 0xC3;
plc_frame[8] = 0xC3;
plc_frame[12] = 0xC3;
// delay for several ms before send reply
for(i=0;i<250;i++)
for(j=0;j<250;j++);
sync_sendchar(BUFFER_WR_TXBUF);
send_block(plc_frame, 18);
send();
while (TX_BUSY == 0); // wait tx finish
}
else
{
// if command not correct, reply with cmd 0xC4
plc_frame[0] = local_address_R;
plc_frame[1] = local_address_L;
plc_frame[2] = 0x00;
plc_frame[3] = 0x00;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -