Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages | Examples

braping.c

Example of BRA usage - ping, signal strenght measurement and low level CC2420 register control.
/*
 * Copyright (C) 2006 BLADOX, s.r.o.  All rights reserved.
 * 
 * This file is part of an example program for Turbo. This example
 * program may be used, distributed and modified without limitation.
 *
 */

#include <config.h>
#include <turbo/turbo.h>

#include <stdlib.h>

u8 PROGMEM t_bra_tag[] = "ping";
u8 PROGMEM t_src[] = "Src: ";
u8 PROGMEM t_dest[] = "Dest: ";
u8 PROGMEM t_tx_q[] = "txq: ";
u8 PROGMEM t_rx_q[] = "rxq: ";
u8 PROGMEM t_No_Link[] = "No Link";

/* *INDENT-OFF* */

lc_char PROGMEM lc_Ping[]={
        LC_EN("Ping")
        LC_END
};

lc_char PROGMEM lc_Freq[]={
        LC_EN("Freq")
        LC_END
};

lc_char PROGMEM lc_Channel[]={
        LC_EN("Channel")
        LC_END
};

lc_char PROGMEM lc_Pwr[]={
        LC_EN("TX Power")
        LC_END
};

lc_char PROGMEM lc_CC2420[]={
        LC_EN("CC2420")
        LC_END
};

lc_char PROGMEM lc_Read[]={
        LC_EN("Read")
        LC_END
};

lc_char PROGMEM lc_Write[]={
        LC_EN("Write")
        LC_END
};

lc_char PROGMEM lc_Addr[]={
        LC_EN("Register: ")
        LC_END
};

lc_char PROGMEM lc_Value[]={
        LC_EN("Value: ")
        LC_END
};

lc_char PROGMEM lc_Result[]={
        LC_EN("Result: ")
        LC_END
};

lc_char PROGMEM lc_Wrong_Addr[]={
        LC_EN("Register must be between 0x10-0x3f")
        LC_END
};

/* *INDENT-ON* */

u8 str2hex (u8 * s)
{
  u8 x = 0;
  u8 c;

  c = *s;
  if (c >= '0' && c <= '9')
    c = c - '0';
  else
  {
    if (c >= 'a' && c <= 'f')
      c = c - 'a' + 0x0a;
    else if (c >= 'A' && c <= 'F')
      c = c - 'A' + 0x0a;
    else
      c = 0;                    // wrong char
  }

  x = c << 4;

  s++;
  c = *s;
  if (c >= '0' && c <= '9')
    c = c - '0';
  else
  {
    if (c >= 'a' && c <= 'f')
      c = c - 'a' + 0x0a;
    else if (c >= 'A' && c <= 'F')
      c = c - 'A' + 0x0a;
    else
      c = 0;                    // wrong char
  }

  x |= c;

  return x;
}

u16 str4hex (u8 * s)
{
  u16 x;

  x = str2hex (s);
  s += 2;
  x <<= 8;
  x |= str2hex (s);
  return x;
}

u8 *sprint_hex16 (u8 * s, u16 val)
{
  u8 i;

  i = (val >> 12) & 0x0f;
  if (i <= 0x09)
    *s++ = i + '0';
  else
    *s++ = i - 0x0a + 'a';

  i = (val >> 8) & 0x0f;
  if (i <= 0x09)
    *s++ = i + '0';
  else
    *s++ = i - 0x0a + 'a';

  i = (val >> 4) & 0x0f;
  if (i <= 0x09)
    *s++ = i + '0';
  else
    *s++ = i - 0x0a + 'a';

  i = val & 0x0f;
  if (i <= 0x09)
    *s++ = i + '0';
  else
    *s++ = i - 0x0a + 'a';

  return s;
}

