# xmpl_radio_stream.c - Using Radio Stream Functions

Application Description

This example shows, how the avr-libc stdio facilities can be used to do a printf to the radio transceiver. The data printed to the transceiver can be watched on a terminal either with the wuart application or with xmpl_linbuf_rx.c.

Code Example

    /* $Id$ */
    /* Example use of the radio stream functions */
    #include <stdio.h>
    #include "board.h"
    #include "hif.h"
    #include "radio.h"
    #include "xmpl.h"

    #define PROMPT() PRINTF("\n\ruracoli[%02d]> ",lc++)

    void incb(buffer_t *pbuf);
    void outcb(buffer_t *pbuf);

    buffer_stream_t Rstream;
    uint8_t frame_header[] = {0x01, 0x80, 0, 0x11,0x22,0x33,0x44};
    #define XMPL_FRAME_SIZE (40)
    uint8_t ibuf[sizeof(buffer_t) + XMPL_FRAME_SIZE + 2];
    uint8_t obuf[sizeof(buffer_t) + XMPL_FRAME_SIZE + 2];

    //volatile buffer_t *pibuf;
    int main(void)
    {
    uint8_t rxbuf[MAX_FRAME_SIZE];
    uint8_t cnt = 0;

        /* setup buffers */
        buffer_init(ibuf, sizeof(ibuf)-2, 0);
        buffer_init(obuf, sizeof(obuf)-2, sizeof(frame_header));

        /* setup buffer stream structure and stdio */
        buffer_stream_init(&Rstream, &incb, &outcb);
        /* todo add buffer assignment as parameters to buffer_stream_init! */
        Rstream.pbufin  = (buffer_t *)ibuf;
        Rstream.pbufout = (buffer_t *)obuf;
        stdout = stdin = &Rstream.bstream;

        /* setup hardware */
        LED_INIT();
        radio_init(rxbuf, MAX_FRAME_SIZE);
        radio_set_state(STATE_OFF);
        radio_set_param(RP_CHANNEL(CHANNEL));
        radio_set_param(RP_IDLESTATE(STATE_RX));
        sei();
        printf_P(PSTR("Hello World %d\n\r"),cnt++);

        while(1)
        {
            WAIT_MS(10);

            int c;
            c = getchar();
            if ( ('a' <= c) && (c <= 'z'))
            {
                printf_P(PSTR(":%c:\n\r"),c);
            }
        }
    }

    void outcb(buffer_t *pbuf)
    {
    static uint8_t frame_header[] = {0x01, 0x80, 0, 0x11,0x22,0x33,0x44};
    char lastchar;
        //LED_TOGGLE(0);

        lastchar = BUFFER_LAST_CHAR(pbuf);
        if ((BUFFER_FREE_AT_END(pbuf) < 1) || (lastchar == '\r'))
        {
            /* prepare send */
            buffer_prepend_block(pbuf, frame_header, sizeof(frame_header));
            radio_set_state(STATE_TX);
            radio_send_frame(BUFFER_SIZE(pbuf)+ 2, BUFFER_PDATA(pbuf), 0);
            /* clean buffer */
            BUFFER_RESET(pbuf, sizeof(frame_header));
            frame_header[2]++;
            /* blink LED if done. */
            //LED_TOGGLE(0);
        }
    }

    void incb(buffer_t *pbuf)
    {
    uint8_t sz;
        sz = BUFFER_SIZE(pbuf);
        if (sz < 1)
        {
            /* buffer is now empty, free it. */
    cli();
            BUFFER_RESET(pbuf,0);
            BUFFER_SET_UNLOCK(pbuf);
    sei();
        }
    }

    uint8_t * usr_radio_receive_frame(uint8_t len, uint8_t *frm, uint8_t lqi, int8_t ed, uint8_t crc)
    {
    uint16_t fctl;
    uint8_t hlength;
        LED_TOGGLE(1);

        if ( BUFFER_IS_LOCKED(Rstream.pbufin) == false && crc == 0)
        {
            fctl = *(uint16_t*)frm;
            /* copy the payload, reduced by the CRC bytes */
            buffer_append_block(Rstream.pbufin, frm, len-2);
            hlength = 3;
            hlength += ((fctl & FCTL_DST_MASK) == FCTL_DST_LONG) ? 10:0;
            hlength += ((fctl & FCTL_DST_MASK) == FCTL_DST_SHORT) ? 4:0;
            hlength += ((fctl & FCTL_SRC_MASK) == FCTL_SRC_LONG) ? 10:0;
            hlength += ((fctl & FCTL_SRC_MASK) == FCTL_SRC_SHORT) ? 4:0;
            if (fctl & FCTL_IPAN_MASK)
            {
                hlength -= (fctl & FCTL_SRC_MASK) ? 2:0;
            }
            BUFFER_ADVANCE(Rstream.pbufin,hlength-1);
            printf("rx=%d\n\r", BUFFER_SIZE(Rstream.pbufin));
            BUFFER_SET_LOCK(Rstream.pbufin);
        }
        return frm;
    }
    /* XEOF */