diff --git a/doc/releases/migration-guide-4.3.rst b/doc/releases/migration-guide-4.3.rst index 15fe5614f7f17..2fca8a480651e 100644 --- a/doc/releases/migration-guide-4.3.rst +++ b/doc/releases/migration-guide-4.3.rst @@ -93,6 +93,12 @@ MISC the ``NRF_ETR`` symbols. Also the driver needs to be explicitly enabled via :kconfig:option:`DEBUG_DRIVER` as it is no longer built by default. +Modem +===== + +* ``CONFIG_MODEM_CELLULAR_NEW_BAUDRATE`` has been removed. Updated baudrates + are now specified in devicetree as the ``target-speed`` property. + PWM === diff --git a/drivers/modem/Kconfig.cellular b/drivers/modem/Kconfig.cellular index cc746ff9770e5..aea9fe8f8f31b 100644 --- a/drivers/modem/Kconfig.cellular +++ b/drivers/modem/Kconfig.cellular @@ -63,12 +63,6 @@ config MODEM_CELLULAR_USER_PIPE_BUFFER_SIZES int "The size of the buffers used for each user pipe in bytes." default 128 -config MODEM_CELLULAR_NEW_BAUDRATE - int "New baudrate to configure modem to, if supported" - range 9600 4000000 - default 3000000 if DT_HAS_U_BLOX_LARA_R6_ENABLED - default 115200 - config MODEM_CELLULAR_NEW_BAUDRATE_DELAY int "Time modem takes to change baudrate, in milliseconds" range 0 1000 diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index 23ea498f8220f..44fc2225b30c9 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -108,6 +108,8 @@ struct modem_cellular_data { struct modem_backend_uart uart_backend; uint8_t uart_backend_receive_buf[CONFIG_MODEM_CELLULAR_UART_BUFFER_SIZES]; uint8_t uart_backend_transmit_buf[CONFIG_MODEM_CELLULAR_UART_BUFFER_SIZES]; + const char *target_baudrate_req; + uint32_t target_baudrate; uint32_t original_baudrate; /* CMUX */ @@ -1062,7 +1064,7 @@ static void modem_cellular_set_baudrate_event_handler(struct modem_cellular_data /* Update UART port baudrate and preserve the original value */ data->original_baudrate = modem_cellular_baudrate_update( - data, CONFIG_MODEM_CELLULAR_NEW_BAUDRATE); + data, data->target_baudrate); break; case MODEM_CELLULAR_EVENT_BUS_CLOSED: @@ -2181,6 +2183,14 @@ static void modem_cellular_init_apn(struct modem_cellular_data *data) modem_cellular_chat_callback_handler); } +__maybe_unused static uint16_t modem_baudrate_cmd(const uint8_t **request, void *user_data) +{ + struct modem_cellular_data *data = (struct modem_cellular_data *)user_data; + + *request = data->target_baudrate_req; + return strlen(*request); +} + static int modem_cellular_init(const struct device *dev) { struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data; @@ -2656,8 +2666,7 @@ MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r5_periodic_chat_script, #if DT_HAS_COMPAT_STATUS_OKAY(u_blox_lara_r6) MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_lara_r6_set_baudrate_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match), - MODEM_CHAT_SCRIPT_CMD_RESP("AT+IPR=" - STRINGIFY(CONFIG_MODEM_CELLULAR_NEW_BAUDRATE), ok_match)); + MODEM_CHAT_SCRIPT_CMD_RESP_FN(modem_baudrate_cmd, ok_match)); MODEM_CHAT_SCRIPT_DEFINE(u_blox_lara_r6_set_baudrate_chat_script, u_blox_lara_r6_set_baudrate_chat_script_cmds, @@ -3141,6 +3150,8 @@ MODEM_CHAT_SCRIPT_DEFINE(sqn_gm02s_periodic_chat_script, .chat_delimiter = "\r", \ .chat_filter = "\n", \ .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ + .target_baudrate_req = "AT+IPR=" STRINGIFY(DT_INST_PROP(inst, target_speed)), \ + .target_baudrate = DT_INST_PROP(inst, target_speed), \ }; \ \ MODEM_CELLULAR_DEFINE_AND_INIT_USER_PIPES(inst, \ diff --git a/dts/bindings/modem/u-blox,lara-r6.yaml b/dts/bindings/modem/u-blox,lara-r6.yaml index 12c802391e6b6..1e2daaf3d7f09 100644 --- a/dts/bindings/modem/u-blox,lara-r6.yaml +++ b/dts/bindings/modem/u-blox,lara-r6.yaml @@ -11,3 +11,10 @@ properties: mdm-power-gpios: type: phandle-array required: true + + target-speed: + type: int + default: 3000000 + description: + UART baudrate which will be requested using AT commands and to which + UART interface will be reconfigured during initialization phase. diff --git a/include/zephyr/modem/chat.h b/include/zephyr/modem/chat.h index e265c7c3b732b..d2d075453af07 100644 --- a/include/zephyr/modem/chat.h +++ b/include/zephyr/modem/chat.h @@ -104,12 +104,34 @@ extern const struct modem_chat_match modem_chat_any_match; /* Helper struct to match nothing. */ extern const struct modem_chat_match modem_chat_empty_matches[0]; +/* Special value that signifies union member is `request_fn`, not `request` */ +#define MODEM_CHAT_REQUEST_FN_LEN UINT16_MAX + +/** + * @brief Function that retrieves the request to send + * + * @note The lifetime of the output request pointer must match or exceed the + * lifetime of script_chat. + * + * @note This function can be called multiple times per request that is sent. + * + * @param request pointer to store the request in + * @param user_data modem chat user data + * + * @retval Length of @a request + */ +typedef uint16_t (*modem_chat_script_request_fn)(const uint8_t **request, void *user_data); + /** * @brief Modem chat script chat */ struct modem_chat_script_chat { - /** Request to send to modem */ - const uint8_t *request; + union { + /** Request to send to modem */ + const uint8_t *request; + /** Function that returns request to send to modem */ + modem_chat_script_request_fn request_fn; + }; /** Size of request */ uint16_t request_size; /** Expected responses to request */ @@ -147,6 +169,33 @@ struct modem_chat_script_chat { .timeout = _timeout_ms, \ } +#define MODEM_CHAT_SCRIPT_CMD_RESP_FN(_request_fn, _response_match) \ + { \ + .request_fn = _request_fn, \ + .request_size = MODEM_CHAT_REQUEST_FN_LEN, \ + .response_matches = &_response_match, \ + .response_matches_size = 1, \ + .timeout = 0, \ + } + +#define MODEM_CHAT_SCRIPT_CMD_RESP_MULT_FN(_request_fn, _response_matches) \ + { \ + .request_fn = _request_fn, \ + .request_size = MODEM_CHAT_REQUEST_FN_LEN, \ + .response_matches = _response_matches, \ + .response_matches_size = ARRAY_SIZE(_response_matches), \ + .timeout = 0, \ + } + +#define MODEM_CHAT_SCRIPT_CMD_RESP_NONE_FN(_request_fn, _timeout_ms) \ + { \ + .request_fn = _request_fn, \ + .request_size = MODEM_CHAT_REQUEST_FN_LEN, \ + .response_matches = NULL, \ + .response_matches_size = 0, \ + .timeout = _timeout_ms, \ + } + #define MODEM_CHAT_SCRIPT_CMDS_DEFINE(_sym, ...) \ const static struct modem_chat_script_chat _sym[] = {__VA_ARGS__} diff --git a/subsys/modem/modem_chat.c b/subsys/modem/modem_chat.c index 57f9e07aaa68c..cfd02389ad2b8 100644 --- a/subsys/modem/modem_chat.c +++ b/subsys/modem/modem_chat.c @@ -275,19 +275,24 @@ static bool modem_chat_send_script_request_part(struct modem_chat *chat) const struct modem_chat_script_chat *script_chat = &chat->script->script_chats[chat->script_chat_it]; - uint8_t *request_part; + const uint8_t *request_part; uint16_t request_size; uint16_t request_part_size; int ret; switch (chat->script_send_state) { case MODEM_CHAT_SCRIPT_SEND_STATE_REQUEST: - request_part = (uint8_t *)(&script_chat->request[chat->script_send_pos]); - request_size = script_chat->request_size; + if (script_chat->request_size == MODEM_CHAT_REQUEST_FN_LEN) { + request_size = script_chat->request_fn(&request_part, chat->user_data); + request_part += chat->script_send_pos; + } else { + request_part = (uint8_t *)(&script_chat->request[chat->script_send_pos]); + request_size = script_chat->request_size; + } break; case MODEM_CHAT_SCRIPT_SEND_STATE_DELIMITER: - request_part = (uint8_t *)(&chat->delimiter[chat->script_send_pos]); + request_part = &chat->delimiter[chat->script_send_pos]; request_size = chat->delimiter_size; break; @@ -1007,9 +1012,9 @@ int modem_chat_script_chat_set_request(struct modem_chat_script_chat *script_cha { size_t size; - size = strnlen(request, UINT16_MAX + 1); + size = strnlen(request, UINT16_MAX); - if (size == (UINT16_MAX + 1)) { + if (size == (UINT16_MAX)) { return -ENOMEM; } diff --git a/tests/subsys/modem/modem_chat/src/main.c b/tests/subsys/modem/modem_chat/src/main.c index c7e5492df8efa..9103a8de46b78 100644 --- a/tests/subsys/modem/modem_chat/src/main.c +++ b/tests/subsys/modem/modem_chat/src/main.c @@ -148,6 +148,18 @@ static void on_script_result(struct modem_chat *cmd, enum modem_chat_script_resu script_result_user_data = user_data; } +/*************************************************************************************************/ +/* Dynamic Command */ +/*************************************************************************************************/ + +static uint16_t modem_baudrate_cmd(const uint8_t **request, void *user_data) +{ + static const char cmd[] = "AT+IPR=921600"; + + *request = cmd; + return sizeof(cmd) - 1; +} + /*************************************************************************************************/ /* Script */ /*************************************************************************************************/ @@ -165,6 +177,7 @@ MODEM_CHAT_MATCHES_DEFINE(unsol_matches, MODEM_CHAT_MATCH("RDY", "", on_rdy), MODEM_CHAT_SCRIPT_CMDS_DEFINE( script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP("AT", ok_match), MODEM_CHAT_SCRIPT_CMD_RESP("ATE0", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP_FN(modem_baudrate_cmd, ok_match), MODEM_CHAT_SCRIPT_CMD_RESP("IMEI?", imei_match), MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), MODEM_CHAT_SCRIPT_CMD_RESP("AT+CREG?;+CGREG?", creg_match), MODEM_CHAT_SCRIPT_CMD_RESP("", cgreg_match), MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), @@ -345,6 +358,19 @@ ZTEST(modem_chat, test_script_no_error) k_msleep(100); + /* + * Script sends "AT+IPR=921600\r\n" + * Modem responds "OK\r\n" + */ + + modem_backend_mock_get(&mock, buffer, ARRAY_SIZE(buffer)); + zassert_true(memcmp(buffer, "AT+IPR=921600\r\n", sizeof("AT+IPR=921600\r\n") - 1) == 0, + "Request not sent as expected"); + + modem_backend_mock_put(&mock, ok_response, sizeof(ok_response) - 1); + + k_msleep(100); + /* * Script sends "IMEI?\r\n" * Modem responds "23412354123123\r\n"