u8 ping_cc2420_read (SCtx * ctx, u8 action)
{
  if (action == APP_ENTER)
  {
    u8 *res;
    u16 addr;
    u16 val;

    res = get_input (locale (lc_Addr), 2, 2, NULL, Q_GET_INPUT_ALPHABET);
    if (res == ENULL)
      return APP_END;
    if (res == NULL)
      return APP_BACK;

    res[res[0] + 1] = '\0';
    addr = str2hex (&res[2]);

    if (addr < 0x10 || addr > 0x3f)
      display_text_raw (locale (lc_Wrong_Addr), Q_DISPLAY_TEXT_USER_CLEAR);
    else
    {
      u8 *buf = buf_B ();
      u8 *r = buf;

      val = bra_cc2420_read (addr);
      r = sprints (r, locale (lc_Result));
      r = sprint_hex16 (r, val);
      r = sprintc (r, '\0');
      display_text_raw (buf, Q_DISPLAY_TEXT_USER_CLEAR);
    }

    return APP_BACK;
  }
  return APP_OK;
}

u8 ping_cc2420_write (SCtx * ctx, u8 action)
{
  if (action == APP_ENTER)
  {
    u8 *res;
    u16 addr;
    u16 val;

    res = get_input (locale (lc_Addr), 2, 2, NULL, Q_GET_INPUT_ALPHABET);
    if (res == ENULL)
      return APP_END;
    if (res == NULL)
      return APP_BACK;

    res[res[0] + 1] = '\0';
    addr = str2hex (&res[2]);

    if (addr < 0x10 || addr > 0x3f)
      display_text_raw (locale (lc_Wrong_Addr), Q_DISPLAY_TEXT_USER_CLEAR);
    else
    {
      u8 *buf = buf_B ();
      u8 *r = buf;

      res = get_input (locale (lc_Value), 4, 4, NULL, Q_GET_INPUT_ALPHABET);
      if (res == ENULL)
        return APP_END;
      if (res == NULL)
        return APP_BACK;

      res[res[0] + 1] = '\0';
      val = str4hex (&res[2]);

      val = bra_cc2420_write (addr, val);
      r = sprints (r, locale (lc_Result));
      r = sprint_hex16 (r, val);
      r = sprintc (r, '\0');
      display_text_raw (buf, Q_DISPLAY_TEXT_USER_CLEAR);
    }

    return APP_BACK;
  }
  return APP_OK;
}

u8 ping_freq (SCtx * ctx, u8 action)
{
  if (action == APP_ENTER)
  {
    u8 *res;
    u16 x;

    res = get_input (locale (lc_Freq), 4, 4, NULL, Q_GET_INPUT_DIGITS);
    if (res == ENULL)
      return APP_END;
    if (res == NULL)
      return APP_BACK;

    res[res[0] + 1] = '\0';
    x = atoi (&res[2]);

    bra_set_freq (x);

    return APP_BACK;
  }
  return APP_OK;
}

u8 ping_channel (SCtx * ctx, u8 action)
{
  if (action == APP_ENTER)
  {
    u8 *res;
    u8 x;

    res = get_input (locale (lc_Channel), 1, 2, NULL, Q_GET_INPUT_DIGITS);
    if (res == ENULL)
      return APP_END;
    if (res == NULL)
      return APP_BACK;

    res[res[0] + 1] = '\0';
    x = atoi (&res[2]);

    bra_set_802_15_4_channel (x);

    return APP_BACK;
  }
  return APP_OK;
}

u8 ping_pwr (SCtx * ctx, u8 action)
{
  if (action == APP_ENTER)
  {
    u8 *res;
    u8 x;

    res = get_input (locale (lc_Pwr), 1, 2, NULL, Q_GET_INPUT_DIGITS);
    if (res == ENULL)
      return APP_END;
    if (res == NULL)
      return APP_BACK;

    res[res[0] + 1] = '\0';
    x = atoi (&res[2]);

    bra_set_tx_power (x);

    return APP_BACK;
  }
  return APP_OK;
}

