From 635134962dbc497fc22aa12f8287a4e5e2b9356b Mon Sep 17 00:00:00 2001 From: Luigi2898 Date: Tue, 23 Jul 2024 09:31:11 +0200 Subject: [PATCH] Update sdk to define functions --- sw/applications/example_dma_sdk/main.c | 22 +- sw/device/lib/sdk/dma/dma_sdk.c | 913 +------------------------ sw/device/lib/sdk/dma/dma_sdk.h | 176 ++--- 3 files changed, 82 insertions(+), 1029 deletions(-) diff --git a/sw/applications/example_dma_sdk/main.c b/sw/applications/example_dma_sdk/main.c index ee055dbb8..767047d27 100644 --- a/sw/applications/example_dma_sdk/main.c +++ b/sw/applications/example_dma_sdk/main.c @@ -56,35 +56,27 @@ uint32_t errors = 0; int main() { - volatile dma *the_dma = dma_peri(0); // Defined as volatile to avoid compiler optimizations - dma_sdk_init(); - DMA_FILL(source_32b, &value_32b, SOURCE_BUFFER_SIZE_32b, uint32_t, uint32_t, 0, the_dma); - DMA_WAIT(0); - DMA_COPY(destin_32b, source_32b, SOURCE_BUFFER_SIZE_32b, uint32_t, uint32_t, 0, the_dma); - DMA_WAIT(0); + dma_fill(source_32b, &value_32b, SOURCE_BUFFER_SIZE_32b, 0, DMA_DATA_TYPE_WORD, DMA_DATA_TYPE_WORD, 0); + dma_copy(destin_32b, source_32b, SOURCE_BUFFER_SIZE_32b, 0, DMA_DATA_TYPE_WORD, DMA_DATA_TYPE_WORD, 0); for (i = 0; i < SOURCE_BUFFER_SIZE_32b; i++) { errors += destin_32b[i] != CONST_VALUE_32B; } - DMA_FILL(source_16b, &value_16b, SOURCE_BUFFER_SIZE_16b, uint16_t, uint16_t, 0, the_dma); - DMA_WAIT(0); - DMA_COPY(destin_16b, source_16b, SOURCE_BUFFER_SIZE_16b, uint16_t, uint16_t, 0, the_dma); - DMA_WAIT(0); + dma_fill(source_16b, &value_16b, SOURCE_BUFFER_SIZE_16b, 0, DMA_DATA_TYPE_HALF_WORD, DMA_DATA_TYPE_HALF_WORD, 0); + dma_copy(destin_16b, source_16b, SOURCE_BUFFER_SIZE_16b, 0, DMA_DATA_TYPE_HALF_WORD, DMA_DATA_TYPE_HALF_WORD, 0); for (i = 0; i < SOURCE_BUFFER_SIZE_16b; i++) { errors += destin_16b[i] != CONST_VALUE_16B; } - DMA_FILL(source_8b, &value_8b, SOURCE_BUFFER_SIZE_8b, uint8_t, uint8_t, 0, the_dma); - DMA_WAIT(0); - DMA_COPY(destin_8b, source_8b, SOURCE_BUFFER_SIZE_8b, uint8_t, uint8_t, 0, the_dma); - DMA_WAIT(0); - + dma_fill(source_8b, &value_8b, SOURCE_BUFFER_SIZE_8b, 0, DMA_DATA_TYPE_BYTE, DMA_DATA_TYPE_BYTE, 0); + dma_copy(destin_8b, source_8b, SOURCE_BUFFER_SIZE_8b, 0, DMA_DATA_TYPE_BYTE, DMA_DATA_TYPE_BYTE, 0); + for (i = 0; i < SOURCE_BUFFER_SIZE_8b; i++) { errors += destin_8b[i] != CONST_VALUE_8B; diff --git a/sw/device/lib/sdk/dma/dma_sdk.c b/sw/device/lib/sdk/dma/dma_sdk.c index 8ab3fa30c..620baeb76 100644 --- a/sw/device/lib/sdk/dma/dma_sdk.c +++ b/sw/device/lib/sdk/dma/dma_sdk.c @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 // // File: dma_sdk.c -// Author: Michele Caon +// Author: Michele Caon, Luigi Giuffrida // Date: 19/06/2023 // Description: Utility functions for DMA peripheral. @@ -16,17 +16,15 @@ #include "csr.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -/******************************/ -/* ---- GLOBAL VARIABLES ---- */ -/******************************/ - -/* Uncomment to use the DMA HALs */ -// #define USE_HEEP_DMA_HAL + /******************************/ + /* ---- GLOBAL VARIABLES ---- */ + /******************************/ -volatile uint8_t dma_sdk_intr_flag; + volatile uint8_t dma_sdk_intr_flag; #define DMA_REGISTER_SIZE_BYTES sizeof(int) #define DMA_SELECTION_OFFSET_START 0 @@ -34,897 +32,40 @@ volatile uint8_t dma_sdk_intr_flag; /* Mask for direct register operations */ #define DMA_CSR_REG_MIE_MASK ((1 << 19) | (1 << 11)) -/**********************************/ -/* ---- FUNCTION DEFINITIONS ---- */ -/**********************************/ - -// Initialize the DMA -void dma_sdk_init(void) -{ - dma_init(NULL); - -#ifndef USE_HEEP_DMA_HAL - - /* Enable global interrupts */ - CSR_SET_BITS(CSR_REG_MSTATUS, 0x8); - - /* Enable fast interrupts */ - CSR_SET_BITS(CSR_REG_MIE, DMA_CSR_REG_MIE_MASK); - -#endif - - return; -} - -// Copy data from source to destination using DMA peripheral -void dma_copy_32b(uint32_t *dst, uint32_t *src, uint32_t size, uint8_t channel) -{ - - dma_config_flags_t res; - - dma_target_t tgt_src = { - .ptr = (uint8_t *)src, - .inc_du = 1, - .size_du = size, - .type = DMA_DATA_TYPE_WORD, - .trig = DMA_TRIG_MEMORY, - }; - dma_target_t tgt_dst = { - .ptr = (uint8_t *)dst, - .inc_du = 1, - .size_du = size, - .type = DMA_DATA_TYPE_WORD, - .trig = DMA_TRIG_MEMORY, - }; - - dma_trans_t trans = { - .src = &tgt_src, - .dst = &tgt_dst, - .src_addr = NULL, - .mode = DMA_TRANS_MODE_SINGLE, - .win_du = 0, - .end = DMA_TRANS_END_INTR, - }; - -#ifdef USE_HEEP_DMA_HAL - res = dma_validate_transaction(&trans, DMA_ENABLE_REALIGN, DMA_PERFORM_CHECKS_INTEGRITY); - res = dma_load_transaction(&trans); - res = dma_launch(&trans); -#else - - dma *peri = dma_peri(channel); - - uint8_t dataSize_b = DMA_DATA_TYPE_2_SIZE(trans.src->type); - trans.size_b = trans.src->size_du * dataSize_b; - /* By default, the source defines the data type.*/ - trans.src_type = trans.src->type; - - /* - * SET THE POINTERS - */ - peri->SRC_PTR = (uint32_t)trans.src->ptr; - peri->DST_PTR = (uint32_t)trans.dst->ptr; - - /* - * SET THE INCREMENTS - */ - - write_register(4, - DMA_SRC_PTR_INC_D1_REG_OFFSET, - DMA_SRC_PTR_INC_D1_INC_MASK, - DMA_SRC_PTR_INC_D1_INC_OFFSET, - peri); - - write_register(4, - DMA_DST_PTR_INC_D1_REG_OFFSET, - DMA_DST_PTR_INC_D1_INC_MASK, - DMA_DST_PTR_INC_D1_INC_OFFSET, - peri); - - /* - * SET THE OPERATION MODE AND WINDOW SIZE - */ - - peri->MODE = trans.mode; - - write_register(trans.src_type, - DMA_SRC_DATA_TYPE_REG_OFFSET, - DMA_SRC_DATA_TYPE_DATA_TYPE_MASK, - DMA_SELECTION_OFFSET_START, - peri); - - peri->INTERRUPT_EN = 0x1; - - /* Load the size and start the transaction. */ - peri->SIZE_D1 = trans.size_b; - -#endif - - while (!dma_is_ready(channel)) - { - // disable_interrupts - // this does not prevent waking up the core as this is controlled by the MIP register - CSR_CLEAR_BITS(CSR_REG_MSTATUS, 0x8); - if (dma_is_ready(channel) == 0) - { - wait_for_interrupt(); - // from here we wake up even if we did not jump to the ISR - } - CSR_SET_BITS(CSR_REG_MSTATUS, 0x8); - } - - return; -} - -// Copy data from source to destination using DMA peripheral -void dma_copy_16b(uint16_t *dst, uint16_t *src, uint32_t size, uint8_t channel) -{ - - dma_config_flags_t res; - - dma_target_t tgt_src = { - .ptr = (uint8_t *)src, - .inc_du = 1, - .size_du = size, - .type = DMA_DATA_TYPE_HALF_WORD, - .trig = DMA_TRIG_MEMORY, - }; - dma_target_t tgt_dst = { - .ptr = (uint8_t *)dst, - .inc_du = 1, - .size_du = size, - .type = DMA_DATA_TYPE_HALF_WORD, - .trig = DMA_TRIG_MEMORY, - }; - - dma_trans_t trans = { - .src = &tgt_src, - .dst = &tgt_dst, - .src_addr = NULL, - .mode = DMA_TRANS_MODE_SINGLE, - .win_du = 0, - .end = DMA_TRANS_END_INTR, - }; - -#ifdef USE_HEEP_DMA_HAL - res = dma_validate_transaction(&trans, DMA_ENABLE_REALIGN, DMA_PERFORM_CHECKS_INTEGRITY); - res = dma_load_transaction(&trans); - res = dma_launch(&trans); -#else - - dma *peri = dma_peri(channel); - - uint8_t dataSize_b = DMA_DATA_TYPE_2_SIZE(trans.src->type); - trans.size_b = trans.src->size_du * dataSize_b; - /* By default, the source defines the data type.*/ - trans.src_type = trans.src->type; - trans.dst_type = trans.dst->type; - - /* - * SET THE POINTERS - */ - peri->SRC_PTR = (uint32_t)trans.src->ptr; - peri->DST_PTR = (uint32_t)trans.dst->ptr; - - /* - * SET THE INCREMENTS - */ - - write_register(2, - DMA_SRC_PTR_INC_D1_REG_OFFSET, - DMA_SRC_PTR_INC_D1_INC_MASK, - DMA_SRC_PTR_INC_D1_INC_OFFSET, - peri); - - write_register(2, - DMA_DST_PTR_INC_D1_REG_OFFSET, - DMA_DST_PTR_INC_D1_INC_MASK, - DMA_DST_PTR_INC_D1_INC_OFFSET, - peri); - - /* - * SET THE OPERATION MODE AND WINDOW SIZE - */ - - peri->MODE = trans.mode; - - write_register(trans.src_type, - DMA_SRC_DATA_TYPE_REG_OFFSET, - DMA_SRC_DATA_TYPE_DATA_TYPE_MASK, - DMA_SELECTION_OFFSET_START, - peri); - - write_register(trans.dst_type, - DMA_SRC_DATA_TYPE_REG_OFFSET, - DMA_SRC_DATA_TYPE_DATA_TYPE_MASK, - DMA_SELECTION_OFFSET_START, - peri); - - peri->INTERRUPT_EN = 0x1; - - /* Load the size and start the transaction. */ - peri->SIZE_D1 = trans.size_b; - -#endif - - while (!dma_is_ready(channel)) - { - // disable_interrupts - // this does not prevent waking up the core as this is controlled by the MIP register - CSR_CLEAR_BITS(CSR_REG_MSTATUS, 0x8); - if (dma_is_ready(channel) == 0) - { - wait_for_interrupt(); - // from here we wake up even if we did not jump to the ISR - } - CSR_SET_BITS(CSR_REG_MSTATUS, 0x8); - } - - return; -} - -// Copy data from source to destination using DMA peripheral -void dma_copy_8b(uint8_t *dst, uint8_t *src, uint32_t size, uint8_t channel) -{ - - dma_config_flags_t res; - - dma_target_t tgt_src = { - .ptr = (uint8_t *)src, - .inc_du = 1, - .size_du = size, - .type = DMA_DATA_TYPE_BYTE, - .trig = DMA_TRIG_MEMORY, - }; - dma_target_t tgt_dst = { - .ptr = (uint8_t *)dst, - .inc_du = 1, - .size_du = size, - .type = DMA_DATA_TYPE_BYTE, - .trig = DMA_TRIG_MEMORY, - }; - - dma_trans_t trans = { - .src = &tgt_src, - .dst = &tgt_dst, - .src_addr = NULL, - .mode = DMA_TRANS_MODE_SINGLE, - .win_du = 0, - .end = DMA_TRANS_END_INTR, - }; - -#ifdef USE_HEEP_DMA_HAL - res = dma_validate_transaction(&trans, DMA_ENABLE_REALIGN, DMA_PERFORM_CHECKS_INTEGRITY); - res = dma_load_transaction(&trans); - res = dma_launch(&trans); -#else - - dma *peri = dma_peri(channel); - - uint8_t dataSize_b = DMA_DATA_TYPE_2_SIZE(trans.src->type); - trans.size_b = trans.src->size_du * dataSize_b; - /* By default, the source defines the data type.*/ - trans.src_type = trans.src->type; - - /* - * SET THE POINTERS - */ - peri->SRC_PTR = (uint32_t)trans.src->ptr; - peri->DST_PTR = (uint32_t)trans.dst->ptr; - - /* - * SET THE INCREMENTS - */ - - write_register(1, - DMA_SRC_PTR_INC_D1_REG_OFFSET, - DMA_SRC_PTR_INC_D1_INC_MASK, - DMA_SRC_PTR_INC_D1_INC_OFFSET, - peri); - - write_register(1, - DMA_DST_PTR_INC_D1_REG_OFFSET, - DMA_DST_PTR_INC_D1_INC_MASK, - DMA_DST_PTR_INC_D1_INC_OFFSET, - peri); - - /* - * SET THE OPERATION MODE AND WINDOW SIZE - */ - - peri->MODE = trans.mode; - - write_register(trans.src_type, - DMA_SRC_DATA_TYPE_REG_OFFSET, - DMA_SRC_DATA_TYPE_DATA_TYPE_MASK, - DMA_SELECTION_OFFSET_START, - peri); - - peri->INTERRUPT_EN = 0x1; - - /* Load the size and start the transaction. */ - peri->SIZE_D1 = trans.size_b; - -#endif - - while (!dma_is_ready(channel)) - { - // disable_interrupts - // this does not prevent waking up the core as this is controlled by the MIP register - CSR_CLEAR_BITS(CSR_REG_MSTATUS, 0x8); - if (dma_is_ready(channel) == 0) - { - wait_for_interrupt(); - // from here we wake up even if we did not jump to the ISR - } - CSR_SET_BITS(CSR_REG_MSTATUS, 0x8); - } - - return; -} - -void dma_fill_32b(uint32_t *dst, uint32_t *value, uint32_t size, uint8_t channel) -{ - dma_config_flags_t res; - - dma_target_t tgt_src = { - .ptr = (uint8_t *)value, - .inc_du = 0, - .size_du = size, - .type = DMA_DATA_TYPE_WORD, - .trig = DMA_TRIG_MEMORY - }; - dma_target_t tgt_dst = { - .ptr = (uint8_t *)dst, - .inc_du = 1, - .size_du = size, - .type = DMA_DATA_TYPE_WORD, - .trig = DMA_TRIG_MEMORY, - }; - - dma_trans_t trans = { - .src = &tgt_src, - .dst = &tgt_dst, - .src_addr = NULL, - .mode = DMA_TRANS_MODE_SINGLE, - .win_du = 0, - .end = DMA_TRANS_END_INTR - }; - -#ifdef USE_HEEP_DMA_HAL - res = dma_validate_transaction(&trans, DMA_ENABLE_REALIGN, DMA_PERFORM_CHECKS_INTEGRITY); - res = dma_load_transaction(&trans); - res = dma_launch(&trans); -#else - - dma *peri = dma_peri(channel); - - /* - * SET THE POINTERS - */ - peri->SRC_PTR = (uint32_t)trans.src->ptr; - peri->DST_PTR = (uint32_t)trans.dst->ptr; - - /* - * SET THE INCREMENTS - */ - - write_register(0, - DMA_SRC_PTR_INC_D1_REG_OFFSET, - DMA_SRC_PTR_INC_D1_INC_MASK, - DMA_SRC_PTR_INC_D1_INC_OFFSET, - peri); - - write_register(4, - DMA_DST_PTR_INC_D1_REG_OFFSET, - DMA_DST_PTR_INC_D1_INC_MASK, - DMA_DST_PTR_INC_D1_INC_OFFSET, - peri); - - /* - * SET THE OPERATION MODE AND WINDOW SIZE - */ - - peri->MODE = trans.mode; - - write_register(trans.src_type, - DMA_SRC_DATA_TYPE_REG_OFFSET, - DMA_SRC_DATA_TYPE_DATA_TYPE_MASK, - DMA_SELECTION_OFFSET_START, - peri); - - peri->INTERRUPT_EN = 0x1; - - /* Load the size and start the transaction. */ - peri->SIZE_D1 = size * sizeof(uint32_t); - -#endif - - while (!dma_is_ready(channel)) - { - // disable_interrupts - // this does not prevent waking up the core as this is controlled by the MIP register - CSR_CLEAR_BITS(CSR_REG_MSTATUS, 0x8); - if (dma_is_ready(channel) == 0) - { - wait_for_interrupt(); - // from here we wake up even if we did not jump to the ISR - } - CSR_SET_BITS(CSR_REG_MSTATUS, 0x8); - } - - return; -} - -void dma_fill_16b(uint16_t *dst, uint16_t *value, uint32_t size, uint8_t channel) -{ - dma_config_flags_t res; - - dma_target_t tgt_src = { - .ptr = (uint8_t *)value, - .inc_du = 0, - .size_du = size, - .type = DMA_DATA_TYPE_HALF_WORD, - .trig = DMA_TRIG_MEMORY, - }; - dma_target_t tgt_dst = { - .ptr = (uint8_t *)dst, - .inc_du = 1, - .size_du = size, - .type = DMA_DATA_TYPE_HALF_WORD, - .trig = DMA_TRIG_MEMORY, - }; - - dma_trans_t trans = { - .src = &tgt_src, - .dst = &tgt_dst, - .src_addr = NULL, - .mode = DMA_TRANS_MODE_SINGLE, - .win_du = 0, - .end = DMA_TRANS_END_INTR, - }; - -#ifdef USE_HEEP_DMA_HAL - res = dma_validate_transaction(&trans, DMA_ENABLE_REALIGN, DMA_PERFORM_CHECKS_INTEGRITY); - res = dma_load_transaction(&trans); - res = dma_launch(&trans); -#else - - dma *peri = dma_peri(channel); - - trans.src_type = trans.src->type; - trans.dst_type = trans.dst->type; - - /* - * SET THE POINTERS - */ - peri->SRC_PTR = (uint32_t)trans.src->ptr; - peri->DST_PTR = (uint32_t)trans.dst->ptr; - - /* - * SET THE INCREMENTS - */ - - write_register(0, - DMA_SRC_PTR_INC_D1_REG_OFFSET, - DMA_SRC_PTR_INC_D1_INC_MASK, - DMA_SRC_PTR_INC_D1_INC_OFFSET, - peri); - - write_register(2, - DMA_DST_PTR_INC_D1_REG_OFFSET, - DMA_DST_PTR_INC_D1_INC_MASK, - DMA_DST_PTR_INC_D1_INC_OFFSET, - peri); - - /* - * SET THE OPERATION MODE AND WINDOW SIZE - */ - - peri->MODE = trans.mode; + /**********************************/ + /* ---- FUNCTION DEFINITIONS ---- */ + /**********************************/ - write_register(trans.src_type, - DMA_SRC_DATA_TYPE_REG_OFFSET, - DMA_SRC_DATA_TYPE_DATA_TYPE_MASK, - DMA_SELECTION_OFFSET_START, - peri); - - write_register(trans.dst_type, - DMA_DST_DATA_TYPE_REG_OFFSET, - DMA_DST_DATA_TYPE_DATA_TYPE_MASK, - DMA_SELECTION_OFFSET_START, - peri); - - peri->INTERRUPT_EN = 0x1; - - /* Load the size and start the transaction. */ - peri->SIZE_D1 = size * sizeof(uint16_t); - -#endif - - while (!dma_is_ready(channel)) + // Initialize the DMA + void dma_sdk_init(void) { - // disable_interrupts - // this does not prevent waking up the core as this is controlled by the MIP register - CSR_CLEAR_BITS(CSR_REG_MSTATUS, 0x8); - if (dma_is_ready(channel) == 0) - { - wait_for_interrupt(); - // from here we wake up even if we did not jump to the ISR - } - CSR_SET_BITS(CSR_REG_MSTATUS, 0x8); - } - - return; -} - -void dma_fill_16b_32b(uint32_t *dst, uint16_t *value, uint32_t size, uint8_t channel, uint32_t sign_extend) -{ - dma_config_flags_t res; - - dma_target_t tgt_src = { - .ptr = (uint8_t *)value, - .inc_du = 0, - .size_du = size, - .type = DMA_DATA_TYPE_HALF_WORD, - .trig = DMA_TRIG_MEMORY, - }; - - dma_target_t tgt_dst = { - .ptr = (uint8_t *)dst, - .inc_du = 1, - .size_du = size, - .type = DMA_DATA_TYPE_WORD, - .trig = DMA_TRIG_MEMORY, - }; + dma_init(NULL); - dma_trans_t trans = { - .src = &tgt_src, - .dst = &tgt_dst, - .src_addr = NULL, - .mode = DMA_TRANS_MODE_SINGLE, - .win_du = 0, - .end = DMA_TRANS_END_INTR, - }; - -#ifdef USE_HEEP_DMA_HAL - res = dma_validate_transaction(&trans, DMA_ENABLE_REALIGN, DMA_PERFORM_CHECKS_INTEGRITY); - res = dma_load_transaction(&trans); - res = dma_launch(&trans); -#else - - dma *peri = dma_peri(channel); - - trans.src_type = trans.src->type; - trans.dst_type = trans.dst->type; - - /* - * SET THE POINTERS - */ - peri->SRC_PTR = (uint32_t) trans.src->ptr; - peri->DST_PTR = (uint32_t) trans.dst->ptr; - - /* - * SET THE INCREMENTS - */ - - write_register(0, - DMA_SRC_PTR_INC_D1_REG_OFFSET, - DMA_SRC_PTR_INC_D1_INC_MASK, - DMA_SRC_PTR_INC_D1_INC_OFFSET, - peri); - - write_register(2, - DMA_DST_PTR_INC_D1_REG_OFFSET, - DMA_DST_PTR_INC_D1_INC_MASK, - DMA_DST_PTR_INC_D1_INC_OFFSET, - peri); - - /* - * SET THE OPERATION MODE AND WINDOW SIZE - */ - - peri->MODE = trans.mode; - - write_register(trans.src_type, - DMA_SRC_DATA_TYPE_REG_OFFSET, - DMA_SRC_DATA_TYPE_DATA_TYPE_MASK, - DMA_SELECTION_OFFSET_START, - peri); - - write_register(trans.dst_type, - DMA_DST_DATA_TYPE_REG_OFFSET, - DMA_DST_DATA_TYPE_DATA_TYPE_MASK, - DMA_SELECTION_OFFSET_START, - peri); - - peri->INTERRUPT_EN = 0x1; - - /* Load the size and start the transaction. */ - peri->SIZE_D1 = size * sizeof(uint16_t); - -#endif - - while (!dma_is_ready(channel)) - { - // disable_interrupts - // this does not prevent waking up the core as this is controlled by the MIP register - CSR_CLEAR_BITS(CSR_REG_MSTATUS, 0x8); - if (dma_is_ready(channel) == 0) - { - wait_for_interrupt(); - // from here we wake up even if we did not jump to the ISR - } + /* Enable global interrupts */ CSR_SET_BITS(CSR_REG_MSTATUS, 0x8); - } - - return; -} - -void dma_fill_8b(uint8_t *dst, uint8_t *value, uint32_t size, uint8_t channel) -{ - dma_config_flags_t res; - - dma_target_t tgt_src = { - .ptr = (uint8_t *)value, - .inc_du = 0, - .size_du = size, - .type = DMA_DATA_TYPE_BYTE, - .trig = DMA_TRIG_MEMORY, - }; - dma_target_t tgt_dst = { - .ptr = (uint8_t *)dst, - .inc_du = 1, - .size_du = size, - .type = DMA_DATA_TYPE_BYTE, - .trig = DMA_TRIG_MEMORY, - }; - - dma_trans_t trans = { - .src = &tgt_src, - .dst = &tgt_dst, - .src_addr = NULL, - .mode = DMA_TRANS_MODE_SINGLE, - .win_du = 0, - .end = DMA_TRANS_END_INTR, - }; - -#ifdef USE_HEEP_DMA_HAL - res = dma_validate_transaction(&trans, DMA_ENABLE_REALIGN, DMA_PERFORM_CHECKS_INTEGRITY); - res = dma_load_transaction(&trans); - res = dma_launch(&trans); -#else - - dma *peri = dma_peri(channel); - - trans.src_type = trans.src->type; - trans.dst_type = trans.dst->type; - /* - * SET THE POINTERS - */ - peri->SRC_PTR = (uint32_t)trans.src->ptr; - peri->DST_PTR = (uint32_t)trans.dst->ptr; + /* Enable fast interrupts */ + CSR_SET_BITS(CSR_REG_MIE, DMA_CSR_REG_MIE_MASK); - /* - * SET THE INCREMENTS - */ - - write_register(0, - DMA_SRC_PTR_INC_D1_REG_OFFSET, - DMA_SRC_PTR_INC_D1_INC_MASK, - DMA_SRC_PTR_INC_D1_INC_OFFSET, - peri); - - write_register(1, - DMA_DST_PTR_INC_D1_REG_OFFSET, - DMA_DST_PTR_INC_D1_INC_MASK, - DMA_DST_PTR_INC_D1_INC_OFFSET, - peri); - - /* - * SET THE OPERATION MODE AND WINDOW SIZE - */ - - peri->MODE = trans.mode; - - write_register(trans.src_type, - DMA_SRC_DATA_TYPE_REG_OFFSET, - DMA_SRC_DATA_TYPE_DATA_TYPE_MASK, - DMA_SELECTION_OFFSET_START, - peri); - - write_register(trans.dst_type, - DMA_DST_DATA_TYPE_REG_OFFSET, - DMA_DST_DATA_TYPE_DATA_TYPE_MASK, - DMA_SELECTION_OFFSET_START, - peri); - - peri->INTERRUPT_EN = 0x1; - - /* Load the size and start the transaction. */ - peri->SIZE_D1 = size * sizeof(uint8_t); - -#endif - - while (!dma_is_ready(channel)) - { - // disable_interrupts - // this does not prevent waking up the core as this is controlled by the MIP register - CSR_CLEAR_BITS(CSR_REG_MSTATUS, 0x8); - if (dma_is_ready(channel) == 0) - { - wait_for_interrupt(); - // from here we wake up even if we did not jump to the ISR - } - CSR_SET_BITS(CSR_REG_MSTATUS, 0x8); + return; } - return; -} - -void dma_copy_16b_32b(uint32_t *dst, uint16_t *src, uint32_t size, uint8_t channel, uint32_t sign_extend) -{ - - dma *peri = dma_peri(channel); - - uint8_t dataSize_b = DMA_DATA_TYPE_2_SIZE(DMA_DATA_TYPE_WORD); - - /* - * SET THE POINTERS - */ - peri->SRC_PTR = (uint32_t)src; - peri->DST_PTR = (uint32_t)dst; - - /* - * SET THE INCREMENTS - */ - - write_register(2, - DMA_SRC_PTR_INC_D1_REG_OFFSET, - DMA_SRC_PTR_INC_D1_INC_MASK, - DMA_SRC_PTR_INC_D1_INC_OFFSET, - peri); - - write_register(4, - DMA_DST_PTR_INC_D1_REG_OFFSET, - DMA_DST_PTR_INC_D1_INC_MASK, - DMA_DST_PTR_INC_D1_INC_OFFSET, - peri); - /* - * SET THE OPERATION MODE AND WINDOW SIZE - */ - - peri->MODE = DMA_TRANS_MODE_SINGLE; - - write_register(DMA_DATA_TYPE_HALF_WORD, - DMA_SRC_DATA_TYPE_REG_OFFSET, - DMA_SRC_DATA_TYPE_DATA_TYPE_MASK, - DMA_SELECTION_OFFSET_START, - peri); - - write_register(DMA_DATA_TYPE_WORD, - DMA_DST_DATA_TYPE_REG_OFFSET, - DMA_DST_DATA_TYPE_DATA_TYPE_MASK, - DMA_SELECTION_OFFSET_START, - peri); - - peri->INTERRUPT_EN = 0x1; - - peri->SIGN_EXT = sign_extend; - - /* Load the size and start the transaction. */ - peri->SIZE_D1 = dataSize_b * size; - - // #endif - - while (!dma_is_ready(channel)) + void dma_copy(uint32_t dst_ptr, uint32_t src_ptr, uint32_t size, uint8_t channel, dma_data_type_t src_type, dma_data_type_t dst_type, uint8_t signed_data) { - // disable_interrupts - // this does not prevent waking up the core as this is controlled by the MIP register - CSR_CLEAR_BITS(CSR_REG_MSTATUS, 0x8); - if (dma_is_ready(channel) == 0) - { - wait_for_interrupt(); - // from here we wake up even if we did not jump to the ISR - } - CSR_SET_BITS(CSR_REG_MSTATUS, 0x8); + volatile dma *the_dma = dma_peri(channel); + DMA_COPY(dst_ptr, src_ptr, size, src_type, dst_type, signed_data, the_dma); + DMA_WAIT(channel); + return; } - return; -} - -// Copy data from source to destination using DMA peripheral -void dma_copy_to_addr_32b(uint32_t *dst_addr, uint32_t *src, uint32_t size, uint8_t channel) -{ - - dma_config_flags_t res; - - dma_target_t tgt_src = { - .ptr = (uint8_t *)src, - .inc_du = 1, - .size_du = size, - .type = DMA_DATA_TYPE_WORD, - .trig = DMA_TRIG_MEMORY, - }; - dma_target_t tgt_addr = { - .ptr = (uint8_t *)dst_addr, - .inc_du = 1, - .size_du = size, - .trig = DMA_TRIG_MEMORY, - }; - - dma_trans_t trans = { - .src = &tgt_src, - .dst = NULL, - .src_addr = &tgt_addr, - .mode = DMA_TRANS_MODE_ADDRESS, - .win_du = 0, - .end = DMA_TRANS_END_INTR, - }; - -#ifdef USE_HEEP_DMA_HAL - /** TO BE DONE */ -#else - - dma *peri = dma_peri(channel); - - uint8_t dataSize_b = DMA_DATA_TYPE_2_SIZE(trans.src->type); - trans.size_b = trans.src->size_du * dataSize_b; - /* By default, the source defines the data type.*/ - trans.src_type = trans.src->type; - - /* - * SET THE POINTERS - */ - peri->SRC_PTR = (uint32_t)trans.src->ptr; - peri->ADDR_PTR = (uint32_t)trans.src_addr->ptr; - - /* - * SET THE INCREMENTS - */ - - write_register(4, - DMA_SRC_PTR_INC_D1_REG_OFFSET, - DMA_SRC_PTR_INC_D1_INC_MASK, - DMA_SRC_PTR_INC_D1_INC_OFFSET, - peri); - - /* - * SET THE OPERATION MODE AND WINDOW SIZE - */ - - peri->MODE = trans.mode; - - write_register(trans.src_type, - DMA_SRC_DATA_TYPE_REG_OFFSET, - DMA_SRC_DATA_TYPE_DATA_TYPE_MASK, - DMA_SELECTION_OFFSET_START, - peri); - - peri->INTERRUPT_EN = 0x1; - - /* Load the size and start the transaction. */ - peri->SIZE_D1 = trans.size_b; - -#endif - - while (!dma_is_ready(channel)) + void dma_fill(uint32_t dst_ptr, uint32_t value_ptr, uint32_t size, uint8_t channel, dma_data_type_t src_type, dma_data_type_t dst_type, uint8_t signed_data) { - // disable_interrupts - // this does not prevent waking up the core as this is controlled by the MIP register - CSR_CLEAR_BITS(CSR_REG_MSTATUS, 0x8); - if (dma_is_ready(channel) == 0) - { - wait_for_interrupt(); - // from here we wake up even if we did not jump to the ISR - } - CSR_SET_BITS(CSR_REG_MSTATUS, 0x8); + volatile dma *the_dma = dma_peri(channel); + DMA_FILL(dst_ptr, value_ptr, size, src_type, dst_type, signed_data, the_dma); + DMA_WAIT(channel); + return; } - return; -} - #ifdef __cplusplus } #endif diff --git a/sw/device/lib/sdk/dma/dma_sdk.h b/sw/device/lib/sdk/dma/dma_sdk.h index d50c2d38d..9cf53a5e3 100644 --- a/sw/device/lib/sdk/dma/dma_sdk.h +++ b/sw/device/lib/sdk/dma/dma_sdk.h @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 // // File: dma_sdk.h -// Author: Michele Caon +// Author: Michele Caon, Luigi Giuffrida // Date: 19/06/2023 // Description: DMA utility functions @@ -19,35 +19,32 @@ extern "C" { #endif // __cplusplus -#define INCREMENT(C_type) (sizeof(C_type)) - -#define C_TYPE_2_DMA_TYPE(C_type) \ - ((sizeof(C_type)) == 1 ? DMA_DATA_TYPE_BYTE : (sizeof(C_type)) == 2 ? DMA_DATA_TYPE_HALF_WORD \ - : DMA_DATA_TYPE_WORD) - -#define DMA_COPY(DST, SRC, SIZE, C_SRC_TYPE, C_DST_TYPE, SIGNED, DMA_PERI) \ - DMA_PERI->INTERRUPT_EN = (uint32_t)0x1; \ - DMA_PERI->SRC_PTR = (uint32_t)SRC; \ - DMA_PERI->DST_PTR = (uint32_t)DST; \ - DMA_PERI->SRC_PTR_INC_D1 = (uint32_t)(INCREMENT(C_SRC_TYPE) & DMA_SRC_PTR_INC_D1_INC_MASK); \ - DMA_PERI->DST_PTR_INC_D1 = (uint32_t)(INCREMENT(C_DST_TYPE) & DMA_DST_PTR_INC_D1_INC_MASK); \ - DMA_PERI->MODE = (uint32_t)(DMA_TRANS_MODE_SINGLE & DMA_MODE_MODE_MASK); \ - DMA_PERI->SRC_DATA_TYPE = (uint32_t)(C_TYPE_2_DMA_TYPE(C_SRC_TYPE) & DMA_SRC_DATA_TYPE_DATA_TYPE_MASK); \ - DMA_PERI->DST_DATA_TYPE = (uint32_t)(C_TYPE_2_DMA_TYPE(C_DST_TYPE) & DMA_DST_DATA_TYPE_DATA_TYPE_MASK); \ - DMA_PERI->SIGN_EXT = (uint32_t)SIGNED; \ - DMA_PERI->SIZE_D1 = (uint32_t)((SIZE * DMA_DATA_TYPE_2_SIZE(C_TYPE_2_DMA_TYPE(C_SRC_TYPE))) & DMA_SIZE_D1_SIZE_MASK); - -#define DMA_FILL(DST, VALUE_PTR, SIZE, C_SRC_TYPE, C_DST_TYPE, SIGNED, DMA_PERI) \ - DMA_PERI->INTERRUPT_EN = (uint32_t)0x1; \ - DMA_PERI->SRC_PTR = (uint32_t)VALUE_PTR; \ - DMA_PERI->DST_PTR = (uint32_t)DST; \ - DMA_PERI->SRC_PTR_INC_D1 = (uint32_t)0; \ - DMA_PERI->DST_PTR_INC_D1 = (uint32_t)(INCREMENT(C_DST_TYPE) & DMA_DST_PTR_INC_D1_INC_MASK); \ - DMA_PERI->MODE = (uint32_t)(DMA_TRANS_MODE_SINGLE & DMA_MODE_MODE_MASK); \ - DMA_PERI->SRC_DATA_TYPE = (uint32_t)(C_TYPE_2_DMA_TYPE(C_SRC_TYPE) & DMA_SRC_DATA_TYPE_DATA_TYPE_MASK); \ - DMA_PERI->DST_DATA_TYPE = (uint32_t)(C_TYPE_2_DMA_TYPE(C_DST_TYPE) & DMA_DST_DATA_TYPE_DATA_TYPE_MASK); \ - DMA_PERI->SIGN_EXT = (uint32_t)SIGNED; \ - DMA_PERI->SIZE_D1 = (uint32_t)((SIZE * DMA_DATA_TYPE_2_SIZE(C_TYPE_2_DMA_TYPE(C_SRC_TYPE))) & DMA_SIZE_D1_SIZE_MASK); +#define INCREMENT(TYPE) ((TYPE == DMA_DATA_TYPE_BYTE) ? 1 : (TYPE == DMA_DATA_TYPE_HALF_WORD) ? 2 \ + : 4) + +#define DMA_COPY(DST, SRC, SIZE, SRC_TYPE, DST_TYPE, SIGNED, DMA_PERI) \ + DMA_PERI->INTERRUPT_EN = (uint32_t)0x1; \ + DMA_PERI->SRC_PTR = (uint32_t)SRC; \ + DMA_PERI->DST_PTR = (uint32_t)DST; \ + DMA_PERI->SRC_PTR_INC_D1 = (uint32_t)(INCREMENT(SRC_TYPE) & DMA_SRC_PTR_INC_D1_INC_MASK); \ + DMA_PERI->DST_PTR_INC_D1 = (uint32_t)(INCREMENT(DST_TYPE) & DMA_DST_PTR_INC_D1_INC_MASK); \ + DMA_PERI->MODE = (uint32_t)(DMA_TRANS_MODE_SINGLE & DMA_MODE_MODE_MASK); \ + DMA_PERI->SRC_DATA_TYPE = (uint32_t)(SRC_TYPE & DMA_SRC_DATA_TYPE_DATA_TYPE_MASK); \ + DMA_PERI->DST_DATA_TYPE = (uint32_t)(DST_TYPE & DMA_DST_DATA_TYPE_DATA_TYPE_MASK); \ + DMA_PERI->SIGN_EXT = (uint32_t)SIGNED; \ + DMA_PERI->SIZE_D1 = (uint32_t)((SIZE * DMA_DATA_TYPE_2_SIZE(SRC_TYPE)) & DMA_SIZE_D1_SIZE_MASK); + +#define DMA_FILL(DST, VALUE_PTR, SIZE, SRC_TYPE, DST_TYPE, SIGNED, DMA_PERI) \ + DMA_PERI->INTERRUPT_EN = (uint32_t)0x1; \ + DMA_PERI->SRC_PTR = (uint32_t)VALUE_PTR; \ + DMA_PERI->DST_PTR = (uint32_t)DST; \ + DMA_PERI->SRC_PTR_INC_D1 = (uint32_t)0; \ + DMA_PERI->DST_PTR_INC_D1 = (uint32_t)(INCREMENT(DST_TYPE) & DMA_DST_PTR_INC_D1_INC_MASK); \ + DMA_PERI->MODE = (uint32_t)(DMA_TRANS_MODE_SINGLE & DMA_MODE_MODE_MASK); \ + DMA_PERI->SRC_DATA_TYPE = (uint32_t)(SRC_TYPE & DMA_SRC_DATA_TYPE_DATA_TYPE_MASK); \ + DMA_PERI->DST_DATA_TYPE = (uint32_t)(DST_TYPE & DMA_DST_DATA_TYPE_DATA_TYPE_MASK); \ + DMA_PERI->SIGN_EXT = (uint32_t)SIGNED; \ + DMA_PERI->SIZE_D1 = (uint32_t)((SIZE * DMA_DATA_TYPE_2_SIZE(SRC_TYPE)) & DMA_SIZE_D1_SIZE_MASK); #define DMA_WAIT(CH) \ while (!dma_is_ready(CH)) \ @@ -66,115 +63,38 @@ extern "C" extern volatile uint8_t dma_sdk_intr_flag; - /* - */ - void dma_sdk_init(void); - - /** - * @brief Copy data words from source address to destination address - * - * @param dst Destination address - * @param src Source address - * @param size Number of words (not bytes) to copy - * @param channel DMA channel to use - */ - void dma_copy_32b(uint32_t *dst, uint32_t *src, uint32_t size, uint8_t channel); - - /** - * @brief Copy data words from source address to destination address - * - * @param dst Destination address - * @param src Source address - * @param size Number of words (not bytes) to copy - * @param channel DMA channel to use - */ - void dma_copy_16b(uint16_t *dst, uint16_t *src, uint32_t size, uint8_t channel); - - /** - * @brief Copy data words from source address to destination address - * - * @param dst Destination address - * @param src Source address - * @param size Number of words (not bytes) to copy - * @param channel DMA channel to use - */ - void dma_copy_8b(uint8_t *dst, uint8_t *src, uint32_t size, uint8_t channel); - /** - * @brief Copy data from source address to explicit destination addresses + * @brief Initializes the DMA SDK. * - * @param dst_addr Array of destination addresses - * @param src Source address - * @param bytes Number of words (not bytes) to copy - * @param channel DMA channel to use + * This function initializes the DMA SDK and prepares it for use. */ - void dma_copy_to_addr_32b(uint32_t *dst_addr, uint32_t *src, uint32_t size, uint8_t channel); - - /** - * @brief Fill a memory region with a 32-bit value - * - * @param dst Destination address - * @param value Pointer to the value to fill the memory with - * @param size Number of words (not bytes) to fill - * @param channel DMA channel to use - * @return int 0 if success, -1 if error - */ - void dma_fill_32b(uint32_t *dst, uint32_t *value, uint32_t size, uint8_t channel); - - /** - * @brief Fill a memory region with a 16-bit value - * - * @param dst Destination address - * @param value Pointer to the value to fill the memory with - * @param size Number of words (not bytes) to fill - * @param channel DMA channel to use - * @return int 0 if success, -1 if error - */ - void dma_fill_16b(uint16_t *dst, uint16_t *value, uint32_t size, uint8_t channel); - - /** - * @brief Fill a memory region with a 16-bit value - * - * @param dst Destination address - * @param value Pointer to the value to fill the memory with - * @param size Number of words (not bytes) to fill - * @param channel DMA channel to use - * @param sign_extend 1 to sign extend the 16-bit values, 0 otherwise - * @return int 0 if success, -1 if error - */ - void dma_fill_16b_32b(uint32_t *dst, uint16_t *value, uint32_t size, uint8_t channel, uint32_t sign_extend); - - /** - * @brief Fill a memory region with an 8-bit value - * - * @param dst Destination address - * @param value Pointer to the value to fill the memory with - * @param size Number of words (not bytes) to fill - * @param channel DMA channel to use - * @return int 0 if success, -1 if error - */ - void dma_fill_8b(uint8_t *dst, uint8_t *value, uint32_t size, uint8_t channel); + void dma_sdk_init(void); /** - * @brief Copy data from source address to destination address (16-bit aligned) + * @brief Copies data from source to destination using DMA. * - * @param size Number of words (not bytes) to fill - * @param channel DMA channel to use - * @param sign_extend 1 to sign extend the 16-bit values, 0 otherwise - * @return int 0 if success, -1 if error + * @param dst_ptr Pointer to the destination memory location. + * @param src_ptr Pointer to the source memory location. + * @param size Size of the data to be copied in bytes. + * @param channel DMA channel to be used for the transfer. + * @param src_type Source variable type (byte, half-word, word). + * @param dst_type Destination variable type (byte, half-word, word). + * @param signed_data Indicates whether the data is signed or unsigned. */ - void dma_fill_16b_32b(uint32_t *dst, uint16_t *value, uint32_t size, uint8_t channel, uint32_t sign_extend); + void dma_copy(uint32_t dst_ptr, uint32_t src_ptr, uint32_t size, uint8_t channel, dma_data_type_t src_type, dma_data_type_t dst_type, uint8_t signed_data); /** - * @brief Fill a memory region with an 8-bit value + * @brief Fills a memory region with a specified value using DMA. * - * @param dst Destination address - * @param value Pointer to the value to fill the memory with - * @param size Number of words (not bytes) to fill - * @param channel DMA channel to use - * @return int 0 if success, -1 if error + * @param dst_ptr Pointer to the destination memory location. + * @param value_ptr Pointer to the value to be filled. + * @param size Size of the memory region to be filled in bytes. + * @param channel DMA channel to be used for the transfer. + * @param src_type Source variable type (byte, half-word, word). + * @param dst_type Destination variable type (byte, half-word, word). + * @param signed_data Indicates whether the data is signed or unsigned. */ - void dma_fill_8b(uint8_t *dst, uint8_t *value, uint32_t size, uint8_t channel); + void dma_fill(uint32_t dst_ptr, uint32_t value_ptr, uint32_t size, uint8_t channel, dma_data_type_t src_type, dma_data_type_t dst_type, uint8_t signed_data); #ifdef __cplusplus }