11/*
2- * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
2+ * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
33 *
44 * SPDX-License-Identifier: Apache-2.0
55 */
@@ -141,21 +141,22 @@ esp_err_t gdma_del_link_list(gdma_link_list_handle_t list)
141141 return ESP_OK ;
142142}
143143
144- esp_err_t gdma_link_mount_buffers (gdma_link_list_handle_t list , uint32_t start_item_index , const gdma_buffer_mount_config_t * buf_config_array , size_t num_buf , uint32_t * end_item_index )
144+ esp_err_t gdma_link_mount_buffers (gdma_link_list_handle_t list , int start_item_index , const gdma_buffer_mount_config_t * buf_config_array , size_t num_buf , int * end_item_index )
145145{
146146 ESP_RETURN_ON_FALSE (list && buf_config_array && num_buf , ESP_ERR_INVALID_ARG , TAG , "invalid argument" );
147- ESP_RETURN_ON_FALSE (start_item_index < list -> num_items , ESP_ERR_INVALID_ARG , TAG , "invalid start item index" );
148147 size_t buffer_alignment = list -> buffer_alignment ;
149148 size_t item_size = list -> item_size ;
150149 uint32_t list_item_capacity = list -> num_items ;
150+ // ensure the start_item_index is between 0 and `list_item_capacity - 1`
151+ start_item_index = (start_item_index % list_item_capacity + list_item_capacity ) % list_item_capacity ;
151152 size_t max_buffer_mount_length = ALIGN_DOWN (GDMA_MAX_BUFFER_SIZE_PER_LINK_ITEM , buffer_alignment );
152153 uint32_t begin_item_idx = start_item_index ;
153154 gdma_link_list_item_t * lli_nc = NULL ;
154155
155156 uint32_t num_items_avail = 0 ;
156157 // if the link list is responsible for checking the ownership, we need to skip the items that are owned by the DMA
157158 if (list -> flags .check_owner ) {
158- for (uint32_t i = 0 ; i < list_item_capacity ; i ++ ) {
159+ for (int i = 0 ; i < list_item_capacity ; i ++ ) {
159160 lli_nc = (gdma_link_list_item_t * )(list -> items_nc + (i + start_item_index ) % list_item_capacity * item_size );
160161 if (lli_nc -> dw0 .owner == GDMA_LLI_OWNER_CPU ) {
161162 num_items_avail ++ ;
@@ -166,8 +167,8 @@ esp_err_t gdma_link_mount_buffers(gdma_link_list_handle_t list, uint32_t start_i
166167 }
167168
168169 // check alignment and length for each buffer
169- for (size_t i = 0 ; i < num_buf ; i ++ ) {
170- const gdma_buffer_mount_config_t * config = & buf_config_array [i ];
170+ for (size_t bi = 0 ; bi < num_buf ; bi ++ ) {
171+ const gdma_buffer_mount_config_t * config = & buf_config_array [bi ];
171172 uint8_t * buf = (uint8_t * )config -> buffer ;
172173 size_t len = config -> length ;
173174 // check the buffer alignment
@@ -183,8 +184,8 @@ esp_err_t gdma_link_mount_buffers(gdma_link_list_handle_t list, uint32_t start_i
183184 lli_nc -> next = (gdma_link_list_item_t * )(list -> items + start_item_index * item_size );
184185
185186 begin_item_idx = start_item_index ;
186- for (size_t i = 0 ; i < num_buf ; i ++ ) {
187- const gdma_buffer_mount_config_t * config = & buf_config_array [i ];
187+ for (size_t bi = 0 ; bi < num_buf ; bi ++ ) {
188+ const gdma_buffer_mount_config_t * config = & buf_config_array [bi ];
188189 uint8_t * buf = (uint8_t * )config -> buffer ;
189190 size_t len = config -> length ;
190191 // skip zero-length buffer
@@ -193,7 +194,7 @@ esp_err_t gdma_link_mount_buffers(gdma_link_list_handle_t list, uint32_t start_i
193194 }
194195 uint32_t num_items_need = (len + max_buffer_mount_length - 1 ) / max_buffer_mount_length ;
195196 // mount the buffer to the link list
196- for (uint32_t i = 0 ; i < num_items_need ; i ++ ) {
197+ for (int i = 0 ; i < num_items_need ; i ++ ) {
197198 lli_nc = (gdma_link_list_item_t * )(list -> items_nc + (i + begin_item_idx ) % list_item_capacity * item_size );
198199 lli_nc -> buffer = buf ;
199200 lli_nc -> dw0 .length = len > max_buffer_mount_length ? max_buffer_mount_length : len ;
@@ -232,25 +233,57 @@ esp_err_t gdma_link_concat(gdma_link_list_handle_t first_link, int first_link_it
232233{
233234 ESP_RETURN_ON_FALSE (first_link && second_link , ESP_ERR_INVALID_ARG , TAG , "invalid argument" );
234235 gdma_link_list_item_t * lli_nc = NULL ;
235- lli_nc = (gdma_link_list_item_t * )(first_link -> items_nc + (first_link -> num_items + first_link_item_index ) % first_link -> num_items * first_link -> item_size );
236- lli_nc -> next = (gdma_link_list_item_t * )(second_link -> items + (second_link -> num_items + second_link_item_index ) % second_link -> num_items * second_link -> item_size );
236+ // ensure the first_link_item_index is between 0 and `num_items - 1`
237+ int num_items = first_link -> num_items ;
238+ first_link_item_index = (first_link_item_index % num_items + num_items ) % num_items ;
239+ lli_nc = (gdma_link_list_item_t * )(first_link -> items_nc + first_link_item_index * first_link -> item_size );
240+ // ensure the second_link_item_index is between 0 and `num_items - 1`
241+ num_items = second_link -> num_items ;
242+ second_link_item_index = (second_link_item_index % num_items + num_items ) % num_items ;
243+ // concatenate the two link lists
244+ lli_nc -> next = (gdma_link_list_item_t * )(second_link -> items + second_link_item_index * second_link -> item_size );
237245 return ESP_OK ;
238246}
239247
240248esp_err_t gdma_link_set_owner (gdma_link_list_handle_t list , int item_index , gdma_lli_owner_t owner )
241249{
242250 ESP_RETURN_ON_FALSE_ISR (list , ESP_ERR_INVALID_ARG , TAG , "invalid argument" );
243- ESP_RETURN_ON_FALSE_ISR (item_index < list -> num_items , ESP_ERR_INVALID_ARG , TAG , "invalid item index" );
244- gdma_link_list_item_t * lli = (gdma_link_list_item_t * )(list -> items_nc + (list -> num_items + item_index ) % list -> num_items * list -> item_size );
251+ int num_items = list -> num_items ;
252+ // ensure the item_index is between 0 and `num_items - 1`
253+ item_index = (item_index % num_items + num_items ) % num_items ;
254+ gdma_link_list_item_t * lli = (gdma_link_list_item_t * )(list -> items_nc + item_index * list -> item_size );
245255 lli -> dw0 .owner = owner ;
246256 return ESP_OK ;
247257}
248258
249259esp_err_t gdma_link_get_owner (gdma_link_list_handle_t list , int item_index , gdma_lli_owner_t * owner )
250260{
251261 ESP_RETURN_ON_FALSE_ISR (list && owner , ESP_ERR_INVALID_ARG , TAG , "invalid argument" );
252- ESP_RETURN_ON_FALSE_ISR (item_index < list -> num_items , ESP_ERR_INVALID_ARG , TAG , "invalid item index" );
253- gdma_link_list_item_t * lli = (gdma_link_list_item_t * )(list -> items_nc + (list -> num_items + item_index ) % list -> num_items * list -> item_size );
262+ int num_items = list -> num_items ;
263+ // ensure the item_index is between 0 and `num_items - 1`
264+ item_index = (item_index % num_items + num_items ) % num_items ;
265+ gdma_link_list_item_t * lli = (gdma_link_list_item_t * )(list -> items_nc + item_index * list -> item_size );
254266 * owner = lli -> dw0 .owner ;
255267 return ESP_OK ;
256268}
269+
270+ size_t gdma_link_count_buffer_size_till_eof (gdma_link_list_handle_t list , int start_item_index )
271+ {
272+ if (!list ) {
273+ return 0 ;
274+ }
275+ int num_items = list -> num_items ;
276+ // ensure the start_item_index is between 0 and `num_items - 1`
277+ start_item_index = (start_item_index % num_items + num_items ) % num_items ;
278+ size_t buf_size = 0 ;
279+ gdma_link_list_item_t * lli_nc = NULL ;
280+ for (int i = 0 ; i < num_items ; i ++ ) {
281+ lli_nc = (gdma_link_list_item_t * )(list -> items_nc + (start_item_index + i ) % num_items * list -> item_size );
282+ buf_size += lli_nc -> dw0 .length ;
283+ // break if the current item is the last one or the EOF item
284+ if (lli_nc -> dw0 .suc_eof || lli_nc -> next == NULL ) {
285+ break ;
286+ }
287+ }
288+ return buf_size ;
289+ }
0 commit comments