Skip to content

Libraries and firmware for OpenBCI Radio Modules

License

Notifications You must be signed in to change notification settings

OpenBCI/OpenBCI_Radios

Repository files navigation

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:

  • OPENBCI_MODE_DEVICE - Radio operates in DEVICE mode. Intended to be a RFduino on the OpenBCI Board when not in debug mode.
  • OPENBCI_MODE_HOST - Radio operates in HOST mode. Intended to be an RFduino on an OpenBCI dongle.
  • OPENBCI_MODE_PASS_THRU - Pass through FTDI driver from Host to Device

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:

  • OPENBCI_MODE_DEVICE - Radio operates in DEVICE mode. Intended to be a RFduino on the OpenBCI Board when not in debug mode.
  • OPENBCI_MODE_HOST - Radio operates in HOST mode. Intended to be an RFduino on an OpenBCI dongle.
  • OPENBCI_MODE_PASS_THRU - Pass through FTDI driver from Host to Device

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:

  • OPENBCI_MODE_DEVICE - Radio operates in DEVICE mode. Intended to be a RFduino on the OpenBCI Board when not in debug mode.
  • OPENBCI_MODE_HOST - Radio operates in HOST mode. Intended to be an RFduino on an OpenBCI dongle.
  • OPENBCI_MODE_PASS_THRU - Pass through FTDI driver from Host to Device

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

  • _code_ {uint8_t} - The code to Serial.write().
    • HOST_MSG_COMMS_DOWN - Print the comms down message
    • HOST_MESSAGE_COMMS_DOWN_CHAN - Print the message when the comms when down trying to change channels.
    • HOST_MESSAGE_COMMS_DOWN_POLL_TIME - Print the message when the comms go down trying to change poll times.
    • HOST_MSG_BAUD_FAST - Baud rate switched to 230400
    • HOST_MSG_BAUD_DEFAULT - Baud rate switched to 115200
    • HOST_MSG_BAUD_HYPER - Baud rate switched to 921600
    • HOST_MSG_SYS_UP - Print the system up message
    • HOST_MSG_SYS_DOWN - Print the system down message
    • HOST_MSG_CHAN - Print the channel number message
    • HOST_MSG_CHAN_OVERRIDE - Print the host over ride message
    • HOST_MSG_CHAN_VERIFY - Print the need to verify the channel number you inputed message
    • HOST_MSG_CHAN_GET_FAILURE - The message to print when there is a comms timeout and to print just the Host channel number.
    • HOST_MSG_CHAN_GET_SUCCESS - The message to print when the Host and Device are communicating.
    • HOST_MSG_POLL_TIME - Prints the poll time when there is no comms.
    • HOST_MESSAGE_SERIAL_ACK - Writes a serial ack (',') to the Driver/PC

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.