/*
 * sensorproto.c
 *
 *  Created on: 22.10.2011
 *      Author: dthiele
 */

#include <stdint.h>
#include <avr/pgmspace.h>

#include <radio.h>
#include <timer.h>

#include "sensorproto.h"

static uint8_t rxbuf[127];		/* buffer for frame receive */
static node_config_t nc;
static uint8_t rxslot;
static volatile timer_hdl_t thdl_rxslot;

static sensorproto_hdr_t hdr;

/* default values if no config is found in EEPROM of FLASH */
static const node_config_t PROGMEM nc_flash = { .short_addr = 0xBEEF, .pan_id = 0x0022,
		.channel = SENSORPROTO_WORKCHANNEL };

void sensorproto_init(uint8_t boardtype)
{
	/* 1st trial: read from internal EEPROM */
	if (get_node_config_eeprom(&nc, 0) == 0) {
		/* using EEPROM config */;
	}
	/* 2nd trial: read from FLASHEND */
	else if (get_node_config(&nc) == 0) {
		/* using FLASHEND config */;
	}
	/* 3rd trial: read default values compiled into the application */
	else {
		/* using application default config */;
		memcpy_P(&nc, &nc_flash, sizeof(node_config_t));
	}

	radio_init(rxbuf, sizeof(rxbuf) / sizeof(rxbuf[0]));
	radio_set_param(RP_CHANNEL(nc.channel));
	radio_set_param(RP_IDLESTATE(STATE_RXAUTO));
	radio_set_param(RP_PANID(nc.pan_id));
	radio_set_param(RP_SHORTADDR(nc.short_addr));

	hdr.FCF = 0x8841; /* data frame, panid compr, no ACK requested */
	hdr.boardtype = boardtype;
}

node_config_t* sensorproto_get_config(void)
{
	return &nc;
}

/*
 * \brief Called on Rx slot timeout
 * No matter if a frame was received or not
 */
time_t tmr_rxslot(timer_arg_t t) {
	radio_set_state(STATE_SLEEP);
	return 0; /* do not restart */
}

/*
 * \brief Callback of libradio_
 */
uint8_t* usr_radio_receive_frame(uint8_t len, uint8_t *frm,
		uint8_t lqi, int8_t ed, uint8_t crc_fail)
{

	timer_stop(thdl_rxslot);
	cb_sensorproto_rx(frm);
	return frm;
}

/*
 * \brief Callback of libradio_
 */
void usr_radio_tx_done(radio_tx_done_t status)
{
	if(rxslot){
		thdl_rxslot = timer_start(tmr_rxslot, T_RX_SLOT, 0);
	}else{
		/* state is set inside libradio_ immediately after leaving this function */
		radio_set_param(RP_IDLESTATE(STATE_SLEEP));
	}
	cb_sensorproto_txdone(status);
}

/* EOF */
