crashtest-r0ket/misc/openbeacon/lpc13xx/openbeacon-usb2/src/main.c

385 lines
9.0 KiB
C

/***************************************************************
*
* OpenBeacon.org - main file for OpenBeacon USB II Bluetooth
*
* Copyright 2010 Milosch Meriac <meriac@openbeacon.de>
*
***************************************************************
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <openbeacon.h>
#include "pin.h"
#include "hid.h"
#include "spi.h"
#include "iap.h"
#include "pmu.h"
#include "crc16.h"
#include "xxtea.h"
#include "bluetooth.h"
#include "storage.h"
#include "nRF_API.h"
#include "nRF_CMD.h"
#include "openbeacon-proto.h"
#include "display.h"
/* OpenBeacon packet */
static TBeaconEnvelope g_Beacon;
/* Default TEA encryption key of the tag - MUST CHANGE ! */
static const uint32_t xxtea_key[4] =
//{ 0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF };
{ 0xb4595344, 0xd3e119b6, 0xa814d0ec, 0xeff5a24e };
/* set nRF24L01 broadcast mac */
static const unsigned char broadcast_mac[NRF_MAX_MAC_SIZE] =
{ 1, 2, 3, 2, 1 };
/* device UUID */
static uint16_t tag_id;
static TDeviceUID device_uuid;
#if (USB_HID_IN_REPORT_SIZE>0)||(USB_HID_OUT_REPORT_SIZE>0)
static uint8_t hid_buffer[USB_HID_IN_REPORT_SIZE];
void
GetInReport (uint8_t * src, uint32_t length)
{
(void) src;
(void) length;
if (length > USB_HID_IN_REPORT_SIZE)
length = USB_HID_IN_REPORT_SIZE;
memcpy (src, hid_buffer, length);
}
void
SetOutReport (uint8_t * dst, uint32_t length)
{
(void) dst;
(void) length;
}
#endif
static void show_version(void)
{
debug_printf(" * Tag ID: %i\n", (uint16_t) device_uuid[3]);
debug_printf(" * Device UID: %08X:%08X:%08X:%08X\n", device_uuid[0],
device_uuid[1], device_uuid[2], device_uuid[3]);
debug_printf(" * free heap memory: %i bytes\n",xPortGetFreeHeapSize());
}
void main_menue(uint8_t cmd)
{
/* ignore non-printable characters */
if (cmd <= ' ')
return;
/* show key pressed */
debug_printf("%c\n", cmd);
/* map lower case to upper case */
if (cmd > 'a' && cmd < 'z')
cmd -= ('a' - 'A');
switch (cmd)
{
case '?':
case 'H':
debug_printf("\n"
" *****************************************************\n"
" * OpenBeacon USB II - Bluetooth Console *\n"
" * (C) 2010 Milosch Meriac <meriac@openbeacon.de> *\n"
" *****************************************************\n"
" * H,? - this help screen\n"
#ifdef MENUE_ALLOW_ISP_REBOOT
" * P - invoke ISP programming mode\n"
#endif
" * S - show device status\n"
" * R - OpenBeacon nRF24L01 register dump\n"
" *****************************************************\n"
"\n");
break;
#ifdef MENUE_ALLOW_ISP_REBOOT
case 'P':
debug_printf ("\nRebooting...");
iap_invoke_isp ();
break;
#endif
case 'R':
nRFCMD_RegisterDump();
break;
case 'S':
debug_printf("\n"
" *****************************************************\n"
" * OpenBeacon Status Information *\n"
" *****************************************************\n");
show_version();
spi_status();
nRFCMD_Status();
// pmu_status ();
#if (DISK_SIZE>0)
storage_status();
#endif
nRFCMD_Status();
debug_printf(" *****************************************************\n"
"\n");
break;
default:
debug_printf("Unknown command '%c' - please press 'H' for help \n", cmd);
}
debug_printf("\n# ");
}
static
void nRF_tx(uint8_t power)
{
/* update crc */
g_Beacon.pkt.crc = htons(crc16(g_Beacon.byte, sizeof(g_Beacon)
- sizeof(uint16_t)));
/* encrypt data */
xxtea_encode(g_Beacon.block, XXTEA_BLOCK_COUNT, xxtea_key);
pin_led(GPIO_LED0);
/* update power pin */
nRFCMD_Power(power & 0x4);
/* disable RX mode */
nRFCMD_CE(0);
vTaskDelay(5 / portTICK_RATE_MS);
/* switch to TX mode */
nRFAPI_SetRxMode(0);
/* set TX power */
nRFAPI_SetTxPower(power & 0x3);
/* upload data to nRF24L01 */
nRFAPI_TX(g_Beacon.byte, sizeof(g_Beacon));
/* transmit data */
nRFCMD_CE(1);
/* wait until packet is transmitted */
vTaskDelay(2 / portTICK_RATE_MS);
/* switch to RX mode again */
nRFAPI_SetRxMode(1);
pin_led(GPIO_LEDS_OFF);
if (power & 0x4)
nRFCMD_Power(0);
}
static
void nRF_Task(void *pvParameters)
{
int t, active;
uint8_t strength, status;
uint16_t crc;
uint32_t seq, oid;
portTickType LastUpdateTicks, Ticks;
(void) pvParameters;
/* Initialize OpenBeacon nRF24L01 interface */
if (!nRFAPI_Init(81, broadcast_mac, sizeof(broadcast_mac), 0))
/* bail out if can't initialize */
for (;;)
{
pin_led(GPIO_LED0 | GPIO_LED1);
vTaskDelay(500 / portTICK_RATE_MS);
pin_led(GPIO_LEDS_OFF);
vTaskDelay(500 / portTICK_RATE_MS);
}
/* blink as a sign of boot to detect crashes */
for (t = 0; t < 20; t++)
{
pin_led(GPIO_LED0);
vTaskDelay(50 / portTICK_RATE_MS);
pin_led(GPIO_LEDS_OFF);
vTaskDelay(50 / portTICK_RATE_MS);
}
nRFAPI_SetRxMode(1);
nRFCMD_CE(1);
LastUpdateTicks = xTaskGetTickCount();
/* main loop */
active = 0;
seq = t = 0;
UARTCount = 0;
while (1)
{
/* turn off after button press */
if (!pin_button0())
{
pin_mode_pmu(0);
pmu_off(0);
}
if (nRFCMD_WaitRx(10 / portTICK_RATE_MS))
do
{
// read packet from nRF chip
nRFCMD_RegReadBuf(RD_RX_PLOAD, g_Beacon.byte, sizeof(g_Beacon));
// adjust byte order and decode
xxtea_decode(g_Beacon.block, XXTEA_BLOCK_COUNT, xxtea_key);
// verify the CRC checksum
crc = crc16(g_Beacon.byte, sizeof(g_Beacon) - sizeof(uint16_t));
if (ntohs (g_Beacon.pkt.crc) == crc)
{
pin_led(GPIO_LED1);
oid = ntohs (g_Beacon.pkt.oid);
if (((g_Beacon.pkt.flags & RFBFLAGS_SENSOR) > 0) && active)
debug_printf("BUTTON: %i\n", oid);
switch (g_Beacon.pkt.proto)
{
case RFBPROTO_READER_ANNOUNCE:
strength = g_Beacon.pkt.p.reader_announce.strength;
break;
case RFBPROTO_BEACONTRACKER:
strength = g_Beacon.pkt.p.tracker.strength;
if (active)
debug_printf(" R: %04i={%i,0x%08X}\n", (int) oid,
(int) strength,
ntohl (g_Beacon.pkt.p.tracker.seq));
break;
case RFBPROTO_PROXREPORT:
strength = 3;
if (active)
debug_printf(" P: %04i={%i,0x%04X}\n", (int) oid,
(int) strength,
(int) ntohs (g_Beacon.pkt.p.prox.seq));
for (t = 0; t < PROX_MAX; t++)
{
crc = (ntohs (g_Beacon.pkt.p.prox.oid_prox[t]));
if (crc && active)
debug_printf("PX: %04i={%04i,%i,%i}\n",
(int) oid, (int) ((crc >> 0) & 0x7FF),
(int) ((crc >> 14) & 0x3), (int) ((crc
>> 11) & 0x7));
}
break;
default:
strength = 0xFF;
if (active)
debug_printf("Unknown Protocol: %i\n",
(int) g_Beacon.pkt.proto);
}
if (strength < 0xFF)
{
/* do something with the data */
}
pin_led(GPIO_LEDS_OFF);
}
status = nRFAPI_GetFifoStatus();
} while ((status & FIFO_RX_EMPTY) == 0);
nRFAPI_ClearIRQ(MASK_IRQ_FLAGS);
// update regularly
if (((Ticks = xTaskGetTickCount()) - LastUpdateTicks)
> UPDATE_INTERVAL_MS)
{
LastUpdateTicks = Ticks;
/* setup tracking packet */
bzero(&g_Beacon, sizeof(g_Beacon));
g_Beacon.pkt.oid = ntohs ((uint16_t)device_uuid[3]);
g_Beacon.pkt.proto = RFBPROTO_BEACONTRACKER;
g_Beacon.pkt.p.tracker.strength = seq % 8;
g_Beacon.pkt.p.tracker.seq = htonl(seq++);
/* send away packet */
nRF_tx(g_Beacon.pkt.p.tracker.strength);
}
if (UARTCount)
{
/* blink LED1 upon Bluetooth command */
pin_led(GPIO_LED1);
/* show help screen upon Bluetooth connect */
if (!active)
{
active = 1;
debug_printf("press 'H' for help...\n# ");
}
else
/* execute menu command with last character received */
main_menue(UARTBuffer[UARTCount - 1]);
/* LED1 off again */
pin_led(GPIO_LEDS_OFF);
/* clear UART buffer */
UARTCount = 0;
}
}
}
int main(void)
{
volatile int i;
/* wait on boot - debounce */
for (i = 0; i < 2000000; i++)
;
//pmu_off(0);
lcdInit();
/* initialize pins */
pin_init();
/* Init SPI */
spi_init();
/* Init Storage */
#ifdef USB_DISK_SUPPORT
storage_init();
#endif
/* Init USB HID interface */
#if (USB_HID_IN_REPORT_SIZE>0)||(USB_HID_OUT_REPORT_SIZE>0)
hid_init ();
#error hid
#endif
/* power management init */
pmu_init();
/* read device UUID */
bzero(&device_uuid, sizeof(device_uuid));
iap_read_uid(&device_uuid);
tag_id = crc16((uint8_t*) &device_uuid, sizeof(device_uuid));
xTaskCreate(nRF_Task, (const signed char*) "nRF", TASK_NRF_STACK_SIZE,
NULL, TASK_NRF_PRIORITY, NULL);
/* Start the tasks running. */
vTaskStartScheduler();
return 0;
}