Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 4790

SDK • DMA not fireing IRQ

$
0
0
Hi,

I have a question about a DMA not fireing an IRQ upon completion. This is a part of a library that aims to use the RP2040/RP2350 as a bridge between an 8080 display data input and RGB ("DPI") display output.
Now, a PIO is busy receiving data from the input. The DMA reads the incoming data. Once a line is received, an interrupt should be triggered to start some data processing and restart the DMA. However, this never happens. In the code below, I expect the IRQ handler to assert zero but that never happens. I am sure that the PIO is working correctly and delivering data as the program is working as expected when using a loop, waiting for the DMA to complete and then retrigger the DMA "manually" (without interrupt).
I guess it must be something stupid as I have used a DMA in conjunction with an IRQ many times before but I just can find the error. I hope that a fresh pair of eyes might immediatly point me to the cause of the error. I have attached the code below, the part of interest is probably in lcd_dma_init; that's where the interrupt handler gets installed (apologies for the messiness as it's at a very early stage of development).

Thank you for any input in advance and best regards

Code:

#include <stdio.h>#include "pico/stdlib.h"#include "hardware/vreg.h"#include "hardware/resets.h"#include "hardware/dma.h"#include "hardware/irq.h"#include "pico/mutex.h"#include "lcd_pio_receive.h"#define LED_BUILTIN (25)#define LCD_RES_X (320)#define LCD_PIN_DB0  (4)#define LCD_PIN_CLK  (20)/******************************* PIO ****************************/typedef enum {  LCD_SUCCESS = 0,  /**< @brief Command completed successfully */  LCD_UNKNOWN_ERROR = -1,   /**< @brief An unknown error occured. */  LCD_NOT_INIT = -3,   /**< @brief The LCD interface has not yet                             * been setup.*/  LCD_DMA_ERR = -4,/**< @brief An error has occcured setup up or                             * using the DMA.*/  LCD_PIO_ERR = -5          /**< @brief An error has occcured setup up or                             * using the PIO.*/} lcd_error_t ; PIO lcd_pio[2] = {pio0, pio1};int8_t lcd_pio_sm_rx[3];bool lcd_pio_enabled = false;/******************************* DMA ****************************/mutex_t line_rxed;#define LCD_DMA_IRQ (DMA_IRQ_0)  // 0 or 1int32_t lcd_dma_chan_rx;dma_channel_config lcd_dma_config_rx;bool lcd_dma_enabled = false;#define NUM_RX_BUF 2uint16_t __aligned(32) linebuf_rx[NUM_RX_BUF][LCD_RES_X];volatile int curlinebuf_rx = 0;/******************************* Implementation ****************************/void __isr lcd_dma_handler_rx() {  assert(0);} // lcd_dma_handler_rxlcd_error_t lcd_dma_init() {  if (!lcd_pio_enabled)    return LCD_PIO_ERR;  if (lcd_dma_enabled)    return LCD_SUCCESS;  lcd_dma_chan_rx = dma_claim_unused_channel(true);  if (lcd_dma_chan_rx < 0)    return LCD_DMA_ERR;  lcd_dma_config_rx = dma_channel_get_default_config(lcd_dma_chan_rx);  channel_config_set_transfer_data_size(&lcd_dma_config_rx, DMA_SIZE_32);  channel_config_set_read_increment(&lcd_dma_config_rx, false);  channel_config_set_dreq(&lcd_dma_config_rx, pio_get_dreq(lcd_pio[1], lcd_pio_sm_rx[0], false /* false = rx */));  dma_irqn_set_channel_enabled(LCD_DMA_IRQ, lcd_dma_chan_rx, true);  // PIO  if (irq_get_exclusive_handler(LCD_DMA_IRQ) == NULL)    irq_set_exclusive_handler(LCD_DMA_IRQ, lcd_dma_handler_rx);  irq_set_enabled(LCD_DMA_IRQ, true);  dma_channel_configure(lcd_dma_chan_rx, &lcd_dma_config_rx, linebuf_rx[curlinebuf_rx], &lcd_pio[1]->rxf[lcd_pio_sm_rx[0]], LCD_RES_X / 2, true /* trigger now */);  lcd_dma_enabled = true;  return LCD_SUCCESS;}  // lcd_dma_initlcd_error_t lcd_pio_init() {  if (lcd_pio_enabled)    return LCD_SUCCESS;  for (int i = 0; i < 2; i++) {    lcd_pio_sm_rx[i] = pio_claim_unused_sm(lcd_pio[1], false);    if (lcd_pio_sm_rx[i] < 0)      return LCD_PIO_ERR;  }  // clear GPIO states (high-impedance, no pullups etc)  gpio_init (LCD_PIN_CLK);  for (int i = 0; i < 8; i++)    gpio_init (LCD_PIN_DB0 + i);  /****************************** data input sm ******************************/  uint32_t program_offset = pio_add_program(lcd_pio[1], &lcd_rx_main_program);  pio_sm_config pio_cfg = lcd_rx_main_program_get_default_config(program_offset);  // setup data pins  sm_config_set_in_pin_base(&pio_cfg, LCD_PIN_DB0);  // configure the SM  sm_config_set_fifo_join(&pio_cfg, PIO_FIFO_JOIN_RX);  sm_config_set_clkdiv_int_frac(&pio_cfg, 1, 0);  sm_config_set_in_shift(&pio_cfg, true, true, 32);               // ISR shifts in to the right (true) = default, autopush, pull threshold  pio_sm_init(lcd_pio[1], lcd_pio_sm_rx[0], program_offset, &pio_cfg);#if 1  // clear FIFO & ISR  for (int i = 0; i < 8; i++)    pio_sm_get(lcd_pio[1], lcd_pio_sm_rx[0]);  pio_sm_exec(lcd_pio[1], lcd_pio_sm_rx[0], pio_encode_in(pio_null, 32));#endif  /****************************** clock sm ******************************/  program_offset = pio_add_program(lcd_pio[1], &lcd_rx_irq_program);  pio_cfg = lcd_rx_irq_program_get_default_config(program_offset);  // setup pins (CLK only)  sm_config_set_in_pin_base(&pio_cfg, LCD_PIN_CLK);  // configure the SM  sm_config_set_clkdiv_int_frac(&pio_cfg, 1, 0);  pio_sm_init(lcd_pio[1], lcd_pio_sm_rx[1], program_offset, &pio_cfg);  // start all SMs  for (int i = 0; i < 2; i++)    pio_sm_set_enabled(lcd_pio[1], lcd_pio_sm_rx[i], true /* enable */);  lcd_pio_enabled = true;  return LCD_SUCCESS;}  // lcd_pio_initlcd_error_t lcd_init() {  lcd_error_t res = LCD_SUCCESS;  curlinebuf_rx = 0;  res = lcd_pio_init();  if (res != LCD_SUCCESS)     return res;  res = lcd_dma_init();  if (res != LCD_SUCCESS)   return res;  return res;}  // lcd_initint main() {  stdio_init_all();  gpio_init(LED_BUILTIN);  gpio_set_dir(LED_BUILTIN, GPIO_OUT);  mutex_init(&line_rxed);  lcd_init();  while (1) {    while(dma_channel_is_busy(lcd_dma_chan_rx));        dma_channel_configure(lcd_dma_chan_rx,                        &lcd_dma_config_rx,                        linebuf_rx[curlinebuf_rx],           // dst                        &lcd_pio[1]->rxf[lcd_pio_sm_rx[0]],  // src                        LCD_RES_X / 2,                        true /* trigger now */);        curlinebuf_rx = (curlinebuf_rx + 1) % 2;  }}

Statistics: Posted by fcipaq — Fri Dec 06, 2024 9:15 am — Replies 0 — Views 35



Viewing all articles
Browse latest Browse all 4790

Trending Articles