Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ***********************************************************
- // Драйвер I2S
- //
- // ***********************************************************
- #include "i2s.h"
- #include "gpio.h"
- #include <stm32f4xx.h>
- // SPI3, альтернативная функция 6
- // PC7: MCK
- // PC10: SCK
- // PC12: SD
- // PA4: WS
- typedef struct
- {
- // Параметры ФАПЧ
- uint16_t PLLN;
- uint16_t PLLR;
- // предделитель
- uint16_t Div;
- // Добавлять 1 к предделителю?
- bool Odd;
- } TI2SClockParams;
- TI2SClockParams Params[] = {
- { 256, 8, 5, false }, // 8 кГц (8000 Гц)
- { 256, 4, 5, false }, // 16 кГц (16000 Гц)
- { 256, 2, 5, false }, // 32 кГц (32000 Гц)
- { 384, 4, 2, true }, // 48 кГц (48000 Гц)
- { 384, 2, 2, true }, // 96 кГц (96000 Гц)
- { 388, 4, 5, true }, // 22.05 кГц (22045 Гц)
- { 388, 2, 5, true }, // 44.1 кГц (44090 Гц)
- };
- // Инициализация
- void i2s_Init(TAudioFrequency Frequency)
- {
- if(Frequency >= FREQ_LAST) return;
- // Альтернативная функция выводов
- gpio_SetAlternateFunction(PORTC, 7, 6); // PC7
- gpio_SetAlternateFunction(PORTC, 10, 6); // PC10
- gpio_SetAlternateFunction(PORTC, 12, 6); // PC12
- gpio_SetAlternateFunction(PORTA, 4, 6); // PA4
- // Скорость: 50 МГц (для линий данных)
- gpio_FastSpeed(PORTC, 7);
- gpio_FastSpeed(PORTC, 10);
- gpio_FastSpeed(PORTC, 12);
- // Тактирование на модуль SPI3
- RCC->APB1ENR |= RCC_APB1ENR_SPI3EN;
- // Выключение модуля
- SPI3->I2SCFGR = 0;
- // В качестве источника тактирования используется PLLI2S
- RCC->CFGR &= ~RCC_CFGR_I2SSRC;
- // Настройка I2C PLL
- {
- uint16_t PLLR = Params[Frequency].PLLR;
- uint16_t PLLN = Params[Frequency].PLLN;
- RCC->PLLI2SCFGR = (PLLR << 28) | (PLLN << 6);
- }
- // Включить источник тактового сигнала PLLI2S
- RCC->CR |= RCC_CR_PLLI2SON;
- // Ожидание готовности
- while (!(RCC->CR & RCC_CR_PLLI2SRDY)) {}
- // Инициализация I2S
- {
- // Предделитель и иже с ним
- uint16_t Divider = Params[Frequency].Div;
- uint16_t Odd = (Params[Frequency].Odd) ? SPI_I2SPR_ODD : 0;
- // Предделитель
- SPI3->I2SPR = Divider | Odd | SPI_I2SPR_MCKOE;
- }
- // Аудио включено
- i2s_AudioOn();
- }
- // Включить передачу аудио
- void i2s_AudioOn(void)
- {
- // Режим I2S, включн
- // Мастер, передача.
- SPI3 ->I2SCFGR = SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SCFG_1 | SPI_I2SCFGR_I2SE;
- }
- // Выключить передачу аудио
- void i2s_AudioOff(void)
- {
- SPI3 ->I2SCFGR = 0;
- }
- // Буфер передачи пуст?
- bool i2s_IsBufferFree(void)
- {
- return (SPI3->SR & SPI_SR_TXE) != 0;
- }
- // Вывести аудиосемпл
- void i2s_Send(int16_t sample)
- {
- SPI3->DR = sample;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement