Advertisement
teplofizik

i2s.c

Aug 7th, 2013
901
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.22 KB | None | 0 0
  1. // ***********************************************************
  2. // Драйвер I2S
  3. //
  4. // ***********************************************************
  5.  
  6. #include "i2s.h"
  7. #include "gpio.h"
  8.  
  9. #include <stm32f4xx.h>
  10.  
  11. // SPI3, альтернативная функция 6
  12. // PC7:  MCK
  13. // PC10: SCK
  14. // PC12: SD
  15. // PA4:  WS
  16.  
  17. typedef struct
  18. {
  19.     // Параметры ФАПЧ
  20.     uint16_t PLLN;
  21.     uint16_t PLLR;
  22.    
  23.     // предделитель
  24.     uint16_t Div;
  25.     // Добавлять 1 к предделителю?
  26.     bool     Odd;
  27. } TI2SClockParams;
  28.  
  29.  
  30. TI2SClockParams Params[] = {
  31.   { 256, 8,  5, false }, // 8  кГц (8000  Гц)
  32.   { 256, 4,  5, false }, // 16 кГц (16000 Гц)
  33.   { 256, 2,  5, false }, // 32 кГц (32000 Гц)
  34.   { 384, 4,  2, true  }, // 48 кГц (48000 Гц)
  35.   { 384, 2,  2, true  }, // 96 кГц (96000 Гц)
  36.   { 388, 4,  5, true  }, // 22.05 кГц (22045 Гц)
  37.   { 388, 2,  5, true }, // 44.1 кГц (44090 Гц)
  38. };
  39.  
  40. // Инициализация
  41. void i2s_Init(TAudioFrequency Frequency)
  42. {
  43.     if(Frequency >= FREQ_LAST) return;
  44.    
  45.     // Альтернативная функция выводов
  46.     gpio_SetAlternateFunction(PORTC,  7, 6); // PC7
  47.     gpio_SetAlternateFunction(PORTC, 10, 6); // PC10
  48.     gpio_SetAlternateFunction(PORTC, 12, 6); // PC12
  49.     gpio_SetAlternateFunction(PORTA,  4, 6); // PA4
  50.    
  51.     // Скорость: 50 МГц (для линий данных)
  52.  
  53.     gpio_FastSpeed(PORTC,  7);
  54.     gpio_FastSpeed(PORTC, 10);
  55.     gpio_FastSpeed(PORTC, 12);
  56.    
  57.     // Тактирование на модуль SPI3
  58.     RCC->APB1ENR |= RCC_APB1ENR_SPI3EN;
  59.    
  60.     // Выключение модуля
  61.     SPI3->I2SCFGR = 0;
  62.    
  63.     // В качестве источника тактирования используется PLLI2S
  64.     RCC->CFGR &= ~RCC_CFGR_I2SSRC;
  65.    
  66.     // Настройка I2C PLL
  67.     {
  68.         uint16_t PLLR = Params[Frequency].PLLR;
  69.         uint16_t PLLN = Params[Frequency].PLLN;
  70.        
  71.         RCC->PLLI2SCFGR = (PLLR << 28) | (PLLN << 6);
  72.     }
  73.    
  74.     // Включить источник тактового сигнала PLLI2S
  75.     RCC->CR |= RCC_CR_PLLI2SON;
  76.  
  77.     // Ожидание готовности
  78.     while (!(RCC->CR & RCC_CR_PLLI2SRDY)) {}
  79.        
  80.     // Инициализация I2S
  81.     {
  82.         // Предделитель и иже с ним
  83.         uint16_t Divider = Params[Frequency].Div;
  84.         uint16_t Odd = (Params[Frequency].Odd) ? SPI_I2SPR_ODD : 0;
  85.        
  86.         // Предделитель
  87.         SPI3->I2SPR = Divider | Odd | SPI_I2SPR_MCKOE;
  88.     }
  89.    
  90.     // Аудио включено
  91.     i2s_AudioOn();
  92. }
  93.  
  94. // Включить передачу аудио
  95. void i2s_AudioOn(void)
  96. {
  97.     // Режим I2S, включн
  98.     // Мастер, передача.
  99.     SPI3 ->I2SCFGR = SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SCFG_1 | SPI_I2SCFGR_I2SE;
  100. }
  101.  
  102. // Выключить передачу аудио
  103. void i2s_AudioOff(void)
  104. {
  105.     SPI3 ->I2SCFGR = 0;
  106. }
  107.  
  108. // Буфер передачи пуст?
  109. bool i2s_IsBufferFree(void)
  110. {
  111.     return (SPI3->SR & SPI_SR_TXE) != 0;
  112. }
  113.  
  114. // Вывести аудиосемпл
  115. void i2s_Send(int16_t sample)
  116. {
  117.     SPI3->DR = sample;
  118. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement