Line data Source code
1 0 : /* 2 : * Copyright 2024 NXP 3 : * 4 : * SPDX-License-Identifier: Apache-2.0 5 : */ 6 : 7 : #include <zephyr/kernel.h> 8 : #include <zephyr/types.h> 9 : #include <zephyr/sys/atomic.h> 10 : 11 : #include <zephyr/modem/pipe.h> 12 : 13 : #ifndef ZEPHYR_MODEM_UBX_ 14 : #define ZEPHYR_MODEM_UBX_ 15 : 16 : #ifdef __cplusplus 17 : extern "C" { 18 : #endif 19 : 20 : /** 21 : * @brief Modem Ubx 22 : * @defgroup modem_ubx Modem Ubx 23 : * @ingroup modem 24 : * @{ 25 : */ 26 : 27 0 : #define UBX_FRM_HEADER_SZ 6 28 0 : #define UBX_FRM_FOOTER_SZ 2 29 0 : #define UBX_FRM_SZ_WITHOUT_PAYLOAD (UBX_FRM_HEADER_SZ + UBX_FRM_FOOTER_SZ) 30 0 : #define UBX_FRM_SZ(payload_size) (payload_size + UBX_FRM_SZ_WITHOUT_PAYLOAD) 31 : 32 0 : #define UBX_PREAMBLE_SYNC_CHAR_1 0xB5 33 0 : #define UBX_PREAMBLE_SYNC_CHAR_2 0x62 34 : 35 0 : #define UBX_FRM_PREAMBLE_SYNC_CHAR_1_IDX 0 36 0 : #define UBX_FRM_PREAMBLE_SYNC_CHAR_2_IDX 1 37 0 : #define UBX_FRM_MSG_CLASS_IDX 2 38 0 : #define UBX_FRM_MSG_ID_IDX 3 39 0 : #define UBX_FRM_PAYLOAD_SZ_L_IDX 4 40 0 : #define UBX_FRM_PAYLOAD_SZ_H_IDX 5 41 0 : #define UBX_FRM_PAYLOAD_IDX 6 42 0 : #define UBX_FRM_CHECKSUM_START_IDX 2 43 0 : #define UBX_FRM_CHECKSUM_STOP_IDX(frame_len) (frame_len - 2) 44 : 45 0 : #define UBX_PAYLOAD_SZ_MAX 256 46 0 : #define UBX_FRM_SZ_MAX UBX_FRM_SZ(UBX_PAYLOAD_SZ_MAX) 47 : 48 0 : struct ubx_frame { 49 0 : uint8_t preamble_sync_char_1; 50 0 : uint8_t preamble_sync_char_2; 51 0 : uint8_t message_class; 52 0 : uint8_t message_id; 53 0 : uint8_t payload_size_low; 54 0 : uint8_t payload_size_high; 55 0 : uint8_t payload_and_checksum[]; 56 : }; 57 : 58 0 : struct modem_ubx_script { 59 0 : struct ubx_frame *request; 60 0 : struct ubx_frame *response; 61 0 : struct ubx_frame *match; 62 : 63 0 : uint16_t retry_count; 64 0 : k_timeout_t timeout; 65 : }; 66 : 67 0 : struct modem_ubx { 68 0 : void *user_data; 69 : 70 0 : atomic_t state; 71 : 72 0 : uint8_t *receive_buf; 73 0 : uint16_t receive_buf_size; 74 : 75 0 : uint8_t *work_buf; 76 0 : uint16_t work_buf_size; 77 0 : uint16_t work_buf_len; 78 0 : bool ubx_preamble_sync_chars_received; 79 : 80 0 : const struct modem_ubx_script *script; 81 : 82 0 : struct modem_pipe *pipe; 83 : 84 0 : struct k_work send_work; 85 0 : struct k_work process_work; 86 0 : struct k_sem script_stopped_sem; 87 0 : struct k_sem script_running_sem; 88 : }; 89 : 90 0 : struct modem_ubx_config { 91 0 : void *user_data; 92 : 93 0 : uint8_t *receive_buf; 94 0 : uint16_t receive_buf_size; 95 0 : uint8_t *work_buf; 96 0 : uint16_t work_buf_size; 97 : }; 98 : 99 : /** 100 : * @brief Attach pipe to Modem Ubx 101 : * 102 : * @param ubx Modem Ubx instance 103 : * @param pipe Pipe instance to attach Modem Ubx instance to 104 : * @returns 0 if successful 105 : * @returns negative errno code if failure 106 : * @note Modem Ubx instance is enabled if successful 107 : */ 108 1 : int modem_ubx_attach(struct modem_ubx *ubx, struct modem_pipe *pipe); 109 : 110 : /** 111 : * @brief Release pipe from Modem Ubx instance 112 : * 113 : * @param ubx Modem Ubx instance 114 : */ 115 1 : void modem_ubx_release(struct modem_ubx *ubx); 116 : 117 : /** 118 : * @brief Initialize Modem Ubx instance 119 : * @param ubx Modem Ubx instance 120 : * @param config Configuration which shall be applied to the Modem Ubx instance 121 : * @note Modem Ubx instance must be attached to a pipe instance 122 : */ 123 1 : int modem_ubx_init(struct modem_ubx *ubx, const struct modem_ubx_config *config); 124 : 125 : /** 126 : * @brief Writes the ubx frame in script.request and reads back its response (if available) 127 : * @details For each ubx frame sent, the device responds in 0, 1 or both of the following ways: 128 : * 1. The device sends back a UBX-ACK frame to denote 'acknowledge' and 'not-acknowledge'. 129 : * Note: the message id of UBX-ACK frame determines whether the device acknowledged. 130 : * Ex: when we send a UBX-CFG frame, the device responds with a UBX-ACK frame. 131 : * 2. The device sends back the same frame that we sent to it, with it's payload populated. 132 : * It's used to get the current configuration corresponding to the frame that we sent. 133 : * Ex: frame types such as "get" or "poll" ubx frames respond this way. 134 : * This response (if received) is written to script.response. 135 : * 136 : * This function writes the ubx frame in script.request then reads back it's response. 137 : * If script.match is not NULL, then every ubx frame received from the device is compared with 138 : * script.match to check if a match occurred. This could be used to match UBX-ACK frame sent 139 : * from the device by populating script.match with UBX-ACK that the script expects to receive. 140 : * 141 : * The script terminates when either of the following happens: 142 : * 1. script.match is successfully received and matched. 143 : * 2. timeout (denoted by script.timeout) occurs. 144 : * @param ubx Modem Ubx instance 145 : * @param script Script to be executed 146 : * @note The length of ubx frame in the script.request should not exceed UBX_FRM_SZ_MAX 147 : * @note Modem Ubx instance must be attached to a pipe instance 148 : * @returns 0 if device acknowledged via UBX-ACK and no "get" response was received 149 : * @returns positive integer denoting the length of "get" response that was received 150 : * @returns negative errno code if failure 151 : */ 152 1 : int modem_ubx_run_script(struct modem_ubx *ubx, const struct modem_ubx_script *script); 153 : 154 : /** 155 : * @brief Initialize ubx frame 156 : * @param ubx_frame Ubx frame buffer 157 : * @param ubx_frame_size Ubx frame buffer size 158 : * @param msg_cls Message class 159 : * @param msg_id Message id 160 : * @param payload Payload buffer 161 : * @param payload_size Payload buffer size 162 : * @returns positive integer denoting the length of the ubx frame created 163 : * @returns negative errno code if failure 164 : */ 165 1 : int modem_ubx_create_frame(uint8_t *ubx_frame, uint16_t ubx_frame_size, uint8_t msg_cls, 166 : uint8_t msg_id, const void *payload, uint16_t payload_size); 167 : /** 168 : * @} 169 : */ 170 : 171 : #ifdef __cplusplus 172 : } 173 : #endif 174 : 175 : #endif /* ZEPHYR_MODEM_UBX_ */