Загрузка данных
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_debug_console.h"
#include "fsl_sai.h"
#include "fsl_sai_sdma.h"
#include "fsl_sdma.h"
#include "ads127l18.h"
#include "adc_control.h"
#define DEMO_DMA SDMAARM3
#define DMA3_SAI2_RECV_EVENT_SOURCE (2U) // RM p.939
#define DMA_CHANNEL 1U
#define EXAMPLE_SAI I2S2
#define BUFFER_SIZE (1026U)
AT_NONCACHEABLE_SECTION_ALIGN(static uint8_t rxBuffer[BUFFER_SIZE*2], 4);
AT_NONCACHEABLE_SECTION_ALIGN(sdma_handle_t rxSdmaHandle, 4);
AT_NONCACHEABLE_SECTION_ALIGN(sdma_context_data_t rxContext, 4);
AT_NONCACHEABLE_SECTION_ALIGN(sai_sdma_handle_t rxSaiSdmaHandle, 4);
AT_NONCACHEABLE_SECTION_ALIGN(volatile bool isFinished, 4);
void delayMS(uint32_t ms)
{
for (uint32_t i = 0; i < ms; i++) {
SDK_DelayAtLeastUs(1000, SystemCoreClock);
}
}
static void rxCallback(I2S_Type *base, sai_sdma_handle_t *handle, status_t status, void *userData)
{
if (kStatus_SAI_RxIdle == status) {
isFinished = true;
}
}
int main(void)
{
BOARD_InitMemory();
BOARD_RdcInit();
BOARD_InitBootPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
adc_stop();
adc_init(ADC_OSR_64, ADC_HIGH_SPEED, ADC_TDM_TWO_PINS, ADC_DCLK_DIV_EIGHT, ADC_CLOCK_EXTERNAL, ADC_CLK_DIV_EIGHT, ADC_CHN_MUX_NORMAL_INPUT_POLARITY);
adc_start();
delayMS(100U);
PRINTF("ADC is configured and run.\r\n");
static sdma_config_t dmaConfig = {0};
SDMA_GetDefaultConfig(&dmaConfig);
dmaConfig.ratio = kSDMA_ARMClockFreq;
SDMA_Init(DEMO_DMA, &dmaConfig);
SDMA_CreateHandle(&rxSdmaHandle, DEMO_DMA, DMA_CHANNEL, &rxContext);
SDMA_SetChannelPriority(DEMO_DMA, DMA_CHANNEL, 2U);
SAI_Init(EXAMPLE_SAI);
SAI_TransferRxCreateHandleSDMA(EXAMPLE_SAI, &rxSaiSdmaHandle, rxCallback, NULL, &rxSdmaHandle,DMA3_SAI2_RECV_EVENT_SOURCE);
static sai_transceiver_t saiConfig;
SAI_GetTDMConfig(&saiConfig, kSAI_FrameSyncLenPerWordWidth, kSAI_WordWidth24bits, 8, kSAI_Channel1Mask | kSAI_Channel0Mask);
saiConfig.masterSlave = kSAI_Slave;
saiConfig.syncMode = kSAI_ModeAsync;
SAI_TransferRxSetConfigSDMA(EXAMPLE_SAI, &rxSaiSdmaHandle, &saiConfig);
PRINTF("SAI and SDMA are configured.\r\n");
isFinished = false;
sai_transfer_t xfer;
xfer.data = rxBuffer;
xfer.dataSize = 30;
if (SAI_TransferReceiveSDMA(EXAMPLE_SAI, &rxSaiSdmaHandle, &xfer) == kStatus_Success) {
PRINTF("Data waiting...\r\n");
while (!isFinished) {
}
PRINTF("Data is received.\r\n");
SAI_TransferAbortSendSDMA(EXAMPLE_SAI, &rxSaiSdmaHandle);
SAI_Deinit(EXAMPLE_SAI);
}
else {
PRINTF("Failed to start receive transfer.\r\n");
}
PRINTF("Stop operating.\r\n");
while (true) {
}
}
I need your assistance. We are developing a device based on the i.MX8M Nano.
At this stage, we are using a combination of the Symphony Board V1.7 and the VAR-SOM-MX8M-NANO V1.5 evaluation boards from Variscite.
An ADC (ADS127L18) is connected to the evaluation boards via the SAI (I2S2) interface. The ADC uses its own independent clock source.
There is an oscilloscope capture of the data transmission in the attached file.
--------| |-------------
ADC | | iMX8M Nano
fsync|----->|sai2_rxfs
dclk|----->|sai2_rxc
dout0|----->|sai2_rxd0
dout1|----->|sai2_rxd1
--------| |-------------
At the moment, I can receive data from the ADC using interrupts, but I can't configure the SDMA + SAI setup correctly.
When the callback is triggered, I observe invalid data in the memory buffer.
The callback is invoked regardless of whether data is actually being transmitted over the interface.
I could not find an SDK example showing how to configure SDMA and SAI for data reception on the i.MX8M Nano, so I used code fragments from examples for other similar SoMs.
Below is my current initialization and configuration code.