Skip to content

Commit

Permalink
dma: adding forge for DMA controllers interrupts listing
Browse files Browse the repository at this point in the history
  • Loading branch information
pthierry-ledger committed Aug 5, 2024
1 parent 8ce44c3 commit bab1f3d
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 6 deletions.
4 changes: 4 additions & 0 deletions dts/examples/nucleo_u5a5.dts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@
};
};

&gpdma1 {
status = "okay";
};

&led0 {
status = "okay";
};
Expand Down
5 changes: 5 additions & 0 deletions kernel/include/bsp/drivers/dma/gpdma.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,11 @@ kstatus_t gpdma_channel_configure(gpdma_stream_cfg_t const*const desc);
*/
kstatus_t gpdma_channel_enable(gpdma_stream_cfg_t const*const desc);

/**
* @brief given a stream, get back the associated IRQn
*/
kstatus_t gpdma_get_interrupt(gpdma_stream_cfg_t const *desc, uint16_t * const IRQn);

#ifdef __cplusplus
}
#endif
Expand Down
21 changes: 20 additions & 1 deletion kernel/src/drivers/dma/stm32-gpdma-dt.c.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,23 @@
#include "stm32-gpdma-dt.h"

{% set gpdma_ports = dts.get_compatible("stm32u5-dma") -%}

{% for port in gpdma_ports -%}
{% if port is owned or port is not enabled -%}
{% continue -%}
{% endif -%}
/* channel ordered interrupts for controller {{ port.label }} */
static const uint16_t stm32_{{ port.label}}_interrupts[] = {
/* {{ port['dma-channels']|int }} DMA channels */
{% for chanirq in range((2*port['dma-channels'])) -%}
{% if port['interrupts'][chanirq]|int != 0 -%}
{{ port['interrupts'][chanirq] }}, /* channel {{ (chanirq / 2)|int }} interrupt identifier */
{% endif -%}
{% endfor -%}
};

{% endfor -%}

/**
* \brief .rodata field: list of current platform GPDMA ports
*/
Expand All @@ -25,15 +42,17 @@ static const stm32_gpdma_desc_t stm32_gpdmas[] = {
.clk_msk = {{ "%#08xUL"|format(clk_msk) }},
.num_chan = {{ num_chan|int }},
.num_req = {{ num_req|int }},
.interrupts = &stm32_{{ port.label}}_interrupts[0],
},
{% endfor -%}
{} /* sentinel */
};


