/*
 Copyright (C) 2012 J. Coliz <maniacbug@ymail.com>

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 version 2 as published by the Free Software Foundation.
 */

/**
 * Example Nordic FOB Receiver 
 *
 * This is an example of how to use the RF24 class to receive signals from the
 * Sparkfun Nordic FOB.  Thanks to Kirk Mower for providing test hardware.
 *
 * See blog post at http://maniacbug.wordpress.com/2012/01/08/nordic-fob/
 */

#include <SPI.h>
#include <RF24.h>
#include "nRF24L01.h"
#include "printf.h"

//
// Hardware configuration
//

// Set up nRF24L01 radio on SPI bus plus pins 9 & 10

RF24 radio(53,52);

//
// Payload
//

struct payload_t
{
  uint8_t buttons;
  uint16_t id;
  uint8_t empty;
};

const char* button_names[] = { "Up", "Down", "Left", "Right", "Center" }; 
const int num_buttons = 5;

//
// Forward declarations
//

uint16_t flip_endian(uint16_t in);

//
// Setup
//

void setup(void)
{
  //
  // Print preamble
  //

  Serial.begin(57600);
  printf_begin();
  printf("\r\nRF24/examples/nordic_fob/\r\n");

  //
  // Setup and configure rf radio according to the built-in parameters
  // of the FOB.
  //

  radio.begin();
  radio.setChannel(2);
  radio.setPayloadSize(4);
  radio.setAutoAck(false);
  radio.setCRCLength(RF24_CRC_8);
  radio.openReadingPipe(1,0xE7E7E7E7E7LL);

  //
  // Start listening
  //

  radio.startListening();

  //
  // Dump the configuration of the rf unit for debugging
  //

  radio.printDetails();
}

//
// Loop
//

void loop(void)
{
  //
  // Receive each packet, dump it out
  //

    // if there is data ready
    if ( radio.available() )
    {
      // Get the packet from the radio
      payload_t payload;
      radio.read( &payload, sizeof(payload) );

      // Print the ID of this message.  Note that the message
      // is sent 'big-endian', so we have to flip it.
      printf("#%05u Buttons ",flip_endian(payload.id));

      // Print the name of each button 
      int i = num_buttons;
      while (i--)
      {
	if ( ! ( payload.buttons & _BV(i) ) )
	{
	  printf("%s ",button_names[i]);
	}
      }

      // If no buttons, print None
      if ( payload.buttons == _BV(num_buttons) - 1 )
	printf("None");

      printf("\r\n");
    }
}

//
// Helper functions
//

// Change a big-endian word into a little-endian
uint16_t flip_endian(uint16_t in)
{
  uint16_t low = in >> 8;
  uint16_t high = in << 8;

  return high | low;
}

// vim:cin:ai:sts=2 sw=2 ft=cpp
