Jonathan Jones
/
Radios
Radio Structures in OOP
modules/CommLink/CommLink.cpp@6:4a3dbfbc30f1, 2015-01-15 (annotated)
- Committer:
- jjones646
- Date:
- Thu Jan 15 07:15:33 2015 +0000
- Revision:
- 6:4a3dbfbc30f1
- Parent:
- 5:146523a0d1f4
socket interface confirmed working.
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 | } |
jjones646 | 2:7d523bdd2f50 | 14 | |
jjones646 | 3:dc7e9c6bc26c | 15 | CommLink::CommLink(PinName mosi, PinName miso, PinName sck, PinName cs, PinName int_pin) : |
jjones646 | 3:dc7e9c6bc26c | 16 | _txQueueHelper(), |
jjones646 | 3:dc7e9c6bc26c | 17 | _rxQueueHelper() |
jjones646 | 3:dc7e9c6bc26c | 18 | { |
jjones646 | 3:dc7e9c6bc26c | 19 | static unsigned int _nbr_links = 0; |
jjones646 | 3:dc7e9c6bc26c | 20 | |
jjones646 | 3:dc7e9c6bc26c | 21 | setup_pins(mosi, miso, sck, cs, int_pin); |
jjones646 | 3:dc7e9c6bc26c | 22 | setup(); |
jjones646 | 3:dc7e9c6bc26c | 23 | _nbr_links++; |
jjones646 | 3:dc7e9c6bc26c | 24 | } |
jjones646 | 3:dc7e9c6bc26c | 25 | |
jjones646 | 2:7d523bdd2f50 | 26 | |
jjones646 | 3:dc7e9c6bc26c | 27 | // =================== CLASS SETUP =================== |
jjones646 | 3:dc7e9c6bc26c | 28 | void CommLink::setup() |
jjones646 | 3:dc7e9c6bc26c | 29 | { |
jjones646 | 3:dc7e9c6bc26c | 30 | // [X] - 1 - Initialize the hardware for communication. |
jjones646 | 3:dc7e9c6bc26c | 31 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 32 | setup_spi(); |
jjones646 | 3:dc7e9c6bc26c | 33 | setup_cs(); |
jjones646 | 3:dc7e9c6bc26c | 34 | setup_interrupt(); |
jjones646 | 3:dc7e9c6bc26c | 35 | |
jjones646 | 6:4a3dbfbc30f1 | 36 | // [X] - 2 - Define the thread tasks for controlling the data queues |
jjones646 | 3:dc7e9c6bc26c | 37 | // ================= |
jjones646 | 2:7d523bdd2f50 | 38 | define_thread(_txDef, &CommLink::txThread); |
jjones646 | 2:7d523bdd2f50 | 39 | define_thread(_rxDef, &CommLink::rxThread); |
jjones646 | 2:7d523bdd2f50 | 40 | |
jjones646 | 6:4a3dbfbc30f1 | 41 | // [X] - 3 - Create the threads and pass them a pointer to the created object |
jjones646 | 6:4a3dbfbc30f1 | 42 | // ================= |
jjones646 | 2:7d523bdd2f50 | 43 | _txID = osThreadCreate(&_txDef, (void*)this); |
jjones646 | 2:7d523bdd2f50 | 44 | _rxID = osThreadCreate(&_rxDef, (void*)this); |
jjones646 | 2:7d523bdd2f50 | 45 | } |
jjones646 | 2:7d523bdd2f50 | 46 | |
jjones646 | 3:dc7e9c6bc26c | 47 | |
jjones646 | 3:dc7e9c6bc26c | 48 | // =================== PIN SETUP =================== |
jjones646 | 3:dc7e9c6bc26c | 49 | void CommLink::setup_pins(PinName mosi, PinName miso, PinName sck, PinName cs, PinName int_pin) |
jjones646 | 2:7d523bdd2f50 | 50 | { |
jjones646 | 3:dc7e9c6bc26c | 51 | _mosi_pin = mosi; |
jjones646 | 3:dc7e9c6bc26c | 52 | _miso_pin = miso; |
jjones646 | 3:dc7e9c6bc26c | 53 | _sck_pin = sck; |
jjones646 | 3:dc7e9c6bc26c | 54 | _cs_pin = cs; |
jjones646 | 3:dc7e9c6bc26c | 55 | _int_pin = int_pin; |
jjones646 | 2:7d523bdd2f50 | 56 | } |
jjones646 | 2:7d523bdd2f50 | 57 | |
jjones646 | 3:dc7e9c6bc26c | 58 | void CommLink::setup_spi(void) |
jjones646 | 3:dc7e9c6bc26c | 59 | { |
jjones646 | 3:dc7e9c6bc26c | 60 | if (_mosi_pin != NC & _miso_pin != NC & _sck_pin != NC) { |
jjones646 | 5:146523a0d1f4 | 61 | _spi = new SPI(_mosi_pin, _miso_pin, _sck_pin); // DON'T FORGET TO DELETE IN DERIVED CLASS |
jjones646 | 3:dc7e9c6bc26c | 62 | _spi->format(8,0); |
jjones646 | 3:dc7e9c6bc26c | 63 | _spi->frequency(5000000); |
jjones646 | 3:dc7e9c6bc26c | 64 | } |
jjones646 | 3:dc7e9c6bc26c | 65 | } |
jjones646 | 3:dc7e9c6bc26c | 66 | |
jjones646 | 3:dc7e9c6bc26c | 67 | void CommLink::setup_cs(void) |
jjones646 | 3:dc7e9c6bc26c | 68 | { |
jjones646 | 3:dc7e9c6bc26c | 69 | if (_cs_pin != NC) { |
jjones646 | 5:146523a0d1f4 | 70 | _cs = new DigitalOut(_cs_pin); // DON'T FORGET TO DELETE IN DERIVED CLASS |
jjones646 | 3:dc7e9c6bc26c | 71 | } |
jjones646 | 3:dc7e9c6bc26c | 72 | } |
jjones646 | 3:dc7e9c6bc26c | 73 | |
jjones646 | 3:dc7e9c6bc26c | 74 | void CommLink::setup_interrupt(void) |
jjones646 | 3:dc7e9c6bc26c | 75 | { |
jjones646 | 3:dc7e9c6bc26c | 76 | if (_int_pin != NC) { |
jjones646 | 5:146523a0d1f4 | 77 | _int_in = new InterruptIn(_int_pin); // DON'T FORGET TO DELETE IN DERIVED CLASS |
jjones646 | 5:146523a0d1f4 | 78 | _int_in->mode(PullDown); |
jjones646 | 3:dc7e9c6bc26c | 79 | } |
jjones646 | 3:dc7e9c6bc26c | 80 | } |
jjones646 | 3:dc7e9c6bc26c | 81 | |
jjones646 | 3:dc7e9c6bc26c | 82 | |
jjones646 | 3:dc7e9c6bc26c | 83 | // =================== TX/RX THREADS =================== |
jjones646 | 2:7d523bdd2f50 | 84 | // Task operations for sending data over the hardware link when a new item is placed in the queue |
jjones646 | 2:7d523bdd2f50 | 85 | void CommLink::txThread(void const *arg) |
jjones646 | 2:7d523bdd2f50 | 86 | { |
jjones646 | 2:7d523bdd2f50 | 87 | CommLink *inst = (CommLink*)arg; |
jjones646 | 3:dc7e9c6bc26c | 88 | |
jjones646 | 3:dc7e9c6bc26c | 89 | // Only continue past this point once the hardware link is initialized |
jjones646 | 3:dc7e9c6bc26c | 90 | osSignalWait(COMM_LINK_SIGNAL_START_THREAD, osWaitForever); |
jjones646 | 3:dc7e9c6bc26c | 91 | |
jjones646 | 5:146523a0d1f4 | 92 | DigitalOut tx_led(LED1, 1); |
jjones646 | 5:146523a0d1f4 | 93 | |
jjones646 | 2:7d523bdd2f50 | 94 | while(1) { |
jjones646 | 6:4a3dbfbc30f1 | 95 | // [X] - 1 - Wait until the CommModule class sends a signal to begin operation on new data being placed in its txQueue |
jjones646 | 3:dc7e9c6bc26c | 96 | // ================= |
jjones646 | 5:146523a0d1f4 | 97 | osSignalWait(COMM_LINK_SIGNAL_TX_TRIGGER, osWaitForever); |
jjones646 | 3:dc7e9c6bc26c | 98 | |
jjones646 | 2:7d523bdd2f50 | 99 | // [] - 2 - Copy the packet from the CommModule txQueue into the CommLink txQueue |
jjones646 | 3:dc7e9c6bc26c | 100 | // ================= |
jjones646 | 5:146523a0d1f4 | 101 | //void * osMailAlloc (osMailQId queue_id, uint32_t millisec); |
jjones646 | 3:dc7e9c6bc26c | 102 | |
jjones646 | 2:7d523bdd2f50 | 103 | // [] - 3 - Call the method for sending the packet over a hardware communication link |
jjones646 | 3:dc7e9c6bc26c | 104 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 105 | |
jjones646 | 3:dc7e9c6bc26c | 106 | // [] - 4 - Blink the TX LED for the hardware link |
jjones646 | 3:dc7e9c6bc26c | 107 | // ================= |
jjones646 | 5:146523a0d1f4 | 108 | tx_led = 1; |
jjones646 | 5:146523a0d1f4 | 109 | osDelay(60); |
jjones646 | 5:146523a0d1f4 | 110 | tx_led = 0; |
jjones646 | 5:146523a0d1f4 | 111 | osDelay(20); |
jjones646 | 2:7d523bdd2f50 | 112 | } |
jjones646 | 2:7d523bdd2f50 | 113 | } |
jjones646 | 2:7d523bdd2f50 | 114 | |
jjones646 | 3:dc7e9c6bc26c | 115 | |
jjones646 | 2:7d523bdd2f50 | 116 | // Task operations for placing received data into the received data queue |
jjones646 | 2:7d523bdd2f50 | 117 | void CommLink::rxThread(void const *arg) |
jjones646 | 2:7d523bdd2f50 | 118 | { |
jjones646 | 2:7d523bdd2f50 | 119 | CommLink *inst = (CommLink*)arg; |
jjones646 | 3:dc7e9c6bc26c | 120 | |
jjones646 | 3:dc7e9c6bc26c | 121 | // Only continue past this point once the hardware link is initialized |
jjones646 | 3:dc7e9c6bc26c | 122 | osSignalWait(COMM_LINK_SIGNAL_START_THREAD & COMM_LINK_SIGNAL_MODULE_LINKED, osWaitForever); |
jjones646 | 3:dc7e9c6bc26c | 123 | |
jjones646 | 3:dc7e9c6bc26c | 124 | // Set the function to call on an interrupt trigger |
jjones646 | 3:dc7e9c6bc26c | 125 | inst->_int_in->rise(inst, &CommLink::ISR); |
jjones646 | 3:dc7e9c6bc26c | 126 | |
jjones646 | 6:4a3dbfbc30f1 | 127 | DigitalOut rx_led(LED2, 1); |
jjones646 | 5:146523a0d1f4 | 128 | |
jjones646 | 2:7d523bdd2f50 | 129 | while(1) { |
jjones646 | 6:4a3dbfbc30f1 | 130 | // [X] - 1 - Wait until new data has arrived - this is interrupt triggered by CommLink::ISR() |
jjones646 | 3:dc7e9c6bc26c | 131 | // ================= |
jjones646 | 5:146523a0d1f4 | 132 | osSignalWait(COMM_LINK_SIGNAL_RX_TRIGGER, osWaitForever); |
jjones646 | 6:4a3dbfbc30f1 | 133 | |
jjones646 | 6:4a3dbfbc30f1 | 134 | |
jjones646 | 3:dc7e9c6bc26c | 135 | // [X] - 2 - Get the received data from the external chip |
jjones646 | 3:dc7e9c6bc26c | 136 | // ================= |
jjones646 | 3:dc7e9c6bc26c | 137 | uint8_t rec_bytes = COMM_LINK_BUFFER_SIZE; |
jjones646 | 3:dc7e9c6bc26c | 138 | RTP_t p; |
jjones646 | 4:989d51f3e6ef | 139 | |
jjones646 | 3:dc7e9c6bc26c | 140 | inst->getData(p.data, &rec_bytes); |
jjones646 | 5:146523a0d1f4 | 141 | //p.port = p.data[0] & 0xF0; |
jjones646 | 5:146523a0d1f4 | 142 | p.port = 8; |
jjones646 | 3:dc7e9c6bc26c | 143 | p.subclass = p.data[0] & 0x0F; |
jjones646 | 3:dc7e9c6bc26c | 144 | |
jjones646 | 5:146523a0d1f4 | 145 | |
jjones646 | 5:146523a0d1f4 | 146 | // [X] - 3 - Write the data to the CommModule object's rxQueue |
jjones646 | 4:989d51f3e6ef | 147 | // ================= |
jjones646 | 6:4a3dbfbc30f1 | 148 | inst->_comm_module->receive(p); |
jjones646 | 3:dc7e9c6bc26c | 149 | |
jjones646 | 3:dc7e9c6bc26c | 150 | |
jjones646 | 5:146523a0d1f4 | 151 | // [~] - 4 - Blink the RX LED for the hardware link |
jjones646 | 3:dc7e9c6bc26c | 152 | // ================= |
jjones646 | 5:146523a0d1f4 | 153 | rx_led = 1; |
jjones646 | 5:146523a0d1f4 | 154 | osDelay(100); |
jjones646 | 5:146523a0d1f4 | 155 | rx_led = 0; |
jjones646 | 5:146523a0d1f4 | 156 | //osDelay(20); |
jjones646 | 2:7d523bdd2f50 | 157 | } |
jjones646 | 2:7d523bdd2f50 | 158 | } |
jjones646 | 2:7d523bdd2f50 | 159 | |
jjones646 | 3:dc7e9c6bc26c | 160 | |
jjones646 | 3:dc7e9c6bc26c | 161 | // Called by the derived class to begin thread operations |
jjones646 | 3:dc7e9c6bc26c | 162 | void CommLink::ready(void) |
jjones646 | 3:dc7e9c6bc26c | 163 | { |
jjones646 | 3:dc7e9c6bc26c | 164 | osSignalSet(_txID, COMM_LINK_SIGNAL_START_THREAD); |
jjones646 | 3:dc7e9c6bc26c | 165 | osSignalSet(_rxID, COMM_LINK_SIGNAL_START_THREAD); |
jjones646 | 3:dc7e9c6bc26c | 166 | } |
jjones646 | 3:dc7e9c6bc26c | 167 | |
jjones646 | 3:dc7e9c6bc26c | 168 | |
jjones646 | 6:4a3dbfbc30f1 | 169 | void CommLink::sendPacket(RTP_t *p) |
jjones646 | 3:dc7e9c6bc26c | 170 | { |
jjones646 | 6:4a3dbfbc30f1 | 171 | sendData(p->raw, p->data_size+1); |
jjones646 | 3:dc7e9c6bc26c | 172 | } |
jjones646 | 3:dc7e9c6bc26c | 173 | |
jjones646 | 3:dc7e9c6bc26c | 174 | |
jjones646 | 5:146523a0d1f4 | 175 | // Interrupt Service Routine - KEEP OPERATIONS TO ABOSOLUTE MINIMUM HERE AND IN ANY OVERRIDEN BASE CLASS IMPLEMENTATIONS OF THIS CLASS METHOD |
jjones646 | 3:dc7e9c6bc26c | 176 | void CommLink::ISR(void) |
jjones646 | 3:dc7e9c6bc26c | 177 | { |
jjones646 | 5:146523a0d1f4 | 178 | osSignalSet(_rxID , COMM_LINK_SIGNAL_RX_TRIGGER); |
jjones646 | 3:dc7e9c6bc26c | 179 | } |
jjones646 | 3:dc7e9c6bc26c | 180 | |
jjones646 | 6:4a3dbfbc30f1 | 181 | |
jjones646 | 3:dc7e9c6bc26c | 182 | void CommLink::toggle_cs(void) |
jjones646 | 3:dc7e9c6bc26c | 183 | { |
jjones646 | 3:dc7e9c6bc26c | 184 | *_cs = !*_cs; |
jjones646 | 3:dc7e9c6bc26c | 185 | } |
jjones646 | 3:dc7e9c6bc26c | 186 | |
jjones646 | 5:146523a0d1f4 | 187 | |
jjones646 | 6:4a3dbfbc30f1 | 188 | void CommLink::setModule(CommModule& com) |
jjones646 | 5:146523a0d1f4 | 189 | { |
jjones646 | 6:4a3dbfbc30f1 | 190 | _comm_module = &com; |
jjones646 | 5:146523a0d1f4 | 191 | osSignalSet(_rxID , COMM_LINK_SIGNAL_MODULE_LINKED); |
jjones646 | 4:989d51f3e6ef | 192 | } |