前言
- 本次使用的框架为threadx+filex+shell组件
程序
共用驱动文件(dma和nvic)
nvic文件
头文件
#ifndef TX_STM32_F4_DRV_NVIC_OS_H
#define TX_STM32_F4_DRV_NVIC_OS_H
#include "drv_common.h"
void stm32_nvic_common_enable(uint32_t instance,uint32_t preempt,uint32_t sub);
void stm32_nvic_common_disable(uint32_t instance);
uint8_t stm32_nvic_common_enabled_check(uint32_t instance);
#endif
源文件
#include "drv_nvic_os.h"
enum stm32_irq_op_enum {
OPEN_IRQn,
CLOSE_IRQn,
READ_IRQn
};
static uint32_t stm32_nvic_common(uint32_t instance, uint32_t preempt, uint32_t sub, enum stm32_irq_op_enum mode) {
uint32_t irq;
switch (instance) {
#define irq_set(IRQn) {irq=IRQn;}break
case (uint32_t) SPI1: irq_set(SPI1_IRQn);
case (uint32_t) SPI2: irq_set(SPI2_IRQn);
case (uint32_t) SPI3: irq_set(SPI3_IRQn);
case (uint32_t) USART1: irq_set(USART1_IRQn);
case (uint32_t) USART2: irq_set(USART2_IRQn);
case (uint32_t) USART3: irq_set(USART3_IRQn);
case (uint32_t) UART4: irq_set(UART4_IRQn);
case (uint32_t) UART5: irq_set(UART5_IRQn);
case (uint32_t) SDIO: irq_set(SDIO_IRQn);
case (uint32_t) DMA2_Stream0: irq_set(DMA2_Stream0_IRQn);
case (uint32_t) DMA2_Stream1: irq_set(DMA2_Stream1_IRQn);
case (uint32_t) DMA2_Stream2: irq_set(DMA2_Stream2_IRQn);
case (uint32_t) DMA2_Stream3: irq_set(DMA2_Stream3_IRQn);
case (uint32_t) DMA2_Stream4: irq_set(DMA2_Stream4_IRQn);
case (uint32_t) DMA2_Stream5: irq_set(DMA2_Stream5_IRQn);
case (uint32_t) DMA2_Stream6: irq_set(DMA2_Stream6_IRQn);
case (uint32_t) DMA2_Stream7: irq_set(DMA2_Stream7_IRQn);
case (uint32_t) DMA1_Stream0: irq_set(DMA1_Stream0_IRQn);
case (uint32_t) DMA1_Stream1: irq_set(DMA1_Stream1_IRQn);
case (uint32_t) DMA1_Stream2: irq_set(DMA1_Stream2_IRQn);
case (uint32_t) DMA1_Stream3: irq_set(DMA1_Stream3_IRQn);
case (uint32_t) DMA1_Stream4: irq_set(DMA1_Stream4_IRQn);
case (uint32_t) DMA1_Stream5: irq_set(DMA1_Stream5_IRQn);
case (uint32_t) DMA1_Stream6: irq_set(DMA1_Stream6_IRQn);
case (uint32_t) DMA1_Stream7: irq_set(DMA1_Stream7_IRQn);
default: {
return UINT32_MAX;
}
}
#undef irq_set
switch (mode) {
case OPEN_IRQn: {
HAL_NVIC_SetPriority(irq, preempt, sub);
HAL_NVIC_EnableIRQ(irq);
}
break;
case CLOSE_IRQn: {
HAL_NVIC_DisableIRQ(irq);
}
break;
default: {
break;
}
}
return irq;
}
void stm32_nvic_common_enable(uint32_t instance, uint32_t preempt, uint32_t sub) {
stm32_nvic_common(instance, preempt, sub, OPEN_IRQn);
}
void stm32_nvic_common_disable(uint32_t instance) {
stm32_nvic_common(instance, 0, 0, CLOSE_IRQn);
}
uint8_t stm32_nvic_common_enabled_check(uint32_t instance) {
uint32_t irq = stm32_nvic_common(instance, 0, 0, READ_IRQn);
return NVIC_GetEnableIRQ(irq);
}
DMA文件
头文件
#ifndef TX_STM32_F4_DRV_DMA_OS_H
#define TX_STM32_F4_DRV_DMA_OS_H
#include "drv_common.h"
struct stm32_dma_info {
uint32_t instance;
DMA_HandleTypeDef *dma_tx;
DMA_HandleTypeDef *dma_rx;
};
struct stm32_dma_info *stm32_dma_info_get(uint32_t instance);
void stm32_dma_clk_enable(const DMA_HandleTypeDef *handle);
void stm32_dma_clk_disable(const DMA_HandleTypeDef *handle);
#endif
源文件
#include "drv_dma_os.h"
#if SPI1_DMA
static DMA_HandleTypeDef spi1_dma_tx = {.Instance=DMA2_Stream3, .Init.Channel=DMA_CHANNEL_3};
static DMA_HandleTypeDef spi1_dma_rx = {.Instance=DMA2_Stream0, .Init.Channel=DMA_CHANNEL_3};
#endif
static DMA_HandleTypeDef sdio_dma_tx = {.Instance = DMA2_Stream6, .Init.Channel = DMA_CHANNEL_4};
static DMA_HandleTypeDef sdio_dma_rx = {.Instance = DMA2_Stream3, .Init.Channel = DMA_CHANNEL_4};
static DMA_HandleTypeDef i2s_spi2_dma_tx = {.Instance = DMA1_Stream4, .Init.Channel = DMA_CHANNEL_0};
static DMA_HandleTypeDef i2s_spi2_dma_rx = {.Instance = DMA1_Stream3, .Init.Channel = DMA_CHANNEL_3};
static struct stm32_dma_info dma_info_map[] = {
#if SPI1_DMA
{(uint32_t) SPI1, &spi1_dma_tx, &spi1_dma_rx},
#endif
{(uint32_t) SDIO, &sdio_dma_tx, &sdio_dma_rx},
{(uint32_t) SPI2, &i2s_spi2_dma_tx,&i2s_spi2_dma_rx}
};
#define DMA_MAP_CNT ( sizeof(dma_info_map)/ sizeof(dma_info_map[0]))
struct stm32_dma_info *stm32_dma_info_get(uint32_t instance) {
for (int i = 0; i < DMA_MAP_CNT; ++i) {
if (dma_info_map[i].instance == instance) {
return dma_info_map + i;
}
}
return NULL;
}
void stm32_dma_clk_enable(const DMA_HandleTypeDef *handle) {
switch ((uint32_t) handle->Instance) {
case (uint32_t) DMA2_Stream0:
case (uint32_t) DMA2_Stream1:
case (uint32_t) DMA2_Stream2:
case (uint32_t) DMA2_Stream3:
case (uint32_t) DMA2_Stream4:
case (uint32_t) DMA2_Stream5:
case (uint32_t) DMA2_Stream6:
case (uint32_t) DMA2_Stream7:
__HAL_RCC_DMA2_CLK_ENABLE();
break;
case (uint32_t) DMA1_Stream0:
case (uint32_t) DMA1_Stream1:
case (uint32_t) DMA1_Stream2:
case (uint32_t) DMA1_Stream3:
case (uint32_t) DMA1_Stream4:
case (uint32_t) DMA1_Stream5:
case (uint32_t) DMA1_Stream6:
case (uint32_t) DMA1_Stream7:
__HAL_RCC_DMA1_CLK_ENABLE();
break;
default:
return;
}
}
void stm32_dma_clk_disable(const DMA_HandleTypeDef *handle) {
switch ((uint32_t) handle->Instance) {
case (uint32_t) DMA2_Stream0:
case (uint32_t) DMA2_Stream1:
case (uint32_t) DMA2_Stream2:
case (uint32_t) DMA2_Stream3:
case (uint32_t) DMA2_Stream4:
case (uint32_t) DMA2_Stream5:
case (uint32_t) DMA2_Stream6:
case (uint32_t) DMA2_Stream7:
__HAL_RCC_DMA2_CLK_DISABLE();
break;
case (uint32_t) DMA1_Stream0:
case (uint32_t) DMA1_Stream1:
case (uint32_t) DMA1_Stream2:
case (uint32_t) DMA1_Stream3:
case (uint32_t) DMA1_Stream4:
case (uint32_t) DMA1_Stream5:
case (uint32_t) DMA1_Stream6:
case (uint32_t) DMA1_Stream7:
__HAL_RCC_DMA1_CLK_DISABLE();
break;
default:
return;
}
}
#if SPI1_DMA
void DMA2_Stream0_IRQHandler(void) {
TX_INTERRUPT_SAVE_AREA
TX_DISABLE
HAL_DMA_IRQHandler(&spi1_dma_rx);
TX_RESTORE
}
void DMA2_Stream3_IRQHandler(void) {
TX_INTERRUPT_SAVE_AREA
TX_DISABLE
HAL_DMA_IRQHandler(&spi1_dma_tx);
TX_RESTORE
}
#endif
void DMA2_Stream3_IRQHandler(void) {
TX_INTERRUPT_SAVE_AREA
TX_DISABLE
HAL_DMA_IRQHandler(&sdio_dma_rx);
TX_RESTORE
}
void DMA2_Stream6_IRQHandler(void) {
TX_INTERRUPT_SAVE_AREA
TX_DISABLE
HAL_DMA_IRQHandler(&sdio_dma_tx);
TX_RESTORE
}
void DMA1_Stream4_IRQHandler(void) {
HAL_DMA_IRQHandler(&i2s_spi2_dma_tx);
}
void DMA1_Stream3_IRQHandler(void) {
HAL_DMA_IRQHandler(&i2s_spi2_dma_rx);
}
i2s底层驱动(使用的是双缓冲方式)
头文件
#ifndef DRV_I2S_OS_H
#define DRV_I2S_OS_H
#include <drv_common.h>
#define I2S_AUDIO_INSTANCE SPI2
void bsp_I2sParSet(uint32_t sample_freq, uint16_t bps);
void bsp_I2sDmaEnable(uint8_t dma_tx_enable, uint8_t dma_rx_enable);
void bsp_I2sDmaParSet(DMA_InitTypeDef *tx_cfg, DMA_InitTypeDef *rx_cfg);
void bsp_I2sInit(void);
void i2s_dma_tx_trans_set(const uint8_t *m0, const uint8_t *m1, uint16_t size);
void i2s_play_start();
void i2s_play_stop();
void i2s_play_pause();
void i2s_play_resume();
void i2s_dma_rx_trans_set(const uint8_t *m0, const uint8_t *m1, uint16_t size);
void i2s_record_start();
void i2s_record_stop();
void i2s_record_pause();
void i2s_record_resume();
#endif
源文件
#include "drv_i2s_os.h"
#include <drv_dma_os.h>
#include <drv_nvic_os.h>
extern void i2s_dma_m0_cpltcallback(struct __DMA_HandleTypeDef *hdma) __attribute__((weak));
extern void i2s_dma_m1_cpltcallback(struct __DMA_HandleTypeDef *hdma) __attribute__((weak));
extern void i2s_dma_errcallback(struct __DMA_HandleTypeDef *hdma)__attribute__((weak));
static I2S_HandleTypeDef handle = {.Instance = I2S_AUDIO_INSTANCE};
#define _i2s_handle (handle)
void bsp_I2sParSet(const uint32_t sample_freq, uint16_t bps) {
RCC_PeriphCLKInitTypeDef RCCI2S2_ClkInitSture;
uint32_t AudioFreq = I2S_AUDIOFREQ_44K;;
if (_i2s_handle.Init.AudioFreq != sample_freq) {
uint32_t PLLI2SN;
uint32_t PLLI2SR;
#define SWITCH_SAMPLE_FREQ(sn,sr,freq) {PLLI2SN = sn;PLLI2SR = sr;AudioFreq =freq;}break;
switch (sample_freq) {
case I2S_AUDIOFREQ_8K: SWITCH_SAMPLE_FREQ(256, 5, sample_freq)
case I2S_AUDIOFREQ_11K: SWITCH_SAMPLE_FREQ(429, 4, sample_freq)
case I2S_AUDIOFREQ_16K: SWITCH_SAMPLE_FREQ(213, 2, sample_freq)
case I2S_AUDIOFREQ_22K: SWITCH_SAMPLE_FREQ(429, 4, sample_freq)
case I2S_AUDIOFREQ_32K: SWITCH_SAMPLE_FREQ(213, 2, sample_freq)
case I2S_AUDIOFREQ_44K: SWITCH_SAMPLE_FREQ(271, 2, sample_freq)
case I2S_AUDIOFREQ_48K: SWITCH_SAMPLE_FREQ(258, 3, sample_freq)
case I2S_AUDIOFREQ_96K: SWITCH_SAMPLE_FREQ(344, 2, sample_freq)
case I2S_AUDIOFREQ_192K: SWITCH_SAMPLE_FREQ(393, 2, sample_freq)
default: SWITCH_SAMPLE_FREQ(271, 2, 44100)
}
#undef SWITCH_SAMPLE_FREQ
RCCI2S2_ClkInitSture.PeriphClockSelection = RCC_PERIPHCLK_I2S;
RCCI2S2_ClkInitSture.PLLI2S.PLLI2SN = PLLI2SN;
RCCI2S2_ClkInitSture.PLLI2S.PLLI2SR = PLLI2SR;
HAL_RCCEx_PeriphCLKConfig(&RCCI2S2_ClkInitSture);
}
{
_i2s_handle.Instance = I2S_AUDIO_INSTANCE;
_i2s_handle.Init.AudioFreq = AudioFreq;
_i2s_handle.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE;
_i2s_handle.Init.ClockSource = I2S_CLOCK_PLL;
switch (bps) {
case 24:
_i2s_handle.Init.Mode = I2S_MODE_MASTER_TX;
_i2s_handle.Init.Standard = I2S_STANDARD_PHILIPS;
_i2s_handle.Init.CPOL = I2S_CPOL_LOW;
_i2s_handle.Init.DataFormat = I2S_DATAFORMAT_24B;
break;
case 32:
_i2s_handle.Init.Mode = I2S_MODE_MASTER_TX;
_i2s_handle.Init.Standard = I2S_STANDARD_PHILIPS;
_i2s_handle.Init.CPOL = I2S_CPOL_LOW;
_i2s_handle.Init.DataFormat = I2S_DATAFORMAT_32B;
break;
default:
_i2s_handle.Init.Mode = I2S_MODE_MASTER_TX;
_i2s_handle.Init.Standard = I2S_STANDARD_PHILIPS;
_i2s_handle.Init.CPOL = I2S_CPOL_LOW;
_i2s_handle.Init.DataFormat = I2S_DATAFORMAT_16B_EXTENDED;
break;
}
}
}
void bsp_I2sDmaEnable(uint8_t dma_tx_enable, uint8_t dma_rx_enable) {
struct stm32_dma_info *dma_info = stm32_dma_info_get((uint32_t) _i2s_handle.Instance);
if (dma_tx_enable && dma_info->dma_tx) {
__HAL_LINKDMA(&_i2s_handle, hdmatx, *(dma_info->dma_tx));
}
if (dma_rx_enable && dma_info->dma_rx) {
__HAL_LINKDMA(&_i2s_handle, hdmarx, *(dma_info->dma_rx));
}
}
void bsp_I2sDmaParSet(DMA_InitTypeDef *tx_cfg, DMA_InitTypeDef *rx_cfg) {
if (_i2s_handle.hdmatx) {
if (tx_cfg) {
_i2s_handle.hdmatx->Init.Direction = tx_cfg->Direction;
_i2s_handle.hdmatx->Init.PeriphInc = tx_cfg->PeriphInc;
_i2s_handle.hdmatx->Init.MemInc = tx_cfg->MemInc;
_i2s_handle.hdmatx->Init.PeriphDataAlignment = tx_cfg->PeriphDataAlignment;
_i2s_handle.hdmatx->Init.MemDataAlignment = tx_cfg->MemDataAlignment;
_i2s_handle.hdmatx->Init.Mode = tx_cfg->Mode;
_i2s_handle.hdmatx->Init.Priority = tx_cfg->Priority;
_i2s_handle.hdmatx->Init.FIFOMode = tx_cfg->FIFOMode;
_i2s_handle.hdmatx->Init.FIFOThreshold = tx_cfg->FIFOThreshold;
_i2s_handle.hdmatx->Init.MemBurst = tx_cfg->MemBurst;
_i2s_handle.hdmatx->Init.PeriphBurst = tx_cfg->PeriphBurst;
} else {
_i2s_handle.hdmatx->Init.Direction = DMA_MEMORY_TO_PERIPH;
_i2s_handle.hdmatx->Init.PeriphInc = DMA_PINC_DISABLE;
_i2s_handle.hdmatx->Init.MemInc = DMA_MINC_ENABLE;
_i2s_handle.hdmatx->Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
_i2s_handle.hdmatx->Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
_i2s_handle.hdmatx->Init.Mode = DMA_CIRCULAR;
_i2s_handle.hdmatx->Init.Priority = DMA_PRIORITY_MEDIUM;
_i2s_handle.hdmatx->Init.FIFOMode = DMA_FIFOMODE_ENABLE;
_i2s_handle.hdmatx->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
_i2s_handle.hdmatx->Init.MemBurst = DMA_MBURST_INC8;
_i2s_handle.hdmatx->Init.PeriphBurst = DMA_MBURST_INC8;
}
}
if (_i2s_handle.hdmarx) {
if (rx_cfg) {
_i2s_handle.hdmarx->Init.Direction = rx_cfg->Direction;
_i2s_handle.hdmarx->Init.PeriphInc = rx_cfg->PeriphInc;
_i2s_handle.hdmarx->Init.MemInc = rx_cfg->MemInc;
_i2s_handle.hdmarx->Init.PeriphDataAlignment = rx_cfg->PeriphDataAlignment;
_i2s_handle.hdmarx->Init.MemDataAlignment = rx_cfg->MemDataAlignment;
_i2s_handle.hdmarx->Init.Mode = rx_cfg->Mode;
_i2s_handle.hdmarx->Init.Priority = rx_cfg->Priority;
_i2s_handle.hdmarx->Init.FIFOMode = rx_cfg->FIFOMode;
_i2s_handle.hdmarx->Init.FIFOThreshold = rx_cfg->FIFOThreshold;
_i2s_handle.hdmarx->Init.MemBurst = rx_cfg->MemBurst;
_i2s_handle.hdmarx->Init.PeriphBurst = rx_cfg->PeriphBurst;
} else {
_i2s_handle.hdmarx->Init.Direction = DMA_PERIPH_TO_MEMORY;
_i2s_handle.hdmarx->Init.PeriphInc = DMA_PINC_DISABLE;
_i2s_handle.hdmarx->Init.MemInc = DMA_MINC_ENABLE;
_i2s_handle.hdmarx->Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
_i2s_handle.hdmarx->Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
_i2s_handle.hdmatx->Init.Mode = DMA_CIRCULAR;
_i2s_handle.hdmatx->Init.Priority = DMA_PRIORITY_MEDIUM;
_i2s_handle.hdmatx->Init.FIFOMode = DMA_FIFOMODE_ENABLE;
_i2s_handle.hdmatx->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
_i2s_handle.hdmatx->Init.MemBurst = DMA_MBURST_INC8;
_i2s_handle.hdmatx->Init.PeriphBurst = DMA_MBURST_INC8;
}
}
}
void bsp_I2sInit(void) {
{
HAL_I2S_Init(&_i2s_handle);
}
}
void i2s_play_start() {
DISABLE_INT();
if (_i2s_handle.Instance) {
__HAL_DMA_ENABLE(_i2s_handle.hdmatx);
__HAL_I2S_ENABLE(&_i2s_handle);
__HAL_I2S_ENABLE_IT(&_i2s_handle, SPI_CR2_TXDMAEN);
}
ENABLE_INT();
}
void i2s_play_stop() {
if (_i2s_handle.Instance) {
__HAL_I2S_DISABLE_IT(&_i2s_handle, SPI_CR2_TXDMAEN);
HAL_I2S_DeInit(&_i2s_handle);
_i2s_handle.Instance = NULL;
}
}
void i2s_play_pause() {
if ((_i2s_handle.hdmatx->Instance->CR & DMA_SxCR_EN)) {
__HAL_DMA_DISABLE(_i2s_handle.hdmatx);
while ((_i2s_handle.hdmatx->Instance->CR & DMA_SxCR_EN) != RESET) {
}
}
}
void i2s_play_resume() {
if ((_i2s_handle.hdmatx->Instance->CR & DMA_SxCR_EN) == RESET) {
__HAL_DMA_ENABLE(_i2s_handle.hdmatx);
}
}
void i2s_dma_tx_trans_set(const uint8_t *m0, const uint8_t *m1, uint16_t size) {
if (_i2s_handle.hdmatx == NULL) {
Error_Handler();
}
_i2s_handle.hdmatx->XferCpltCallback = i2s_dma_m0_cpltcallback;
_i2s_handle.hdmatx->XferM1CpltCallback = i2s_dma_m1_cpltcallback;
_i2s_handle.hdmatx->XferErrorCallback = i2s_dma_errcallback;
_i2s_handle.hdmatx->Instance->CR |= (uint32_t) DMA_SxCR_DBM;
_i2s_handle.hdmatx->Instance->M1AR = (uint32_t) m1;
_i2s_handle.hdmatx->Instance->M0AR = (uint32_t) m0;
_i2s_handle.hdmatx->Instance->NDTR = size;
_i2s_handle.hdmatx->Instance->PAR = (uint32_t) &(_i2s_handle.Instance->DR);
__HAL_DMA_CLEAR_FLAG(_i2s_handle.hdmatx, __HAL_DMA_GET_TC_FLAG_INDEX( _i2s_handle.hdmatx));
__HAL_DMA_CLEAR_FLAG(_i2s_handle.hdmatx, __HAL_DMA_GET_HT_FLAG_INDEX( _i2s_handle.hdmatx));
__HAL_DMA_CLEAR_FLAG(_i2s_handle.hdmatx, __HAL_DMA_GET_TE_FLAG_INDEX( _i2s_handle.hdmatx));
__HAL_DMA_CLEAR_FLAG(_i2s_handle.hdmatx, __HAL_DMA_GET_DME_FLAG_INDEX( _i2s_handle.hdmatx));
__HAL_DMA_CLEAR_FLAG(_i2s_handle.hdmatx, __HAL_DMA_GET_FE_FLAG_INDEX( _i2s_handle.hdmatx));
_i2s_handle.hdmatx->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
_i2s_handle.hdmatx->Instance->FCR |= DMA_IT_FE;
}
void i2s_dma_rx_trans_set(const uint8_t *m0, const uint8_t *m1, uint16_t size) {
if (_i2s_handle.hdmarx == NULL) {
Error_Handler();
}
_i2s_handle.hdmarx->XferCpltCallback = i2s_dma_m0_cpltcallback;
_i2s_handle.hdmarx->XferM1CpltCallback = i2s_dma_m1_cpltcallback;
_i2s_handle.hdmarx->XferErrorCallback = i2s_dma_errcallback;
_i2s_handle.hdmarx->Instance->CR |= (uint32_t) DMA_SxCR_DBM;
_i2s_handle.hdmarx->Instance->M1AR = (uint32_t) m1;
_i2s_handle.hdmarx->Instance->M0AR = (uint32_t) m0;
_i2s_handle.hdmarx->Instance->NDTR = size;
_i2s_handle.hdmarx->Instance->PAR = (uint32_t) &(_i2s_handle.Instance->DR);
__HAL_DMA_CLEAR_FLAG(_i2s_handle.hdmarx, __HAL_DMA_GET_TC_FLAG_INDEX( _i2s_handle.hdmarx));
__HAL_DMA_CLEAR_FLAG(_i2s_handle.hdmarx, __HAL_DMA_GET_HT_FLAG_INDEX( _i2s_handle.hdmarx));
__HAL_DMA_CLEAR_FLAG(_i2s_handle.hdmarx, __HAL_DMA_GET_TE_FLAG_INDEX( _i2s_handle.hdmarx));
__HAL_DMA_CLEAR_FLAG(_i2s_handle.hdmarx, __HAL_DMA_GET_DME_FLAG_INDEX( _i2s_handle.hdmarx));
__HAL_DMA_CLEAR_FLAG(_i2s_handle.hdmarx, __HAL_DMA_GET_FE_FLAG_INDEX( _i2s_handle.hdmarx));
_i2s_handle.hdmarx->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
_i2s_handle.hdmarx->Instance->FCR |= DMA_IT_FE;
}
void i2s_record_start() {
DISABLE_INT();
if (_i2s_handle.Instance) {
__HAL_DMA_ENABLE(_i2s_handle.hdmarx);
__HAL_I2S_ENABLE(&_i2s_handle);
__HAL_I2S_ENABLE_IT(&_i2s_handle, SPI_CR2_RXDMAEN);
}
ENABLE_INT();
}
void i2s_record_stop() {
if (_i2s_handle.Instance) {
__HAL_I2S_DISABLE_IT(&_i2s_handle, SPI_CR2_RXDMAEN);
HAL_I2S_DeInit(&_i2s_handle);
_i2s_handle.Instance = NULL;
}
}
void i2s_record_pause() {
if ((_i2s_handle.hdmarx->Instance->CR & DMA_SxCR_EN)) {
__HAL_DMA_DISABLE(_i2s_handle.hdmarx);
while ((_i2s_handle.hdmarx->Instance->CR & DMA_SxCR_EN) != RESET) {
}
}
}
void i2s_record_resume() {
if ((_i2s_handle.hdmarx->Instance->CR & DMA_SxCR_EN) == RESET) {
__HAL_DMA_ENABLE(_i2s_handle.hdmarx);
}
}
硬件io文件
#include "bsp.h"
void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s_ptr) {
if (hi2s_ptr->Instance == SPI2) {
{
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_SPI2_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF6_I2S2ext;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3 | GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_12 | GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
if (hi2s_ptr->hdmatx) {
stm32_dma_clk_enable(hi2s_ptr->hdmatx);
HAL_DMA_Init(hi2s_ptr->hdmatx);
stm32_nvic_common_enable((uint32_t) hi2s_ptr->hdmatx->Instance, 0, 0);
};
}
}
void HAL_I2S_MspDeInit(I2S_HandleTypeDef *handle_ptr) {
if (handle_ptr->Instance == SPI2) {
__HAL_RCC_SPI2_CLK_DISABLE();
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_6);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10 | GPIO_PIN_12);
if (handle_ptr->hdmatx) {
HAL_DMA_DeInit(handle_ptr->hdmatx);
stm32_nvic_common_disable((uint32_t) handle_ptr->hdmatx->Instance);
}
}
}