/**
* @warning this is a private function, port id must be valid and checked by caller
*/
const stm32_gpdma_desc_t * stm32_usartport_get_desc(uint8_t ctrl)
const stm32_gpdma_desc_t * stm32_gpdma_get_desc(uint8_t ctrl)
{
const stm32_gpdma_desc_t *desc = NULL;
if (unlikely(ctrl >= GPDMA_NUMBER)) {
Expand Down
1 change: 1 addition & 0 deletions kernel/src/drivers/dma/stm32-gpdma-dt.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ typedef struct stm32_gpdma_desc {
uint32_t clk_msk; /**< IP clocks mask on the given bus */
uint16_t num_chan; /***< IP number of channels */
uint16_t num_req; /**< IP number of requests */
uint16_t const *interrupts; /**< IP interrupts, hyp: 1 IRQ per channel */
} stm32_gpdma_desc_t;

const stm32_gpdma_desc_t * stm32_gpdma_get_desc(uint8_t ctrl);
Expand Down
62 changes: 57 additions & 5 deletions kernel/src/drivers/dma/stm32u5-gpdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ typedef union gpdma_register {
gpdma_c12br2_t cxbr2;
} gpdma_register_t;


/**
* @fn check given channel idle flag
*
Expand All @@ -84,6 +85,55 @@ static inline bool smt32u5_gpdma_is_channel_idle(uint8_t ctrl, uint16_t chanid)
return !!sr->idlef;
}

kstatus_t stm32u5_gpdma_get_interrupt(gpdma_stream_cfg_t const *desc, uint16_t * const IRQn)
{
kstatus_t status = K_ERROR_INVPARAM;
stm32_gpdma_desc_t const * ctrl = NULL;

if (unlikely(desc == NULL)) {
goto end;
}
if (unlikely(IRQn == NULL)) {
goto end;
}
ctrl = stm32_gpdma_get_desc(desc->controller);
if (unlikely(ctrl == NULL)) {
goto end;
}
*IRQn = ctrl->interrupts[desc->channel];
status = K_STATUS_OKAY;
end:
return status;
}

/**
* @fn clear GPDMA global interrupt
*
* clear both GPDMA interrupt status register for given channel and
* NVIC related interrupt.
*
* This is the driver level clear
*/
kstatus_t stm32u5_gpdma_interrupt_clear(gpdma_stream_cfg_t const*const desc)
{
kstatus_t status = K_ERROR_INVPARAM;
const stm32_gpdma_desc_t * ctrl = NULL;

uint16_t IRQn;
if (unlikely(desc == NULL)) {
goto end;
}
ctrl = stm32_gpdma_get_desc(desc->controller);
if (unlikely(ctrl == NULL)) {
goto end;
}
/* FCR is in write1_clear mode, clearing channel CR */
iowrite32(ctrl->base_addr + GPDMA_CxFCR(desc->channel), (0xF7FUL << 8));
status = K_STATUS_OKAY;
end:
return status;
}

kstatus_t stm32u5_gpdma_probe(uint8_t controller)
{
kstatus_t status = K_ERROR_INVPARAM;
Expand Down Expand Up @@ -142,7 +192,8 @@ kstatus_t smt32u5_gpdma_channel_clear_status(gpdma_stream_cfg_t const*const desc
if (unlikely(desc->channel >= ctrl_desc->num_chan)) {
goto end;
}
iowrite32(ctrl_desc->base_addr + GPDMA_CxFCR(desc->channel), 0x0UL);
/* FCR is in write1_clear mode */
iowrite32(ctrl_desc->base_addr + GPDMA_CxFCR(desc->channel), (0xF7FUL << 8));
status = K_STATUS_OKAY;
end:
return status;
Expand Down Expand Up @@ -393,7 +444,8 @@ kstatus_t stm32u5_gpdma_channel_restart(void)

/* aliasing functions to generic API */
kstatus_t gpdma_probe(uint8_t controller) __attribute((alias("stm32u5_gpdma_probe")));
kstatus_t gpdma_channel_clear_status(gpdma_stream_cfg_t const*const desc) __attribute((alias("smt32u5_gpdma_channel_clear_status")));
kstatus_t gpdma_channel_get_status(gpdma_stream_cfg_t const*const desc, gpdma_chan_status_t * status) __attribute((alias("smt32u5_gpdma_channel_get_status")));
kstatus_t gpdma_channel_configure(gpdma_stream_cfg_t const*const desc) __attribute((alias("stm32u5_gpdma_channel_configure")));
kstatus_t gpdma_channel_enable(gpdma_stream_cfg_t const*const desc) __attribute((alias("stm32u5_gpdma_channel_enable")));
kstatus_t gpdma_channel_clear_status(gpdma_stream_cfg_t const*const desc) __attribute__((alias("smt32u5_gpdma_channel_clear_status")));
kstatus_t gpdma_channel_get_status(gpdma_stream_cfg_t const*const desc, gpdma_chan_status_t * status) __attribute__((alias("smt32u5_gpdma_channel_get_status")));
kstatus_t gpdma_channel_configure(gpdma_stream_cfg_t const*const desc) __attribute__((alias("stm32u5_gpdma_channel_configure")));
kstatus_t gpdma_channel_enable(gpdma_stream_cfg_t const*const desc) __attribute__((alias("stm32u5_gpdma_channel_enable")));
kstatus_t gpdma_get_interrupt(gpdma_stream_cfg_t const *desc, uint16_t * const IRQn) __attribute__((alias("stm32u5_gpdma_get_interrupt")));

0 comments on commit bab1f3d

Please sign in to comment.