Files
kunlun/app/demo/demo_speed_test.c
2024-09-28 14:24:04 +08:00

1278 lines
37 KiB
C
Executable File

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
#include "os_task_api.h"
#include "os_event_api.h"
#include "os_timer_api.h"
#include "os_utils_api.h"
#include "iot_task_api.h"
#include "iot_module_api.h"
#include "os_lock_api.h"
#include "iot_plc_cco_api.h"
#include "iot_plc_sta_api.h"
#include "iot_config_api.h"
#include "iot_app_api.h"
#include "iot_errno_api.h"
#include "iot_io_api.h"
#include "iot_flash_api.h"
#include "iot_uart_api.h"
#include "iot_utils_api.h"
#include "iot_oem_api.h"
#include "iot_board_api.h"
#include "iot_gpio_api.h"
#include "iot_adc_api.h"
#include "demo.h"
#include "demo_speed_test.h"
/*
LIGHT WORDS:
1 -> LIGHT ON , 0 -> LIGHT OFF.
A: PREPARE
GR : | 01010101 |
RD : | 01010101 |
B: IN TEST
GR : | 01010101 |
RD : | 10101010 |
C: REPORT THE SPEED
IF SPEED LEVEL IS 500Kbps (450Kbps ~ 550Kbps) :
UCAST :
| PRE | SPEED |
GR : | 00000000 | 0101010101 |
RD : | 00111100 | 0000000000 |
BCAST :
| PRE | SPEED |
GR : | 00111100 | 0000000000 |
RD : | 00000000 | 0101010101 |
*/
#define APP_DEMO_SPD_CCO_MAC {0x48, 0x55, 0x5C, 0xAA, 0xBB, 0xCC}
#define APP_DEMO_SPD_STA_MAC {0x48, 0x55, 0x5C, 0xCC, 0xDD, 0xEE}
#define APP_DEMO_SPD_TMR_INTVAL 500 /* 500ms */
#define APP_DEMO_SPD_TEST_BUFFER_LEN 1024
#define APP_DEMO_SPD_TIMEOUT_MAX 20 /* 10 seconds */
/* ucast && bcast */
#define APP_DEMO_SPD_CAST_NUM 2
#if (IOT_DEMO_SUB_FUN == IOT_DEMO_SEL_SPEED_TEST)
#if INCLUDE_APP_DEMO_SPD_SENDER
/***************** CONFIG AREA START *********************/
/* [6/7/8] ms * [64/128/256/512/1024]Kbps */
const uint32_t g_demo_spd_interval[] = {6, 7, 8};
const uint32_t g_demo_spd_speed[] = {128, 256, 320, 448, 512, 640};
#define APP_DEMO_SPD_TEST_PACKET_NUM 500
/***************** CONFIG AREA END *********************/
#define APP_DEMO_SPD_INTVL_NUM \
(sizeof(g_demo_spd_interval)/sizeof(g_demo_spd_interval[0]))
#define APP_DEMO_SPD_SPEED_NUM \
(sizeof(g_demo_spd_speed)/sizeof(g_demo_spd_speed[0]))
typedef struct app_demo_spd_info_t
{
uint16_t speed; /* Kbps */
uint8_t is_bcast;
uint8_t interval; /* ms */
uint16_t pkt_size; /* bytes */
uint16_t rcv_used_time;
uint32_t rcv_bytes;
uint32_t rcv_pkts;
uint32_t pkt_lost_rate;
}spd_info_t;
spd_info_t g_app_demo_spd_test_items[APP_DEMO_SPD_CAST_NUM][APP_DEMO_SPD_SPEED_NUM][APP_DEMO_SPD_INTVL_NUM];
const uint8_t app_demo_mac_local[] = APP_DEMO_SPD_CCO_MAC;
const uint8_t app_demo_mac_remote[] = APP_DEMO_SPD_STA_MAC;
#else /* INCLUDE_APP_DEMO_SPD_SENDER */
uint32_t g_app_demo_spd_rcvd_bytes;
uint32_t g_app_demo_spd_rcvd_packets;
const uint8_t app_demo_mac_local[] = APP_DEMO_SPD_STA_MAC;
const uint8_t app_demo_mac_remote[] = APP_DEMO_SPD_CCO_MAC;
#endif /* INCLUDE_APP_DEMO_SPD_SENDER */
typedef struct iot_app_demo_spd_msg
{
iot_task_msg_t msg; /* The main entity of message. */
void *data; /* The user data inside this message. */
}demo_spd_msg_t;
uint8_t app_demo_spd_buf[APP_DEMO_SPD_TEST_BUFFER_LEN];
#define APP_DEMO_RDY_REG 0x01
#define APP_DEMO_RDY_LOCAL 0x02
#define APP_DEMO_RDY_REMOTE 0x04
#define APP_DEMO_RDY_WL 0x08
#define APP_DEMO_RDY_RESTART 0x10
#define APP_DEMO_RDY_IDLE 0x20
#define APP_DEMO_RDY_TEST 0x40
#define APP_DEMO_RDY_S_REPORT 0x80 /* Wait or send single report. */
#define APP_DEMO_RDY_FINISH 0x100
iot_plc_app_h app_demo_spd_app_handle;
iot_task_h app_demo_spd_task_handle;
volatile uint32_t app_demo_spd_ready;
uint32_t app_demo_spd_current_key = 0x67676767;
#define APP_DEMO_SPD_READY() \
(((APP_DEMO_RDY_WL|APP_DEMO_RDY_REMOTE|APP_DEMO_RDY_LOCAL|APP_DEMO_RDY_REG)\
& app_demo_spd_ready) == \
(APP_DEMO_RDY_WL|APP_DEMO_RDY_REMOTE|APP_DEMO_RDY_LOCAL|APP_DEMO_RDY_REG) ? \
1 : 0)
#define APP_DEMO_SPD_RESTART() \
(((APP_DEMO_RDY_WL|APP_DEMO_RDY_REMOTE|APP_DEMO_RDY_LOCAL|APP_DEMO_RDY_REG|APP_DEMO_RDY_RESTART)\
& app_demo_spd_ready) == \
(APP_DEMO_RDY_WL|APP_DEMO_RDY_REMOTE|APP_DEMO_RDY_LOCAL|APP_DEMO_RDY_REG|APP_DEMO_RDY_RESTART) ? \
1 : 0)
#define APP_DEMO_SPD_CLEAR_STATUS() \
(app_demo_spd_ready &= ~(APP_DEMO_RDY_RESTART | APP_DEMO_RDY_IDLE \
| APP_DEMO_RDY_TEST | APP_DEMO_RDY_S_REPORT | APP_DEMO_RDY_FINISH))
#define APP_DEMO_SPD_HEADER_FLAG 0xEA5E94CD
uint32_t app_demo_spd_led_red;
uint32_t app_demo_spd_led_green;
timer_id_t app_demo_spd_led_tmr;
timer_id_t app_demo_spd_trcvd_tmr;
#define APP_DEMO_SPD_EVT_LED_TMR 0x01
#define APP_DEMO_SPD_EVT_TRSVD_TMR 0x02
enum app_demo_spd_header_type_e
{
HDR_TYPE_TESTING = 0x5A5A,
HDR_TYPE_S_REPORT= 0x7E7E,
HDR_TYPE_F_REPORT= 0xD6D6,
};
/* Sender -> Receiver */
typedef struct app_demo_spd_test_header_t
{
uint32_t flag;
uint16_t type;
uint16_t time_left_ms;
uint32_t cur_key;
uint32_t index;
}spd_t_hr_t;
/* Receiver -> Sender */
typedef struct app_demo_spd_single_report_header_t
{
uint32_t flag;
uint16_t type;
uint16_t time;
uint32_t cur_key;
uint32_t bytes;
uint32_t packets;
}spd_s_hr_t;
/* Sender -> Receiver */
typedef struct app_demo_spd_final_report_header_t
{
uint32_t flag;
uint16_t type;
uint16_t bcast;
uint16_t intval;
uint16_t speed; /* Test speed for sender. */
uint16_t pkt_size;
uint16_t final_speed; /* receive speed for receiver. We trust this speed. */
uint32_t pkt_lost_rate; /* 8888 -> 88.88% */
}spd_f_hr_t;
spd_f_hr_t app_demo_spd_winner[APP_DEMO_SPD_CAST_NUM];
#define APP_DEMO_SPD_LW_STEPS_MAX 64
typedef struct app_demo_spd_light_words
{
uint16_t steps; /* Steps to run out of a final report. */
uint16_t pos; /* current step */
uint32_t green[APP_DEMO_SPD_LW_STEPS_MAX/32]; /* BIT map for LED, 1 -> light on , 0 -> off */
uint32_t red[APP_DEMO_SPD_LW_STEPS_MAX/32]; /* BIT map for LED, 1 -> light on , 0 -> off */
}light_wd_t;
light_wd_t g_app_demo_spd_lght_words;
inline static void app_demo_spd_print_iterm(spd_f_hr_t *p_iterm, uint32_t banner)
{
if(banner)
{
iot_cus_printf(
"\n SPEED(KbPS) CAST INTVAL(MS) PKT-SIZE(B) PKT-LOST TRUE-SPEED(Kbps)");
}
iot_cus_printf(
"\n %5d %c %6d %8d %2d.%02d%% %10d",
p_iterm->speed,
p_iterm->bcast ? 'B' : 'U',
p_iterm->intval,
p_iterm->pkt_size,
p_iterm->pkt_lost_rate/100,
p_iterm->pkt_lost_rate%100,
p_iterm->final_speed);
}
uint32_t app_demo_set_band(uint8_t band_id)
{
iot_cus_printf("%s: set band to band %d\n", __FUNCTION__, band_id);
iot_plc_set_freq_band(app_demo_spd_app_handle,
IOT_PLC_API_REQ_ID_DEFAULT, band_id);
return ERR_OK;
}
/* set sta scan band */
void app_demo_set_sta_scan_band(uint8_t band_id)
{
iot_cus_printf("%s: set scan band to band %d\n", __FUNCTION__, band_id);
uint8_t fb_bitmap[IOT_PLC_BAND_BITMAP_SIZE] = { 0 };
fb_bitmap[band_id / 8] |= 1 << (band_id % 8);
iot_plc_set_scan_band_bitmap(app_demo_spd_app_handle,
IOT_PLC_API_REQ_ID_DEFAULT, fb_bitmap, IOT_PLC_BAND_BITMAP_SIZE);
}
void app_demo_spd_plc_send(uint8_t *p_buf, uint32_t size, uint32_t bcast)
{
iot_pkt_t *msdu_pkt;
uint8_t *ptr;
if(bcast)
{
msdu_pkt = iot_plc_alloc_msdu(app_demo_spd_app_handle,
IOT_PLC_MSG_TYPE_BCAST, IOT_PLC_ACK_TYPE_NONE,
NULL,
(uint8_t *)app_demo_mac_local,
DEMO_APP_LINK_ID, size, 1);
}
else
{
msdu_pkt = iot_plc_alloc_msdu(app_demo_spd_app_handle,
IOT_PLC_MSG_TYPE_UNICAST, IOT_PLC_ACK_TYPE_NONE,
(uint8_t *)app_demo_mac_remote,
(uint8_t *)app_demo_mac_local,
DEMO_APP_LINK_ID, size, 0);
}
if(NULL == msdu_pkt)
{
DEMO_ERROR("ALLOC PACKET FAILED !!", 1,2,3,4,5,6);
return;
}
ptr = iot_pkt_block_ptr(msdu_pkt, IOT_PKT_BLOCK_TAIL);
os_mem_cpy(ptr, p_buf, size);
iot_pkt_put(msdu_pkt, size);
/* Forword to PLC. */
iot_plc_send_msdu(app_demo_spd_app_handle, msdu_pkt);
}
void app_demo_spd_make_light_words_data(void)
{
uint32_t b_speed, u_speed, red, green, i, steps;
u_speed = (((app_demo_spd_winner[0].final_speed % 100) > 50)
? ((app_demo_spd_winner[0].final_speed / 100) + 1)
: (app_demo_spd_winner[0].final_speed / 100));
b_speed = (((app_demo_spd_winner[1].final_speed % 100) > 50)
? (app_demo_spd_winner[1].final_speed / 100 + 1)
: (app_demo_spd_winner[1].final_speed / 100));
g_app_demo_spd_lght_words.steps = 8 + u_speed * 2 + 8 + b_speed * 2;
/* UCAST */
green = 0x0;
steps = 8;
red = 0x3C;
for(i = 0; i < u_speed; i++)
{
green <<= 2;
red <<= 2;
green |= 1;
}
green <<= 1;
red <<= 1;
steps += u_speed * 2 + 1;
g_app_demo_spd_lght_words.green[0] = green << (32 - steps);
g_app_demo_spd_lght_words.red[0] = red << (32 - steps);
g_app_demo_spd_lght_words.pos = steps;
/* BCAST */
red = 0x0;
steps = 7;
green = 0x3C;
for(i = 0; i < b_speed; i++)
{
red <<= 2;
green <<= 2;
red |= 1;
}
green <<= 1;
red <<= 1;
steps += b_speed * 2 + 1;
/* First 32bits left */
i = 32 - g_app_demo_spd_lght_words.pos;
if(g_app_demo_spd_lght_words.steps > 32)
{
g_app_demo_spd_lght_words.green[0] |= (green >> (steps - i));
g_app_demo_spd_lght_words.red[0] |= (red >> (steps - i));
g_app_demo_spd_lght_words.green[1] = (green << (32 - (steps - i)));
g_app_demo_spd_lght_words.red[1] = (red << (32 - (steps - i)));
}
else
{
g_app_demo_spd_lght_words.green[0] |= (green << (i - steps));
g_app_demo_spd_lght_words.red[0] |= (red << (i - steps));
}
/* Start from bit-0. */
g_app_demo_spd_lght_words.pos = 0;
DEMO_INFO("LW BITMAP RED : #0x%08x%08x, GREEN #0x%08x%08x, STEPS #%d.",
g_app_demo_spd_lght_words.red[0],
g_app_demo_spd_lght_words.red[1],
g_app_demo_spd_lght_words.green[0],
g_app_demo_spd_lght_words.green[1],
g_app_demo_spd_lght_words.steps, 6);
return;
}
#if INCLUDE_APP_DEMO_SPD_SENDER
uint32_t g_app_demo_spd_remain_pkts;
spd_info_t *p_app_demo_spd_current_item;
void app_demo_spd_mac_data_process(iot_plc_msdu_recv_t *p_msdu)
{
spd_s_hr_t *p_hdr = (spd_s_hr_t *)p_msdu->data;
uint32_t cast_inx, iterm_inx;
spd_info_t *p_iterm;
spd_f_hr_t iterm_print;
if((APP_DEMO_SPD_HEADER_FLAG != p_hdr->flag)
|| (HDR_TYPE_S_REPORT != p_hdr->type)
|| (app_demo_spd_current_key != p_hdr->cur_key)
|| (!(app_demo_spd_ready & APP_DEMO_RDY_S_REPORT)))
{
return;
}
DEMO_INFO("Got report from remote, BYTES # %d, PKTS # %d, TIME # %d.",
p_hdr->bytes, p_hdr->packets, p_hdr->time, 4, 5, 6);
p_app_demo_spd_current_item->rcv_bytes = p_hdr->bytes;
p_app_demo_spd_current_item->rcv_pkts = p_hdr->packets;
p_app_demo_spd_current_item->rcv_used_time = p_hdr->time;
os_stop_timer(app_demo_spd_trcvd_tmr);
if(p_app_demo_spd_current_item ==
&g_app_demo_spd_test_items\
[APP_DEMO_SPD_CAST_NUM - 1][APP_DEMO_SPD_SPEED_NUM - 1][APP_DEMO_SPD_INTVL_NUM - 1])
{
/* All items finished. */
iot_cus_printf("\n\nAll test cases:");
for(cast_inx = 0; cast_inx < APP_DEMO_SPD_CAST_NUM; cast_inx++)
{
p_iterm = &g_app_demo_spd_test_items[cast_inx][0][0];
app_demo_spd_winner[cast_inx].pkt_lost_rate = 10000;
for(iterm_inx = 0; iterm_inx < APP_DEMO_SPD_SPEED_NUM*APP_DEMO_SPD_INTVL_NUM; iterm_inx++)
{
p_iterm->pkt_lost_rate = 10000 - ((p_iterm->rcv_pkts * 100) / (APP_DEMO_SPD_TEST_PACKET_NUM / 100));
iterm_print.bcast = p_iterm->is_bcast;
iterm_print.intval = p_iterm->interval;
iterm_print.speed = p_iterm->speed;
iterm_print.pkt_lost_rate = p_iterm->pkt_lost_rate;
iterm_print.pkt_size = p_iterm->pkt_size;
iterm_print.final_speed = (8 * p_iterm->rcv_bytes) / p_iterm->rcv_used_time;
/* OS ticks may not be precise. */
iterm_print.final_speed = (iterm_print.final_speed > iterm_print.speed)
? iterm_print.speed : iterm_print.final_speed;
if((app_demo_spd_winner[cast_inx].pkt_lost_rate >= iterm_print.pkt_lost_rate)
|| (p_iterm->pkt_lost_rate <= 1000))
{
os_mem_cpy(&app_demo_spd_winner[cast_inx], &iterm_print, sizeof(iterm_print));
}
if((0 != cast_inx) || (0 != iterm_inx))
{
app_demo_spd_print_iterm(&iterm_print, 0);
}
else
{
app_demo_spd_print_iterm(&iterm_print, 1);
}
p_iterm++;
}
}
APP_DEMO_SPD_CLEAR_STATUS();
app_demo_spd_make_light_words_data();
iot_cus_printf("\n\nThe best cases:");
for(cast_inx = 0; cast_inx < APP_DEMO_SPD_CAST_NUM; cast_inx++)
{
if(0 == cast_inx)
{
app_demo_spd_print_iterm(&app_demo_spd_winner[cast_inx], 1);
}
else
{
app_demo_spd_print_iterm(&app_demo_spd_winner[cast_inx], 0);
}
}
/* Start timer to send finally report */
os_start_timer(app_demo_spd_trcvd_tmr, 500);
app_demo_spd_ready |= APP_DEMO_RDY_FINISH;
}
else
{
app_demo_spd_ready &= ~APP_DEMO_RDY_S_REPORT;
p_app_demo_spd_current_item++;
g_app_demo_spd_remain_pkts = APP_DEMO_SPD_TEST_PACKET_NUM;
DEMO_INFO("Test %s : speed # %dkbps, psize # %dbytes...",
p_app_demo_spd_current_item->is_bcast ? "bcast" : "ucast",
p_app_demo_spd_current_item->speed, p_app_demo_spd_current_item->pkt_size,
4, 5, 6);
os_start_timer(app_demo_spd_trcvd_tmr, p_app_demo_spd_current_item->interval);
}
return;
}
void app_demo_spd_trcvd_tmr_process(void)
{
static uint32_t static_cnt = APP_DEMO_SPD_TIMEOUT_MAX;
spd_t_hr_t *p_hdr;
spd_f_hr_t *p_finally_report;
if(!APP_DEMO_SPD_READY())
{
if(os_is_timer_active(app_demo_spd_trcvd_tmr))
{
os_stop_timer(app_demo_spd_trcvd_tmr);
}
return;
}
/* Check if receiver reports the resoult. */
if(APP_DEMO_RDY_S_REPORT & app_demo_spd_ready)
{
/* If no report received, stop this testing. */
if(0 == static_cnt)
{
/* Regard this as receiver dropped. */
APP_DEMO_SPD_CLEAR_STATUS();
app_demo_spd_ready |= (APP_DEMO_RDY_IDLE | APP_DEMO_RDY_RESTART);
os_stop_timer(app_demo_spd_trcvd_tmr);
DEMO_ERROR("WAIT THE REPORT TIMEOUT !!", 1, 2,3,4,5,6);
}
else
{
static_cnt--;
}
}
else if(APP_DEMO_RDY_FINISH & app_demo_spd_ready)
{
static_cnt++;
static_cnt = (static_cnt >= APP_DEMO_SPD_CAST_NUM)? 0 : static_cnt;
p_finally_report = (spd_f_hr_t *)app_demo_spd_buf;
p_finally_report->flag = APP_DEMO_SPD_HEADER_FLAG;
p_finally_report->type = HDR_TYPE_F_REPORT;
p_finally_report->intval = app_demo_spd_winner[static_cnt].intval;
p_finally_report->bcast = app_demo_spd_winner[static_cnt].bcast;
p_finally_report->speed = app_demo_spd_winner[static_cnt].speed;
p_finally_report->pkt_size = app_demo_spd_winner[static_cnt].pkt_size;
p_finally_report->pkt_lost_rate = app_demo_spd_winner[static_cnt].pkt_lost_rate;
p_finally_report->final_speed = app_demo_spd_winner[static_cnt].final_speed;
app_demo_spd_plc_send(app_demo_spd_buf, sizeof(*p_finally_report), 0);
}
else
{
static_cnt = APP_DEMO_SPD_TIMEOUT_MAX;
}
if(g_app_demo_spd_remain_pkts > 0)
{
/* The last packet. */
if(1 == g_app_demo_spd_remain_pkts)
{
app_demo_spd_ready |= APP_DEMO_RDY_S_REPORT;
os_stop_timer(app_demo_spd_trcvd_tmr);
os_start_timer(app_demo_spd_trcvd_tmr, 500);
}
if(APP_DEMO_SPD_TEST_PACKET_NUM == g_app_demo_spd_remain_pkts)
{
p_hdr = (spd_t_hr_t *)app_demo_spd_buf;
p_hdr->flag = APP_DEMO_SPD_HEADER_FLAG;
p_hdr->type = HDR_TYPE_TESTING;
p_hdr->cur_key = os_boot_time32();
app_demo_spd_current_key = p_hdr->cur_key;
p_hdr->index = 0;
p_hdr->time_left_ms = APP_DEMO_SPD_TEST_PACKET_NUM * p_app_demo_spd_current_item->interval;
}
else
{
p_hdr->index++;
p_hdr->time_left_ms -= p_app_demo_spd_current_item->interval;
}
app_demo_spd_plc_send(app_demo_spd_buf,
p_app_demo_spd_current_item->pkt_size, p_app_demo_spd_current_item->is_bcast);
g_app_demo_spd_remain_pkts--;
}
return;
}
void app_demo_spd_restart(void)
{
APP_DEMO_SPD_CLEAR_STATUS();
app_demo_spd_ready |= APP_DEMO_RDY_TEST;
p_app_demo_spd_current_item = (spd_info_t*)g_app_demo_spd_test_items;
g_app_demo_spd_remain_pkts = APP_DEMO_SPD_TEST_PACKET_NUM;
DEMO_INFO("Test %s : speed # %dkbps, psize # %dbytes...",
p_app_demo_spd_current_item->is_bcast ? "bcast" : "ucast",
p_app_demo_spd_current_item->speed, p_app_demo_spd_current_item->pkt_size,
4, 5, 6);
os_start_timer(app_demo_spd_trcvd_tmr, p_app_demo_spd_current_item->interval);
return;
}
#else
uint32_t g_app_demo_spd_test_time;
uint32_t g_app_demo_spd_end_test_time;
void app_demo_spd_mac_data_process(iot_plc_msdu_recv_t *p_msdu)
{
spd_t_hr_t *p_hdr = (spd_t_hr_t *)p_msdu->data;
spd_f_hr_t *p_f_hr;
uint32_t cast_inx;
if(APP_DEMO_SPD_HEADER_FLAG != p_hdr->flag)
{
return;
}
if(HDR_TYPE_TESTING == p_hdr->type)
{
if((app_demo_spd_current_key == p_hdr->cur_key)
&& (!(APP_DEMO_RDY_S_REPORT & app_demo_spd_ready)))
{
g_app_demo_spd_rcvd_bytes += p_msdu->len;
g_app_demo_spd_rcvd_packets++;
g_app_demo_spd_end_test_time = os_boot_time32();
}
else
{
if(os_is_timer_active(app_demo_spd_trcvd_tmr))
{
os_stop_timer(app_demo_spd_trcvd_tmr);
}
APP_DEMO_SPD_CLEAR_STATUS();
/* Clear all info since new test begains. */
for(cast_inx = 0; cast_inx < APP_DEMO_SPD_CAST_NUM; cast_inx++)
{
app_demo_spd_winner[cast_inx].speed = 0;
}
app_demo_spd_ready |= APP_DEMO_RDY_TEST;
g_app_demo_spd_rcvd_bytes = p_msdu->len;
g_app_demo_spd_rcvd_packets = 1;
app_demo_spd_current_key = p_hdr->cur_key;
g_app_demo_spd_test_time = (p_hdr->time_left_ms > 20000)
? 20000 : p_hdr->time_left_ms;
os_start_timer(app_demo_spd_trcvd_tmr, g_app_demo_spd_test_time * 2);
g_app_demo_spd_test_time = os_boot_time32();
DEMO_INFO("NEW TEST KEY # %d.", app_demo_spd_current_key,2,3,4,5,6);
}
}
else if((HDR_TYPE_F_REPORT == p_hdr->type)
&& (!(app_demo_spd_ready & APP_DEMO_RDY_FINISH)))
{
p_f_hr = (spd_f_hr_t *)p_msdu->data;
app_demo_spd_winner[p_f_hr->bcast ? 1 : 0] = *p_f_hr;
for(cast_inx = 0; cast_inx < APP_DEMO_SPD_CAST_NUM; cast_inx++)
{
if(0 == app_demo_spd_winner[cast_inx].speed)
{
break;
}
}
if(APP_DEMO_SPD_CAST_NUM == cast_inx)
{
os_stop_timer(app_demo_spd_trcvd_tmr);
APP_DEMO_SPD_CLEAR_STATUS();
app_demo_spd_ready |= APP_DEMO_RDY_FINISH;
app_demo_spd_make_light_words_data();
iot_cus_printf("\n\nThe best cases:");
for(cast_inx = 0; cast_inx < APP_DEMO_SPD_CAST_NUM; cast_inx++)
{
if(0 == cast_inx)
{
app_demo_spd_print_iterm(&app_demo_spd_winner[cast_inx], 1);
}
else
{
app_demo_spd_print_iterm(&app_demo_spd_winner[cast_inx], 0);
}
}
}
}
return;
}
void app_demo_spd_trcvd_tmr_process(void)
{
spd_s_hr_t *p_rpt = (spd_s_hr_t *)app_demo_spd_buf;
uint32_t cost_time;
APP_DEMO_SPD_CLEAR_STATUS();
app_demo_spd_ready |= APP_DEMO_RDY_S_REPORT;
cost_time = (g_app_demo_spd_test_time < g_app_demo_spd_end_test_time)
?(g_app_demo_spd_end_test_time - g_app_demo_spd_test_time)
:(0xFFFFFFFF - g_app_demo_spd_test_time + g_app_demo_spd_end_test_time);
p_rpt->bytes = g_app_demo_spd_rcvd_bytes;
p_rpt->cur_key = app_demo_spd_current_key;
p_rpt->flag = APP_DEMO_SPD_HEADER_FLAG;
p_rpt->packets = g_app_demo_spd_rcvd_packets;
p_rpt->time = cost_time;
p_rpt->type = HDR_TYPE_S_REPORT;
DEMO_INFO("REPORT KEY # %d, TIME # %d, PKT # %d.",
app_demo_spd_current_key,
cost_time,
g_app_demo_spd_rcvd_packets,
4,5,6);
app_demo_spd_plc_send(app_demo_spd_buf, sizeof(*p_rpt), 0);
os_start_timer(app_demo_spd_trcvd_tmr, 1000);
}
#endif
uint32_t app_demo_spd_post_msg( uint16_t msg_type, uint16_t msg_id, void *data)
{
iot_task_msg_t *msg;
demo_spd_msg_t *task_msg;
msg = iot_task_alloc_msg_with_reserved(app_demo_spd_task_handle, 0);
if (NULL == msg) {
DEMO_ERROR("ALLOC MSG-BUFFER FAILED !!", 1, 2,3,4,5,6);
return ERR_FAIL;
}
task_msg = (demo_spd_msg_t*)msg;
task_msg->msg.type = msg_type;
task_msg->msg.id = msg_id;
task_msg->data = data;
iot_task_queue_msg(app_demo_spd_task_handle,
&task_msg->msg, DEMO_TASK_MSG_PRIO);
return ERR_OK;
}
void app_demo_spd_mac_status_process(iot_pkt_t *pkt)
{
iot_plc_msg_header_t *hdr =
(iot_plc_msg_header_t*)iot_pkt_data(pkt);
/* Check if this packet belongs to me. */
if ((IOT_PLC_APP_ID_BCAST != hdr->app_id) &&
(IOT_PLC_APP_DEMO_ID != hdr->app_id))
{
DEMO_ERROR("INVALID PACKET FROM MAC, APP ID#%d.", hdr->app_id,2,3,4,5,6);
iot_pkt_free(pkt);
return;
}
/* Check if I'm registerd before handling msg. */
if ((!(app_demo_spd_ready & APP_DEMO_RDY_REG)) &&
(IOT_PLC_MSG_APP_REG_CONF != hdr->msg_id))
{
DEMO_ERROR("INVALID PACKET FROM MAC, MSG ID#%d, STATUS#0x%08X.",
hdr->msg_id, app_demo_spd_ready,3,4,5,6);
iot_pkt_free(pkt);
return;
}
switch (hdr->msg_id)
{
case IOT_PLC_MSG_APP_REG_CONF :
{
iot_plc_app_reg_conf_t* rpt = (iot_plc_app_reg_conf_t*)(hdr + 1);
iot_plc_cfg_set_req_t cfg;
if ((IOT_PLC_SUCCESS == rpt->result) ||
(IOT_PLC_SUCCESS_MODIFIED == rpt->result)) {
app_demo_spd_ready |= APP_DEMO_RDY_REG;
DEMO_INFO("APP REGISTERED SUCCESSFULLY.",1,2,3,4,5,6);
os_mem_set(&cfg, 0, sizeof(cfg));
cfg.addr_valid = 1;
cfg.addr_type = IOT_PLC_MAC_ADDR_TYPE_METER;
iot_mac_addr_cpy(cfg.addr, (uint8_t *)app_demo_mac_local);
cfg.dev_type_valid = 1;
#if INCLUDE_APP_DEMO_SPD_SENDER
cfg.dev_type = IOT_PLC_DEV_TYPE_CONCENTRATOR;
#else
cfg.dev_type = IOT_PLC_DEV_TYPE_METER_CONTROLLER;
#endif
cfg.reset = 1;
DEMO_INFO("SET LOCAL MAC : %02x-%02x-%02x-%02x-%02x-%02x.",
app_demo_mac_local[0], app_demo_mac_local[1],
app_demo_mac_local[2], app_demo_mac_local[3],
app_demo_mac_local[4], app_demo_mac_local[5]);
iot_plc_set_cfg
(app_demo_spd_app_handle, IOT_PLC_API_REQ_ID_DEFAULT, &cfg);
iot_plc_set_whitelist
(app_demo_spd_app_handle, IOT_PLC_API_REQ_ID_DEFAULT,
IOT_PLC_WL_ENABLE, 0, NULL);
}
break;
}
case IOT_PLC_MSG_DEV_STATE_CHANGE_RPT :
{
iot_plc_dev_state_change_rpt_t* rpt =
(iot_plc_dev_state_change_rpt_t*)(hdr + 1);
if(rpt->is_ready)
{
DEMO_INFO("STATE CHANGE REPORT MAC GET READY, MY ROLE TYPE#%d.",
rpt->dev_role,2,3,4,5,6);
DEMO_INFO("CCO MAC : %02x-%02x-%02x-%02x-%02x-%02x.",
rpt->cco_mac[0], rpt->cco_mac[1], rpt->cco_mac[2],
rpt->cco_mac[3], rpt->cco_mac[4], rpt->cco_mac[5]);
DEMO_INFO("LOCAL MAC : %02x-%02x-%02x-%02x-%02x-%02x.",
rpt->local_mac[0], rpt->local_mac[1], rpt->local_mac[2],
rpt->local_mac[3], rpt->local_mac[4], rpt->local_mac[5]);
if((IOT_PLC_DEV_ROLE_STA == rpt->dev_role)
&& (!os_mem_cmp(app_demo_mac_remote, rpt->cco_mac, sizeof(app_demo_mac_remote))))
{
app_demo_spd_ready |= APP_DEMO_RDY_REMOTE;
}
app_demo_spd_ready |= APP_DEMO_RDY_LOCAL;
}
else
{
DEMO_INFO("MAC IS NOT READY.",1,2,3,4,5,6);
app_demo_spd_ready &= (~APP_DEMO_RDY_LOCAL);
app_demo_spd_ready |= APP_DEMO_RDY_RESTART;
}
break;
}
case IOT_PLC_MSG_DEV_INFO_RPT :
{
iot_plc_dev_info_rpt_t* rpt =
(iot_plc_dev_info_rpt_t*)(hdr + 1);
if(rpt->is_ready)
{
DEMO_INFO("DEVICE INFO REPORT MAC GET READY, MY ROLE TYPE#%d.",
rpt->dev_role,2,3,4,5,6);
DEMO_INFO("CCO MAC : %02x-%02x-%02x-%02x-%02x-%02x.",
rpt->cco_mac[0], rpt->cco_mac[1], rpt->cco_mac[2],
rpt->cco_mac[3], rpt->cco_mac[4], rpt->cco_mac[5]);
DEMO_INFO("LOCAL MAC : %02x-%02x-%02x-%02x-%02x-%02x.",
rpt->local_mac[0], rpt->local_mac[1], rpt->local_mac[2],
rpt->local_mac[3], rpt->local_mac[4], rpt->local_mac[5]);
if((IOT_PLC_DEV_ROLE_STA == rpt->dev_role)
&& iot_mac_addr_cmp(app_demo_mac_remote, rpt->cco_mac))
{
app_demo_spd_ready |= APP_DEMO_RDY_REMOTE;
}
app_demo_spd_ready |= APP_DEMO_RDY_LOCAL;
}
else
{
DEMO_INFO("MAC IS NOT READY.",1,2,3,4,5,6);
app_demo_spd_ready &= (~APP_DEMO_RDY_LOCAL);
app_demo_spd_ready |= APP_DEMO_RDY_RESTART;
}
break;
}
case IOT_PLC_MSG_STA_JOIN_INFO :
{
iot_plc_sta_join_info_t* rpt = (iot_plc_sta_join_info_t*)(hdr + 1);
DEMO_INFO("STA JOINED : %02x-%02x-%02x-%02x-%02x-%02x.",
rpt->sta_info.addr[0], rpt->sta_info.addr[1],
rpt->sta_info.addr[2], rpt->sta_info.addr[3],
rpt->sta_info.addr[4], rpt->sta_info.addr[5]);
if(iot_mac_addr_cmp(app_demo_mac_remote, rpt->sta_info.addr))
{
app_demo_spd_ready |= APP_DEMO_RDY_REMOTE;
}
break;
}
case IOT_PLC_MSG_STA_LEAVE_INFO :
{
uint32_t cnt;
iot_plc_sta_leave_info_t* rpt =
(iot_plc_sta_leave_info_t*)(hdr + 1);
for(cnt = 0; cnt < rpt->sta_count; cnt++)
{
DEMO_INFO("STA LEAVED : %02x-%02x-%02x-%02x-%02x-%02x.",
rpt->sta[cnt].mac_addr[0], rpt->sta[cnt].mac_addr[1],
rpt->sta[cnt].mac_addr[2], rpt->sta[cnt].mac_addr[3],
rpt->sta[cnt].mac_addr[4], rpt->sta[cnt].mac_addr[5]);
if(iot_mac_addr_cmp(app_demo_mac_remote, rpt->sta[cnt].mac_addr))
{
app_demo_spd_ready &= ~APP_DEMO_RDY_REMOTE;
app_demo_spd_ready |= APP_DEMO_RDY_RESTART;
}
}
break;
}
case IOT_PLC_MSG_NW_WL_SET_RPT:
{
if(!(APP_DEMO_RDY_WL & app_demo_spd_ready))
{
iot_plc_set_whitelist
(app_demo_spd_app_handle, IOT_PLC_API_REQ_ID_DEFAULT,
IOT_PLC_WL_ADD, 1, (uint8_t *)app_demo_mac_remote);
DEMO_INFO("SET WHITELIST : %02x-%02x-%02x-%02x-%02x-%02x.",
app_demo_mac_remote[0], app_demo_mac_remote[1],
app_demo_mac_remote[2], app_demo_mac_remote[3],
app_demo_mac_remote[4], app_demo_mac_remote[5]);
app_demo_spd_ready |= APP_DEMO_RDY_WL;
}
}
case IOT_PLC_MSG_MSDU_RECV:
{
iot_plc_msdu_recv_t *p_msdu = (iot_plc_msdu_recv_t*)
(iot_pkt_data(pkt) + sizeof(iot_plc_msg_header_t));
if(APP_DEMO_SPD_READY())
{
app_demo_spd_mac_data_process(p_msdu);
}
}
default :
{
break;
}
}
if(pkt)
{
iot_pkt_free(pkt);
}
return;
}
void app_demo_spd_plc_rcv(void *param, iot_pkt_t *p_pkt)
{
(void)param;
app_demo_spd_post_msg(E_DEMO_MSG_FROM_MAC, 0, (void*)p_pkt);
return;
}
/* Register an APP to PLC-layer,so we can transmit/receive packet from it. */
uint32_t app_demo_spd_app_reg(void)
{
iot_plc_app_t app;
app.app_id = IOT_PLC_APP_DEMO_ID;
app.param = NULL;
app.prio = DEMO_PLC_CMD_PRIO;
app.recv = app_demo_spd_plc_rcv;
app_demo_spd_app_handle = iot_plc_register_app(&app);
if(NULL == app_demo_spd_app_handle)
{
DEMO_ERROR("REGISTER APP FAILED !!", 1, 2,3,4,5,6);
return ERR_FAIL;
}
return ERR_OK;
}
void app_demo_spd_light_status_idle(void)
{
static uint32_t status = 0;
iot_gpio_value_set(app_demo_spd_led_green, status);
iot_gpio_value_set(app_demo_spd_led_red, status);
status = status ? 0 : 1;
return;
}
void app_demo_spd_light_status_test(void)
{
static uint32_t status = 0;
if(status)
{
iot_gpio_value_set(app_demo_spd_led_green, 0);
iot_gpio_value_set(app_demo_spd_led_red, 1);
status = 0;
}
else
{
iot_gpio_value_set(app_demo_spd_led_green, 1);
iot_gpio_value_set(app_demo_spd_led_red, 0);
status = 1;
}
return;
}
void app_demo_spd_light_status_report(void)
{
uint32_t green, red, mask;
if(g_app_demo_spd_lght_words.pos >= g_app_demo_spd_lght_words.steps)
{
g_app_demo_spd_lght_words.pos = 0;
}
if(g_app_demo_spd_lght_words.pos > 31)
{
mask = 1 << ( 63 - g_app_demo_spd_lght_words.pos);
green = g_app_demo_spd_lght_words.green[1];
red = g_app_demo_spd_lght_words.red[1];
}
else
{
mask = 1 << ( 31 - g_app_demo_spd_lght_words.pos);
green = g_app_demo_spd_lght_words.green[0];
red = g_app_demo_spd_lght_words.red[0];
}
if(mask & green)
{
iot_gpio_value_set(app_demo_spd_led_green, 0);
}
else
{
iot_gpio_value_set(app_demo_spd_led_green, 1);
}
if(mask & red)
{
iot_gpio_value_set(app_demo_spd_led_red, 0);
}
else
{
iot_gpio_value_set(app_demo_spd_led_red, 1);
}
g_app_demo_spd_lght_words.pos++;
return;
}
void app_demo_spd_led_tmr_process(void)
{
#if INCLUDE_APP_DEMO_SPD_SENDER
if(APP_DEMO_SPD_RESTART())
{
app_demo_spd_restart();
}
#endif
if((APP_DEMO_RDY_TEST | APP_DEMO_RDY_S_REPORT) & app_demo_spd_ready)
{
app_demo_spd_light_status_test();
}
else if(APP_DEMO_RDY_FINISH & app_demo_spd_ready)
{
app_demo_spd_light_status_report();
}
else
{
app_demo_spd_light_status_idle();
}
}
void app_demo_spd_task_event_handle(iot_task_h task_h, uint32_t event)
{
(void)task_h;
if(APP_DEMO_SPD_EVT_TRSVD_TMR == event)
{
app_demo_spd_trcvd_tmr_process();
}
else
{
app_demo_spd_led_tmr_process();
}
return;
}
void app_demo_spd_tmr_handle(timer_id_t tid, void *data)
{
(void)tid;
os_set_task_event_with_v
(iot_task_get_os_task_h(app_demo_spd_task_handle), (uint32_t)data);
return;
}
void app_demo_spd_task_msg_handle(iot_task_h task_h, iot_task_msg_t *msg)
{
demo_spd_msg_t *dm_msg = (demo_spd_msg_t *)msg;
(void)task_h;
if((NULL == dm_msg)
||(!DEMO_MSG_VALID(dm_msg->msg.type)))
{
/* Maybe this can cause memory overflow! */
DEMO_ERROR("HANDLE AN INVALID MSG !!", 1,2,3,4,5,6);
return;
}
if(E_DEMO_MSG_FROM_MAC == dm_msg->msg.type)
{
app_demo_spd_mac_status_process((iot_pkt_t *)dm_msg->data);
}
iot_task_free_msg(task_h, &(dm_msg->msg));
return;
}
void app_demo_spd_task_msg_cancel(iot_task_h task_h, iot_task_msg_t *msg)
{
(void)task_h;
(void)msg;
}
uint32_t app_demo_spd_module_init(void)
{
iot_task_config_t t_cfg;
#if INCLUDE_APP_DEMO_SPD_SENDER
uint32_t intval_inx, speed_inx, cast_inx;
spd_info_t *p_spd_info;
#endif
t_cfg.stack_size = 0;
t_cfg.task_prio = DEMO_MSG_HANDLE_TASK_PRIO;
t_cfg.msg_size = sizeof(demo_spd_msg_t);
t_cfg.msg_cnt = DEMO_MSG_PENDING_LIMIT;
t_cfg.queue_cnt = DEMO_MSG_TASK_PRIO_QUE;
t_cfg.queue_cfg[0].quota = 0;
t_cfg.task_event_func = app_demo_spd_task_event_handle;
t_cfg.msg_exe_func = app_demo_spd_task_msg_handle;
t_cfg.msg_cancel_func = app_demo_spd_task_msg_cancel;
app_demo_spd_task_handle = iot_task_create(IOT_APP_DEMO_MID, &t_cfg);
if(NULL == app_demo_spd_task_handle)
{
DEMO_ERROR("iot_task_create RETURNS NULL !!", 1,2,3,4,5,6);
return ERR_FAIL;
}
#if INCLUDE_APP_DEMO_SPD_SENDER
os_mem_set(g_app_demo_spd_test_items, 0x0, sizeof(g_app_demo_spd_test_items));
for(cast_inx = 0; cast_inx < APP_DEMO_SPD_CAST_NUM; cast_inx++)
{
for(speed_inx = 0; speed_inx < APP_DEMO_SPD_SPEED_NUM; speed_inx++)
{
for(intval_inx = 0; intval_inx < APP_DEMO_SPD_INTVL_NUM; intval_inx++)
{
p_spd_info = &g_app_demo_spd_test_items[cast_inx][speed_inx][intval_inx];
p_spd_info->is_bcast = cast_inx ? 1 : 0;
p_spd_info->speed = g_demo_spd_speed[speed_inx];
p_spd_info->interval = g_demo_spd_interval[intval_inx];
p_spd_info->pkt_size = (p_spd_info->speed * p_spd_info->interval) / 8;
}
}
}
g_app_demo_spd_remain_pkts = APP_DEMO_SPD_TEST_PACKET_NUM;
#endif
app_demo_spd_ready = APP_DEMO_RDY_RESTART | APP_DEMO_RDY_IDLE;
app_demo_spd_led_red = iot_board_get_gpio(GPIO_TX_LED);
app_demo_spd_led_green = iot_board_get_gpio(GPIO_RX_LED);
if((ERR_OK != iot_gpio_open_as_output(app_demo_spd_led_red))
||(ERR_OK != iot_gpio_set_pull_mode(app_demo_spd_led_red, GPIO_PULL_UP)))
{
DEMO_ERROR("OPEN GPIO#%d FAILED !!", app_demo_spd_led_red, 2,3,4,5,6);
return ERR_FAIL;
}
if((ERR_OK != iot_gpio_open_as_output(app_demo_spd_led_green))
||(ERR_OK != iot_gpio_set_pull_mode(app_demo_spd_led_green, GPIO_PULL_UP)))
{
DEMO_ERROR("OPEN GPIO#%d FAILED !!", app_demo_spd_led_green, 2,3,4,5,6);
return ERR_FAIL;
}
if((timer_id_t)NULL == (app_demo_spd_led_tmr = os_create_timer
(IOT_APP_DEMO_MID, 1, (os_timer_func_t)app_demo_spd_tmr_handle,
(void *)APP_DEMO_SPD_EVT_LED_TMR)))
{
DEMO_ERROR("CREATE LED TMR FAILED !!", 1, 2,3,4,5,6);
return ERR_FAIL;
}
if((timer_id_t)NULL == (app_demo_spd_trcvd_tmr = os_create_timer
(IOT_APP_DEMO_MID, 1, (os_timer_func_t)app_demo_spd_tmr_handle,
(void *)APP_DEMO_SPD_EVT_TRSVD_TMR)))
{
DEMO_ERROR("CREATE TRANSEICE TMR FAILED !!", 1, 2,3,4,5,6);
return ERR_FAIL;
}
if(ERR_OK != app_demo_spd_app_reg())
{
return ERR_FAIL;
}
if (iot_plc_is_client_mode()) {
/* default set sta only scan band 1, freq: 2.4M to 5.6M */
app_demo_set_sta_scan_band(PLC_LIB_FREQ_BAND_1);
/* close watchdog */
iot_plc_wdg_set(app_demo_spd_app_handle, 0, 0);
}
DEMO_INFO(" SET BAND ID...", 1,2,3,4,5,6);
if(ERR_OK != app_demo_set_band(PLC_LIB_FREQ_BAND_1))
{
DEMO_ERROR("SET BAND ID FAILED !!", 1,2,3,4,5,6);
return ERR_FAIL;
}
app_demo_spd_ready |= APP_DEMO_RDY_IDLE;
os_start_timer(app_demo_spd_led_tmr, APP_DEMO_SPD_TMR_INTVAL);
DEMO_INFO("SPEED TEST INIT DONE.",1,2,3,4,5,6);
return ERR_OK;
}
#endif