driver for the WNC M14A2A Cellular Data Module

Committer:
JMF
Date:
Tue Feb 06 16:10:48 2018 +0000
Revision:
0:6a2d96c2a520
Incorporating changes suggested by ARM

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JMF 0:6a2d96c2a520 1 /*
JMF 0:6a2d96c2a520 2 Copyright (c) 2016 Fred Kellerman
JMF 0:6a2d96c2a520 3
JMF 0:6a2d96c2a520 4 Permission is hereby granted, free of charge, to any person obtaining a copy
JMF 0:6a2d96c2a520 5 of this software and associated documentation files (the "Software"), to deal
JMF 0:6a2d96c2a520 6 in the Software without restriction, including without limitation the rights
JMF 0:6a2d96c2a520 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
JMF 0:6a2d96c2a520 8 copies of the Software, and to permit persons to whom the Software is
JMF 0:6a2d96c2a520 9 furnished to do so, subject to the following conditions:
JMF 0:6a2d96c2a520 10
JMF 0:6a2d96c2a520 11 The above copyright notice and this permission notice shall be included in
JMF 0:6a2d96c2a520 12 all copies or substantial portions of the Software.
JMF 0:6a2d96c2a520 13
JMF 0:6a2d96c2a520 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
JMF 0:6a2d96c2a520 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
JMF 0:6a2d96c2a520 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
JMF 0:6a2d96c2a520 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
JMF 0:6a2d96c2a520 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
JMF 0:6a2d96c2a520 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
JMF 0:6a2d96c2a520 20 THE SOFTWARE.
JMF 0:6a2d96c2a520 21
JMF 0:6a2d96c2a520 22 @file WncControllerK64F.cpp
JMF 0:6a2d96c2a520 23 @purpose Contains K64F and mbed specifics to control the WNC modem using the WncController base class.
JMF 0:6a2d96c2a520 24 @version 1.0
JMF 0:6a2d96c2a520 25 @date July 2016
JMF 0:6a2d96c2a520 26 @author Fred Kellerman
JMF 0:6a2d96c2a520 27 */
JMF 0:6a2d96c2a520 28
JMF 0:6a2d96c2a520 29 #include "WncControllerK64F.h"
JMF 0:6a2d96c2a520 30
JMF 0:6a2d96c2a520 31 using namespace WncControllerK64F_fk;
JMF 0:6a2d96c2a520 32
JMF 0:6a2d96c2a520 33 WncControllerK64F::WncControllerK64F(struct WncGpioPinListK64F * pPins, BufferedSerial * wnc_uart, WNCDebug * debug_uart)
JMF 0:6a2d96c2a520 34 {
JMF 0:6a2d96c2a520 35 m_logTimer.start(); // Start the log timer now!
JMF 0:6a2d96c2a520 36 m_pDbgUart = debug_uart;
JMF 0:6a2d96c2a520 37 m_pWncUart = wnc_uart;
JMF 0:6a2d96c2a520 38 m_gpioPinList = *pPins;
JMF 0:6a2d96c2a520 39 }
JMF 0:6a2d96c2a520 40
JMF 0:6a2d96c2a520 41 bool WncControllerK64F::enterWncTerminalMode(BufferedSerial * pUart, bool echoOn)
JMF 0:6a2d96c2a520 42 {
JMF 0:6a2d96c2a520 43 if (pUart == NULL)
JMF 0:6a2d96c2a520 44 return (false); // Need a uart!
JMF 0:6a2d96c2a520 45
JMF 0:6a2d96c2a520 46 string * resp;
JMF 0:6a2d96c2a520 47 AtCmdErr_e r = sendWncCmd("AT", &resp, 500);
JMF 0:6a2d96c2a520 48 if (r == WNC_AT_CMD_TIMEOUT)
JMF 0:6a2d96c2a520 49 return (false);
JMF 0:6a2d96c2a520 50
JMF 0:6a2d96c2a520 51 pUart->puts("\r\nEntering WNC Terminal Mode - press <CTRL>-Q to exit!\r\n");
JMF 0:6a2d96c2a520 52
JMF 0:6a2d96c2a520 53 while (1) {
JMF 0:6a2d96c2a520 54 if (pUart->readable()) {
JMF 0:6a2d96c2a520 55 char c = pUart->getc();
JMF 0:6a2d96c2a520 56 if (c == '\x11') {
JMF 0:6a2d96c2a520 57 pUart->puts("\r\nExiting WNC Terminal Mode!\r\n");
JMF 0:6a2d96c2a520 58 // Cleanup in case user doesn't finish command:
JMF 0:6a2d96c2a520 59 sendWncCmd("AT", &resp, 300);
JMF 0:6a2d96c2a520 60 // Above AT may fail but should get WNC back in sync
JMF 0:6a2d96c2a520 61 return (sendWncCmd("AT", &resp, 500) == WNC_AT_CMD_OK);
JMF 0:6a2d96c2a520 62 }
JMF 0:6a2d96c2a520 63 if (echoOn == true) {
JMF 0:6a2d96c2a520 64 pUart->putc(c);
JMF 0:6a2d96c2a520 65 }
JMF 0:6a2d96c2a520 66 m_pWncUart->putc(c);
JMF 0:6a2d96c2a520 67 }
JMF 0:6a2d96c2a520 68 if (m_pWncUart->readable())
JMF 0:6a2d96c2a520 69 pUart->putc(m_pWncUart->getc());
JMF 0:6a2d96c2a520 70 }
JMF 0:6a2d96c2a520 71 }
JMF 0:6a2d96c2a520 72
JMF 0:6a2d96c2a520 73 int WncControllerK64F::putc(char c)
JMF 0:6a2d96c2a520 74 {
JMF 0:6a2d96c2a520 75 return (m_pWncUart->putc(c));
JMF 0:6a2d96c2a520 76 }
JMF 0:6a2d96c2a520 77
JMF 0:6a2d96c2a520 78 int WncControllerK64F::puts(const char * s)
JMF 0:6a2d96c2a520 79 {
JMF 0:6a2d96c2a520 80 return (m_pWncUart->puts(s));
JMF 0:6a2d96c2a520 81 }
JMF 0:6a2d96c2a520 82
JMF 0:6a2d96c2a520 83 char WncControllerK64F::getc(void)
JMF 0:6a2d96c2a520 84 {
JMF 0:6a2d96c2a520 85 return (m_pWncUart->getc());
JMF 0:6a2d96c2a520 86 }
JMF 0:6a2d96c2a520 87
JMF 0:6a2d96c2a520 88 int WncControllerK64F::charReady(void)
JMF 0:6a2d96c2a520 89 {
JMF 0:6a2d96c2a520 90 return (m_pWncUart->readable());
JMF 0:6a2d96c2a520 91 }
JMF 0:6a2d96c2a520 92
JMF 0:6a2d96c2a520 93 int WncControllerK64F::dbgWriteChar(char b)
JMF 0:6a2d96c2a520 94 {
JMF 0:6a2d96c2a520 95 if (m_pDbgUart != NULL)
JMF 0:6a2d96c2a520 96 return (m_pDbgUart->putc(b));
JMF 0:6a2d96c2a520 97 else
JMF 0:6a2d96c2a520 98 return (0);
JMF 0:6a2d96c2a520 99 }
JMF 0:6a2d96c2a520 100
JMF 0:6a2d96c2a520 101 int WncControllerK64F::dbgWriteChars(const char * b)
JMF 0:6a2d96c2a520 102 {
JMF 0:6a2d96c2a520 103 if (m_pDbgUart != NULL)
JMF 0:6a2d96c2a520 104 return (m_pDbgUart->puts(b));
JMF 0:6a2d96c2a520 105 else
JMF 0:6a2d96c2a520 106 return (0);
JMF 0:6a2d96c2a520 107 }
JMF 0:6a2d96c2a520 108
JMF 0:6a2d96c2a520 109 bool WncControllerK64F::initWncModem(uint8_t powerUpTimeoutSecs)
JMF 0:6a2d96c2a520 110 {
JMF 0:6a2d96c2a520 111 // Hard reset the modem (doesn't go through
JMF 0:6a2d96c2a520 112 // the signal level translator)
JMF 0:6a2d96c2a520 113 *m_gpioPinList.mdm_reset = 0;
JMF 0:6a2d96c2a520 114
JMF 0:6a2d96c2a520 115 // disable signal level translator (necessary
JMF 0:6a2d96c2a520 116 // for the modem to boot properly). All signals
JMF 0:6a2d96c2a520 117 // except mdm_reset go through the level translator
JMF 0:6a2d96c2a520 118 // and have internal pull-up/down in the module. While
JMF 0:6a2d96c2a520 119 // the level translator is disabled, these pins will
JMF 0:6a2d96c2a520 120 // be in the correct state.
JMF 0:6a2d96c2a520 121 *m_gpioPinList.shield_3v3_1v8_sig_trans_ena = 0;
JMF 0:6a2d96c2a520 122
JMF 0:6a2d96c2a520 123 // While the level translator is disabled and ouptut pins
JMF 0:6a2d96c2a520 124 // are tristated, make sure the inputs are in the same state
JMF 0:6a2d96c2a520 125 // as the WNC Module pins so that when the level translator is
JMF 0:6a2d96c2a520 126 // enabled, there are no differences.
JMF 0:6a2d96c2a520 127 *m_gpioPinList.mdm_uart2_rx_boot_mode_sel = 1; // UART2_RX should be high
JMF 0:6a2d96c2a520 128 *m_gpioPinList.mdm_power_on = 0; // powr_on should be low
JMF 0:6a2d96c2a520 129 *m_gpioPinList.mdm_wakeup_in = 1; // wake-up should be high
JMF 0:6a2d96c2a520 130 *m_gpioPinList.mdm_uart1_cts = 0; // indicate that it is ok to send
JMF 0:6a2d96c2a520 131
JMF 0:6a2d96c2a520 132 // Now, wait for the WNC Module to perform its initial boot correctly
JMF 0:6a2d96c2a520 133 waitMs(1000);
JMF 0:6a2d96c2a520 134
JMF 0:6a2d96c2a520 135 // The WNC module initializes comms at 115200 8N1 so set it up
JMF 0:6a2d96c2a520 136 m_pWncUart->baud(115200);
JMF 0:6a2d96c2a520 137
JMF 0:6a2d96c2a520 138 //Now, enable the level translator, the input pins should now be the
JMF 0:6a2d96c2a520 139 //same as how the M14A module is driving them with internal pull ups/downs.
JMF 0:6a2d96c2a520 140 //When enabled, there will be no changes in these 4 pins...
JMF 0:6a2d96c2a520 141 *m_gpioPinList.shield_3v3_1v8_sig_trans_ena = 1;
JMF 0:6a2d96c2a520 142
JMF 0:6a2d96c2a520 143 bool res = waitForPowerOnModemToRespond(powerUpTimeoutSecs);
JMF 0:6a2d96c2a520 144
JMF 0:6a2d96c2a520 145 // Toggle wakeup to prevent future dropped 'A' of "AT", this was
JMF 0:6a2d96c2a520 146 // suggested by ATT.
JMF 0:6a2d96c2a520 147 if (res == true) {
JMF 0:6a2d96c2a520 148 dbgPuts("\r\nToggling Wakeup...");
JMF 0:6a2d96c2a520 149 waitMs(20);
JMF 0:6a2d96c2a520 150 *m_gpioPinList.mdm_wakeup_in = 0;
JMF 0:6a2d96c2a520 151 waitMs(2000);
JMF 0:6a2d96c2a520 152 *m_gpioPinList.mdm_wakeup_in = 1;
JMF 0:6a2d96c2a520 153 waitMs(20);
JMF 0:6a2d96c2a520 154 dbgPuts("Toggling complete.");
JMF 0:6a2d96c2a520 155 }
JMF 0:6a2d96c2a520 156
JMF 0:6a2d96c2a520 157 return (res);
JMF 0:6a2d96c2a520 158 }
JMF 0:6a2d96c2a520 159
JMF 0:6a2d96c2a520 160 void WncControllerK64F::waitMs(int t)
JMF 0:6a2d96c2a520 161 {
JMF 0:6a2d96c2a520 162 wait_ms(t);
JMF 0:6a2d96c2a520 163 }
JMF 0:6a2d96c2a520 164
JMF 0:6a2d96c2a520 165 void WncControllerK64F::waitUs(int t)
JMF 0:6a2d96c2a520 166 {
JMF 0:6a2d96c2a520 167 wait_ms(t);
JMF 0:6a2d96c2a520 168 }
JMF 0:6a2d96c2a520 169
JMF 0:6a2d96c2a520 170 int WncControllerK64F::getLogTimerTicks(void)
JMF 0:6a2d96c2a520 171 {
JMF 0:6a2d96c2a520 172 return (m_logTimer.read_us());
JMF 0:6a2d96c2a520 173 }
JMF 0:6a2d96c2a520 174
JMF 0:6a2d96c2a520 175 void WncControllerK64F::startTimerA(void)
JMF 0:6a2d96c2a520 176 {
JMF 0:6a2d96c2a520 177 m_timerA.start();
JMF 0:6a2d96c2a520 178 m_timerA.reset();
JMF 0:6a2d96c2a520 179 }
JMF 0:6a2d96c2a520 180
JMF 0:6a2d96c2a520 181 void WncControllerK64F::stopTimerA(void)
JMF 0:6a2d96c2a520 182 {
JMF 0:6a2d96c2a520 183 m_timerA.stop();
JMF 0:6a2d96c2a520 184 }
JMF 0:6a2d96c2a520 185
JMF 0:6a2d96c2a520 186 int WncControllerK64F::getTimerTicksA_mS(void)
JMF 0:6a2d96c2a520 187 {
JMF 0:6a2d96c2a520 188 return (m_timerA.read_ms());
JMF 0:6a2d96c2a520 189 }
JMF 0:6a2d96c2a520 190
JMF 0:6a2d96c2a520 191 void WncControllerK64F::startTimerB(void)
JMF 0:6a2d96c2a520 192 {
JMF 0:6a2d96c2a520 193 m_timerB.start();
JMF 0:6a2d96c2a520 194 m_timerB.reset();
JMF 0:6a2d96c2a520 195 }
JMF 0:6a2d96c2a520 196
JMF 0:6a2d96c2a520 197 void WncControllerK64F::stopTimerB(void)
JMF 0:6a2d96c2a520 198 {
JMF 0:6a2d96c2a520 199 m_timerB.stop();
JMF 0:6a2d96c2a520 200 }
JMF 0:6a2d96c2a520 201
JMF 0:6a2d96c2a520 202 int WncControllerK64F::getTimerTicksB_mS(void)
JMF 0:6a2d96c2a520 203 {
JMF 0:6a2d96c2a520 204 return (m_timerB.read_ms());
JMF 0:6a2d96c2a520 205 }
JMF 0:6a2d96c2a520 206