Andriy Makukha / Mbed 2 deprecated football_project_wo_output

Dependencies:   mbed

Fork of football_project by MZJ

Radio.cpp

Committer:
AntonLS
Date:
2016-01-14
Revision:
52:060fdec99780
Parent:
44:4ad6133987ed
Child:
62:9b34dc1b265d

File content as of revision 52:060fdec99780:

#include <RFM69.h>
#include <SPI.h>
#include "types.h"
#include "TA.h"

#define RADIO_STARTUP_ID 99
#define NETWORKID     101   //the same on all nodes that talk to each other

#define FREQUENCY     RF69_915MHZ

//#define IS_RFM69HW   //NOTE: uncomment this ONLY for RFM69HW or RFM69HCW
#define ENCRYPT_KEY    "EncryptKey123456"  // use same 16byte encryption key for all devices on net
#define ACK_TIME       50                  // max msec for ACK wait
#define LED            9                   // Anardino miniWireless has LEDs on D9
#define SERIAL_BAUD    115200
#define VERSION  "1.0"

#define MSGBUFSIZE 64   // message buffersize, but for this demo we only use: 
                        // 1-byte NODEID + 4-bytes for time + 1-byte for temp in C + 2-bytes for vcc(mV)

//RFM69::RFM69(PinName  PinName mosi, PinName miso, PinName sclk,slaveSelectPin, PinName int)
RFM69 radio(P0_24,P0_23,P0_25,P0_28,P0_7);

static bool promiscuousMode = true; // set 'true' to sniff all packets on the same network
extern "C" void writeToPhone(char *format, ...);
extern unsigned long millis();

#ifdef MASTER
static bool is_master = true;
#else
static bool is_master = false;
#endif

static int my_node_id = NODE_ID;

struct node_id_mapping
{
    int mac;
    int node_id;     
};

struct extended_message
{
    Message m;
    int mac;    
};

static node_id_mapping nodes[10] = {0};
static int node_idx = 0;
static int my_mac = 0;

void radio_init()
{
  radio.initialize(FREQUENCY, my_node_id, NETWORKID);
  radio.encrypt(0);
  radio.promiscuous(promiscuousMode);
}

static int get_node_id(int mac)
{
    for (int i = 0; i < node_idx; ++i)
    {
        if (nodes[i].mac == mac)
        {
            return nodes[i].node_id;    
        }    
    }
    
    return 0;    
}

static void slave_process(extended_message *em)
{
    if (em->m.command == 'R')
    {
        // We have been given a node id
        my_node_id = em->m.value;
        
        if( Dbg )  writeToPhone("NID: %d\r\n", my_node_id);
        
        // Now reset the radio :)
        radio_init();
    }
}

static void master_process(Message *m)
{
    byte payload[10] = {0};
    int node_id = 0;
    
    if (m->command == 'S')
    {
        // Message from a cone requesting an ID.
        // The payload should be part of the MAC address
        node_id = 0;
        
        if (node_idx == 0)
        {
            node_id = 2;   
        }
        else
        {
            node_id = nodes[node_idx-1].node_id + 1;
        }
        
        int node_found = get_node_id(m->value);
   
        if (node_found == 0)
        {
            nodes[node_idx].node_id = node_id;
            nodes[node_idx++].mac   = m->value; 
        }
        else
        {
            node_id = node_found;    
        }
        
        // Send the cone it's ID
        extended_message em;
        em.m.cone    = 99;
        em.m.command = 'R';
        em.m.value   = node_id;
        em.mac       = m->value;
        
        payload[0] = (byte)em.m.command;
        
        payload[4] = (byte)em.m.value & 255;
        payload[3] = (byte)(em.m.value >> 8);
        payload[2] = (byte)(em.m.value >> 16);
        payload[1] = (byte)(em.m.value >> 24);
        
        payload[8] = (byte)em.mac & 255;
        payload[7] = (byte)(em.mac >> 8);
        payload[6] = (byte)(em.mac >> 16);
        payload[5] = (byte)(em.mac >> 24);
        
        radio.send(em.m.cone, payload, sizeof(payload));
        
        if( Dbg )  writeToPhone("SND: %d %d 0x%x\r\n", em.m.cone, node_id, em.mac);
    }
}

void radio_send(Message *m)
{
    static byte payload [6] = {0};
 
    if (m == NULL)
    {
        return;    
    }
    
    //if( Dbg )  writeToPhone("SM: %c to: %d frm: %d (%d)\r\n", m->command, m->cone, NODE_ID, m->value);

    payload[0] = (byte)m->command;
    
    payload[4] = (byte)m->value & 255;
    payload[3] = (byte)(m->value >> 8);
    payload[2] = (byte)(m->value >> 16);
    payload[1] = (byte)(m->value >> 24);
    
    payload[5] = (byte)'%';
 
    radio.send(m->cone, payload, sizeof(payload));     
}

bool radio_receive_complete()
{
    return radio.receiveDone();    
}

bool radio_receive(Message *m)
{
    Message lm;
    extended_message em;
    
    if (m == NULL)
    {
        return false;    
    }
    
    if (radio.receiveDone())
    {   
        if (radio.DATALEN < 6)
        {
            return false;    
        }
        
        lm.cone     = radio.SENDERID;
        lm.command  = radio.DATA[0];
            
        lm.value    = ((int)radio.DATA[1] << 24);
        lm.value   |= ((int)radio.DATA[2] << 16);
        lm.value   |= (((int)radio.DATA[3]) << 8);
        lm.value   |= (radio.DATA[4]);
        
        if (is_master && lm.command == 'S')
        {
            // Don't pass on radio startup messages
            master_process(&lm);    
            return false;
        }
        else if (!is_master && radio.TARGETID == RADIO_STARTUP_ID)
        {
            
            em.mac  = (int)radio.DATA[8] & 0xff;
            em.mac |= (int)radio.DATA[7] << 8;
            em.mac |= (int)radio.DATA[6] << 16;
            em.mac |= (int)radio.DATA[5] << 24;
            
            if( Dbg )  writeToPhone("RP: 0x%x\r\n", em.mac);
            
            if (em.mac != my_mac)
            {
                if( Dbg )  writeToPhone("DM 0x%x\r\n", em.mac);
                return false; // This message was meant for someone else
            }
            
            memcpy(&em.m, &lm, sizeof(Message));
            slave_process(&em);    
            
        }
        else if (radio.TARGETID == my_node_id)
        {
            memcpy(m, &lm, sizeof(Message));
            
            if( Dbg )  writeToPhone("GM: %d %c %d\r\n", radio.SENDERID, m->command, m->value);

            return true;
        }
    }
    
    return false;
}

bool radio_ack_received(int cone)
{
    return radio.ACKReceived(cone);
}

void radio_loop(int mac)
{
    static unsigned long last_send = 0L;
    unsigned long current = millis();
    Message m;
    
    if (my_mac == 0)
    {
        my_mac = mac;    
    }
    
    if (is_master)
    {
        return; // Only needed for slave cones    
    }
    
    if (my_node_id != RADIO_STARTUP_ID && current - last_send > 1000L)
    {
        if( Dbg )  writeToPhone("NID: %d\r\n", my_node_id);
        last_send = current;
    }
    
    // Send out an i'm here message
    if (my_node_id != RADIO_STARTUP_ID || current - last_send < 1000L)
    {
        return;
    }
    
    m.command = 'S';
    m.cone    = 1;
    m.value   = my_mac;
    
    if( Dbg )  writeToPhone("SNM\r\n");
    
    last_send = current;
    
    radio_send(&m);
}