1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/drivers/at86rf231/at86rf231_tx.c

117 lines
3.5 KiB
C
Raw Normal View History

/*
* Copyright (C) 2014 INRIA
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
2013-12-16 17:54:58 +01:00
#include "at86rf231.h"
#include "at86rf231_arch.h"
2014-02-20 03:05:35 +01:00
#include "at86rf231_spi.h"
2014-07-07 00:00:16 +02:00
static void at86rf231_xmit(uint8_t *data, radio_packet_length_t length);
static void at86rf231_gen_pkt(uint8_t *buf, at86rf231_packet_t *packet);
static uint8_t sequenz_nr;
int16_t at86rf231_send(at86rf231_packet_t *packet)
{
2013-08-15 19:13:00 +02:00
// Set missing frame information
packet->frame.fcf.frame_ver = 0;
if (packet->frame.src_pan_id == packet->frame.dest_pan_id) {
packet->frame.fcf.panid_comp = 1;
}
else {
packet->frame.fcf.panid_comp = 0;
}
if (packet->frame.fcf.src_addr_m == 2) {
2014-02-20 14:35:46 +01:00
packet->frame.src_addr[0] = (uint8_t)(at86rf231_get_address() >> 8);
packet->frame.src_addr[1] = (uint8_t)(at86rf231_get_address() & 0xFF);
2013-08-15 19:13:00 +02:00
}
else if (packet->frame.fcf.src_addr_m == 3) {
2014-02-20 14:35:46 +01:00
packet->frame.src_addr[0] = (uint8_t)(at86rf231_get_address_long() >> 56);
packet->frame.src_addr[1] = (uint8_t)(at86rf231_get_address_long() >> 48);
packet->frame.src_addr[2] = (uint8_t)(at86rf231_get_address_long() >> 40);
packet->frame.src_addr[3] = (uint8_t)(at86rf231_get_address_long() >> 32);
packet->frame.src_addr[4] = (uint8_t)(at86rf231_get_address_long() >> 24);
packet->frame.src_addr[5] = (uint8_t)(at86rf231_get_address_long() >> 16);
packet->frame.src_addr[6] = (uint8_t)(at86rf231_get_address_long() >> 8);
packet->frame.src_addr[7] = (uint8_t)(at86rf231_get_address_long() & 0xFF);
2013-08-15 19:13:00 +02:00
}
packet->frame.src_pan_id = at86rf231_get_pan();
packet->frame.seq_nr = sequenz_nr;
sequenz_nr += 1;
// calculate size of the frame (payload + FCS) */
packet->length = ieee802154_frame_get_hdr_len(&packet->frame) +
packet->frame.payload_len + 1;
2013-08-15 19:13:00 +02:00
if (packet->length > AT86RF231_MAX_PKT_LENGTH) {
return -1;
}
// FCS is added in hardware
uint8_t pkt[packet->length];
/* generate pkt */
at86rf231_gen_pkt(pkt, packet);
// transmit packet
at86rf231_xmit(pkt, packet->length);
return packet->length;
}
2014-07-07 00:00:16 +02:00
static void at86rf231_xmit(uint8_t *data, radio_packet_length_t length)
{
2013-08-15 19:13:00 +02:00
// Go to state PLL_ON
at86rf231_reg_write(AT86RF231_REG__TRX_STATE, AT86RF231_TRX_STATE__PLL_ON);
2013-08-15 19:13:00 +02:00
// wait until it is on PLL_ON state
uint8_t status;
uint8_t max_wait = 100; // TODO : move elsewhere, this is in 10us
2013-08-15 19:13:00 +02:00
do {
status = at86rf231_get_status();
2013-08-15 19:13:00 +02:00
vtimer_usleep(10);
2013-08-15 19:13:00 +02:00
if (!--max_wait) {
printf("at86rf231 : ERROR : could not enter PLL_ON mode");
break;
}
}
2013-08-15 19:13:00 +02:00
while ((status & AT86RF231_TRX_STATUS_MASK__TRX_STATUS) != AT86RF231_TRX_STATUS__PLL_ON);
2013-08-15 19:13:00 +02:00
// copy the packet to the radio FIFO
at86rf231_write_fifo(data, length);
2013-08-15 19:13:00 +02:00
// Start TX
at86rf231_reg_write(AT86RF231_REG__TRX_STATE, AT86RF231_TRX_STATE__TX_START);
}
/**
* @brief Static function to generate byte array from at86rf231 packet.
*
*/
static void at86rf231_gen_pkt(uint8_t *buf, at86rf231_packet_t *packet)
{
uint8_t index, offset;
index = ieee802154_frame_init(&packet->frame, &buf[1]);
// add length for at86rf231
2013-08-15 19:13:00 +02:00
buf[0] = packet->length + 1;
index++;
2013-07-27 10:54:44 +02:00
offset = index;
2013-08-15 19:13:00 +02:00
while (index < packet->length) {
2014-02-20 14:35:46 +01:00
buf[index] = packet->frame.payload[index - offset];
index += 1;
}
}