Jonathan Jones
/
Radios
Radio Structures in OOP
modules/CommLink/CommLink.cpp@3:dc7e9c6bc26c, 2015-01-03 (annotated)
- Committer:
- jjones646
- Date:
- Sat Jan 03 04:35:32 2015 +0000
- Revision:
- 3:dc7e9c6bc26c
- Parent:
- 2:7d523bdd2f50
- Child:
- 4:989d51f3e6ef
updating with threaded tasks for communication classes
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jjones646 | 2:7d523bdd2f50 | 1 | #include "CommLink.h" |
jjones646 | 2:7d523bdd2f50 | 2 | |
jjones646 | 3:dc7e9c6bc26c | 3 | |
jjones646 | 2:7d523bdd2f50 | 4 | // Set the class's constants for streamlined use in other areas of the code |
jjones646 | 2:7d523bdd2f50 | 5 | const int CommLink::TX_QUEUE_SIZE = COMM_LINK_TX_QUEUE_SIZE; |
jjones646 | 2:7d523bdd2f50 | 6 | const int CommLink::RX_QUEUE_SIZE = COMM_LINK_RX_QUEUE_SIZE; |
jjones646 | 2:7d523bdd2f50 | 7 | |
jjones646 | 3:dc7e9c6bc26c | 8 | |
jjones646 | 3:dc7e9c6bc26c | 9 | // =================== CONSTRUCTORS =================== |
jjones646 | 2:7d523bdd2f50 | 10 | // Default constructor |
jjones646 | 2:7d523bdd2f50 | 11 | CommLink::CommLink() |
jjones646 | 2:7d523bdd2f50 | 12 | { |
jjones646 | 3:dc7e9c6bc26c | 13 | setup_pins(); |
jjones646 | 3:dc7e9c6bc26c | 14 | setup(); |
jjones646 | 3:dc7e9c6bc26c | 15 | } |
jjones646 | 2:7d523bdd2f50 | 16 | |
jjones646 | 3:dc7e9c6bc26c | 17 | CommLink::CommLink(PinName mosi, PinName miso, PinName sck, PinName cs, PinName int_pin) : |
jjones646 | 3:dc7e9c6bc26c | 18 | _txQueueHelper(), |
jjones646 | 3:dc7e9c6bc26c | 19 | _rxQueueHelper() |
jjones646 | 3:dc7e9c6bc26c | 20 | { |
jjones646 | 3:dc7e9c6bc26c | 21 | static unsigned int _nbr_links = 0; |
jjones646 | 3:dc7e9c6bc26c | 22 | |
jjones646 | 3:dc7e9c6bc26c | 23 | setup_pins(mosi, miso, sck, cs, int_pin); |
jjones646 | 3:dc7e9c6bc26c | 24 | setup(); |
jjones646 | 3:dc7e9c6bc26c | 25 | _nbr_links++; |
jjones646 | 3:dc7e9c6bc26c | 26 | } |
jjones646 | 3:dc7e9c6bc26c | 27 | |
jjones646 | 2:7d523bdd2f50 | 28 | |
jjones646 | 3:dc7e9c6bc26c | 29 | // =================== CLASS SETUP =================== |
jjones646 | 3:dc7e9c6bc26c | 30 | void CommLink::setup() |
jjones646 | 3:dc7e9c6bc26c | 31 | { |
jjones646 | 3:dc7e9c6bc26c | 32 | // [X] - 1 - Initialize the hardware for communication. |
jjones646 | 3:dc7e9c6bc26c | 33 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 34 | setup_spi(); |
jjones646 | 3:dc7e9c6bc26c | 35 | setup_cs(); |
jjones646 | 3:dc7e9c6bc26c | 36 | setup_interrupt(); |
jjones646 | 3:dc7e9c6bc26c | 37 | |
jjones646 | 2:7d523bdd2f50 | 38 | |
jjones646 | 3:dc7e9c6bc26c | 39 | // [X] - 2.1 - Define the TX & RX queues. |
jjones646 | 3:dc7e9c6bc26c | 40 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 41 | // The size allocations for each queue are dependent upon what interface that communication is occuring on (radio/serial/usb/etc.) |
jjones646 | 2:7d523bdd2f50 | 42 | |
jjones646 | 3:dc7e9c6bc26c | 43 | // [X] - 2.2 - Create small TX & RX queues. |
jjones646 | 3:dc7e9c6bc26c | 44 | // ================= |
jjones646 | 2:7d523bdd2f50 | 45 | |
jjones646 | 3:dc7e9c6bc26c | 46 | |
jjones646 | 3:dc7e9c6bc26c | 47 | // [X] - 3.1 - define the thread tasks for controlling the data queues |
jjones646 | 3:dc7e9c6bc26c | 48 | // ================= |
jjones646 | 2:7d523bdd2f50 | 49 | // Outline the thread definitions |
jjones646 | 2:7d523bdd2f50 | 50 | define_thread(_txDef, &CommLink::txThread); |
jjones646 | 2:7d523bdd2f50 | 51 | define_thread(_rxDef, &CommLink::rxThread); |
jjones646 | 2:7d523bdd2f50 | 52 | |
jjones646 | 3:dc7e9c6bc26c | 53 | // [X] - 3.2 - Create the threads and pass them a pointer to the created object |
jjones646 | 2:7d523bdd2f50 | 54 | _txID = osThreadCreate(&_txDef, (void*)this); |
jjones646 | 2:7d523bdd2f50 | 55 | _rxID = osThreadCreate(&_rxDef, (void*)this); |
jjones646 | 2:7d523bdd2f50 | 56 | } |
jjones646 | 2:7d523bdd2f50 | 57 | |
jjones646 | 3:dc7e9c6bc26c | 58 | |
jjones646 | 3:dc7e9c6bc26c | 59 | // =================== PIN SETUP =================== |
jjones646 | 3:dc7e9c6bc26c | 60 | void CommLink::setup_pins(PinName mosi, PinName miso, PinName sck, PinName cs, PinName int_pin) |
jjones646 | 2:7d523bdd2f50 | 61 | { |
jjones646 | 3:dc7e9c6bc26c | 62 | _mosi_pin = mosi; |
jjones646 | 3:dc7e9c6bc26c | 63 | _miso_pin = miso; |
jjones646 | 3:dc7e9c6bc26c | 64 | _sck_pin = sck; |
jjones646 | 3:dc7e9c6bc26c | 65 | _cs_pin = cs; |
jjones646 | 3:dc7e9c6bc26c | 66 | _int_pin = int_pin; |
jjones646 | 2:7d523bdd2f50 | 67 | } |
jjones646 | 2:7d523bdd2f50 | 68 | |
jjones646 | 3:dc7e9c6bc26c | 69 | void CommLink::setup_spi(void) |
jjones646 | 3:dc7e9c6bc26c | 70 | { |
jjones646 | 3:dc7e9c6bc26c | 71 | if (_mosi_pin != NC & _miso_pin != NC & _sck_pin != NC) { |
jjones646 | 3:dc7e9c6bc26c | 72 | // Setup the spi for 8 bit data, high steady state clock, second edge capture |
jjones646 | 3:dc7e9c6bc26c | 73 | _spi = new SPI(_mosi_pin, _miso_pin, _sck_pin); |
jjones646 | 3:dc7e9c6bc26c | 74 | _spi->format(8,0); |
jjones646 | 3:dc7e9c6bc26c | 75 | _spi->frequency(5000000); |
jjones646 | 3:dc7e9c6bc26c | 76 | } |
jjones646 | 3:dc7e9c6bc26c | 77 | } |
jjones646 | 3:dc7e9c6bc26c | 78 | |
jjones646 | 3:dc7e9c6bc26c | 79 | void CommLink::setup_cs(void) |
jjones646 | 3:dc7e9c6bc26c | 80 | { |
jjones646 | 3:dc7e9c6bc26c | 81 | if (_cs_pin != NC) { |
jjones646 | 3:dc7e9c6bc26c | 82 | _cs = new DigitalOut(_cs_pin); |
jjones646 | 3:dc7e9c6bc26c | 83 | } |
jjones646 | 3:dc7e9c6bc26c | 84 | } |
jjones646 | 3:dc7e9c6bc26c | 85 | |
jjones646 | 3:dc7e9c6bc26c | 86 | void CommLink::setup_interrupt(void) |
jjones646 | 3:dc7e9c6bc26c | 87 | { |
jjones646 | 3:dc7e9c6bc26c | 88 | if (_int_pin != NC) { |
jjones646 | 3:dc7e9c6bc26c | 89 | _int_in = new InterruptIn(_int_pin); |
jjones646 | 3:dc7e9c6bc26c | 90 | //_int_in->mode(PullDown); |
jjones646 | 3:dc7e9c6bc26c | 91 | } |
jjones646 | 3:dc7e9c6bc26c | 92 | } |
jjones646 | 3:dc7e9c6bc26c | 93 | |
jjones646 | 3:dc7e9c6bc26c | 94 | |
jjones646 | 3:dc7e9c6bc26c | 95 | // =================== TX/RX THREADS =================== |
jjones646 | 2:7d523bdd2f50 | 96 | // Task operations for sending data over the hardware link when a new item is placed in the queue |
jjones646 | 2:7d523bdd2f50 | 97 | void CommLink::txThread(void const *arg) |
jjones646 | 2:7d523bdd2f50 | 98 | { |
jjones646 | 2:7d523bdd2f50 | 99 | CommLink *inst = (CommLink*)arg; |
jjones646 | 3:dc7e9c6bc26c | 100 | |
jjones646 | 3:dc7e9c6bc26c | 101 | // Only continue past this point once the hardware link is initialized |
jjones646 | 3:dc7e9c6bc26c | 102 | osSignalWait(COMM_LINK_SIGNAL_START_THREAD, osWaitForever); |
jjones646 | 3:dc7e9c6bc26c | 103 | |
jjones646 | 2:7d523bdd2f50 | 104 | while(1) { |
jjones646 | 2:7d523bdd2f50 | 105 | // [] - 1 - Wait until the CommModule class sends a signal to begin operation on new data being placed in its txQueue |
jjones646 | 3:dc7e9c6bc26c | 106 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 107 | |
jjones646 | 2:7d523bdd2f50 | 108 | // [] - 2 - Copy the packet from the CommModule txQueue into the CommLink txQueue |
jjones646 | 3:dc7e9c6bc26c | 109 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 110 | void * osMailAlloc (osMailQId queue_id, uint32_t millisec); |
jjones646 | 3:dc7e9c6bc26c | 111 | |
jjones646 | 2:7d523bdd2f50 | 112 | // [] - 3 - Call the method for sending the packet over a hardware communication link |
jjones646 | 3:dc7e9c6bc26c | 113 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 114 | uint8_t temp[20] = { 0 }; |
jjones646 | 3:dc7e9c6bc26c | 115 | inst->sendData(temp, 20); |
jjones646 | 3:dc7e9c6bc26c | 116 | |
jjones646 | 3:dc7e9c6bc26c | 117 | // [] - 4 - Blink the TX LED for the hardware link |
jjones646 | 3:dc7e9c6bc26c | 118 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 119 | |
jjones646 | 2:7d523bdd2f50 | 120 | } |
jjones646 | 2:7d523bdd2f50 | 121 | } |
jjones646 | 2:7d523bdd2f50 | 122 | |
jjones646 | 3:dc7e9c6bc26c | 123 | |
jjones646 | 2:7d523bdd2f50 | 124 | // Task operations for placing received data into the received data queue |
jjones646 | 2:7d523bdd2f50 | 125 | void CommLink::rxThread(void const *arg) |
jjones646 | 2:7d523bdd2f50 | 126 | { |
jjones646 | 2:7d523bdd2f50 | 127 | CommLink *inst = (CommLink*)arg; |
jjones646 | 3:dc7e9c6bc26c | 128 | |
jjones646 | 3:dc7e9c6bc26c | 129 | // Only continue past this point once the hardware link is initialized |
jjones646 | 3:dc7e9c6bc26c | 130 | osSignalWait(COMM_LINK_SIGNAL_START_THREAD & COMM_LINK_SIGNAL_MODULE_LINKED, osWaitForever); |
jjones646 | 3:dc7e9c6bc26c | 131 | |
jjones646 | 3:dc7e9c6bc26c | 132 | // Set the function to call on an interrupt trigger |
jjones646 | 3:dc7e9c6bc26c | 133 | inst->_int_in->rise(inst, &CommLink::ISR); |
jjones646 | 3:dc7e9c6bc26c | 134 | |
jjones646 | 2:7d523bdd2f50 | 135 | while(1) { |
jjones646 | 3:dc7e9c6bc26c | 136 | // [X] - 1 - Wait until new data has arrived |
jjones646 | 3:dc7e9c6bc26c | 137 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 138 | osSignalWait(COMM_LINK_SIGNAL_INTERRUPT_TRIGGER, osWaitForever); |
jjones646 | 3:dc7e9c6bc26c | 139 | |
jjones646 | 3:dc7e9c6bc26c | 140 | // [X] - 2 - Get the received data from the external chip |
jjones646 | 3:dc7e9c6bc26c | 141 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 142 | uint8_t rec_bytes = COMM_LINK_BUFFER_SIZE; |
jjones646 | 3:dc7e9c6bc26c | 143 | RTP_t p; |
jjones646 | 2:7d523bdd2f50 | 144 | |
jjones646 | 3:dc7e9c6bc26c | 145 | //uint8_t *buf_ptr = p.data; |
jjones646 | 3:dc7e9c6bc26c | 146 | inst->getData(p.data, &rec_bytes); |
jjones646 | 2:7d523bdd2f50 | 147 | |
jjones646 | 3:dc7e9c6bc26c | 148 | p.port = p.data[0] & 0xF0; |
jjones646 | 3:dc7e9c6bc26c | 149 | p.subclass = p.data[0] & 0x0F; |
jjones646 | 3:dc7e9c6bc26c | 150 | |
jjones646 | 3:dc7e9c6bc26c | 151 | // [] - 3 - Write the data to the CommModule object's rxQueue |
jjones646 | 3:dc7e9c6bc26c | 152 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 153 | //_comm_module->receive(p); |
jjones646 | 3:dc7e9c6bc26c | 154 | |
jjones646 | 3:dc7e9c6bc26c | 155 | |
jjones646 | 2:7d523bdd2f50 | 156 | // [] - 4 - Blink the RX LED for the hardware link |
jjones646 | 3:dc7e9c6bc26c | 157 | // ================= |
jjones646 | 2:7d523bdd2f50 | 158 | } |
jjones646 | 2:7d523bdd2f50 | 159 | } |
jjones646 | 2:7d523bdd2f50 | 160 | |
jjones646 | 3:dc7e9c6bc26c | 161 | |
jjones646 | 3:dc7e9c6bc26c | 162 | // Called by the derived class to begin thread operations |
jjones646 | 3:dc7e9c6bc26c | 163 | void CommLink::ready(void) |
jjones646 | 3:dc7e9c6bc26c | 164 | { |
jjones646 | 3:dc7e9c6bc26c | 165 | osSignalSet(_txID, COMM_LINK_SIGNAL_START_THREAD); |
jjones646 | 3:dc7e9c6bc26c | 166 | osSignalSet(_rxID, COMM_LINK_SIGNAL_START_THREAD); |
jjones646 | 3:dc7e9c6bc26c | 167 | } |
jjones646 | 3:dc7e9c6bc26c | 168 | |
jjones646 | 3:dc7e9c6bc26c | 169 | |
jjones646 | 3:dc7e9c6bc26c | 170 | void CommLink::write_tx_queue(RTP_t *p) |
jjones646 | 3:dc7e9c6bc26c | 171 | { |
jjones646 | 3:dc7e9c6bc26c | 172 | // [] - 1 - Write the data to the RX queue |
jjones646 | 3:dc7e9c6bc26c | 173 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 174 | |
jjones646 | 3:dc7e9c6bc26c | 175 | // [] - 2 - Signal the TX thread of new data |
jjones646 | 3:dc7e9c6bc26c | 176 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 177 | |
jjones646 | 3:dc7e9c6bc26c | 178 | } |
jjones646 | 3:dc7e9c6bc26c | 179 | |
jjones646 | 3:dc7e9c6bc26c | 180 | |
jjones646 | 3:dc7e9c6bc26c | 181 | void CommLink::sendPacket(RTP_t *p) |
jjones646 | 2:7d523bdd2f50 | 182 | { |
jjones646 | 3:dc7e9c6bc26c | 183 | |
jjones646 | 3:dc7e9c6bc26c | 184 | |
jjones646 | 3:dc7e9c6bc26c | 185 | |
jjones646 | 3:dc7e9c6bc26c | 186 | } |
jjones646 | 3:dc7e9c6bc26c | 187 | |
jjones646 | 3:dc7e9c6bc26c | 188 | void CommLink::receivePacket(RTP_t *p) |
jjones646 | 3:dc7e9c6bc26c | 189 | { |
jjones646 | 3:dc7e9c6bc26c | 190 | |
jjones646 | 2:7d523bdd2f50 | 191 | } |
jjones646 | 3:dc7e9c6bc26c | 192 | |
jjones646 | 3:dc7e9c6bc26c | 193 | // Interrupt Service Routine - KEEP OPERATIONS TO ABOSOLUTE MINIMUM HERE AND IN OVERRIDEN BASE CLASS IMPLEMENTATIONS OF THIS CLASS METHOD |
jjones646 | 3:dc7e9c6bc26c | 194 | void CommLink::ISR(void) |
jjones646 | 3:dc7e9c6bc26c | 195 | { |
jjones646 | 3:dc7e9c6bc26c | 196 | osSignalSet(_rxID , COMM_LINK_SIGNAL_INTERRUPT_TRIGGER); |
jjones646 | 3:dc7e9c6bc26c | 197 | } |
jjones646 | 3:dc7e9c6bc26c | 198 | |
jjones646 | 3:dc7e9c6bc26c | 199 | void CommLink::toggle_cs(void) |
jjones646 | 3:dc7e9c6bc26c | 200 | { |
jjones646 | 3:dc7e9c6bc26c | 201 | *_cs = !*_cs; |
jjones646 | 3:dc7e9c6bc26c | 202 | } |
jjones646 | 3:dc7e9c6bc26c | 203 | |
jjones646 | 3:dc7e9c6bc26c | 204 | /* |
jjones646 | 3:dc7e9c6bc26c | 205 | void CommLink::module(CommModule& module) |
jjones646 | 3:dc7e9c6bc26c | 206 | { |
jjones646 | 3:dc7e9c6bc26c | 207 | _comm_module = &module; |
jjones646 | 3:dc7e9c6bc26c | 208 | osSignalSet(_rxID, COMM_LINK_SIGNAL_MODULE_LINKED); |
jjones646 | 3:dc7e9c6bc26c | 209 | } |
jjones646 | 3:dc7e9c6bc26c | 210 | */ |