Jonathan Jones
/
Radios
Radio Structures in OOP
modules/CommModule/CommModule.cpp
- Committer:
- jjones646
- Date:
- 2015-01-15
- Revision:
- 6:4a3dbfbc30f1
- Parent:
- 5:146523a0d1f4
File content as of revision 6:4a3dbfbc30f1:
#include "CommModule.h" // Set the class's constants for streamlined use in other areas of the code const int CommModule::TX_QUEUE_SIZE = COMM_MODULE_TX_QUEUE_SIZE; const int CommModule::RX_QUEUE_SIZE = COMM_MODULE_RX_QUEUE_SIZE; const int CommModule::NBR_PORTS = COMM_MODULE_NBR_PORTS; // Default constructor CommModule::CommModule() : // [X] - 1.1 - Define the data queues. // ================= _txQueueHelper(), _rxQueueHelper() { // [X] - 1.2 - Create the data queues. // ================= _txQueue = osMailCreate(_txQueueHelper.def(), NULL); _rxQueue = osMailCreate(_rxQueueHelper.def(), NULL); // [X] - 2.1 - Define the TX & RX task threads. // ================= define_thread(_txDef, &CommModule::txThread); define_thread(_rxDef, &CommModule::rxThread); // [X] - 2.2 - Create the TX & RX threads - pass them a pointer to the created object. // ================= _txID = osThreadCreate(&_txDef, (void*)this); _rxID = osThreadCreate(&_rxDef, (void*)this); _txH_called = false; } CommModule::~CommModule() { if (_open_ports) delete _open_ports; } void CommModule::txThread(void const *arg) { CommModule *inst = (CommModule*)arg; // Only continue past this point once at least one (1) hardware link is initialized osSignalWait(COMM_MODULE_SIGNAL_START_THREAD, osWaitForever); LOG("TX Ready!\r\n"); while(1) { // When a new RTP packet is put in the tx queue, begin operations (does nothing if no new data in queue) osEvent evt = osMailGet(inst->_txQueue, osWaitForever); if (evt.status == osEventMail) { // Get a pointer to the packet's memory location RTP_t *p = (RTP_t*)evt.value.p; // Send the packet on the active communication link inst->_tx_handles[p->port].call(p); EVENT("Transmission: Port: %u Subclass: %u\r\n", p->port, p->subclass); // Release the allocated memory once data is sent osMailFree(inst->_txQueue, p); } } } void CommModule::rxThread(void const *arg) { CommModule *inst = (CommModule*)arg; // Only continue past this point once at least one (1) hardware link is initialized osSignalWait(COMM_MODULE_SIGNAL_START_THREAD, osWaitForever); LOG("RX Ready!\r\n"); RTP_t *p; osEvent evt; while(1) { // Wait until new data is placed in the class's rxQueue from a CommLink class evt = osMailGet(inst->_rxQueue, osWaitForever); if (evt.status == osEventMail) { DigitalOut led(LED4, 1); // get a pointer to where the data is stored p = (RTP_t*)evt.value.p; // If there is an open socket for the port, call it. if (std::binary_search(inst->_open_ports->begin(), inst->_open_ports->end(), p->port)) { inst->_rx_handles[p->port].call(); } EVENT("Reception: \r\n Port: %u\r\n Subclass: %u\r\n", p->port, p->subclass); osMailFree(inst->_rxQueue, p); // free memory allocated for mail } } } void CommModule::TxHandler(void(*ptr)(RTP_t*), uint8_t portNbr) { _txH_called = true; ready(); _tx_handles[portNbr].attach(ptr); } void CommModule::RxHandler(void(*ptr)(RTP_t*), uint8_t portNbr) { ready(); _rx_handles[portNbr].attach(ptr); } void CommModule::RxHandler(void(*ptr)(void), uint8_t portNbr) { ready(); _rx_handles[portNbr].attach(ptr); } void CommModule::openSocket(CommLink *link, void(*rx)(void const *arg), uint8_t portNbr) { ready(); if (_txH_called) { if (std::binary_search(_open_ports->begin(), _open_ports->end(), portNbr)) { WARNING("Port number %u already binded to open socket.\r\n", portNbr); } else { // [X] - 1 - Add the port number to the list of active ports & keep sorted _open_ports->push_back(portNbr); std::sort(_open_ports->begin(), _open_ports->end()); // [X] - 2 - Set the passed communication link object's pointer to the link pointers array. // ================= _link[portNbr] = link; // [X] - 3 - Associate the given port number with the passed function pointer. // ================= _rx_handles[portNbr].attach(rx); LOG("Port %u ready for RX.\r\n", portNbr); } } } void CommModule::openSocket(uint8_t portNbr) { ready(); if (_txH_called) { if (std::binary_search(_open_ports->begin(), _open_ports->end(), portNbr)) { WARNING("Port number %u already opened.\r\n", portNbr); } else { // [X] - 1 - Add the port number to the list of active ports & keep sorted _open_ports->push_back(portNbr); std::sort(_open_ports->begin(), _open_ports->end()); LOG("Port %u opened.\r\n", portNbr); } } else { WARNING("Must set TX & RX callback functions before opening socket.\r\n"); } } template <class T> void openSocket(T *tptr, void(T::*mptr)(void const *arg), uint8_t portNbr) { } void CommModule::ready(void) { static bool isReady = false; if (isReady) { return; } isReady = true; _open_ports = new std::vector<uint8_t>; osSignalSet(_txID, COMM_MODULE_SIGNAL_START_THREAD); osSignalSet(_rxID, COMM_MODULE_SIGNAL_START_THREAD); } void CommModule::send(RTP_t& packet) { // [X] - 1 - Check to make sure a socket for the port exists if (std::binary_search(_open_ports->begin(), _open_ports->end(), packet.port)) { // [X] - 1.1 - Allocate a block of memory for the data. // ================= RTP_t *p = (RTP_t*)osMailAlloc(_txQueue, osWaitForever); // [X] - 1.2 - Copy the contents into the allocated memory block // ================= p->port = packet.port; p->subclass = packet.subclass; p->data_size = packet.data_size; for (int i=0; i<(sizeof(packet)/sizeof(uint8_t)); i++) p->data[i] = packet.data[i]; // [X] - 1.3 - Place the passed packet into the txQueue. // ================= osMailPut(_txQueue, p); } else { WARNING("Failure to send packet: There is no open socket for port %u.\r\n", packet.port); } } void CommModule::receive(RTP_t& packet) { // [X] - 1 - Check to make sure a socket for the port exists if (std::binary_search(_open_ports->begin(), _open_ports->end(), packet.port)) { // [X] - 1.1 - Allocate a block of memory for the data. // ================= RTP_t *p = (RTP_t*)osMailAlloc(_rxQueue, osWaitForever); // [X] - 1.2 - Copy the contents into the allocated memory block // ================= p->port = packet.port; p->subclass = packet.subclass; for (int i=0; i<packet.data_size; i++) p->data[i] = packet.data[i]; // [X] - 1.3 - Place the passed packet into the txQueue. // ================= osMailPut(_rxQueue, p); } else { WARNING("Received pack from unopen port %u.\r\n", packet.port); } }