Radio Structures in OOP

Dependencies:   mbed mbed-rtos

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?

UserRevisionLine numberNew 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 */