Jonathan Jones
/
Radios
Radio Structures in OOP
modules/CommLink/CommLink.cpp
- Committer:
- jjones646
- Date:
- 2015-01-14
- Revision:
- 5:146523a0d1f4
- Parent:
- 4:989d51f3e6ef
- Child:
- 6:4a3dbfbc30f1
File content as of revision 5:146523a0d1f4:
#include "CommLink.h" // Set the class's constants for streamlined use in other areas of the code const int CommLink::TX_QUEUE_SIZE = COMM_LINK_TX_QUEUE_SIZE; const int CommLink::RX_QUEUE_SIZE = COMM_LINK_RX_QUEUE_SIZE; // =================== CONSTRUCTORS =================== // Default constructor CommLink::CommLink() { setup_pins(); setup(); } CommLink::CommLink(PinName mosi, PinName miso, PinName sck, PinName cs, PinName int_pin) : _txQueueHelper(), _rxQueueHelper() { static unsigned int _nbr_links = 0; setup_pins(mosi, miso, sck, cs, int_pin); setup(); _nbr_links++; } // =================== CLASS SETUP =================== void CommLink::setup() { // [X] - 1 - Initialize the hardware for communication. // ================= setup_spi(); setup_cs(); setup_interrupt(); // [X] - 2.1 - Define the TX & RX queues. // ================= // The size allocations for each queue are dependent upon what interface that communication is occuring on (radio/serial/usb/etc.) // [X] - 2.2 - Create small TX & RX queues. // ================= // [X] - 3.1 - define the thread tasks for controlling the data queues // ================= // Outline the thread definitions define_thread(_txDef, &CommLink::txThread); define_thread(_rxDef, &CommLink::rxThread); // [X] - 3.2 - Create the threads and pass them a pointer to the created object _txID = osThreadCreate(&_txDef, (void*)this); _rxID = osThreadCreate(&_rxDef, (void*)this); } // =================== PIN SETUP =================== void CommLink::setup_pins(PinName mosi, PinName miso, PinName sck, PinName cs, PinName int_pin) { _mosi_pin = mosi; _miso_pin = miso; _sck_pin = sck; _cs_pin = cs; _int_pin = int_pin; } void CommLink::setup_spi(void) { if (_mosi_pin != NC & _miso_pin != NC & _sck_pin != NC) { // Setup the spi for 8 bit data, high steady state clock, second edge capture _spi = new SPI(_mosi_pin, _miso_pin, _sck_pin); // DON'T FORGET TO DELETE IN DERIVED CLASS _spi->format(8,0); _spi->frequency(5000000); } } void CommLink::setup_cs(void) { if (_cs_pin != NC) { _cs = new DigitalOut(_cs_pin); // DON'T FORGET TO DELETE IN DERIVED CLASS } } void CommLink::setup_interrupt(void) { if (_int_pin != NC) { _int_in = new InterruptIn(_int_pin); // DON'T FORGET TO DELETE IN DERIVED CLASS _int_in->mode(PullDown); } } // =================== TX/RX THREADS =================== // Task operations for sending data over the hardware link when a new item is placed in the queue void CommLink::txThread(void const *arg) { CommLink *inst = (CommLink*)arg; // Only continue past this point once the hardware link is initialized osSignalWait(COMM_LINK_SIGNAL_START_THREAD, osWaitForever); DigitalOut tx_led(LED1, 1); while(1) { // [] - 1 - Wait until the CommModule class sends a signal to begin operation on new data being placed in its txQueue // ================= osSignalWait(COMM_LINK_SIGNAL_TX_TRIGGER, osWaitForever); // [] - 2 - Copy the packet from the CommModule txQueue into the CommLink txQueue // ================= //void * osMailAlloc (osMailQId queue_id, uint32_t millisec); // [] - 3 - Call the method for sending the packet over a hardware communication link // ================= // [] - 4 - Blink the TX LED for the hardware link // ================= tx_led = 1; osDelay(60); tx_led = 0; osDelay(20); } } // Task operations for placing received data into the received data queue void CommLink::rxThread(void const *arg) { CommLink *inst = (CommLink*)arg; // Only continue past this point once the hardware link is initialized osSignalWait(COMM_LINK_SIGNAL_START_THREAD & COMM_LINK_SIGNAL_MODULE_LINKED, osWaitForever); // Set the function to call on an interrupt trigger inst->_int_in->rise(inst, &CommLink::ISR); DigitalOut rx_led(LED2, 0); while(1) { // [X] - 1 - Wait until new data has arrived // ================= LOG("WAITING FOR TRIGGER"); osSignalWait(COMM_LINK_SIGNAL_RX_TRIGGER, osWaitForever); LOG("TRIGGERED"); // [X] - 2 - Get the received data from the external chip // ================= uint8_t rec_bytes = COMM_LINK_BUFFER_SIZE; RTP_t p; //uint8_t *buf_ptr = p.data; inst->getData(p.data, &rec_bytes); //p.port = p.data[0] & 0xF0; p.port = 8; p.subclass = p.data[0] & 0x0F; // [X] - 3 - Write the data to the CommModule object's rxQueue // ================= inst->_comm_module_ptr->receive(p); // [~] - 4 - Blink the RX LED for the hardware link // ================= rx_led = 1; osDelay(100); rx_led = 0; //osDelay(20); } } // Called by the derived class to begin thread operations void CommLink::ready(void) { osSignalSet(_txID, COMM_LINK_SIGNAL_START_THREAD); osSignalSet(_rxID, COMM_LINK_SIGNAL_START_THREAD); } void CommLink::write_tx_queue(RTP_t *p) { // [] - 1 - Write the data to the RX queue // ================= // [] - 2 - Signal the TX thread of new data // ================= } void CommLink::sendPacket(RTP_t *p) { sendData(p->data, sizeof(p->data)); } void CommLink::receivePacket(RTP_t *p) { } // Interrupt Service Routine - KEEP OPERATIONS TO ABOSOLUTE MINIMUM HERE AND IN ANY OVERRIDEN BASE CLASS IMPLEMENTATIONS OF THIS CLASS METHOD void CommLink::ISR(void) { osSignalSet(_rxID , COMM_LINK_SIGNAL_RX_TRIGGER); } void CommLink::toggle_cs(void) { *_cs = !*_cs; } void CommLink::triggerReceive(void) { CommLink::ISR(); } void CommLink::triggerTransmit(void) { osSignalSet(_txID , COMM_LINK_SIGNAL_TX_TRIGGER); } void CommLink::setCommModule(CommModule& com) { _comm_module_ptr = &com; osSignalSet(_rxID , COMM_LINK_SIGNAL_MODULE_LINKED); }