Jonathan Jones
/
Radios
Radio Structures in OOP
Embed:
(wiki syntax)
Show/hide line numbers
CommModule.cpp
00001 #include "CommModule.h" 00002 00003 // Set the class's constants for streamlined use in other areas of the code 00004 const int CommModule::TX_QUEUE_SIZE = COMM_MODULE_TX_QUEUE_SIZE; 00005 const int CommModule::RX_QUEUE_SIZE = COMM_MODULE_RX_QUEUE_SIZE; 00006 const int CommModule::NBR_PORTS = COMM_MODULE_NBR_PORTS; 00007 00008 // Default constructor 00009 CommModule::CommModule() : 00010 // [X] - 1.1 - Define the data queues. 00011 // ================= 00012 _txQueueHelper(), 00013 _rxQueueHelper() 00014 { 00015 // [X] - 1.2 - Create the data queues. 00016 // ================= 00017 _txQueue = osMailCreate(_txQueueHelper.def(), NULL); 00018 _rxQueue = osMailCreate(_rxQueueHelper.def(), NULL); 00019 00020 // [X] - 2.1 - Define the TX & RX task threads. 00021 // ================= 00022 define_thread(_txDef, &CommModule::txThread); 00023 define_thread(_rxDef, &CommModule::rxThread); 00024 00025 // [X] - 2.2 - Create the TX & RX threads - pass them a pointer to the created object. 00026 // ================= 00027 _txID = osThreadCreate(&_txDef, (void*)this); 00028 _rxID = osThreadCreate(&_rxDef, (void*)this); 00029 00030 _txH_called = false; 00031 } 00032 00033 CommModule::~CommModule() 00034 { 00035 if (_open_ports) 00036 delete _open_ports; 00037 } 00038 00039 void CommModule::txThread(void const *arg) 00040 { 00041 CommModule *inst = (CommModule*)arg; 00042 00043 // Only continue past this point once at least one (1) hardware link is initialized 00044 osSignalWait(COMM_MODULE_SIGNAL_START_THREAD, osWaitForever); 00045 00046 LOG("TX Ready!\r\n"); 00047 00048 while(1) { 00049 00050 // When a new RTP packet is put in the tx queue, begin operations (does nothing if no new data in queue) 00051 osEvent evt = osMailGet(inst->_txQueue, osWaitForever); 00052 00053 if (evt.status == osEventMail) { 00054 00055 // Get a pointer to the packet's memory location 00056 RTP_t *p = (RTP_t*)evt.value.p; 00057 00058 // Send the packet on the active communication link 00059 inst->_tx_handles[p->port].call(p); 00060 00061 EVENT("Transmission: Port: %u Subclass: %u\r\n", p->port, p->subclass); 00062 00063 // Release the allocated memory once data is sent 00064 osMailFree(inst->_txQueue, p); 00065 } 00066 } 00067 } 00068 00069 void CommModule::rxThread(void const *arg) 00070 { 00071 CommModule *inst = (CommModule*)arg; 00072 00073 // Only continue past this point once at least one (1) hardware link is initialized 00074 osSignalWait(COMM_MODULE_SIGNAL_START_THREAD, osWaitForever); 00075 00076 LOG("RX Ready!\r\n"); 00077 00078 RTP_t *p; 00079 osEvent evt; 00080 while(1) { 00081 00082 // Wait until new data is placed in the class's rxQueue from a CommLink class 00083 evt = osMailGet(inst->_rxQueue, osWaitForever); 00084 00085 if (evt.status == osEventMail) { 00086 DigitalOut led(LED4, 1); 00087 00088 // get a pointer to where the data is stored 00089 p = (RTP_t*)evt.value.p; 00090 00091 // If there is an open socket for the port, call it. 00092 if (std::binary_search(inst->_open_ports->begin(), inst->_open_ports->end(), p->port)) { 00093 inst->_rx_handles[p->port].call(); 00094 } 00095 00096 EVENT("Reception: \r\n Port: %u\r\n Subclass: %u\r\n", p->port, p->subclass); 00097 00098 osMailFree(inst->_rxQueue, p); // free memory allocated for mail 00099 00100 } 00101 } 00102 } 00103 00104 void CommModule::TxHandler(void(*ptr)(RTP_t*), uint8_t portNbr) 00105 { 00106 _txH_called = true; 00107 ready(); 00108 _tx_handles[portNbr].attach(ptr); 00109 } 00110 00111 void CommModule::RxHandler(void(*ptr)(RTP_t*), uint8_t portNbr) 00112 { 00113 ready(); 00114 _rx_handles[portNbr].attach(ptr); 00115 } 00116 00117 void CommModule::RxHandler(void(*ptr)(void), uint8_t portNbr) 00118 { 00119 ready(); 00120 _rx_handles[portNbr].attach(ptr); 00121 } 00122 00123 00124 void CommModule::openSocket(CommLink *link, void(*rx)(void const *arg), uint8_t portNbr) 00125 { 00126 ready(); 00127 if (_txH_called) { 00128 if (std::binary_search(_open_ports->begin(), _open_ports->end(), portNbr)) { 00129 WARNING("Port number %u already binded to open socket.\r\n", portNbr); 00130 } else { 00131 // [X] - 1 - Add the port number to the list of active ports & keep sorted 00132 _open_ports->push_back(portNbr); 00133 std::sort(_open_ports->begin(), _open_ports->end()); 00134 00135 // [X] - 2 - Set the passed communication link object's pointer to the link pointers array. 00136 // ================= 00137 _link[portNbr] = link; 00138 00139 // [X] - 3 - Associate the given port number with the passed function pointer. 00140 // ================= 00141 _rx_handles[portNbr].attach(rx); 00142 00143 LOG("Port %u ready for RX.\r\n", portNbr); 00144 } 00145 } 00146 } 00147 00148 void CommModule::openSocket(uint8_t portNbr) 00149 { 00150 ready(); 00151 if (_txH_called) { 00152 if (std::binary_search(_open_ports->begin(), _open_ports->end(), portNbr)) { 00153 WARNING("Port number %u already opened.\r\n", portNbr); 00154 } else { 00155 // [X] - 1 - Add the port number to the list of active ports & keep sorted 00156 _open_ports->push_back(portNbr); 00157 std::sort(_open_ports->begin(), _open_ports->end()); 00158 00159 LOG("Port %u opened.\r\n", portNbr); 00160 } 00161 } else { 00162 WARNING("Must set TX & RX callback functions before opening socket.\r\n"); 00163 } 00164 } 00165 00166 template <class T> 00167 void openSocket(T *tptr, void(T::*mptr)(void const *arg), uint8_t portNbr) 00168 { 00169 00170 } 00171 00172 00173 void CommModule::ready(void) 00174 { 00175 static bool isReady = false; 00176 00177 if (isReady) { 00178 return; 00179 } 00180 00181 isReady = true; 00182 00183 _open_ports = new std::vector<uint8_t>; 00184 00185 osSignalSet(_txID, COMM_MODULE_SIGNAL_START_THREAD); 00186 osSignalSet(_rxID, COMM_MODULE_SIGNAL_START_THREAD); 00187 } 00188 00189 00190 void CommModule::send(RTP_t& packet) 00191 { 00192 // [X] - 1 - Check to make sure a socket for the port exists 00193 if (std::binary_search(_open_ports->begin(), _open_ports->end(), packet.port)) { 00194 00195 // [X] - 1.1 - Allocate a block of memory for the data. 00196 // ================= 00197 RTP_t *p = (RTP_t*)osMailAlloc(_txQueue, osWaitForever); 00198 00199 // [X] - 1.2 - Copy the contents into the allocated memory block 00200 // ================= 00201 p->port = packet.port; 00202 p->subclass = packet.subclass; 00203 p->data_size = packet.data_size; 00204 00205 for (int i=0; i<(sizeof(packet)/sizeof(uint8_t)); i++) 00206 p->data[i] = packet.data[i]; 00207 00208 // [X] - 1.3 - Place the passed packet into the txQueue. 00209 // ================= 00210 osMailPut(_txQueue, p); 00211 } else { 00212 WARNING("Failure to send packet: There is no open socket for port %u.\r\n", packet.port); 00213 } 00214 } 00215 00216 00217 void CommModule::receive(RTP_t& packet) 00218 { 00219 // [X] - 1 - Check to make sure a socket for the port exists 00220 if (std::binary_search(_open_ports->begin(), _open_ports->end(), packet.port)) { 00221 00222 // [X] - 1.1 - Allocate a block of memory for the data. 00223 // ================= 00224 RTP_t *p = (RTP_t*)osMailAlloc(_rxQueue, osWaitForever); 00225 00226 // [X] - 1.2 - Copy the contents into the allocated memory block 00227 // ================= 00228 p->port = packet.port; 00229 p->subclass = packet.subclass; 00230 00231 for (int i=0; i<packet.data_size; i++) 00232 p->data[i] = packet.data[i]; 00233 00234 // [X] - 1.3 - Place the passed packet into the txQueue. 00235 // ================= 00236 osMailPut(_rxQueue, p); 00237 } else { 00238 WARNING("Received pack from unopen port %u.\r\n", packet.port); 00239 } 00240 }
Generated on Mon Jul 18 2022 20:09:01 by 1.7.2