OpenBCI / OpenBCI_Radios

Libraries and firmware for OpenBCI Radio Modules
MIT License
18 stars 21 forks source link
firmware openbci

Stories in Ready Join the chat at https://gitter.im/OpenBCI/openbci-js-sdk

OpenBCI_Radios

Libraries and firmware for OpenBCI Radio Modules.

General Overview

The OpenBCI board has an on-board RFDuino radio module acting as a "Device". The OpenBCI system includes a USB dongle for the PC, which acts as the RFDuino "Host". The format of the OpenBCI data as seen on the PC is defined by a combination of the Arduino code on the OpenBCI board and of the RFDuino code running on the Host.

For a general discussion of the OpenBCI Radio firmware please refer to software section on the learning pages on openbci.com.

IMPORTANT: The channelNumber will be stored into memory the first and only time from the begin() function into memory. Why? As of firmware v2 channels can be changed over the air, that required us to retain the channel number during power cycle periods, i.e. turning the boards on and off. See our learning docs for the commands on how to change the channels over the air. Our main Processing GUI also contains tools to change channels along with a config utility just for this purpose.

Installation

For detailed installation and upload instructions please refer to our learning section on openbci.com.

Developing

Running Tests

Before we begin, let's declare there are two types of testing, functional and unit testing. The unit testing for this library uses the PTW-Arduino-Assert framework. The functional testing is completed with the OpenBCI_NodeJS libraries extensive automated testing that will functionally verify all components of the entire system.

This library is heavily dependent on automated testing. Thus this library uses the Push The World Arduino Test Framework which you must install to your libraries folder in order to run the automated tests.

Contributing

Contributions are more then welcomed, they are encouraged!

Contribute to the library

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Make changes and ensure tests all pass, add tests if able.
  4. Commit your changes: git commit -m 'Add some feature'
  5. Push to the branch: git push origin my-new-feature
  6. Submit a pull request :D

Reference Guide

Functions

begin(mode)

The function that the radio will call in setup()

mode - unint8_t

The mode the radio shall operate in, can be:

begin(mode, channelNumber)

The function that the radio will call in setup() with radio channelNumber. NOTE channelNumber is stored to non-volatile memory! More about this in a couple lines.

mode - unint8_t

The mode the radio shall operate in, can be:

channelNumber - uint32_t

The channelNumber the RFduinoGZLL will use to communicate with the other RFduinoGZLL. NOTE can only be from 0 to 25 inclusive. Further, and this is really important channelNumber will only be stored into memory on the first time this function is executed.

beginDebug(mode, channelNumber)

The function that the radio will call in setup() with radio channelNumber. This puts the system in dongle to dongle debug mode. During the development of this NOTE channelNumber is stored to non-volatile memory! More about this in a couple lines.

mode - unint8_t

The mode the radio shall operate in, can be:

channelNumber - uint32_t

The channelNumber the RFduinoGZLL will use to communicate with the other RFduinoGZLL. NOTE can only be from 0 to 25 inclusive. Further, and this is really important channelNumber will only be stored into memory on the first time this function is executed.

bufferAddStreamPacket(buf)

Moves bytes from StreamPacketBuffers to the main radio buffer.

buf - StreamPacketBuffer *

A buffer to read into the ring buffer

bufferRadioClean()

Used to fill the buffer with all zeros. Should be used as frequently as possible. This is very useful if you need to ensure that no bad data is sent over the serial port.

bufferRadioFlush()

Called when all the packets have been received to flush the contents of the radio buffer to the serial port.

bufferRadioFlushBuffers()

Used to flush any radio buffer that is ready to be flushed to the serial port. For now flushes just bufferRadio and bufferRadioBackUp on the Host.

bufferRadioHasData()

Used to determine if there is data in the radio buffer. Most likely this data needs to be cleared.

Returns {boolean}

true if the radio buffer has data, false if not...

bufferRadioReset()

Used to reset the flags and positions of the radio buffer.

bufferSerialAddChar(newChar)

Stores a char to the serial buffer. Used by both the Device and the Host. Protects the system from buffer overflow.

newChar - {char}

The new char to store to the serial buffer.

Returns - {boolean}

true if the new char was added to the serial buffer, false if not.

bufferSerialHasData()

If there are packets to be sent in the serial buffer.

Returns - {boolean}

true if there are packets waiting to be sent from the serial buffer, false if not...

bufferSerialProcessCommsFailure()

Used to process the the serial buffer if the device fails to poll the host more than 3 * pollTime. This function should process the serial buffer for a Host channel change override and channel get request. Further this function should clear the serial buffer if there is anything inside it. In the special circumstances where the Host is waiting for either a channel change confirmation or a poll time change confirmation Should also revert to the pervious channel number

bufferSerialReset(n)

Function to clean (clear/reset) the bufferSerial.

n - uint8_t

