338 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			338 lines
		
	
	
		
			10 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 "mac_channel.h"
 | 
						|
#include "iot_config.h"
 | 
						|
#include "iot_gpio_api.h"
 | 
						|
#include "os_types.h"
 | 
						|
#include "mac_vdev.h"
 | 
						|
#include "mac_pdev.h"
 | 
						|
#include "iot_io.h"
 | 
						|
#include "gpio_mtx.h"
 | 
						|
 | 
						|
#include "phy_bb.h"
 | 
						|
#include "phy_phase.h"
 | 
						|
#include "plc_protocol.h"
 | 
						|
#include "hw_phy_init.h"
 | 
						|
#include "hw_phy_api.h"
 | 
						|
 | 
						|
/*  ch 0 - A channel
 | 
						|
       1 - B channel
 | 
						|
       2 - C channel
 | 
						|
 | 
						|
    A channel:  GPIO23 GPIO28 -> 1 others 0
 | 
						|
    B channel:  GPIO22 GPIO35 -> 1 others 0
 | 
						|
    C channel:  GPIO23 GPIO35 -> 1 others 0
 | 
						|
*/
 | 
						|
void iot_mac_k48sta_setchannel_gpio(uint8_t ch)
 | 
						|
{
 | 
						|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
 | 
						|
    if (ch == MAC_CHANNEL_L_PE) {
 | 
						|
        /* L - PE */
 | 
						|
        iot_gpio_value_set(22, 0);
 | 
						|
        iot_gpio_value_set(23, 0);
 | 
						|
        iot_gpio_value_set(28, 0);
 | 
						|
        iot_gpio_value_set(9, 0);
 | 
						|
        iot_gpio_value_set(23, 1);
 | 
						|
        iot_gpio_value_set(9, 1);
 | 
						|
    } else if(ch == MAC_CHANNEL_L_N) {
 | 
						|
        /* L - N */
 | 
						|
        iot_gpio_value_set(22, 0);
 | 
						|
        iot_gpio_value_set(23, 0);
 | 
						|
        iot_gpio_value_set(28, 0);
 | 
						|
        iot_gpio_value_set(9, 0);
 | 
						|
        iot_gpio_value_set(23, 1);
 | 
						|
        iot_gpio_value_set(28, 1);
 | 
						|
    } else if(ch == MAC_CHANNEL_N_PE) {
 | 
						|
        /* N - PE */
 | 
						|
        iot_gpio_value_set(22, 0);
 | 
						|
        iot_gpio_value_set(23, 0);
 | 
						|
        iot_gpio_value_set(28, 0);
 | 
						|
        iot_gpio_value_set(9, 0);
 | 
						|
        iot_gpio_value_set(22, 1);
 | 
						|
        iot_gpio_value_set(9, 1);
 | 
						|
    } else {
 | 
						|
        iot_gpio_value_set(22, 0);
 | 
						|
        iot_gpio_value_set(23, 0);
 | 
						|
        iot_gpio_value_set(28, 0);
 | 
						|
        iot_gpio_value_set(9, 0);
 | 
						|
    }
 | 
						|
#else
 | 
						|
    (void)ch;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
void iot_mac_chan_select(uint8_t phase)
 | 
						|
{
 | 
						|
#if K48_STA_MULTI_CHANNEL_SELECT_ENABLE
 | 
						|
    if(PLC_PHASE_A == phase) {
 | 
						|
        iot_mac_k48sta_setchannel_gpio(MAC_CHANNEL_L_PE);
 | 
						|
    } else if(PLC_PHASE_B == phase) {
 | 
						|
        iot_mac_k48sta_setchannel_gpio(MAC_CHANNEL_L_N);
 | 
						|
    } else if(PLC_PHASE_C == phase) {
 | 
						|
        iot_mac_k48sta_setchannel_gpio(MAC_CHANNEL_N_PE);
 | 
						|
    } else {
 | 
						|
        iot_printf("Error: Phase index mismatched, configure failed...\n");
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    iot_printf("K48 STA Switch Phase to %d...\n", phase);
 | 
						|
#else
 | 
						|
    phy_trx_phase_switch_gpio_init();
 | 
						|
    phy_set_trx_switch_gpio_phase(phase);
 | 
						|
 | 
						|
    iot_printf("Switch Phase to %d...\n", phase);
 | 
						|
    if (phy_is_sta_role()) {
 | 
						|
        phy_rx_phase_force_set(true, PLC_PHASE_A);
 | 
						|
    } else {
 | 
						|
        phy_rx_phase_force_set(true, phase);
 | 
						|
    }
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
void iot_mac_k48sta_init_channelgpio(void)
 | 
						|
{
 | 
						|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
 | 
						|
    iot_gpio_open_as_output(23);
 | 
						|
    iot_gpio_set_pull_mode(23, GPIO_PULL_UP);
 | 
						|
    iot_gpio_open_as_output(28);
 | 
						|
    iot_gpio_set_pull_mode(28, GPIO_PULL_UP);
 | 
						|
    iot_gpio_open_as_output(22);
 | 
						|
    iot_gpio_set_pull_mode(22, GPIO_PULL_UP);
 | 
						|
    iot_gpio_open_as_output(9);
 | 
						|
    iot_gpio_set_pull_mode(9, GPIO_PULL_UP);
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
void iot_mac_k48cco_init_channelgpio(void)
 | 
						|
{
 | 
						|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
 | 
						|
    gpio_mtx_enable();
 | 
						|
    gpio_sig_info_t info1 = {
 | 
						|
        3,
 | 
						|
        {
 | 
						|
            {IO_TYPE_OUT, 0, 23, 0xff, 67},
 | 
						|
            {IO_TYPE_OUT, 0, 22, 0xff, 68},
 | 
						|
            {IO_TYPE_OUT, 0, 28, 0xff, 69},
 | 
						|
        }
 | 
						|
    };
 | 
						|
    gpio_module_pin_select(&info1);
 | 
						|
    gpio_module_sig_select(&info1, GPIO_MTX_MODE_MATRIX);
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
void mac_channel_scan_timer_handler(timer_id_t timer_id, void * arg) {
 | 
						|
    (void) timer_id;
 | 
						|
    mac_pdev_t *pdev = (mac_pdev_t*) arg;
 | 
						|
 | 
						|
    /* timer context */
 | 
						|
    mac_msg_t *msg = mac_alloc_msg();
 | 
						|
 | 
						|
    if (msg == NULL) {
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    msg->type = MAC_MSG_TYPE_TIMER;
 | 
						|
    msg->id = MAC_MSG_ID_CHANNEL_SCAN_TIMER;
 | 
						|
    msg->data1 = 0;
 | 
						|
    msg->data2 = pdev;
 | 
						|
    mac_queue_msg(msg, MAC_MSG_QUEUE_HP);
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
void iot_mac_k48sta_switch_next_channel(void *pdev)
 | 
						|
{
 | 
						|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
 | 
						|
    mac_pdev_t *pdev_ptr = (mac_pdev_t*)pdev;
 | 
						|
 | 
						|
    if (pdev_ptr->channel_scan.k48_cur_channel == MAC_CHANNEL_MAX_NUM) {
 | 
						|
        pdev_ptr->channel_scan.k48_cur_channel = MAC_CHANNEL_L_N;
 | 
						|
    } else {
 | 
						|
        pdev_ptr->channel_scan.k48_cur_channel = \
 | 
						|
            (pdev_ptr->channel_scan.k48_cur_channel == MAC_CHANNEL_N_PE) ? \
 | 
						|
                MAC_CHANNEL_L_PE: (pdev_ptr->channel_scan.k48_cur_channel + 1);
 | 
						|
    }
 | 
						|
 | 
						|
    iot_printf("mac channel scan next %d\n", pdev_ptr->channel_scan.k48_cur_channel);
 | 
						|
    iot_mac_k48sta_setchannel_gpio((uint8_t)pdev_ptr->channel_scan.k48_cur_channel);
 | 
						|
 | 
						|
#else
 | 
						|
    (void)pdev;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
void iot_mac_k48sta_scan_channel_init(void *pdev)
 | 
						|
{
 | 
						|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
 | 
						|
    mac_pdev_t *pdev_ptr = (mac_pdev_t*)pdev;
 | 
						|
 | 
						|
    for (uint8_t i = 0; i < MAC_CHANNEL_MAX_NUM; i++) {
 | 
						|
        pdev_ptr->channel_scan.k48_channel_snr[i] = INV_SNR;
 | 
						|
    }
 | 
						|
    pdev_ptr->channel_scan.k48_cur_channel = MAC_CHANNEL_L_N;
 | 
						|
    iot_mac_k48sta_setchannel_gpio(MAC_CHANNEL_L_N);
 | 
						|
    pdev_ptr->channel_scan.k48_channel_rx_count = 0;
 | 
						|
    pdev_ptr->channel_scan.k48_channel_is_sel = 0;
 | 
						|
    pdev_ptr->channel_scan.dwell_time_s = 180;  //180s
 | 
						|
 | 
						|
#if K48_STA_MULTI_CHANNEL_SELECT_ENABLE
 | 
						|
    if (pdev_ptr->channel_scan.scan_timer == 0) {
 | 
						|
        pdev_ptr->channel_scan.scan_timer =
 | 
						|
            os_create_timer(PLC_MAC_CHANNEL_SCAN_MID, true,
 | 
						|
                    mac_channel_scan_timer_handler, pdev);
 | 
						|
    }
 | 
						|
#else
 | 
						|
    pdev_ptr->channel_scan.scan_timer = 0;
 | 
						|
#endif
 | 
						|
#else
 | 
						|
    (void)pdev;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
uint32_t iot_mac_k48sta_scan_channel_start(void *pdev)
 | 
						|
{
 | 
						|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
 | 
						|
    mac_pdev_t *pdev_ptr = (mac_pdev_t*)pdev;
 | 
						|
 | 
						|
    if (pdev_ptr == NULL) {
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        return ERR_INVAL;
 | 
						|
    }
 | 
						|
 | 
						|
    pdev_ptr->channel_scan.k48_cur_channel = MAC_CHANNEL_L_N;
 | 
						|
    iot_mac_k48sta_setchannel_gpio(MAC_CHANNEL_L_N);
 | 
						|
 | 
						|
    //iot_mac_k48sta_scan_channel_init(pdev_ptr);
 | 
						|
    if (pdev_ptr->channel_scan.scan_timer) {
 | 
						|
        os_start_timer(pdev_ptr->channel_scan.scan_timer, \
 | 
						|
            pdev_ptr->channel_scan.dwell_time_s * 1000);
 | 
						|
    } else {
 | 
						|
        return ERR_INVAL;
 | 
						|
    }
 | 
						|
    return ERR_OK;
 | 
						|
#else
 | 
						|
    (void)pdev;
 | 
						|
    return ERR_OK;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
uint32_t iot_mac_k48sta_scan_channel_stop(void *pdev)
 | 
						|
{
 | 
						|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
 | 
						|
    mac_pdev_t *pdev_ptr = (mac_pdev_t*)pdev;
 | 
						|
 | 
						|
    if (pdev_ptr == NULL) {
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        return ERR_INVAL;
 | 
						|
    }
 | 
						|
 | 
						|
    if (pdev_ptr->channel_scan.scan_timer) {
 | 
						|
        os_stop_timer(pdev_ptr->channel_scan.scan_timer);
 | 
						|
        iot_printf("channel is selected %d, stop scan\n", \
 | 
						|
            pdev_ptr->channel_scan.k48_cur_channel);
 | 
						|
    } else {
 | 
						|
        return ERR_INVAL;
 | 
						|
    }
 | 
						|
 | 
						|
    return ERR_OK;
 | 
						|
#else
 | 
						|
    (void)pdev;
 | 
						|
    return ERR_OK;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#if 0
 | 
						|
uint32_t iot_mac_k48sta_channel_snr_cal(void *pdev, int8_t snr, int8_t ppm)
 | 
						|
{
 | 
						|
#if HW_PLATFORM >= HW_PLATFORM_FPGA
 | 
						|
    mac_pdev_t *pdev_ptr = (mac_pdev_t*)pdev;
 | 
						|
    uint8_t cur_channel;
 | 
						|
 | 
						|
    if (pdev_ptr == NULL) {
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        return ERR_INVAL;
 | 
						|
    }
 | 
						|
 | 
						|
    /* if channel is selected, return */
 | 
						|
    if (pdev_ptr->channel_scan.k48_channel_is_sel) {
 | 
						|
        return ERR_OK;
 | 
						|
    }
 | 
						|
 | 
						|
    /* if cur rx ppm is not sync or channel scan is not start, ignore it */
 | 
						|
    if ((ppm < -5 || ppm > 5) || \
 | 
						|
       (pdev_ptr->channel_scan.k48_cur_channel == MAC_CHANNEL_MAX_NUM)) {
 | 
						|
        return ERR_INVAL;
 | 
						|
    }
 | 
						|
 | 
						|
    /* if cur channel rx snr is very well, select cur channel and stop scan */
 | 
						|
    if (snr >= MIN_SNR_STOP_SCAN) {
 | 
						|
        iot_mac_k48sta_scan_channel_stop(pdev_ptr);
 | 
						|
        iot_mac_k48sta_setchannel_gpio((uint8_t)pdev_ptr->channel_scan.k48_cur_channel);
 | 
						|
        pdev_ptr->channel_scan.k48_channel_is_sel = 1;
 | 
						|
        iot_printf("cur bcn snr is %d, stop scan and mac channel is selected %d\n", \
 | 
						|
            snr, pdev_ptr->channel_scan.k48_cur_channel);
 | 
						|
        return ERR_OK;
 | 
						|
    }
 | 
						|
 | 
						|
    /* cal cur channel rx snr avg */
 | 
						|
    cur_channel = pdev_ptr->channel_scan.k48_cur_channel;
 | 
						|
    switch(cur_channel)
 | 
						|
    {
 | 
						|
        case MAC_CHANNEL_L_PE:
 | 
						|
        case MAC_CHANNEL_L_N:
 | 
						|
        case MAC_CHANNEL_N_PE:
 | 
						|
        {
 | 
						|
            if (pdev_ptr->channel_scan.k48_channel_snr[cur_channel] != INV_SNR) {
 | 
						|
                pdev_ptr->channel_scan.k48_channel_snr[cur_channel] = \
 | 
						|
                    CHANNL_CAL_AVG_SNR(pdev_ptr->channel_scan.k48_channel_snr[cur_channel], snr);
 | 
						|
            } else {
 | 
						|
                pdev_ptr->channel_scan.k48_channel_snr[cur_channel] = snr;
 | 
						|
            }
 | 
						|
            iot_printf("snr = %d,channel %d avg snr = %d\n", snr, cur_channel, \
 | 
						|
                pdev_ptr->channel_scan.k48_channel_snr[cur_channel]);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
        {
 | 
						|
            iot_printf("cur channel %d is invalid\n",cur_channel);
 | 
						|
            IOT_ASSERT(0);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    pdev_ptr->channel_scan.k48_channel_rx_count++;
 | 
						|
 | 
						|
    /* stop channel scan */
 | 
						|
    if (pdev_ptr->channel_scan.k48_channel_rx_count >= MAX_BCN_RX_CNT) {
 | 
						|
        iot_mac_k48sta_scan_channel_stop(pdev_ptr);
 | 
						|
 | 
						|
        /* find the max avg snr and select the channel */
 | 
						|
        pdev_ptr->channel_scan.k48_cur_channel= \
 | 
						|
            GET_BEST_CHANNEL(pdev_ptr->channel_scan.k48_channel_snr[MAC_CHANNEL_L_PE], \
 | 
						|
            pdev_ptr->channel_scan.k48_channel_snr[MAC_CHANNEL_L_N], \
 | 
						|
            pdev_ptr->channel_scan.k48_channel_snr[MAC_CHANNEL_N_PE]);
 | 
						|
 | 
						|
        iot_mac_k48sta_setchannel_gpio((uint8_t)pdev_ptr->channel_scan.k48_cur_channel);
 | 
						|
        pdev_ptr->channel_scan.k48_channel_is_sel = 1;
 | 
						|
        iot_printf("mac channel is selected %d\n", pdev_ptr->channel_scan.k48_cur_channel);
 | 
						|
    }
 | 
						|
 | 
						|
    return ERR_OK;
 | 
						|
#else
 | 
						|
    (void)pdev;
 | 
						|
    (void)snr;
 | 
						|
    return ERR_OK;
 | 
						|
#endif
 | 
						|
}
 | 
						|
#endif
 |