/** * \Brief ATSAMD20 UART w/ Quectel-M95 * * \Application: SMS TX-RX Store selected message contents on EEPROM DTMF symbol structure and decision making */ /* ---------------------------HEADERS-------------------------- */ #include #include #include /* ----------------------------MACROS-------------------------- */ #define MAX_RX_BUFFER_LENGTH 1 /* --------------------------FUNCTIONS------------------------- */ /* EDBG UART functions */ void usart_read_callback(struct usart_module *const usart_module); void usart_write_callback(struct usart_module *const usart_module); void configure_usart(void); void configure_usart_callbacks(void); /* EXT1 UART Module - SERCOM4 */ void usart2_read_callback(struct usart_module *const usart_module); void usart2_write_callback(struct usart_module *const usart_module); void configure_usart2(void); void configure_usart2_callbacks(void); /* EEPROM and BOD config functions */ void configure_eeprom(void); static void configure_bod(void); /* AT commands response functions */ void OK_Status(void); void ATE0(void); void AT(void); void AT_CMGF(void); void AT_CMGS(void); void AT_CMGS2(void); void AT_CMGR(void); void CMGR_RESP(void); void CMGS_RESP(void); void CMGS2_RESP(void); void CR_LF(void); /* ----------------------------STRUCTS----------------------------- */ struct usart_module usart_instance; struct usart_module usart2_instance; /* ---------------------VARIABLE DECLARATIONS---------------------- */ //volatile uint8_t rx_buffer[EEPROM_PAGE_SIZE] = ""; uint8_t ee_buffer[EEPROM_PAGE_SIZE] = ""; //\r\n+CMGR: \"REC READ\",\"+917745095886\",\"\",\"2020/12/13 10:39:31+22\"\r\nQuectel M95 testing.\r\n\r\nOK uint8_t msg_buffer[EEPROM_PAGE_SIZE] = ""; // Received message buffer, write EEPROM page parameter uint8_t rxdata1[EEPROM_PAGE_SIZE]; // Read EEPROM page parameter uint8_t rxdata2[EEPROM_PAGE_SIZE]; // Read EEPROM page parameter int i = 0; // ee/rx buffer element uint8_t cr = 0x0D; // Carriage return uint8_t lf = 0x0A; // Line feed uint8_t ati[] = "ATI\r\n"; // Module info uint8_t ate0[] = "ATE0\r\n"; // ATE0 uint8_t at_ok[] = "AT\r\n"; // AT-OK uint8_t at_cmgf[] = "AT+CMGF=1\r\n"; // Select the TExt mode for SMS uint8_t at_cmgs[] = "AT+CMGS=\"9082284496\"\r\n";// Send SMS to the number uint8_t at_cmgs2[] = "AT+CMGS=\"7745095886\"\r\n"; uint8_t ctrl_z = 0x1A; // End char to commence msg sending (Substitution) uint8_t at_cmgr[] = "AT+CMGR=1\r\n"; // Read Text mode Rxd SMS uint8_t crlf[] = "\n\r"; // Line feed + carriage return uint8_t ack[] = "Ack msg rxd\r\n"; // Ack sent to the number whose text is stored /* ---------------------FUNCTION DEFINITIONS---------------------- */ void usart_read_callback(struct usart_module *const usart_module) { usart_write_buffer_job(&usart2_instance, (uint8_t *)rx_buffer, MAX_RX_BUFFER_LENGTH); } void usart_write_callback(struct usart_module *const usart_module) { // port_pin_toggle_output_level(LED_0_PIN); } void usart2_read_callback(struct usart_module *const usart_module) { usart_write_buffer_job(&usart_instance, (uint8_t *)rx_buffer, MAX_RX_BUFFER_LENGTH); } void usart2_write_callback(struct usart_module *const usart_module) { // port_pin_toggle_output_level(LED_0_PIN); } //! [setup] void configure_usart(void) { //! [setup_config] struct usart_config config_usart; //! [setup_config] //! [setup_config_defaults] usart_get_config_defaults(&config_usart); //! [setup_config_defaults] config_usart.baudrate = 115200; config_usart.mux_setting = EDBG_CDC_SERCOM_MUX_SETTING; config_usart.pinmux_pad0 = EDBG_CDC_SERCOM_PINMUX_PAD0; config_usart.pinmux_pad1 = EDBG_CDC_SERCOM_PINMUX_PAD1; config_usart.pinmux_pad2 = EDBG_CDC_SERCOM_PINMUX_PAD2; config_usart.pinmux_pad3 = EDBG_CDC_SERCOM_PINMUX_PAD3; //! [setup_change_config] //! [setup_set_config] while (usart_init(&usart_instance, EDBG_CDC_MODULE, &config_usart) != STATUS_OK) { } //! [setup_set_config] //! [setup_enable] usart_enable(&usart_instance); //! [setup_enable] } void configure_usart2(void) { struct usart_config config_usart2; usart_get_config_defaults(&config_usart2); config_usart2.baudrate = 115200; config_usart2.mux_setting = EXT1_UART_SERCOM_MUX_SETTING; config_usart2.pinmux_pad0 = EXT1_UART_SERCOM_PINMUX_PAD0; config_usart2.pinmux_pad1 = EXT1_UART_SERCOM_PINMUX_PAD1; config_usart2.pinmux_pad2 = EXT1_UART_SERCOM_PINMUX_PAD2; config_usart2.pinmux_pad3 = EXT1_UART_SERCOM_PINMUX_PAD3; while (usart_init(&usart2_instance, EXT1_UART_MODULE, &config_usart2) != STATUS_OK) { } usart_enable(&usart2_instance); } void configure_usart_callbacks(void) { //! [setup_register_callbacks] usart_register_callback(&usart_instance, usart_write_callback, USART_CALLBACK_BUFFER_TRANSMITTED); usart_register_callback(&usart_instance, usart_read_callback, USART_CALLBACK_BUFFER_RECEIVED); //! [setup_register_callbacks] //! [setup_enable_callbacks] usart_enable_callback(&usart_instance, USART_CALLBACK_BUFFER_TRANSMITTED); usart_enable_callback(&usart_instance, USART_CALLBACK_BUFFER_RECEIVED); //! [setup_enable_callbacks] } void configure_usart2_callbacks(void) { usart_register_callback(&usart2_instance, usart2_write_callback, USART_CALLBACK_BUFFER_TRANSMITTED); usart_register_callback(&usart2_instance, usart2_read_callback, USART_CALLBACK_BUFFER_RECEIVED); usart_enable_callback(&usart2_instance, USART_CALLBACK_BUFFER_TRANSMITTED); usart_enable_callback(&usart2_instance, USART_CALLBACK_BUFFER_RECEIVED); } /* EEPROM config function */ void configure_eeprom(void) { /* Setup EEPROM emulator service */ //! [init_eeprom_service] enum status_code error_code = eeprom_emulator_init(); //! [init_eeprom_service] //! [check_init_ok] if (error_code == STATUS_ERR_NO_MEMORY) { while (true) { /* No EEPROM section has been set in the device's fuses */ } } //! [check_init_ok] //! [check_re-init] else if (error_code != STATUS_OK) { /* Erase the emulated EEPROM memory (assume it is unformatted or * irrecoverably corrupt) */ eeprom_emulator_erase_memory(); eeprom_emulator_init(); } //! [check_re-init] } #if (SAMD || SAMR21) void SYSCTRL_Handler(void) { if (SYSCTRL->INTFLAG.reg & SYSCTRL_INTFLAG_BOD33DET) { SYSCTRL->INTFLAG.reg = SYSCTRL_INTFLAG_BOD33DET; eeprom_emulator_commit_page_buffer(); } } #endif static void configure_bod(void) { #if (SAMD || SAMR21) struct bod_config config_bod33; bod_get_config_defaults(&config_bod33); config_bod33.action = BOD_ACTION_INTERRUPT; /* BOD33 threshold level is about 3.2V */ config_bod33.level = 48; bod_set_config(BOD_BOD33, &config_bod33); bod_enable(BOD_BOD33); SYSCTRL->INTENSET.reg = SYSCTRL_INTENCLR_BOD33DET; system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_SYSCTRL); #endif } /* AT Commands send functions */ void ATE0(void) { usart_write_buffer_wait(&usart_instance, ate0, sizeof(ate0)); //Send a string to PC usart_write_buffer_wait(&usart2_instance, ate0, sizeof(ate0)); //Send a string to GSM OK_Status(); } void AT(void) { usart_write_buffer_wait(&usart_instance, at_ok, sizeof(at_ok)); //Send a string to PC usart_write_buffer_wait(&usart2_instance, at_ok, sizeof(at_ok)); //Send a string to GSM OK_Status(); } void AT_CMGF(void) { usart_write_buffer_wait(&usart_instance, at_cmgf, sizeof(at_cmgf)); //Send a string to PC usart_write_buffer_wait(&usart2_instance, at_cmgf, sizeof(at_cmgf)); //Send a string to GSM OK_Status(); } void AT_CMGR(void) { usart_write_buffer_wait(&usart_instance, at_cmgr, sizeof(at_cmgr)); //Send a string to PC usart_write_buffer_wait(&usart2_instance, at_cmgr, sizeof(at_cmgr)); //Send a string to GSM CMGR_RESP(); } void CR_LF(void) { usart_write_buffer_wait(&usart_instance, crlf, sizeof(crlf)); //Send a string to PC } void AT_CMGS(void) { usart_write_buffer_wait(&usart_instance, at_cmgs, sizeof(at_cmgs)); //Send a string to PC usart_write_buffer_wait(&usart2_instance, at_cmgs, sizeof(at_cmgs)); //Send a string to GSM CMGS_RESP(); } void AT_CMGS2(void) { usart_write_buffer_wait(&usart_instance, at_cmgs2, sizeof(at_cmgs2)); //Send a string to PC usart_write_buffer_wait(&usart2_instance, at_cmgs2, sizeof(at_cmgs2)); //Send a string to GSM CMGS2_RESP(); } /* AT commands response functions */ void OK_Status(void) { while (strncmp((char*)rx_buffer, "K", 1) != 0) { usart_read_buffer_job(&usart2_instance, (uint8_t *)rx_buffer, 1); //Read op-check from GSM } rx_buffer[0] = '\0'; } void CMGR_RESP(void) { do { usart_read_buffer_job(&usart2_instance, (uint8_t *)rx_buffer, 1); //Read op-check from GSM strncpy((char*)ee_buffer, (char*)rx_buffer, 1); } while (strncmp((char*)rx_buffer, "K", 1) != 0); rx_buffer[0] = '\0'; } void CMGS_RESP(void) { port_pin_toggle_output_level(LED_0_PIN); while (strncmp((char*)rx_buffer, ">", 1) != 0) { usart_read_buffer_job(&usart2_instance, (uint8_t *)rx_buffer, 1); //Read op-check from GSM } usart_write_buffer_wait(&usart2_instance, (uint8_t *)rxdata1, sizeof(rxdata1)); usart_write_wait(&usart2_instance, ctrl_z); rx_buffer[0] = '\0'; } void CMGS2_RESP(void) { while (strncmp((char*)rx_buffer, ">", 1) != 0) { usart_read_buffer_job(&usart2_instance, (uint8_t *)rx_buffer, 1); //Read op-check from GSM } usart_write_buffer_wait(&usart2_instance, (uint8_t *)ack, sizeof(ack)); usart_write_wait(&usart2_instance, ctrl_z); rx_buffer[0] = '\0'; } /* ------------------------------MAIN----------------------------- */ int main(void) { system_init(); //! [setup_init] configure_eeprom(); configure_bod(); //! [setup_init] //! [setup_init] configure_usart(); configure_usart_callbacks(); configure_usart2(); configure_usart2_callbacks(); //! [setup_init] //! [main] //! [enable_global_interrupts] system_interrupt_enable_global(); //! [enable_global_interrupts] //! [main_send_string] ATE0(); CR_LF(); delay_ms(200); AT(); CR_LF(); delay_ms(200); AT_CMGF(); CR_LF(); delay_ms(200); AT_CMGR(); //! [main_send_string] /* Write the received message to EEPROM page */ eeprom_emulator_write_page(0, ee_buffer); eeprom_emulator_commit_page_buffer(); enum status_code rd_cd = eeprom_emulator_read_page(0, rxdata1); if (rd_cd == STATUS_OK) { usart_write_buffer_wait(&usart_instance, (uint8_t*)rxdata1, sizeof(rxdata1)); port_pin_toggle_output_level(LED_0_PIN); } delay_s(5); // if (strncmp((char*)rx_buffer, "\0", 1) != 0) // { // AT_CMGS(); // CR_LF(); // } //! [main_loop] while (true) { //! [main_loop] //! [main_read] usart_read_buffer_job(&usart_instance, (uint8_t *)rx_buffer, MAX_RX_BUFFER_LENGTH); usart_read_buffer_job(&usart2_instance, (uint8_t *)rx_buffer, MAX_RX_BUFFER_LENGTH); //! [main_read] } //! [main] }