u8 ping_ping (SCtx * ctx, u8 action)
{
  if (action == APP_ENTER)
  {
    u8 *r = buf_A ();
    u8 *b = buf_B ();
    u16 q;
    u8 l;

  X1:
    r = buf_A ();
    b = buf_B ();
    r = bra_make_head (r, NULL, t_bra_tag, 1);

    l = bra_txrx (buf_A (), r - buf_A (), t_bra_tag, 20, 1, 5);
    if (l > 0)
    {
      u8 mac[DEF_BRA_MAC_LEN];

      q = bra_lqi ();

      b = sprints (b, t_src);
      bra_mac_get (mac);
      b = sprinti (b, mac[0]);
      b = sprintc (b, '.');
      b = sprinti (b, mac[1]);
      b = sprintc (b, '.');
      b = sprinti (b, mac[2]);
      b = sprintc (b, '.');
      b = sprinti (b, mac[3]);
      b = sprintc (b, '\n');

      b = sprints (b, t_dest);
      r = bra_seek_head (buf_A (), T_BRA_SRC);
      b = sprinti (b, r[0]);
      b = sprintc (b, '.');
      b = sprinti (b, r[1]);
      b = sprintc (b, '.');
      b = sprinti (b, r[2]);
      b = sprintc (b, '.');
      b = sprinti (b, r[3]);
      b = sprintc (b, '\n');

      r = bra_seek_head (buf_A (), T_BRA_DATA);
      b = sprints (b, t_tx_q);
      b = sprintch (b, r[0]);
      b = sprintch (b, r[1]);
      b = sprintc (b, '\n');

      b = sprints (b, t_rx_q);
      b = sprintch (b, q);
      b = sprintch (b, q >> 8);
      b = sprintc (b, '\n');

      b = sprintc (b, '\0');
      r = display_text_raw (buf_B (), Q_DISPLAY_TEXT_DELAY_CLEAR);
    }
    else
      r = display_text_raw (t_No_Link, Q_DISPLAY_TEXT_DELAY_CLEAR);
    l = get_tag (r, T_RESULT);
    if (l != 0)
    {
      l++;
      l++;
      if (r[l] == 0x10 || r[l] == 0x11)
        return APP_BACK;
    }

    goto X1;
  }
  return APP_OK;
}

/* *INDENT-OFF* */
SNodeP ping_n = { lc_Ping, NULL };
SNodeP ping_ping_n = { lc_Ping, ping_ping };
SNodeP ping_freq_n = { lc_Freq, ping_freq };
SNodeP ping_channel_n = { lc_Channel, ping_channel };
SNodeP ping_pwr_n = { lc_Pwr, ping_pwr };
SNodeP ping_cc2420_n = { lc_CC2420, NULL };
SNodeP ping_cc2420_read_n = { lc_Read, ping_cc2420_read };
SNodeP ping_cc2420_write_n = { lc_Write, ping_cc2420_write };


SEdgeP ping_edges_p[] = {
  {&ping_n, &ping_ping_n},
  {&ping_n, &ping_pwr_n},
  {&ping_n, &ping_freq_n},
  {&ping_n, &ping_channel_n},
  {&ping_n, &ping_cc2420_n},
  {&ping_cc2420_n, &ping_cc2420_read_n},
  {&ping_cc2420_n, &ping_cc2420_write_n},
  NULL
};
/* *INDENT-ON* */

void action_menu (void *data)
{
  SCtx *c;

  c = spider_init ();
  c->n = &ping_n;
  c->eP = &ping_edges_p;

  spider (c);
}

void turbo_handler (u8 action, void *data)
{
  switch (action)
  {
    case ACTION_INSERT_MENU:
      insert_menu (locale (lc_Ping));
      break;
    case ACTION_MENU_SELECTION:
      stk_thread (action_menu, data);
      break;
    default:
      break;
  }
}


Copyright © 2004-2006 BLADOX
Turbo version 1.2