IMXRT1052, spdif_edma driver crashing doing init

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IMXRT1052, spdif_edma driver crashing doing init

1,090 Views
mmlee
Contributor II

Hello,

I'm unsure whatever my problems comes from a wrong initialization, or actual bug in the spdif_edma driver, or possibly the MCUXpresso config tool. The crash causes the IMXRT to become unresponsive both to my jtag (segger) and the on-board DAP debugger. I need to set it to boot from the sd-card, reflash with working firmware, and set it to boot from the device again. It's not something simple as a hardfault, as the mcu becomes completely unresponsive.

My peripheral.c/peripheral.h is generated by the MCUXpresso config tool (v5). Using the newest SDK (2.5.0).

This is peripheral.h:

/***********************************************************************************************************************
 * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file
 * will be overwritten if the respective MCUXpresso Config Tools is used to update this file.
 **********************************************************************************************************************/

#ifndef _PERIPHERALS_H_
#define _PERIPHERALS_H_

/***********************************************************************************************************************
 * Included files
 **********************************************************************************************************************/
#include "fsl_edma.h"
#include "fsl_dmamux.h"
#include "fsl_common.h"
#include "fsl_spdif.h"
#include "fsl_spdif_edma.h"

#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */

/***********************************************************************************************************************
 * Definitions
 **********************************************************************************************************************/
/* Definitions for BOARD_InitPeripherals functional group */
/* Used DMA device. */
#define EDMA_1_DMA_BASEADDR DMA0
/* Associated DMAMUX device that is used for muxing of requests. */
#define EDMA_1_DMAMUX_BASEADDR DMAMUX
/* BOARD_InitPeripherals defines for SPDIF */
/* Definition of peripheral ID. */
#define SPDIF_1_PERIPHERAL SPDIF
/* Definition Tx clock source frequency. */
#define SPDIF_1_TX_CLK_FREQ 30000000U
/* Definition Tx sample rate. */
#define SPDIF_1_TX_SAMPLE_RATE 44100U
/* Definition Tx eDMA transfer buffer size. */
#define SPDIF_1_TX_EDMA_BUFFER_SIZE 6U
/* SPDIF_1 eDMA source request. */
#define SPDIF_1_TX_LEFT_DMA_REQUEST kDmaRequestMuxSpdifTx
/* Selected eDMA channel number. */
#define SPDIF_1_TX_LEFT_DMA_CHANNEL 0
/* DMAMUX device that is used for muxing of the request. */
#define SPDIF_1_TX_LEFT_DMAMUX_BASEADDR DMAMUX
/* Used DMA device. */
#define SPDIF_1_TX_LEFT_DMA_BASEADDR DMA0
/* SPDIF_1 eDMA source request. */
#define SPDIF_1_TX_RIGHT_DMA_REQUEST kDmaRequestMuxSpdifTx
/* Selected eDMA channel number. */
#define SPDIF_1_TX_RIGHT_DMA_CHANNEL 1
/* DMAMUX device that is used for muxing of the request. */
#define SPDIF_1_TX_RIGHT_DMAMUX_BASEADDR DMAMUX
/* Used DMA device. */
#define SPDIF_1_TX_RIGHT_DMA_BASEADDR DMA0

/***********************************************************************************************************************
 * Global variables
 **********************************************************************************************************************/
extern const edma_config_t eDMA_1_config;
extern const spdif_config_t SPDIF_1_config;
extern edma_handle_t SPDIF_1_TX_Left_Handle;
extern edma_handle_t SPDIF_1_TX_Right_Handle;
extern uint8_t SPDIF_1_txLeftData[SPDIF_XFER_QUEUE_SIZE][SPDIF_1_TX_EDMA_BUFFER_SIZE];
extern uint8_t SPDIF_1_txRightData[SPDIF_XFER_QUEUE_SIZE][SPDIF_1_TX_EDMA_BUFFER_SIZE];
extern spdif_edma_handle_t SPDIF_1_tx_SPDIF_eDMA_Handle;