The number of packets you want to clean, for example, on init, we would clean all packets, but on cleaning from the RFduinoGZLL_onReceive() we would only clean the number of packets actually used.

bufferSerialTimeout()

Based off the last time the serial port was read from, Determines if enough time has passed to qualify this data as a full serial page.

Returns - {boolean}

true if enough time has passed, false if not.

bufferStreamAddChar(buf, newChar)

Process a char from the serial port on the Device. Enters the char into the stream state machine.

buf - StreamPacketBuffer *

The stream packet buffer to add the char to.

newChar - char

A new char to process.

bufferStreamReadyToSendToHost(buf)

Utility function to return true if the the streamPacketBuffer is in the STREAM_STATE_READY. Normally used for determining if a stream packet is ready to be sent.

buf - StreamPacketBuffer *

The stream packet buffer to send to the Host.

Returns - {boolean}

true is the buf is in the ready state, false otherwise.

bufferStreamReset()

Resets the first stream packet buffer to default settings.

bufferStreamReset(buf)

Resets the stream packet buffer to default settings

buf - StreamPacketBuffer *

Pointer to a stream packet buffer to reset.

bufferStreamSendToHost(buf)

Sends the contents of the buf to the HOST, sends as stream packet with the proper byteId.

buf - StreamPacketBuffer *

Pointer to a stream packet buffer to be sent to the Host.

bufferStreamTimeout()

Based off the last time the serial port was read from, Determines if enough time has passed to qualify this data as a stream packet.

Returns - {boolean}

true if enough time has passed, false if not.

commsFailureTimeout()

The first line of defense against a system that has lost it's device. The timeout is 15ms longer than the longest poll time (255ms) possible.

Returns {boolean}

true if enough time has passed since last poll, false if not...

didPCSendDataToHost()

Private function to handle a request to read serial as a host

Returns {boolean}

true if there is data to read, false if not...

flashNonVolatileMemory()

Used to reset the non-volatile memory back to it's factory state so the parameters in begin() will be accepted.

Returns {boolean}

true if the memory was successfully reset, false if not...

getChannelNumber()

Gets the channel number from non-volatile flash memory

Returns {uint32_t}

The channel number from non-volatile memory

getPollTime()

Gets the poll time from non-volatile flash memory

Returns {uint32_t}

The poll time from non-volatile memory

hostPacketToSend()

Answers the question of if a packet is ready to be sent. need to check and there is no packet in the TX Radio Buffer, there are in fact packets to send and enough time has passed.

Returns {boolean}

true if there is a packet ready to send on the Host

ledFeedBackForPassThru()

Used to flash the led to indicate to the user the device is in pass through mode.

packetToSend()

Used to determine if there are packets in the serial buffer to be sent.

Returns {boolean}

true if there are packets in the buffer and enough time has passed

packetsInSerialBuffer()

Used to determine if there are packets in the serial buffer to be sent.

Returns {boolean}

true if there are packets in the buffer

pollRefresh()

Reset the time since the last packet was sent to HOST. Very important with polling.

printMessageToDriver(code)

Writes to the serial port a message that matches a specific code.

code

processDeviceRadioCharData(data, len)

Entered from RFduinoGZLL_onReceive if the Device receives a packet of length greater than 1.

data - {volatile char * }

The data buffer to process.

len - {int}

The length of data

Returns - {boolean}

true if there is a packet to send to the Host.

processHostRadioCharData(device, data, len)

Entered from RFduinoGZLL_onReceive if the Host receives a packet of length greater than 1.

device - {device_t}

The device that sent a packet to the Host.

data - {volatile char * }

The data buffer to process.

len - {int}

The length of data

Returns - {boolean}

true if there is a packet to send to the Device.

processRadioCharDevice(newChar)

Used to process a single char message received on the Device radio aka a private radio message. See OpenBCI_Radios_Definitions.h for a full list of ORPMs.

newChar - {char}

The char to be read in.

Returns - {boolean}

true if a packet should be sent from the serial buffer.

processRadioCharHost(newChar)

Used to process a single char message received on the Host radio aka a private radio message. See OpenBCI_Radios_Definitions.h for a full list of ORPMs.

newChar - {char}

The char to be read in.

Returns - {boolean}

true if a packet should be sent from the serial buffer.

resetPic32()

Sends a soft reset command to the Pic 32 incase of an emergency.

sendPacketToDevice(device)

Called from Host's RFduinoGZLL_onReceive if a packet will be sent.

device - {device_t}

The device to send the packet to.

sendPacketToHost()

Called from Devices to send a packet to Host. Uses global variables to send the correct packet.

Returns - {int}

The packet number sent.

sendPollMessageToHost()

Sends a null byte to the host.

serialWriteTimeOut()

Used to see if enough time has passed since the last serial read. Useful to if a serial transmission from the PC/Driver has concluded.

Returns - {boolean}

true if enough time has passed.