bool modem_expect(const char *expected, uint32_t timeout) { char response[255] = {0}; size_t len, expected_len = strlen(expected); while (true) { len = modem_readline(response, BOARD_CELL_BUFSIZE - 1, timeout); if (len == 0) return false; if (check_urc(response) >= 0) continue; CIODEBUG("GSM (%02d) -> '%s'\r\n", len, response); return strncmp(expected, (const char *) response, MIN(len, expected_len)) == 0; } }
int modem_expect_scan(const char *pattern, uint32_t timeout, ...) { char response[BOARD_CELL_BUFSIZE]; va_list ap; do { modem_readline(response, BOARD_CELL_BUFSIZE - 1, timeout); } while (check_urc(response) != -1); CIODEBUG("GSM (%02d) -> '%s'\r\n", strlen(response), response); va_start(ap, timeout); int matched = vsscanf(response, pattern, ap); va_end(ap); return matched; }
uint32_t gsm_read( uint8_t num_lines, char ** line ) { uint32_t _size = 0; for(uint8_t i = 0;i < num_lines;i++) { vPortFree(line[i]); uint32_t _len = modem_readline(gsm.buff); line[i] = pvPortMalloc(_len); memcpy(line[i], gsm.buff, _len); _size += _len; } return _size; }
bool modem_expect_urc(int n, uint32_t timeout) { char response[128] = {0}; bool urc_found = false; do { const size_t len = modem_readline(response, BOARD_CELL_BUFSIZE - 1, timeout); if (!len) break; int r = check_urc(response); urc_found = r == n; #ifndef NDEBUG if (r == 0 && !urc_found) { CIODEBUG("GSM .... ?? "); for (int i = 0; i < len; i++) CIODEBUG("%02x '%c' ", *(response + i), *(response + i)); CIODEBUG("\r\n"); } #endif } while (!urc_found); return urc_found; }
void modem_send(const char *pattern, ...) { char cmd[BOARD_CELL_BUFSIZE]; // cleanup the input buffer and check for URC messages uint32_t remaining = timer_timeout_remaining(); while (modem_readline(cmd, BOARD_CELL_BUFSIZE - 1, 100)) check_urc(cmd); timer_set_timeout(remaining); cmd[0] = '\0'; va_list ap; va_start(ap, pattern); vsnprintf(cmd, BOARD_CELL_BUFSIZE, pattern, ap); va_end(ap); CIODEBUG("GSM (%02d) <- '%s'\r\n", strlen(cmd), cmd); modem_writeline(cmd); }
bool modem_enable() { char response[10]; size_t len; #if BOARD_CELL_PWR_DOMAIN CSTDEBUG("GSM #### -- power on\r\n"); GPIO_WritePinOutput(BOARD_CELL_PWR_EN_GPIO, BOARD_CELL_PWR_EN_PIN, true); // TODO check that power has come up correctly #endif // after enabling power, power on the SIM800 while (modem_read() != -1) /* clear buffer */; // we need to identify if the chip is already on by sending AT commands // send AT and just ignore the echo and OK to get into a stable state // sometimes there is initial noise on the serial line modem_send("AT"); len = modem_readline(response, 9, 500); CIODEBUG("GSM (%02d) -> '%s'\r\n", len, response); len = modem_readline(response, 9, 500); CIODEBUG("GSM (%02d) -> '%s'\r\n", len, response); // now identify if the chip is actually on, by issue AT and expecting something // if we can't read a response, either AT or OK, we need to run the power on sequence modem_send("AT"); len = modem_readline(response, 9, 1000); CIODEBUG("GSM (%02d) -> '%s'\r\n", len, response); if (!len) { CSTDEBUG("GSM #### !! trigger PWRKEY\r\n"); #if defined(BOARD_UBIRCH_1R02) // there is a bug in the circuit on the board which does not use an extra // transistor to switch the PWRKEY pin, so the signals are reversed // power on the SIM800H GPIO_WritePinOutput(BOARD_CELL_PIN_GPIO, BOARD_CELL_PWRKEY_PIN, true); delay(10); //10ms GPIO_WritePinOutput(BOARD_CELL_PIN_GPIO, BOARD_CELL_PWRKEY_PIN, false); delay(1100); // 1.1s GPIO_WritePinOutput(BOARD_CELL_PIN_GPIO, BOARD_CELL_PWRKEY_PIN, true); #else // power on the cell phone chip GPIO_WritePinOutput(BOARD_CELL_PIN_GPIO, BOARD_CELL_PWRKEY_PIN, false); delay(10); //10ms GPIO_WritePinOutput(BOARD_CELL_PIN_GPIO, BOARD_CELL_PWRKEY_PIN, true); delay(1100); // 1.1s GPIO_WritePinOutput(BOARD_CELL_PIN_GPIO, BOARD_CELL_PWRKEY_PIN, false); #endif } else { CSTDEBUG("GSM #### !! already on\r\n"); } bool is_on = false; // wait for the chip to boot and react to commands for (int i = 0; i < 5; i++) { modem_send("ATE0"); // if we still have echo on, this fails and falls through to the next OK if ((is_on = modem_expect_OK(1000))) break; if ((is_on = modem_expect_OK(1000))) break; } return is_on; }