fix(st16): audio chip init and data transfer (#6299)
This commit is contained in:
@@ -151,8 +151,6 @@ static void _init_gpios(const stm32_spi_t* spi)
|
||||
static void _config_dma_streams(const stm32_spi_t* spi)
|
||||
{
|
||||
stm32_dma_enable_clock(spi->DMA);
|
||||
LL_DMA_DeInit(spi->DMA, spi->rxDMA_Stream);
|
||||
LL_DMA_DeInit(spi->DMA, spi->txDMA_Stream);
|
||||
|
||||
LL_DMA_InitTypeDef dmaInit;
|
||||
LL_DMA_StructInit(&dmaInit);
|
||||
@@ -160,42 +158,77 @@ static void _config_dma_streams(const stm32_spi_t* spi)
|
||||
#if defined(STM32H7)
|
||||
dmaInit.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT;
|
||||
dmaInit.Priority = LL_DMA_PRIORITY_VERYHIGH;
|
||||
dmaInit.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_HALFWORD;
|
||||
dmaInit.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_HALFWORD;
|
||||
dmaInit.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
|
||||
dmaInit.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
|
||||
#elif defined(STM32H7RS)
|
||||
dmaInit.Priority = LL_DMA_LOW_PRIORITY_HIGH_WEIGHT;
|
||||
#endif
|
||||
|
||||
#if defined(STM32H7)
|
||||
dmaInit.PeriphRequest = spi->rxDMA_PeriphRequest;
|
||||
dmaInit.PeriphOrM2MSrcAddress = LL_SPI_DMA_GetRxRegAddr(spi->SPIx);
|
||||
#elif defined(STM32H7RS)
|
||||
dmaInit.Request = spi->rxDMA_PeriphRequest;
|
||||
dmaInit.SrcAddress = LL_SPI_DMA_GetRxRegAddr(spi->SPIx);
|
||||
dmaInit.SrcIncMode = LL_DMA_SRC_FIXED;
|
||||
dmaInit.DestIncMode = LL_DMA_DEST_INCREMENT;
|
||||
dmaInit.SrcDataWidth = LL_DMA_DEST_DATAWIDTH_HALFWORD;
|
||||
dmaInit.DestDataWidth = LL_DMA_DEST_DATAWIDTH_HALFWORD;
|
||||
#endif
|
||||
|
||||
dmaInit.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
|
||||
LL_DMA_Init(spi->DMA, spi->rxDMA_Stream, &dmaInit);
|
||||
if (spi->rxDMA_PeriphRequest) {
|
||||
LL_DMA_DeInit(spi->DMA, spi->rxDMA_Stream);
|
||||
|
||||
#if defined(STM32H7)
|
||||
dmaInit.PeriphRequest = spi->txDMA_PeriphRequest;
|
||||
dmaInit.PeriphOrM2MSrcAddress = LL_SPI_DMA_GetTxRegAddr(spi->SPIx);
|
||||
dmaInit.PeriphRequest = spi->rxDMA_PeriphRequest;
|
||||
dmaInit.PeriphOrM2MSrcAddress = LL_SPI_DMA_GetRxRegAddr(spi->SPIx);
|
||||
#elif defined(STM32H7RS)
|
||||
dmaInit.Request = spi->rxDMA_PeriphRequest;
|
||||
dmaInit.DestAddress = LL_SPI_DMA_GetTxRegAddr(spi->SPIx);
|
||||
dmaInit.SrcIncMode = LL_DMA_SRC_INCREMENT;
|
||||
dmaInit.DestIncMode = LL_DMA_DEST_FIXED;
|
||||
dmaInit.SrcDataWidth = LL_DMA_SRC_DATAWIDTH_HALFWORD;
|
||||
dmaInit.DestDataWidth = LL_DMA_SRC_DATAWIDTH_HALFWORD;
|
||||
dmaInit.Request = spi->rxDMA_PeriphRequest;
|
||||
dmaInit.SrcAddress = LL_SPI_DMA_GetRxRegAddr(spi->SPIx);
|
||||
dmaInit.SrcIncMode = LL_DMA_SRC_FIXED;
|
||||
dmaInit.DestIncMode = LL_DMA_DEST_INCREMENT;
|
||||
dmaInit.SrcDataWidth = LL_DMA_SRC_DATAWIDTH_BYTE;
|
||||
dmaInit.DestDataWidth = LL_DMA_DEST_DATAWIDTH_BYTE;
|
||||
#endif
|
||||
|
||||
dmaInit.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
|
||||
LL_DMA_Init(spi->DMA, spi->txDMA_Stream, &dmaInit);
|
||||
dmaInit.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
|
||||
LL_DMA_Init(spi->DMA, spi->rxDMA_Stream, &dmaInit);
|
||||
}
|
||||
|
||||
if (spi->txDMA_PeriphRequest) {
|
||||
LL_DMA_DeInit(spi->DMA, spi->txDMA_Stream);
|
||||
|
||||
#if defined(STM32H7)
|
||||
dmaInit.PeriphRequest = spi->txDMA_PeriphRequest;
|
||||
dmaInit.PeriphOrM2MSrcAddress = LL_SPI_DMA_GetTxRegAddr(spi->SPIx);
|
||||
#elif defined(STM32H7RS)
|
||||
dmaInit.Request = spi->txDMA_PeriphRequest;
|
||||
dmaInit.DestAddress = LL_SPI_DMA_GetTxRegAddr(spi->SPIx);
|
||||
dmaInit.SrcIncMode = LL_DMA_SRC_INCREMENT;
|
||||
dmaInit.DestIncMode = LL_DMA_DEST_FIXED;
|
||||
dmaInit.SrcDataWidth = LL_DMA_SRC_DATAWIDTH_BYTE;
|
||||
dmaInit.DestDataWidth = LL_DMA_DEST_DATAWIDTH_BYTE;
|
||||
#endif
|
||||
|
||||
dmaInit.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
|
||||
LL_DMA_Init(spi->DMA, spi->txDMA_Stream, &dmaInit);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(STM32H7)
|
||||
static void _config_tx_dma_data_width(const stm32_spi_t* spi, uint32_t data_width)
|
||||
{
|
||||
uint32_t periph_size = LL_DMA_PDATAALIGN_BYTE;
|
||||
uint32_t memory_size = LL_DMA_MDATAALIGN_BYTE;
|
||||
if (data_width == sizeof(uint16_t)) {
|
||||
periph_size = LL_DMA_PDATAALIGN_HALFWORD;
|
||||
memory_size = LL_DMA_MDATAALIGN_HALFWORD;
|
||||
}
|
||||
LL_DMA_SetPeriphSize(spi->DMA, spi->txDMA_Stream, periph_size);
|
||||
LL_DMA_SetMemorySize(spi->DMA, spi->txDMA_Stream, memory_size);
|
||||
}
|
||||
#elif defined(STM32H7RS)
|
||||
static void _config_tx_dma_data_width(const stm32_spi_t* spi, uint32_t data_width)
|
||||
{
|
||||
uint32_t src_width = LL_DMA_SRC_DATAWIDTH_BYTE;
|
||||
uint32_t dest_width = LL_DMA_DEST_DATAWIDTH_BYTE;
|
||||
if (data_width == sizeof(uint16_t)) {
|
||||
src_width = LL_DMA_SRC_DATAWIDTH_HALFWORD;
|
||||
memory_size = LL_DMA_DEST_DATAWIDTH_HALFWORD;
|
||||
}
|
||||
LL_DMA_SetSrcDataWidth(spi->DMA, spi->txDMA_Stream, src_width);
|
||||
LL_DMA_SetDestDataWidth(spi->DMA, spi->txDMA_Stream, dest_width);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
void stm32_spi_init(const stm32_spi_t* spi, uint32_t data_width)
|
||||
@@ -427,13 +460,13 @@ uint32_t stm32_spi_dma_receive_bytes(const stm32_spi_t* spi, uint8_t* data,
|
||||
#if !defined(USE_SPI_DMA)
|
||||
return stm32_spi_transfer_bytes(spi, nullptr, data, length);
|
||||
#else
|
||||
uint32_t xfer_len = length / 2;
|
||||
uint32_t xfer_len = length;
|
||||
while (xfer_len > 0) {
|
||||
uint16_t single_xfer_len =
|
||||
xfer_len > SPI_MAX_XFER_SIZE ? SPI_MAX_XFER_SIZE : xfer_len;
|
||||
spi_receive_dma(spi, data, single_xfer_len);
|
||||
xfer_len -= single_xfer_len;
|
||||
data += single_xfer_len * 2;
|
||||
data += single_xfer_len;
|
||||
}
|
||||
|
||||
return length;
|
||||
@@ -460,25 +493,29 @@ uint32_t stm32_spi_dma_transmit_bytes(const stm32_spi_t* spi,
|
||||
#if !defined(USE_SPI_DMA)
|
||||
return stm32_spi_transfer_bytes(spi, data, nullptr, length);
|
||||
#else
|
||||
uint32_t xfer_len = length / 2;
|
||||
_config_tx_dma_data_width(spi, sizeof(uint8_t));
|
||||
|
||||
uint32_t xfer_len = length;
|
||||
while (xfer_len > 0) {
|
||||
uint16_t single_xfer_len =
|
||||
xfer_len > SPI_MAX_XFER_SIZE ? SPI_MAX_XFER_SIZE : xfer_len;
|
||||
spi_transmit_dma(spi, data, single_xfer_len);
|
||||
xfer_len -= single_xfer_len;
|
||||
data += single_xfer_len * 2;
|
||||
data += single_xfer_len;
|
||||
}
|
||||
|
||||
return length;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t stm32_spi_dma_transmit_words(const stm32_spi_t* spi,
|
||||
const uint16_t* data, uint32_t length)
|
||||
{
|
||||
#if !defined(USE_SPI_DMA)
|
||||
return stm32_spi_transfer_words(spi, data, nullptr, length);
|
||||
#else
|
||||
_config_tx_dma_data_width(spi, sizeof(uint16_t));
|
||||
|
||||
return length;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t stm32_spi_dma_transmit_words(const stm32_spi_t* spi,
|
||||
const uint16_t* data, uint32_t length)
|
||||
{
|
||||
#if !defined(USE_SPI_DMA)
|
||||
return stm32_spi_transfer_words(spi, data, nullptr, length);
|
||||
#else
|
||||
uint32_t xfer_len = length;
|
||||
while (xfer_len > 0) {
|
||||
uint16_t single_xfer_len =
|
||||
|
||||
@@ -33,46 +33,48 @@
|
||||
#include "edgetx.h"
|
||||
#include "timers_driver.h"
|
||||
|
||||
#define VS_WRITE_COMMAND 0x02
|
||||
#define VS_READ_COMMAND 0x03
|
||||
#define VS_WRITE_COMMAND 0x02
|
||||
#define VS_READ_COMMAND 0x03
|
||||
|
||||
#define SPI_MODE 0x00
|
||||
#define SPI_STATUS 0x01
|
||||
#define SPI_BASS 0x02
|
||||
#define SPI_CLOCKF 0x03
|
||||
#define SPI_DECODE_TIME 0x04
|
||||
#define SPI_AUDATA 0x05
|
||||
#define SPI_WRAM 0x06
|
||||
#define SPI_WRAMADDR 0x07
|
||||
#define SPI_HDAT0 0x08
|
||||
#define SPI_HDAT1 0x09
|
||||
#define SPI_AIADDR 0x0a
|
||||
#define SPI_VOL 0x0b
|
||||
#define SPI_AICTRL0 0x0c
|
||||
#define SPI_AICTRL1 0x0d
|
||||
#define SPI_AICTRL2 0x0e
|
||||
#define SPI_AICTRL3 0x0f
|
||||
#define SPI_MODE 0x00
|
||||
#define SPI_STATUS 0x01
|
||||
#define SPI_BASS 0x02
|
||||
#define SPI_CLOCKF 0x03
|
||||
#define SPI_DECODE_TIME 0x04
|
||||
#define SPI_AUDATA 0x05
|
||||
#define SPI_WRAM 0x06
|
||||
#define SPI_WRAMADDR 0x07
|
||||
#define SPI_HDAT0 0x08
|
||||
#define SPI_HDAT1 0x09
|
||||
#define SPI_AIADDR 0x0a
|
||||
#define SPI_VOL 0x0b
|
||||
#define SPI_AICTRL0 0x0c
|
||||
#define SPI_AICTRL1 0x0d
|
||||
#define SPI_AICTRL2 0x0e
|
||||
#define SPI_AICTRL3 0x0f
|
||||
|
||||
#define SM_DIFF 0x01
|
||||
#define SM_LAYER12 0x02
|
||||
#define SM_RESET 0x04
|
||||
#define SM_CANCEL 0x08
|
||||
#define SM_EARSPEAKER_LO 0x10
|
||||
#define SM_TESTS 0x20
|
||||
#define SM_STREAM 0x40
|
||||
#define SM_EARSPEAKER_HI 0x80
|
||||
#define SM_DACT 0x100
|
||||
#define SM_SDIORD 0x200
|
||||
#define SM_SDISHARE 0x400
|
||||
#define SM_SDINEW 0x800
|
||||
#define SM_ADPCM 0x1000
|
||||
#define SM_LINE1 0x4000
|
||||
#define SM_CLK_RANGE 0x8000
|
||||
#define SM_DIFF 0x01
|
||||
#define SM_LAYER12 0x02
|
||||
#define SM_RESET 0x04
|
||||
#define SM_CANCEL 0x08
|
||||
#define SM_EARSPEAKER_LO 0x10
|
||||
#define SM_TESTS 0x20
|
||||
#define SM_STREAM 0x40
|
||||
#define SM_EARSPEAKER_HI 0x80
|
||||
#define SM_DACT 0x100
|
||||
#define SM_SDIORD 0x200
|
||||
#define SM_SDISHARE 0x400
|
||||
#define SM_SDINEW 0x800
|
||||
#define SM_ADPCM 0x1000
|
||||
#define SM_LINE1 0x4000
|
||||
#define SM_CLK_RANGE 0x8000
|
||||
|
||||
#define SPI_LOW_SPEED 1500000
|
||||
#define SPI_HIGH_SPEED 12000000
|
||||
#define SPI_LOW_SPEED 1500000
|
||||
#define SPI_HIGH_SPEED 12000000
|
||||
|
||||
#define VS1053_BUFFER_SIZE 32
|
||||
#define VS1053_BUFFER_SIZE 32
|
||||
|
||||
#define DEFAULT_VOLUME 0xFEFE
|
||||
|
||||
#define XDCS_HIGH() _xdcs_high()
|
||||
#define XDCS_LOW() _xdcs_low()
|
||||
@@ -87,11 +89,13 @@ static uint32_t _last_play_ts = 0;
|
||||
static uint8_t* _audio_buffer = nullptr;
|
||||
static uint32_t _audio_buffer_len = 0;
|
||||
|
||||
static void(*_spi_transmit_data)(const uint8_t*, uint32_t) = nullptr;
|
||||
|
||||
// volume is set asynchronously:
|
||||
// - first saved in _async_volume
|
||||
// - then vs1053b_update_volume() is called periodically
|
||||
// to actually send the new setting to the device.
|
||||
static int16_t _async_volume = -1;
|
||||
static int16_t _async_volume;
|
||||
|
||||
static inline void _xdcs_high() { gpio_set(_instance->XDCS); }
|
||||
static inline void _xdcs_low() { gpio_clear(_instance->XDCS); }
|
||||
@@ -127,6 +131,7 @@ static void vs1053b_gpio_init(void)
|
||||
_set_mute_pin(true);
|
||||
|
||||
stm32_spi_init(_instance->spi, LL_SPI_DATAWIDTH_8BIT);
|
||||
stm32_spi_set_max_baudrate(_instance->spi, SPI_LOW_SPEED);
|
||||
}
|
||||
|
||||
static uint8_t vs1053b_spi_rw_byte(uint8_t value)
|
||||
@@ -134,122 +139,85 @@ static uint8_t vs1053b_spi_rw_byte(uint8_t value)
|
||||
return stm32_spi_transfer_byte(_instance->spi, value);
|
||||
}
|
||||
|
||||
static uint8_t vs1053b_wait_dreq(int32_t delay_us)
|
||||
static void vs1053b_spi_transmit_bytes(const uint8_t* data, uint32_t length)
|
||||
{
|
||||
stm32_spi_transfer_bytes(_instance->spi, data, nullptr, length);
|
||||
}
|
||||
|
||||
static void vs1053b_spi_dma_transmit_bytes(const uint8_t* data, uint32_t length)
|
||||
{
|
||||
#if __CORTEX_M >= 0x07
|
||||
SCB_CleanDCache_by_Addr((void*)data, length);
|
||||
#endif
|
||||
stm32_spi_dma_transmit_bytes(_instance->spi, data, length);
|
||||
}
|
||||
|
||||
static uint8_t vs1053b_wait_dreq(uint32_t timeout_us)
|
||||
{
|
||||
uint32_t start = timersGetUsTick();
|
||||
while (READ_DREQ() == 0) {
|
||||
if (delay_us-- == 0) return 0;
|
||||
delay_01us(10);
|
||||
if (timersGetUsTick() - start >= timeout_us) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint16_t vs1053b_read_reg(uint8_t address)
|
||||
static void _wait_us(uint32_t delay_us)
|
||||
{
|
||||
if (!vs1053b_wait_dreq(100))
|
||||
return 0;
|
||||
uint32_t start = timersGetUsTick();
|
||||
while (timersGetUsTick() - start < delay_us) {}
|
||||
}
|
||||
|
||||
stm32_spi_set_max_baudrate(_instance->spi, SPI_LOW_SPEED);
|
||||
XDCS_HIGH();
|
||||
stm32_spi_select(_instance->spi);
|
||||
vs1053b_spi_rw_byte(VS_READ_COMMAND);
|
||||
vs1053b_spi_rw_byte(address);
|
||||
volatile uint16_t result = vs1053b_spi_rw_byte(0xff) << 8;
|
||||
result += vs1053b_spi_rw_byte(0xff);
|
||||
delay_01us(100); // 10us
|
||||
stm32_spi_unselect(_instance->spi);
|
||||
|
||||
stm32_spi_set_max_baudrate(_instance->spi, SPI_HIGH_SPEED);
|
||||
return result;
|
||||
static void _wait_ms(uint32_t delay_ms)
|
||||
{
|
||||
uint32_t start = timersGetMsTick();
|
||||
while (timersGetMsTick() - start < delay_ms) {}
|
||||
}
|
||||
|
||||
static uint8_t vs1053b_write_cmd(uint8_t address, uint16_t data)
|
||||
{
|
||||
if (!vs1053b_wait_dreq(100))
|
||||
return 0;
|
||||
|
||||
stm32_spi_set_max_baudrate(_instance->spi, SPI_LOW_SPEED);
|
||||
XDCS_HIGH();
|
||||
|
||||
stm32_spi_select(_instance->spi);
|
||||
vs1053b_spi_rw_byte(VS_WRITE_COMMAND);
|
||||
vs1053b_spi_rw_byte(address);
|
||||
vs1053b_spi_rw_byte(data >> 8);
|
||||
vs1053b_spi_rw_byte(data);
|
||||
delay_01us(50); // 5us
|
||||
stm32_spi_unselect(_instance->spi);
|
||||
|
||||
// wait for command to be processed
|
||||
_wait_us(20);
|
||||
vs1053b_wait_dreq(100);
|
||||
|
||||
stm32_spi_set_max_baudrate(_instance->spi, SPI_HIGH_SPEED);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void vs1053b_reset_decode_time()
|
||||
{
|
||||
vs1053b_write_cmd(SPI_DECODE_TIME, 0x0000);
|
||||
vs1053b_write_cmd(SPI_DECODE_TIME, 0x0000);
|
||||
}
|
||||
|
||||
static uint8_t vs1053b_hard_reset()
|
||||
static void vs1053b_hard_reset()
|
||||
{
|
||||
XDCS_HIGH();
|
||||
stm32_spi_unselect(_instance->spi);
|
||||
|
||||
_reset_low();
|
||||
delay_ms(100); // 100ms
|
||||
_wait_ms(100);
|
||||
_reset_high();
|
||||
|
||||
if (!vs1053b_wait_dreq(5000))
|
||||
return 0;
|
||||
|
||||
delay_ms(20); // 20ms
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint8_t vs1053b_soft_reset()
|
||||
{
|
||||
stm32_spi_set_max_baudrate(_instance->spi, SPI_LOW_SPEED);
|
||||
if (!vs1053b_wait_dreq(100))
|
||||
return 0;
|
||||
|
||||
vs1053b_spi_rw_byte(0x00); // start the transfer
|
||||
|
||||
uint8_t retry = 0;
|
||||
uint16_t mode = SM_SDINEW;
|
||||
while (vs1053b_read_reg(SPI_MODE) != mode && retry < 100) {
|
||||
retry++;
|
||||
vs1053b_write_cmd(SPI_MODE, mode | SM_RESET);
|
||||
delay_ms(2);
|
||||
}
|
||||
|
||||
// wait for set up successful
|
||||
retry = 0;
|
||||
while (vs1053b_read_reg(SPI_CLOCKF) != 0x9800 && retry < 100) {
|
||||
retry++;
|
||||
vs1053b_write_cmd(SPI_CLOCKF, 0x9800);
|
||||
}
|
||||
|
||||
vs1053b_reset_decode_time(); // reset the decoding time
|
||||
stm32_spi_set_max_baudrate(_instance->spi, SPI_HIGH_SPEED);
|
||||
|
||||
XDCS_LOW();
|
||||
vs1053b_spi_rw_byte(0X0);
|
||||
vs1053b_spi_rw_byte(0X0);
|
||||
vs1053b_spi_rw_byte(0X0);
|
||||
vs1053b_spi_rw_byte(0X0);
|
||||
delay_01us(100); // 10us
|
||||
XDCS_HIGH();
|
||||
|
||||
return 1;
|
||||
// datasheet says 1.8ms at default clock speed
|
||||
vs1053b_wait_dreq(3000);
|
||||
}
|
||||
|
||||
static uint32_t vs1053b_send_data(const uint8_t * buffer, uint32_t size)
|
||||
{
|
||||
XDCS_LOW();
|
||||
|
||||
uint32_t index = 0;
|
||||
while (index < size && READ_DREQ() != 0) {
|
||||
for (int i = 0; i < VS1053_BUFFER_SIZE && index < size; i++) {
|
||||
vs1053b_spi_rw_byte(buffer[index++]);
|
||||
}
|
||||
const uint8_t* data = buffer;
|
||||
while (size > 0 && READ_DREQ() != 0) {
|
||||
uint32_t xfer_size = size > VS1053_BUFFER_SIZE ? VS1053_BUFFER_SIZE : size;
|
||||
XDCS_LOW();
|
||||
_spi_transmit_data(data, xfer_size);
|
||||
XDCS_HIGH();
|
||||
size -= xfer_size;
|
||||
data += xfer_size;
|
||||
}
|
||||
|
||||
return index;
|
||||
return data - buffer;
|
||||
}
|
||||
|
||||
static void vs1053b_send_buffer(const uint8_t * buffer, uint32_t size)
|
||||
@@ -341,13 +309,24 @@ void vs1053b_init(const vs1053b_t* dev)
|
||||
{
|
||||
_instance = dev;
|
||||
|
||||
if (_instance->spi->DMA) {
|
||||
_spi_transmit_data = vs1053b_spi_dma_transmit_bytes;
|
||||
} else {
|
||||
_spi_transmit_data = vs1053b_spi_transmit_bytes;
|
||||
}
|
||||
|
||||
vs1053b_gpio_init();
|
||||
vs1053b_hard_reset();
|
||||
vs1053b_soft_reset();
|
||||
|
||||
vs1053b_write_cmd(SPI_MODE, SM_SDINEW);
|
||||
|
||||
_async_volume = DEFAULT_VOLUME;
|
||||
vs1053b_update_volume();
|
||||
|
||||
vs1053b_write_cmd(SPI_CLOCKF, 0x9800);
|
||||
vs1053b_wait_dreq(1000);
|
||||
|
||||
stm32_spi_set_max_baudrate(_instance->spi, SPI_HIGH_SPEED);
|
||||
delay_ms(1); // 1ms
|
||||
|
||||
vs1053b_send_riff_header();
|
||||
}
|
||||
|
||||
|
||||
@@ -102,6 +102,9 @@ static stm32_spi_t audioSpi =
|
||||
.MISO = AUDIO_SPI_MISO_GPIO,
|
||||
.MOSI = AUDIO_SPI_MOSI_GPIO,
|
||||
.CS = AUDIO_CS_GPIO,
|
||||
.DMA = AUDIO_SPI_DMA,
|
||||
.txDMA_PeriphRequest = AUDIO_SPI_DMA_REQ,
|
||||
.txDMA_Stream = AUDIO_SPI_DMA_STREAM,
|
||||
};
|
||||
|
||||
static void audio_set_rst_pin(bool set)
|
||||
|
||||
@@ -21,6 +21,22 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
// DMA streams:
|
||||
//
|
||||
// - LEDs TIM2_UP: DMA1 stream 0
|
||||
// - Audio SPI1_TX: DMA1 stream 1
|
||||
// - Gimbals USART2_RX: DMA1 stream 2
|
||||
// - Telemytry UART5_RX: DMA1 stream 3
|
||||
// - Telemetry UART5_TX: DMA1 stream 7
|
||||
//
|
||||
// - ADC3: DMA2 stream 0
|
||||
// - ADC1: DMA2 stream 4
|
||||
// - Ext. Mod. UART4_RX: DMA2 stream 4 (!)
|
||||
// - Ext. Mod. UART4_TX: DMA2 stream 6
|
||||
// - Ext. Mod. TIM4_UP: DMA2 stream 6
|
||||
//
|
||||
|
||||
|
||||
#define CPU_FREQ 400000000
|
||||
|
||||
#define PERI1_FREQUENCY 100000000
|
||||
@@ -342,6 +358,9 @@
|
||||
#define AUDIO_SPI_SCK_GPIO GPIO_PIN(GPIOA, 5) // PA.05
|
||||
#define AUDIO_SPI_MISO_GPIO GPIO_PIN(GPIOG, 9) // PG.09
|
||||
#define AUDIO_SPI_MOSI_GPIO GPIO_PIN(GPIOD, 7) // PD.07
|
||||
#define AUDIO_SPI_DMA DMA1
|
||||
#define AUDIO_SPI_DMA_REQ LL_DMAMUX1_REQ_SPI1_TX
|
||||
#define AUDIO_SPI_DMA_STREAM LL_DMA_STREAM_1
|
||||
#define AUDIO_MUTE_GPIO 0
|
||||
#define AUDIO_UNMUTE_DELAY 180 // ms
|
||||
#define AUDIO_MUTE_DELAY 200 // ms
|
||||
|
||||
Reference in New Issue
Block a user