/***********************************************************************************************************************
 * Callback functions
 **********************************************************************************************************************/
/* SPDIF eDMA callback function for the SPDIF_1 component (init. function BOARD_InitPeripherals)*/
extern void rxDMAcallback(SPDIF_Type *, spdif_edma_handle_t *, status_t, void *);

/***********************************************************************************************************************
 * Initialization functions
 **********************************************************************************************************************/
void BOARD_InitPeripherals(void);

/***********************************************************************************************************************
 * BOARD_InitBootPeripherals function
 **********************************************************************************************************************/
void BOARD_InitBootPeripherals(void);

#if defined(__cplusplus)
}
#endif

#endif /* _PERIPHERALS_H_ */

And my peripheral.c:

/***********************************************************************************************************************
 * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file
 * will be overwritten if the respective MCUXpresso Config Tools is used to update this file.
 **********************************************************************************************************************/

/* clang-format off */
/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
!!GlobalInfo
product: Peripherals v5.0
processor: MIMXRT1052xxxxB
package_id: MIMXRT1052DVL6B
mcu_data: ksdk2_0
processor_version: 5.0.0
board: IMXRT1050-EVKB
functionalGroups:
- name: BOARD_InitPeripherals
  called_from_default_init: true
  selectedCore: core0
 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/

/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
component:
- type: 'system'
- type_id: 'system_54b53072540eeeb8f8e9343e71f28176'
- global_system_definitions: []
 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
/* clang-format on */

/***********************************************************************************************************************
 * Included files
 **********************************************************************************************************************/
#include "peripherals.h"

/***********************************************************************************************************************
 * BOARD_InitPeripherals functional group
 **********************************************************************************************************************/
/***********************************************************************************************************************
 * eDMA_1 initialization code
 **********************************************************************************************************************/
/* clang-format off */
/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
instance:
- name: 'eDMA_1'
- type: 'edma'
- mode: 'basic'
- type_id: 'edma_a23fca76a894e1bcdf9d01a687505ff9'
- functional_group: 'BOARD_InitPeripherals'
- peripheral: 'DMA0'
- config_sets:
  - fsl_edma:
    - common_settings:
      - enableContinuousLinkMode: 'false'
      - enableHaltOnError: 'true'
      - enableRoundRobinArbitration: 'false'
      - enableDebugMode: 'false'
    - edma_channels: []
    - quick_selection: 'default'
 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
/* clang-format on */
const edma_config_t eDMA_1_config = {
  .enableContinuousLinkMode = false,
  .enableHaltOnError = true,
  .enableRoundRobinArbitration = false,
  .enableDebugMode = false
};

void eDMA_1_init(void) {
}

/***********************************************************************************************************************
 * SPDIF_1 initialization code
 **********************************************************************************************************************/
/* clang-format off */
/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
instance:
- name: 'SPDIF_1'
- type: 'spdif'
- mode: 'edma'
- type_id: 'spdif_040614b5288766ad77a1a386b39d0a3c'
- functional_group: 'BOARD_InitPeripherals'
- peripheral: 'SPDIF'
- config_sets:
  - fsl_spdif:
    - usage: 'transmit'
    - wrapper:
      - tx_spdif_config:
        - isTxAutoSync: 'true'
        - txClkSource: 'SpdifClock'
        - txSourceFreq: 'BOARD_BootClockRUN'
        - txSampleRate: '44.1kHz'
        - txFullSelect: 'kSPDIF_TxEmpty0Sample'
        - txSource: 'kSPDIF_txNormal'
        - validityConfig: 'kSPDIF_validityFlagAlwaysClear'
        - edma_channels:
          - enable_edma_channel_left: 'true'
          - edma_channel_left:
            - eDMAn: '0'
            - eDMA_source: 'kDmaRequestMuxSpdifTx'
            - enable_custom_name: 'false'
          - enable_edma_channel_right: 'true'
          - edma_channel_right:
            - eDMAn: '1'
            - eDMA_source: 'kDmaRequestMuxSpdifTx'
            - enable_custom_name: 'false'
        - spdif_edma_handle:
          - enable_custom_name: 'false'
          - init_transfer: 'true'
          - transfer:
            - dataSize: '6'
            - allocate_buffer: 'true'
          - init_callback: 'true'
          - callback_fcn: 'rxDMAcallback'
          - user_data: ''
 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
