
This is an example program that shows how to use the RadioHeadLite library, and does it using threads.
Dependencies: RadioHeadLite
Revision 1:75d533f15c95, committed 2018-11-26
- Comitter:
- rlanders73
- Date:
- Mon Nov 26 21:01:04 2018 +0000
- Parent:
- 0:f4015c8e84c3
- Child:
- 2:57fefd8ae87c
- Commit message:
- merged in _write and _read functions
Changed in this revision
--- a/USBDevice.lib Sat Nov 24 05:53:37 2018 +0000 +++ b/USBDevice.lib Mon Nov 26 21:01:04 2018 +0000 @@ -1,1 +1,1 @@ -https://os.mbed.com/teams/PointLabs/code/USBDeviceSTM32L476/#3d21c913753e +https://os.mbed.com/teams/PointLabs/code/USBDeviceSTM32L476/#772335cfca9a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBSerial_copy.cpp Mon Nov 26 21:01:04 2018 +0000 @@ -0,0 +1,106 @@ +/* Copyright (c) 2010-2011 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "stdint.h" +#include "USBSerial.h" + +int USBSerial::_putc(int c) { + if (!terminal_connected) + return 0; + send((uint8_t *)&c, 1); + return 1; +} + +int USBSerial::_getc() { + uint8_t c = 0; + while (buf.isEmpty()); + buf.dequeue(&c); + return c; +} + +int USBSerial::_read(void* buffer, int length) +{ + int data_read = 0; + + uint8_t *ptr = static_cast<uint8_t *>(buffer); + + if (length == 0) { + return 0; + } + + if (buf.isEmpty()) { + return -EAGAIN; + } + + while (data_read < length && !buf.isEmpty()) { + buf.dequeue(ptr++); + data_read++; + } + + return data_read; +} + +int USBSerial::_write(uint8_t * buf, uint16_t size) { + uint16_t sent = size; + + // This handles the case where we have more to send than one bulk frame + while(size > MAX_PACKET_SIZE_EPBULK && send(buf, MAX_PACKET_SIZE_EPBULK)) { + size -= MAX_PACKET_SIZE_EPBULK; + } + if(!send(buf, size)) { + return -EAGAIN; + } + return sent; +} + +bool USBSerial::writeBlock(uint8_t * buf, uint16_t size) { + if(size > MAX_PACKET_SIZE_EPBULK) { + return false; + } + if(!send(buf, size)) { + return false; + } + return true; +} + + + +bool USBSerial::EPBULK_OUT_callback() { + uint8_t c[65]; + uint32_t size = 0; + + //we read the packet received and put it on the circular buffer + readEP(c, &size); + for (uint32_t i = 0; i < size; i++) { + buf.queue(c[i]); + } + + //call a potential handlenr + if (rx) + rx.call(); + + return true; +} + +uint8_t USBSerial::available() { + return buf.available(); +} + +bool USBSerial::connected() { + return terminal_connected; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBSerial_copy.h Mon Nov 26 21:01:04 2018 +0000 @@ -0,0 +1,175 @@ +/* Copyright (c) 2010-2011 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef USBSERIAL_H +#define USBSERIAL_H + +#include "USBCDC.h" +#include "Stream.h" +#include "CircBuffer.h" +#include "Callback.h" + +/** +* USBSerial example +* +* @code +* #include "mbed.h" +* #include "USBSerial.h" +* +* //Virtual serial port over USB +* USBSerial serial; +* +* int main(void) { +* +* while(1) +* { +* serial.printf("I am a virtual serial port\n"); +* wait(1); +* } +* } +* @endcode +*/ +class USBSerial: public USBCDC, public Stream { +public: + + /** + * Constructor + * + * @param vendor_id Your vendor_id (default: 0x1f00) + * @param product_id Your product_id (default: 0x2012) + * @param product_release Your preoduct_release (default: 0x0001) + * @param connect_blocking define if the connection must be blocked if USB not plugged in + * + */ + USBSerial(uint16_t vendor_id = 0x1f00, uint16_t product_id = 0x2012, uint16_t product_release = 0x0001, bool connect_blocking = true): USBCDC(vendor_id, product_id, product_release, connect_blocking){ + settingsChangedCallback = 0; + }; + + + /** + * Send a character. You can use puts, printf. + * + * @param c character to be sent + * @returns true if there is no error, false otherwise + */ + virtual int _putc(int c); + + /** + * Read a character: blocking + * + * @returns character read + */ + virtual int _getc(); + + /** + * Read a string of characters + * + * @returns character read + */ + virtual int _read(void* buffer, int length); + virtual int _write(uint8_t * buf, uint16_t size); + /** + * Check the number of bytes available. + * + * @returns the number of bytes available + */ + uint8_t available(); + + /** + * Check if the terminal is connected. + * + * @returns connection status + */ + bool connected(); + + /** Determine if there is a character available to read + * + * @returns + * 1 if there is a character available to read, + * 0 otherwise + */ + int readable() { return available() ? 1 : 0; } + + /** Determine if there is space available to write a character + * + * @returns + * 1 if there is space to write a character, + * 0 otherwise + */ + int writeable() { return 1; } // always return 1, for write operation is blocking + + /** + * Write a block of data. + * + * For more efficiency, a block of size 64 (maximum size of a bulk endpoint) has to be written. + * + * @param buf pointer on data which will be written + * @param size size of the buffer. The maximum size of a block is limited by the size of the endpoint (64 bytes) + * + * @returns true if successfull + */ + bool writeBlock(uint8_t * buf, uint16_t size); + + /** + * Attach a member function to call when a packet is received. + * + * @param tptr pointer to the object to call the member function on + * @param mptr pointer to the member function to be called + */ + template<typename T> + void attach(T* tptr, void (T::*mptr)(void)) { + if((mptr != NULL) && (tptr != NULL)) { + rx.attach(tptr, mptr); + } + } + + /** + * Attach a callback called when a packet is received + * + * @param fptr function pointer + */ + void attach(void (*fptr)(void)) { + if(fptr != NULL) { + rx.attach(fptr); + } + } + + /** + * Attach a callback to call when serial's settings are changed. + * + * @param fptr function pointer + */ + void attach(void (*fptr)(int baud, int bits, int parity, int stop)) { + settingsChangedCallback = fptr; + } + +protected: + virtual bool EPBULK_OUT_callback(); + virtual void lineCodingChanged(int baud, int bits, int parity, int stop){ + if (settingsChangedCallback) { + settingsChangedCallback(baud, bits, parity, stop); + } + } + +private: + Callback<void()> rx; + CircBuffer<uint8_t,128> buf; + void (*settingsChangedCallback)(int baud, int bits, int parity, int stop); +}; + +#endif
--- a/main.cpp Sat Nov 24 05:53:37 2018 +0000 +++ b/main.cpp Mon Nov 26 21:01:04 2018 +0000 @@ -2,11 +2,11 @@ #include "USBSerial.h" #include "Geneva.h" -#define PASSTHROUGH 1 +#define PASSTHROUGH 0 /******************** Comms *********************/ USBSerial pc; // moved the pc interface to the USB serial device -Serial modemSerial(MDMTXD, MDMRXD, 115200); +UARTSerial modemUartSerial(MDMTXD, MDMRXD, 115200); DigitalInOut cellRst(MDMRST); @@ -27,9 +27,9 @@ InterruptIn *rxPin; DigitalOut samplePin(PA_0); -Thread passThread; +Thread myThread; - static char scanBuffer[512]; +static char scanBuffer[512]; static bool buttonWasPushed = false; typedef struct @@ -44,81 +44,41 @@ cellContext_t cell; -uint8_t buffer[64]; - -#if PASSTHROUGH -static void passthroughThread(void) -{ - - while (1) - { - // Housekeeping - check button - if (pc.readable()) - { - char c = pc.getc(); // grab the available character - pc.putc(c); // provide local echo - modemSerial.putc(c);// push the charcter to the modem - } - - if (modemSerial.readable()) - { - pc.putc(modemSerial.getc()); - } - } -} -#endif +char buffer[64]; static void buttonPushed(void) { buttonWasPushed = true; } - - - -int main(void) +#if PASSTHROUGH +static void passthroughThread(void) { - // Enable flow control on MDM uart - //modemUartSerial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS); - - buttonInt.mode(PullUp); - buttonInt.fall(buttonPushed); - - cellRst.mode(OpenDrainNoPull); - cellRst.output(); - cellRst = 1; - - cellPwrKey.mode(OpenDrainNoPull); - cellPwrKey.output(); - cellPwrKey = 1; + char c; + pc.printf("Passthrough mode\r\n"); + blueLed = 0; - wait(1); // wait just a bit for the USB to enumerate + while (1) + { + // Housekeeping - check button + if (pc.readable()) + { + c = pc.getc(); + modemUartSerial.write(&c, 1);// push the charcter to the modem + } - pc.printf("Modem Test\r\n", 12); - - pc.set_blocking(false); - modemSerial.set_blocking(false); - - // Power up the modem! - cellVcc = 1; - pc.printf("Modem VCC UP\r\n", 14); - wait(3); - - cellPwrKey = 0; - wait(0.9); - cellPwrKey = 1; - pc.printf("Modem Power\r\n", 13); - - redLed = 0; - - wait(5); - -#if PASSTHROUGH - pc.printf("Passthrough mode\r\n", 18); - blueLed = 0; - passThread.start(passthroughThread); + if (modemUartSerial.readable()) + { + modemUartSerial.read(&c, 1); + pc.putc(c); + } + } +} #else + +static void autoModeThread(void) +{ pc.printf("Auto mode\r\n", 11); cell.fileHandle = &modemUartSerial; @@ -193,7 +153,54 @@ } cell.rawParser->send("AT+COPS=2") && cell.rawParser->recv("OK"); +} +#endif +void setup(void) +{ + // Enable flow control on MDM uart + //modemUartSerial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS); + buttonInt.mode(PullUp); + buttonInt.fall(buttonPushed); + + cellRst.mode(OpenDrainNoPull); + cellRst.output(); + cellRst = 1; + + cellPwrKey.mode(OpenDrainNoPull); + cellPwrKey.output(); + cellPwrKey = 1; + + wait(1); // wait just a bit for the USB to enumerate + + pc.printf("Modem Test\r\n", 12); + + pc.set_blocking(false); + modemUartSerial.set_blocking(false); + + // Power up the modem! + cellVcc = 1; + pc.printf("Modem VCC UP\r\n", 14); + wait(3); + + cellPwrKey = 0; + wait(0.9); + cellPwrKey = 1; + pc.printf("Modem Power\r\n", 13); + + redLed = 0; + + wait(5); +} + +int main(void) +{ + setup(); + +#if PASSTHROUGH + myThread.start(passthroughThread); +#else + myThread.start(autoModeThread); #endif Thread::wait(osWaitForever);