
#include "t1001.h"

#include "omw_dbg.h"
#include "omw_gpio.h"
#include "Inital.h"

#include <stdio.h>
#include "string.h"

#include "t100x_hal_2g4.h"

//only for demo
#define SLEEP_ELAPSE 0xFFFFFFFF   //ms

void RF_2G4_PrepareStart(void);
void RF_2G4_UpdateDesc_TxPkt(void);
void RF_2G4_UpdateDesc_RxPkt(void);

extern omw_2g4_param_t rf_2g4_mgr;

uint8_t num_timer1,num_timer2;
uint32_t Key_1,Key_2,Key_3,Key_4;
uint32_t test_num1,test_num2,test_num3;
uint8_t TX_FLG;
uint8_t Key_success_FLG;
uint8_t Key_status,Sleep_flg;
//only for demo
uint8_t tx_ble_adv_data_buf[] = {
	0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00,
};

#if (!defined(OMW_2G4_ROLE_SLAVE) && !defined(OMW_2G4_ROLE_SLAVE_NO_SLP)) || defined(OMW_2G4_RX_ON_SLEEP)
//only for demo
#define RX_DATA_LEN  (sizeof(tx_ble_adv_data_buf))
//#define MAX_RX_DATA_BUF_LEN  8
//uint32_t rx_ble_adv_data_buf[MAX_RX_DATA_BUF_LEN];
uint8_t rx_2G4_data_buf[8];	
uint8_t Init_Data;
uint8_t R_LED_TIME;

int  sync_cnts, crc_ok_cnts;
//if need to call when not wakeup fully, MUST put omw_svc_rx_end into RAM， and DO NOT CALL functions at FLASH SECTION
//otherwise, can put into FLASH(del __RAM_CODE_SECTION)
//when sync ok, this callback will be called
//OP: will call one time per-rxok
__RAM_CODE_SECTION
void omw_svc_24g_sync_end()
{
    sync_cnts++;
}

//if need to call when not wakeup fully, MUST put omw_svc_rx_end into RAM， and DO NOT CALL functions at FLASH SECTION
//otherwise, can put into FLASH(del __RAM_CODE_SECTION)
__RAM_CODE_SECTION
void omw_svc_24g_rx_end(uint8_t is_crc_err)
{
    //TODO: your code start
    if (!is_crc_err)
    {//data is rcved into rx_ble_adv_data_buf
        //only for demo, if call omw_svc_24g_rx_end when not wakeup fully, should not call printf(@flash)
        crc_ok_cnts++;
        if (rx_2G4_data_buf[0] == 0x01 && rx_2G4_data_buf[1] == 0x02)
        {
			printf("rx data: %02X, %02X, %02X, %02X,%02X, %02X, %02X, %02X\n", (unsigned char)rx_2G4_data_buf[0], (unsigned char)rx_2G4_data_buf[1], (unsigned char)rx_2G4_data_buf[2], (unsigned char)rx_2G4_data_buf[3], (unsigned char)rx_2G4_data_buf[4],(unsigned char)rx_2G4_data_buf[5],(unsigned char)rx_2G4_data_buf[6],(unsigned char)rx_2G4_data_buf[7]);
            printf("sync: %u, crc ok: %u\n", (unsigned int)sync_cnts, (unsigned int)crc_ok_cnts);
        }
		else {
			for (uint8_t i=0; i < 8; i++) {
				rx_2G4_data_buf[i] = 0;
			}
		}
    }
    //TODO: your code end
}

__RAM_CODE_SECTION
void omw_svc_24g_tx_end()
{
    //TODO: Custom code after TX, should NOT place huge codes here
}
#endif
//wkup_type: 0 timeout,  != 0 GPIO trigger, mask
//reture: 0 goto sleep again, 1 fully wake-up
//DO NOT CALL omw_sleep_goto_sleep in omw_sleep_wkup_worker
//DO NOT CALL omw_sleep_goto_sleep in omw_sleep_wkup_worker
//DO NOT CALL omw_sleep_goto_sleep in omw_sleep_wkup_worker
__RAM_CODE_SECTION
uint8_t omw_sleep_wkup_worker(uint32_t wkup_type)
{
    if (wkup_type)  return 1;  //wakeup fully

    int chl_idx = 0;
    uint8_t chl_map[]     = {38,  62, 116};
    uint8_t ble_chl_map[] = {37,  38, 39};

    __enable_irq();

    //only for demo
    while(1)
    {
        #ifdef OMW_EN_WDG
        if (SYS_CTRL->WDT_CFG != 0)
        {
            uint32_t cur_fd_wdt_val = *(volatile uint32_t *)(SYS_CTRL_BASE + WTD_SET_ADDR);
            FEED_WTD(cur_fd_wdt_val);
        }
        #endif

        omw_svc_2g4_tx_data(tx_ble_adv_data_buf, sizeof(tx_ble_adv_data_buf), chl_map[chl_idx], ble_chl_map[chl_idx]);

        ////wait for TX done
        while(rf_2g4_mgr.status_WTR)
        {
            __WFI();
        }

        #ifdef OMW_2G4_RX_ON_SLEEP
        omw_svc_2g4_rx_data((uint8_t*)rx_2G4_data_buf, RX_DATA_LEN, 62, 38);

        while(rf_2g4_mgr.status_WTR)
        {
            __WFI();
        }
        #endif

        if (sizeof(tx_ble_adv_data_buf) > 8)
        {
            tx_ble_adv_data_buf[sizeof(tx_ble_adv_data_buf) - 1]++;
        }

        chl_idx++;
        if (chl_idx >= sizeof(chl_map))
        {
            break;
        }
    }

    __disable_irq();

    return 0; //not wakeup fully
}