/* clang-format on */
const spdif_config_t SPDIF_1_config = {
  .isTxAutoSync = true,
  .isRxAutoSync = false,
  .DPLLClkSource = 1U,
  .txClkSource = 1U,
  .rxFullSelect = kSPDIF_RxFull8Samples,
  .txFullSelect = kSPDIF_TxEmpty0Sample,
  .uChannelSrc = kSPDIF_UChannelFromTx,
  .txSource = kSPDIF_txNormal,
  .validityConfig = kSPDIF_validityFlagAlwaysClear,
  .gain = kSPDIF_GAIN_8
};
edma_handle_t SPDIF_1_TX_Left_Handle;
edma_handle_t SPDIF_1_TX_Right_Handle;
spdif_edma_handle_t SPDIF_1_tx_SPDIF_eDMA_Handle;
uint8_t SPDIF_1_txLeftData[SPDIF_XFER_QUEUE_SIZE][SPDIF_1_TX_EDMA_BUFFER_SIZE];
uint8_t SPDIF_1_txRightData[SPDIF_XFER_QUEUE_SIZE][SPDIF_1_TX_EDMA_BUFFER_SIZE];

void SPDIF_1_init(void) {
  /* Buffer iterator */
  uint32_t i;
  /* Create the eDMA SPDIF_1_TX_Left_Handle handle */
  EDMA_CreateHandle(&SPDIF_1_TX_Left_Handle, SPDIF_1_TX_LEFT_DMA_BASEADDR, SPDIF_1_TX_LEFT_DMA_CHANNEL);
  /* Create the eDMA SPDIF_1_TX_Right_Handle handle */
  EDMA_CreateHandle(&SPDIF_1_TX_Right_Handle, SPDIF_1_TX_RIGHT_DMA_BASEADDR, SPDIF_1_TX_RIGHT_DMA_CHANNEL);
  /* Set the source kDmaRequestMuxSpdifTx request in the DMAMUX */
  DMAMUX_SetSource(SPDIF_1_TX_LEFT_DMAMUX_BASEADDR, SPDIF_1_TX_LEFT_DMA_CHANNEL, SPDIF_1_TX_LEFT_DMA_REQUEST);
  /* Enable the 0 channel in the DMAMUX */
  DMAMUX_EnableChannel(SPDIF_1_TX_LEFT_DMAMUX_BASEADDR, SPDIF_1_TX_LEFT_DMA_CHANNEL);
  /* Set the source kDmaRequestMuxSpdifTx request in the DMAMUX */
  DMAMUX_SetSource(SPDIF_1_TX_RIGHT_DMAMUX_BASEADDR, SPDIF_1_TX_RIGHT_DMA_CHANNEL, SPDIF_1_TX_RIGHT_DMA_REQUEST);
  /* Enable the 1 channel in the DMAMUX */
  DMAMUX_EnableChannel(SPDIF_1_TX_RIGHT_DMAMUX_BASEADDR, SPDIF_1_TX_RIGHT_DMA_CHANNEL);
  /* Create the SPDIF Tx eDMA handle. */
  SPDIF_TransferTxCreateHandleEDMA(SPDIF_1_PERIPHERAL, &SPDIF_1_tx_SPDIF_eDMA_Handle, rxDMAcallback, NULL, &SPDIF_1_TX_Left_Handle, &SPDIF_1_TX_Right_Handle);
  /* Assign allocated buffer to the handle */
  for (i = 0U; i < SPDIF_XFER_QUEUE_SIZE; i++) {
    SPDIF_1_tx_SPDIF_eDMA_Handle.spdifQueue[i].dataSize = SPDIF_1_TX_EDMA_BUFFER_SIZE;
    SPDIF_1_tx_SPDIF_eDMA_Handle.spdifQueue[i].leftData = &(SPDIF_1_txLeftData[i][0]);
    SPDIF_1_tx_SPDIF_eDMA_Handle.spdifQueue[i].rightData = &(SPDIF_1_txRightData[i][0]);
  }
  /* Initialize the SPDIF. */
  SPDIF_Init(SPDIF_1_PERIPHERAL, &SPDIF_1_config);
  /* Set SPDIF TX sample rate to 44.1kHz. */
  SPDIF_TxSetSampleRate(SPDIF_1_PERIPHERAL, SPDIF_1_TX_SAMPLE_RATE, SPDIF_1_TX_CLK_FREQ);
  /* Enable SPDIF transmitter. */
  SPDIF_TxEnable(SPDIF_1_PERIPHERAL, true);
  /* Enable DMA requests from SPDIF. */
  SPDIF_EnableDMA(SPDIF_1_PERIPHERAL, kSPDIF_TxDMAEnable, true);
}

/***********************************************************************************************************************
 * Initialization functions
 **********************************************************************************************************************/
void BOARD_InitPeripherals(void)
{
  /* Global initialization */
  DMAMUX_Init(EDMA_1_DMAMUX_BASEADDR);
  EDMA_Init(EDMA_1_DMA_BASEADDR, &eDMA_1_config);

  /* Initialize components */
  eDMA_1_init();
  SPDIF_1_init();
}

/***********************************************************************************************************************
 * BOARD_InitBootPeripherals function
 **********************************************************************************************************************/
void BOARD_InitBootPeripherals(void)
{
  BOARD_InitPeripherals();
}

The crash happens in fsl_spdig_edma.c in "SPDIF_TransferTxCreateHandleEDMA", when trying to read the "base->SCR" register (line 265/266):

void SPDIF_TransferTxCreateHandleEDMA(SPDIF_Type *base,
                                      spdif_edma_handle_t *handle,
                                      spdif_edma_callback_t callback,
                                      void *userData,
                                      edma_handle_t *dmaLeftHandle,
                                      edma_handle_t *dmaRightHandle)
{
    //[...]
    handle->count =
        s_spdif_tx_watermark[(base->SCR & SPDIF_SCR_TXFIFOEMPTY_SEL_MASK) >> SPDIF_SCR_TXFIFOEMPTY_SEL_SHIFT];‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I've checked myself and simply trying to read the base->SCR inside the function can cause the crash.

Any idea what might be causing this?

I'm not sure whatever it's a bug or not, but there are no examples for the spdif (using edma or not), and I've also found other bugs in the spdif driver. So I think it's possible that the spdif_edma might contain some bugs as well.

Is there any plan on making a spdif_edma example, like the one already made for SAI (and sai_edma)?

3 Replies

843 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi mmlee,

I think there is a bug in peripherals.c. SPDIF_TransferTxCreateHandleEDMA() is called before SPDIF_Init(). When it read SPDIF_SCR register, SPDIF's clock is still gated. This cause a hardfault.

You can call SPDIF_Init() before it. Or just open the clock.

I'll report this bug. Thanks a lot!

Regards,

Jing

843 Views
mmlee
Contributor II

Thanks a lot, that's definitely part of the issue, and moving the SPDIF_Init() before the SPDIF_TransferTxCreateHandleEDMA(), stop crashes from occurring. I still have some issues with the spdif_edma: can it really be right that the edma should be set up to transferring 4 bytes to the spdif FIFO? The spdif FIFO is only 3bytes long (16x24)? 

0 Kudos

843 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi mmlee,

The data handled by the SPDIF module is 24-bit wide. The 24-bit SPDIF data is aligned in the 24 least significant bits of the 32-bit shared peripheral bus data word. The 8 most significant bits of the 32-bit word are ignored by the SPDIF Transmitter when data is being stored in the Transmit FIFOs from the peripheral bus. The 8 most significant bits of
the 32-bit word are zeroed by the SPDIF Receiver module when the data is being read from the Receiver FIFOs to the peripheral bus.

Regards

Jing

0 Kudos