int main(void)
{
    omw_rf_init();

    #if (!defined(OMW_2G4_ROLE_SLAVE) && !defined(OMW_2G4_ROLE_SLAVE_NO_SLP))|| defined(OMW_2G4_RX_ON_SLEEP)
    rf_2g4_fifo = (uint8_t *)rx_2G4_data_buf;
    #endif

    omw_2g4_param_t tmp_rf_cfg = {
        .channel = 38,
        .phy_mode = RF_RATE_250K,  //2M: RF_RATE_2M
        .preamble_len = 1, //2M: 2
        .access_code = { 0xD6, 0xBE, 0x89, 0x8E },
        .access_len = 4,

        .white_en = 0,
        .white_init = 37,

        .crc_en = 1,
        .crc_len = 3,
        .crc_init = 0x555555,
        .crc_poly = 0x100065b,

        #if (!defined(OMW_2G4_ROLE_SLAVE) && !defined(OMW_2G4_ROLE_SLAVE_NO_SLP)) || defined(OMW_2G4_RX_ON_SLEEP) || defined(OMW_2G4_ROLE_BOTH)
        //only for demo
        .rx_timeout = 0x5000,
        .fifo_len   = RX_DATA_LEN,
        #endif
    };

    omw_svc_2g4_init(&tmp_rf_cfg);

    omw_rf_set_tx_power(10);   //int: -25 ~ 12

    RF_2G4_PrepareStart();
    RF_2G4_UpdateDesc_TxPkt();
    RF_2G4_UpdateDesc_RxPkt();

    //RETENTION RAM CFG: 0x7A=16KB,  0x3A=8KB,  0x1A=4KB
    AON_CTRL->AON_CTRL0 = 0x7A;

	#ifdef OMW_2G4_ROLE_SLAVE_NO_SLP
	hc_Timer_init(); 		//开启Timer0中断
	printf("start 2g4 data xfer test[tx_no_slp]!\n");
    omw_svc_2g4_en_whiten_tx(1);
	#else
    #ifdef OMW_2G4_ROLE_SLAVE_ON_SLP
	printf("start 2g4 data xfer test[tx]!\n");
    omw_svc_2g4_en_whiten_tx(1);	
    //set sleep len and goto sleep
    omw_sleep_set_sleep_len(SLEEP_ELAPSE);
	hc_gpio_init();
	hc_Timer_init();
	omw_sleep_goto_sleep(); 	
    #else
    #ifndef OMW_2G4_ROLE_SLAVE_NO_SLP
	omw_gpio_set_output_en(OMW_GPIO_PIN19,ENABLE);
	omw_gpio_set_output(OMW_GPIO_PIN19,HIGH);
	printf("start 2g4 data xfer test[rx]!\n");
    omw_svc_2g4_en_whiten_rx(1);

    omw_svc_2g4_rx_data((uint8_t*)rx_2G4_data_buf, RX_DATA_LEN, 38, 38);
    #endif
	#endif
	#endif
	
    while(1)
    {

        #ifdef OMW_2G4_ROLE_SLAVE_ON_SLP
        //TODO: do your bussiness
		KEY_statusswitch();
		
		if(TX_FLG)
		{
			TX_FLG = 0;
			omw_timer_it_en(TIMER0,DISABLE);
			
			omw_svc_2g4_tx_data((uint8_t*)tx_ble_adv_data_buf, sizeof(tx_ble_adv_data_buf), 38, 38);
			
			while(rf_2g4_mgr.status_WTR == 1) {
				__WFI();
			}
			
			omw_timer_it_en(TIMER0,ENABLE);
			Sleep_flg = 0;
			num_timer2 = 0;
		}
		
		if(Sleep_flg == 1)
		{
			Sleep_flg = 0;
			KEY_off_status();
			if(Key_success_FLG==1)
			{
				omw_sleep_goto_sleep();
			}
		}
        #else
        #ifndef OMW_2G4_ROLE_SLAVE_NO_SLP
        while(rf_2g4_mgr.status_WTR == 1) {
            __WFI();
        }

        omw_svc_2g4_rx_data((uint8_t*)rx_2G4_data_buf, RX_DATA_LEN, 38, 38);	
		if(rx_2G4_data_buf[7] != Init_Data)
		{
			Init_Data = rx_2G4_data_buf[7];
			R_LED_TIME = 0; 
			omw_gpio_set_output(OMW_GPIO_PIN19,LOW);
		}
		else {
			R_LED_TIME++;
			if(R_LED_TIME>20)
			{
				R_LED_TIME=0;
				omw_gpio_set_output(OMW_GPIO_PIN19,HIGH);
			}
		}
		#ifdef OMW_2G4_ROLE_BOTH
        while(rf_2g4_mgr.status_WTR == 1) {
            __WFI();
        }
        omw_svc_2g4_tx_data((uint8_t*)tx_ble_adv_data_buf, sizeof(tx_ble_adv_data_buf), 38, 38);
        #endif
        #else
		
		KEY_statusswitch();
		
		if(TX_FLG)
		{
			TX_FLG = 0;
			omw_timer_it_en(TIMER0,DISABLE);
			
			omw_svc_2g4_tx_data((uint8_t*)tx_ble_adv_data_buf, sizeof(tx_ble_adv_data_buf), 38, 38);
			
			while(rf_2g4_mgr.status_WTR == 1) {
				__WFI();
			}
			
			omw_timer_it_en(TIMER0,ENABLE);
		}
        #endif
        #endif
    }
}
