First Publish. Works fine.

Dependents:   unzen_sample_nucleo_f746 unzen_delay_sample_nucleo_f746 skeleton_unzen_nucleo_f746 ifmag_noise_canceller ... more

Nucleo F746ZG用のオーディオ・フレームワークです。フレームワーク地震の詳細は『雲仙』オーディオ・フレームワークを参照してください。

参考リンク

  • skeleton_unzen_nucleo_f746 Nucleo F746ZGおよびUI基板を使う場合のスケルトンプログラム。F746を使う方はここから読み始めると良いでしょう。
Committer:
shorie
Date:
Sun Jan 29 02:50:31 2017 +0000
Revision:
20:e995396b427b
Parent:
16:9db140409038
Update comment.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shorie 0:5ac19c994288 1 #include "unzen_hal.h"
shorie 0:5ac19c994288 2
shorie 16:9db140409038 3 // #define DEBUGSAI
shorie 0:5ac19c994288 4 namespace unzen
shorie 0:5ac19c994288 5 {
shorie 15:76871e578c10 6 // for timing control.
shorie 15:76871e578c10 7 volatile unsigned int dummy;
shorie 15:76871e578c10 8
shorie 0:5ac19c994288 9 // Set up I2S peripheral to ready to start.
shorie 0:5ac19c994288 10 // By this HAL, the I2S have to become :
shorie 0:5ac19c994288 11 // - slave mode
shorie 0:5ac19c994288 12 // - clock must be ready
shorie 2:6613e62da521 13 void hal_i2s_setup(void)
shorie 0:5ac19c994288 14 {
shorie 15:76871e578c10 15 // STM32F746ZG SAI1 Block A :RX : Slave to the external BCLK/WS
shorie 15:76871e578c10 16 // STM32F746ZG SAI1 Block B :TX : Sync with Block A.
shorie 15:76871e578c10 17 // See stm32f746xx.h source here : https://developer.mbed.org/teams/Rigado/code/mbed-src-bmd-200/docs/255afbe6270c/stm32f746xx_8h_source.html
shorie 15:76871e578c10 18 // This implementation kills SPI6 interrupt
shorie 2:6613e62da521 19
shorie 15:76871e578c10 20 // Setup PLL
shorie 15:76871e578c10 21 // RCC_PLLCFGR : Has PLLM ( Division Factor M )
shorie 15:76871e578c10 22 // RCC_CIR : PLL clock interrupt register
shorie 16:9db140409038 23 // RCC_CFGR
shorie 16:9db140409038 24
shorie 16:9db140409038 25 // RCC_DKCFGR1 : RCC Dedicated clocks configuration register
shorie 16:9db140409038 26 // clear the relevant field
shorie 16:9db140409038 27 RCC->DCKCFGR1 &= ~ (
shorie 16:9db140409038 28 3 << 20 | // SAI1 SEL
shorie 16:9db140409038 29 31 << 8 ); // PLLSAIDIVQ
shorie 16:9db140409038 30 // set the value
shorie 16:9db140409038 31 RCC->DCKCFGR1 |=
shorie 16:9db140409038 32 0 << 20 | // SAI1 SEL : 0, PLLSAI
shorie 16:9db140409038 33 0 << 8 ; // PLLSAIDIVQ : 0, div by 1
shorie 0:5ac19c994288 34
shorie 15:76871e578c10 35 // RCC_PLLSAICFGR : PLLSAI configuration register. mbed set the pre-devider as 8. So, PLL input is 1MHz
shorie 15:76871e578c10 36 // The VCO have to be more than 100Mhaz. So, set it 192MHz.
shorie 15:76871e578c10 37 RCC->PLLSAICFGR =
shorie 15:76871e578c10 38 4 << 28 | // PLLSAIR : 4 is dividing by 4 for LCD clock ( 48Mhz )
shorie 15:76871e578c10 39 4 << 24 | // PLLSAIQ : 4 is dividing by 4 for SAI clock ( 48Mhz )
shorie 15:76871e578c10 40 1 << 16 | // PLLSAIR : 1 is dividing by 4 for USB clock ( 48Mhz )
shorie 15:76871e578c10 41 192 << 6 ; // PLLSAIN : 192 is dividing by 192 for vco freq ( 192Mhz )
shorie 0:5ac19c994288 42
shorie 15:76871e578c10 43 // RCC_CR : Starting/Status of PLLSAI
shorie 15:76871e578c10 44 RCC->CR |= (1 << 28); // PLL SAI On
shorie 15:76871e578c10 45 // wait while PLL SAI is not ready
shorie 15:76871e578c10 46 while ( !( RCC->CR & ( 1<<29 ) ) )
shorie 15:76871e578c10 47 ;
shorie 15:76871e578c10 48
shorie 0:5ac19c994288 49
shorie 15:76871e578c10 50 // RCC_APB2ENR : APB2 peripherals clock enable register
shorie 15:76871e578c10 51 RCC->APB2ENR |= ( 1 << 22); // SAI1 enable
shorie 15:76871e578c10 52
shorie 15:76871e578c10 53 // RCC_AHB1ENR : AHB1 peripherals clock enable register
shorie 15:76871e578c10 54 RCC->AHB1ENR |= 1<<4; // GPIOE enable
shorie 15:76871e578c10 55
shorie 15:76871e578c10 56 // Control the stability timing. The STM32F746 reference manual requires
shorie 15:76871e578c10 57 // to wait 2 peripheral cylecs, after enabling its clock.
shorie 15:76871e578c10 58 // See chapter 5.2.12
shorie 15:76871e578c10 59 // Two guarantee the 2 peripheral cyucles, reading status register twice.
shorie 15:76871e578c10 60 dummy = RCC->CR;
shorie 15:76871e578c10 61 dummy = RCC->CR;
shorie 15:76871e578c10 62
shorie 15:76871e578c10 63 // RCC_APB2RSTR : APB2 peripherals reset register
shorie 15:76871e578c10 64 RCC->APB2RSTR |= ( 1 << 22); // SAI1 reset
shorie 15:76871e578c10 65 RCC->APB2RSTR &= ~( 1 << 22); // SAI1 reset release
shorie 15:76871e578c10 66
shorie 15:76871e578c10 67
shorie 15:76871e578c10 68 /*
shorie 15:76871e578c10 69 RCC_CR :03078483
shorie 15:76871e578c10 70 RCC_PLLCFGR :29406c08
shorie 15:76871e578c10 71 RCC_CFGR :0000940a
shorie 15:76871e578c10 72 RCC_CIR :00000000
shorie 15:76871e578c10 73 RCC_APB2RSTR :00000000
shorie 15:76871e578c10 74 RCC_CR :03078483
shorie 15:76871e578c10 75 RCC_PLLSAICFGR :24003000
shorie 15:76871e578c10 76 */
shorie 15:76871e578c10 77
shorie 15:76871e578c10 78 // Setup Global Configuraion Register
shorie 15:76871e578c10 79 SAI1->GCR =
shorie 15:76871e578c10 80 0 << 0 | // syncin : ingnored because none of the block is external synch from outside of SAI module
shorie 15:76871e578c10 81 0 << 4 ; // syncout : 0 : No sync output for other SAI. 1,Block A(RX) is used for input of otehr block
shorie 15:76871e578c10 82
shorie 15:76871e578c10 83 // Setup SAI Block configuration register.
shorie 15:76871e578c10 84 // Block A : RX
shorie 15:76871e578c10 85 // Block B : TX
shorie 15:76871e578c10 86 SAI1_Block_A->CR1 =
shorie 16:9db140409038 87 #ifndef DEBUGSAI
shorie 15:76871e578c10 88 0 << 20 | // MCKDIV : Meaningless because the block is slave mode.
shorie 16:9db140409038 89 #else
shorie 16:9db140409038 90 2 << 20 | // MCKDIV : Master Clock Divider.: Div by 4
shorie 16:9db140409038 91 #endif
shorie 16:9db140409038 92 1 << 19 | // NODIV : Master clock divider is enabled ( perhaps, meaningless in slave mode )
shorie 15:76871e578c10 93 0 << 17 | // DMAEN : 0, DMA disanble, 1: DMA Enable
shorie 15:76871e578c10 94 0 << 16 | // SAIXEN : 0, Disable, 1, Enable. Disable at this moment
shorie 15:76871e578c10 95 0 << 13 | // OUTDRIV : 0, Audio is driven only when SAIXEN is 1. 1, Audio is driven
shorie 15:76871e578c10 96 0 << 12 | // MONO : 0, Stereo. 1, Mono
shorie 15:76871e578c10 97 0 << 10 | // SYNCEN : 0, Async mode. The Async mode referes the outside sync signal in slave mode.
shorie 16:9db140409038 98 1 << 9 | // CKSTR : 0, sample by falling edge, 1, sample by rising edge. I2S is sample by rising edge
shorie 15:76871e578c10 99 0 << 8 | // LSBFIRST : 0, MSB first. 1, LSB first. I2S is MSB first
shorie 15:76871e578c10 100 7 << 5 | // DS : 7, 32bit.
shorie 15:76871e578c10 101 0 << 2 | // PRTCFG : 0, Free protocol, 1, SPDIF, 2, AC97. I2S is Free protocol
shorie 16:9db140409038 102 #ifndef DEBUGSAI
shorie 15:76871e578c10 103 3 << 0 ; // MODE : 0, master tx. 1, master rx. 2, slave tx. 3, slave rx
shorie 16:9db140409038 104 #else
shorie 16:9db140409038 105 1 << 0 ; // MODE : 0, master tx. 1, master rx. 2, slave tx. 3, slave rx
shorie 16:9db140409038 106 #endif
shorie 15:76871e578c10 107 // configuration register 2
shorie 15:76871e578c10 108 SAI1_Block_A->CR2 =
shorie 15:76871e578c10 109 0 << 14 | // COMP : 0, No companding
shorie 15:76871e578c10 110 0 << 13 | // CPL : Ignoered when no companding
shorie 15:76871e578c10 111 0 << 7 | // MUTECNT : 0, ignored when no muting
shorie 15:76871e578c10 112 0 << 6 | // MUTEVAL : 0, meaningless except SPDIF mode
shorie 15:76871e578c10 113 0 << 5 | // MUTE : 0, No mute. 1, mute
shorie 15:76871e578c10 114 0 << 4 | // TRIS : 0, Drive all slot. 1, Drive only active slot. Meaningless for I2S and RX
shorie 15:76871e578c10 115 1 << 3 | // FFLUSH : 0, No FIFO Flush. 1, FIFO Flush
shorie 15:76871e578c10 116 1 << 0; // FTH : 0, FIFO empty. 1, 1/4 FIFO. 2, 1/2 FIFO. 3, 3/4 FIFO. 4, FIFO full
shorie 15:76871e578c10 117
shorie 15:76871e578c10 118 // Frame configuration register
shorie 15:76871e578c10 119 SAI1_Block_A->FRCR =
shorie 15:76871e578c10 120 1 << 18 | // FSOFF : 0, FS is asserted on the first bit. 1, FS is asserted before the first bit.
shorie 15:76871e578c10 121 0 << 17 | // FSPOL : 0, Active low. 1, active high. I2S in left first operation is actilve low FS.
shorie 15:76871e578c10 122 1 << 16 | // FSDEF : 0, FS is start frame signal. 1, FS has also channel side info. I2S have to set 1
shorie 15:76871e578c10 123 31 << 8 | // FSALL : Frame sync active level lenght. Seems to be meaningless in slave mode. Set as to be sure.
shorie 15:76871e578c10 124 63 << 0 ; // FRL : Frame length. Seems to be meaning less in slave mode. Set as to be sure.
shorie 0:5ac19c994288 125
shorie 15:76871e578c10 126 // Slot register
shorie 15:76871e578c10 127 SAI1_Block_A->SLOTR =
shorie 15:76871e578c10 128 0xFFFF << 16 | // SLOTEN : bit mask to specify the active slot. In I2S, 2 slts are active.
shorie 15:76871e578c10 129 1 << 8 | // NBSLOT : Number of slots - 1 ( Ref manual seems to be wrong )
shorie 16:9db140409038 130 2 << 6 | // SLOTSZ : 0, same with data size. 1, 16bit. 2, 32bit
shorie 15:76871e578c10 131 0 << 0 ; // FBOFF : The manual is not clear. Perhaps, 0 is OK.
shorie 15:76871e578c10 132
shorie 15:76871e578c10 133 // interrupt mask. Only FIFO interrupt is allowed.
shorie 15:76871e578c10 134 SAI1_Block_A->IMR =
shorie 15:76871e578c10 135 0 << 6 | // LFSDETIE : Late frame synchronization detection interrupt enable
shorie 15:76871e578c10 136 0 << 5 | // AFSDETIE : Anticipated frame synchronization detection interrupt enable. AC97 only
shorie 15:76871e578c10 137 0 << 4 | // CNDYIE : CODEC nott ready interrupt. AC97 only
shorie 15:76871e578c10 138 1 << 3 | // FREQIE : FIFO Interrupt Request. Enable for RX
shorie 15:76871e578c10 139 0 << 2 | // WCKCFGIE : Wrong clock configuration interrupt enable.
shorie 15:76871e578c10 140 0 << 1 | // MUTEDETIE: Mute detection interrupt enable.
shorie 15:76871e578c10 141 0 << 0; // OVRUDRIE : Overrun/underrun interrupt enable
shorie 15:76871e578c10 142
shorie 15:76871e578c10 143 // Clear flag register
shorie 15:76871e578c10 144 SAI1_Block_A->CLRFR = 0xFFFFFFFF; // clear all flags
shorie 15:76871e578c10 145
shorie 15:76871e578c10 146 // Setup SAI Block configuration register.
shorie 15:76871e578c10 147 // Block A : RX
shorie 15:76871e578c10 148 // Block B : TX
shorie 15:76871e578c10 149 SAI1_Block_B->CR1 =
shorie 15:76871e578c10 150 0 << 20 | // MCKDIV : Meaningless because the block is slave mode.
shorie 15:76871e578c10 151 0 << 19 | // NODIV : Master clock divider is enabled ( perhaps, meaningless in slave mode )
shorie 15:76871e578c10 152 0 << 17 | // DMAEN : 0, DMA disanble, 1: DMA Enable
shorie 15:76871e578c10 153 0 << 16 | // SAIXEN : 0, Disable, 1, Enable. Disable at this moment
shorie 15:76871e578c10 154 0 << 13 | // OUTDRIV : 0, Audio is driven only when SAIXEN is 1. 1, Audio is driven
shorie 15:76871e578c10 155 0 << 12 | // MONO : 0, Stereo. 1, Mono
shorie 15:76871e578c10 156 1 << 10 | // SYNCEN : 1, sync with internal audio block.
shorie 16:9db140409038 157 1 << 9 | // CKSTR : 0, sample by falling edge, 1, sample by rising edge. I2S is sample by rising edge
shorie 15:76871e578c10 158 0 << 8 | // LSBFIRST : 0, MSB first. 1, LSB first. I2S is MSB first
shorie 15:76871e578c10 159 7 << 5 | // DS : 7, 32bit.
shorie 15:76871e578c10 160 0 << 2 | // PRTCFG : 0, Free protocol, 1, SPDIF, 2, AC97. I2S is Free protocol
shorie 15:76871e578c10 161 2 << 0 ; // MODE : 0, master tx. 1, master rx. 2, slave tx. 3, slave rx
shorie 0:5ac19c994288 162
shorie 15:76871e578c10 163 // configuration register 2
shorie 15:76871e578c10 164 SAI1_Block_B->CR2 =
shorie 15:76871e578c10 165 0 << 14 | // COMP : 0, No companding
shorie 15:76871e578c10 166 0 << 13 | // CPL : Ignoered when no companding
shorie 15:76871e578c10 167 0 << 7 | // MUTECNT : 0, ignored when no muting
shorie 15:76871e578c10 168 0 << 6 | // MUTEVAL : 0, meaningless except SPDIF mode
shorie 15:76871e578c10 169 0 << 5 | // MUTE : 0, No mute. 1, mute
shorie 15:76871e578c10 170 0 << 4 | // TRIS : 0, Drive all slot. 1, Drive only active slot. Meaningless for I2S and RX
shorie 15:76871e578c10 171 1 << 3 | // FFLUSH : 0, No FIFO Flush. 1, FIFO Flush
shorie 15:76871e578c10 172 1 << 0; // FTH : 0, FIFO empty. 1, 1/4 FIFO. 2, 1/2 FIFO. 3, 3/4 FIFO. 4, FIFO full
shorie 15:76871e578c10 173
shorie 15:76871e578c10 174 // Frame configuration register
shorie 15:76871e578c10 175 SAI1_Block_B->FRCR =
shorie 15:76871e578c10 176 1 << 18 | // FSOFF : 0, FS is asserted on the first bit. 1, FS is asserted before the first bit.
shorie 15:76871e578c10 177 0 << 17 | // FSPOL : 0, Active low. 1, active high. I2S in left first operation is actilve low FS.
shorie 15:76871e578c10 178 1 << 16 | // FSDEF : 0, FS is start frame signal. 1, FS has also channel side info. I2S have to set 1
shorie 15:76871e578c10 179 31 << 8 | // FSALL : Frame sync active level lenght. Seems to be meaningless in slave mode. Set as to be sure.
shorie 15:76871e578c10 180 63 << 0 ; // FRL : Frame length. Seems to be meaning less in slave mode. Set as to be sure.
shorie 15:76871e578c10 181
shorie 15:76871e578c10 182 // Slot register
shorie 15:76871e578c10 183 SAI1_Block_B->SLOTR =
shorie 15:76871e578c10 184 0xFFFF << 16 | // SLOTEN : bit mask to specify the active slot. In I2S, 2 slts are active.
shorie 15:76871e578c10 185 1 << 8 | // NBSLOT : Number of slots - 1 ( Ref manual seems to be wrong )
shorie 16:9db140409038 186 2 << 6 | // SLOTSZ : 0, same with data size. 1, 16bit. 2, 32bit
shorie 15:76871e578c10 187 0 << 0 ; // FBOFF : The manual is not clear. Perhaps, 0 is OK.
shorie 15:76871e578c10 188
shorie 15:76871e578c10 189 // interrupt mask : TX doesn't trigger interrupt
shorie 15:76871e578c10 190 SAI1_Block_B->IMR =
shorie 15:76871e578c10 191 0 << 6 | // LFSDETIE : Late frame synchronization detection interrupt enable
shorie 15:76871e578c10 192 0 << 5 | // AFSDETIE : Anticipated frame synchronization detection interrupt enable. AC97 only
shorie 15:76871e578c10 193 0 << 4 | // CNDYIE : CODEC nott ready interrupt. AC97 only
shorie 15:76871e578c10 194 0 << 3 | // FREQIE : FIFO Interrupt Request. Enable for RX
shorie 15:76871e578c10 195 0 << 2 | // WCKCFGIE : Wrong clock configuration interrupt enable.
shorie 15:76871e578c10 196 0 << 1 | // MUTEDETIE: Mute detection interrupt enable.
shorie 15:76871e578c10 197 0 << 0; // OVRUDRIE : Overrun/underrun interrupt enable
shorie 15:76871e578c10 198
shorie 15:76871e578c10 199 // Clear flag register
shorie 15:76871e578c10 200 SAI1_Block_B->CLRFR = 0xFFFFFFFF; // clear all flags
shorie 0:5ac19c994288 201
shorie 0:5ac19c994288 202
shorie 2:6613e62da521 203 // Fill up tx FIO by 3 stereo samples.
shorie 2:6613e62da521 204 hal_put_i2s_tx_data( 0 ); // left
shorie 2:6613e62da521 205 hal_put_i2s_tx_data( 0 ); // right
shorie 2:6613e62da521 206 hal_put_i2s_tx_data( 0 ); // left
shorie 2:6613e62da521 207 hal_put_i2s_tx_data( 0 ); // right
shorie 2:6613e62da521 208 hal_put_i2s_tx_data( 0 ); // left
shorie 2:6613e62da521 209 hal_put_i2s_tx_data( 0 ); // right
shorie 0:5ac19c994288 210
shorie 0:5ac19c994288 211 }
shorie 0:5ac19c994288 212
shorie 2:6613e62da521 213 // Pin configuration and sync with WS signal
shorie 2:6613e62da521 214 void hal_i2s_pin_config_and_wait_ws(void)
shorie 1:9710fb328a08 215 {
shorie 15:76871e578c10 216 // See DM00166116.pdf ST32F746ZG Datasheet Rev 4 Table 12
shorie 15:76871e578c10 217 // See https://developer.mbed.org/platforms/ST-Nucleo-F746ZG/
shorie 15:76871e578c10 218 // See stm32f746xx.h source here : https://developer.mbed.org/teams/Rigado/code/mbed-src-bmd-200/docs/255afbe6270c/stm32f746xx_8h_source.html
shorie 14:bdf11487a94b 219
shorie 15:76871e578c10 220 // PE3 SAI1_SD_B (AF6) : DAC
shorie 15:76871e578c10 221 // PE4 SAI1_FS_A (AF6) : WS
shorie 15:76871e578c10 222 // PE5 SAI1_SCK_A (AF6) : CLK
shorie 15:76871e578c10 223 // PE6 SAI1_SD_A (AF6) : ADC
shorie 2:6613e62da521 224
shorie 15:76871e578c10 225 // Clear the mode field of PE3-6
shorie 15:76871e578c10 226 GPIOE->MODER &=
shorie 15:76871e578c10 227 ~( 3 << 6 | // PE3
shorie 15:76871e578c10 228 3 << 8 | // PE4
shorie 15:76871e578c10 229 3 << 10 | // PE5
shorie 15:76871e578c10 230 3 << 12 ); // PE6
shorie 14:bdf11487a94b 231
shorie 15:76871e578c10 232 // Set the pin mode
shorie 15:76871e578c10 233 GPIOE->MODER |=
shorie 15:76871e578c10 234 2 << 6 | // PE3 is Alternate Function
shorie 16:9db140409038 235 2 << 8 | // PE4 is Alternate Function
shorie 16:9db140409038 236 2 << 10 | // PE5 is Alternate Function
shorie 16:9db140409038 237 2 << 12; // PE6 is Alternate Function
shorie 15:76871e578c10 238
shorie 15:76871e578c10 239
shorie 15:76871e578c10 240 // Clear the OTYPE field of PE3-6 ( Clear is push-pull )
shorie 15:76871e578c10 241 GPIOE->OTYPER &=
shorie 15:76871e578c10 242 ~( 1 << 3 | // PE3
shorie 15:76871e578c10 243 1 << 4 | // PE4
shorie 15:76871e578c10 244 1 << 5 | // PE5
shorie 15:76871e578c10 245 1 << 6 ); // PE6
shorie 15:76871e578c10 246
shorie 14:bdf11487a94b 247
shorie 15:76871e578c10 248 // Clear the OSPEEDR field of PE3-6
shorie 15:76871e578c10 249 GPIOE->OSPEEDR &=
shorie 15:76871e578c10 250 ~( 3 << 6 | // PE3
shorie 15:76871e578c10 251 3 << 8 | // PE4
shorie 15:76871e578c10 252 3 << 10 | // PE5
shorie 15:76871e578c10 253 3 << 12 ); // PE6
shorie 15:76871e578c10 254
shorie 15:76871e578c10 255 // Set the OSPEEDR
shorie 15:76871e578c10 256 GPIOE->OSPEEDR |=
shorie 15:76871e578c10 257 1 << 6 | // PE3 DAC is medium speed
shorie 15:76871e578c10 258 0 << 8 | // PE4 is input
shorie 15:76871e578c10 259 0 << 10 | // PE5 is input
shorie 15:76871e578c10 260 0 << 12; // PE6 is input
shorie 15:76871e578c10 261
shorie 2:6613e62da521 262
shorie 15:76871e578c10 263 // Clear the PUPDR field of PE3-6 ( Clear is no pull-up/no pull-down )
shorie 15:76871e578c10 264 GPIOE->PUPDR &=
shorie 15:76871e578c10 265 ~( 3 << 6 | // PE3
shorie 15:76871e578c10 266 3 << 8 | // PE4
shorie 15:76871e578c10 267 3 << 10 | // PE5
shorie 15:76871e578c10 268 3 << 12 ); // PE6
shorie 15:76871e578c10 269
shorie 15:76871e578c10 270
shorie 15:76871e578c10 271 // Clear the Alternate funciton of PE3-6
shorie 15:76871e578c10 272 GPIOE->AFR[0] &=
shorie 15:76871e578c10 273 ~( 0xF << 12 | // PE3
shorie 15:76871e578c10 274 0xF << 16 | // PE4
shorie 15:76871e578c10 275 0xF << 20 | // PE5
shorie 15:76871e578c10 276 0xF << 24 );// PE6
shorie 15:76871e578c10 277
shorie 15:76871e578c10 278 // Set the Alternate function of PE3-6
shorie 15:76871e578c10 279 GPIOE->AFR[0] |=
shorie 15:76871e578c10 280 6 << 12 | // PE3 Alternalte Funciton 6
shorie 15:76871e578c10 281 6 << 16 | // PE4 Alternalte Funciton 6
shorie 15:76871e578c10 282 6 << 20 | // PE5 Alternalte Funciton 6
shorie 15:76871e578c10 283 6 << 24 ; // PE6 Alternalte Funciton 6
shorie 15:76871e578c10 284
shorie 15:76871e578c10 285 // Now, we set all the pin. We don't need to wait the WS,
shorie 15:76871e578c10 286 // Because SAI has TX/RX sync.
shorie 1:9710fb328a08 287 }
shorie 1:9710fb328a08 288
shorie 1:9710fb328a08 289
shorie 0:5ac19c994288 290 // Start I2S transfer. Interrupt starts
shorie 2:6613e62da521 291 void hal_i2s_start(void)
shorie 0:5ac19c994288 292 {
shorie 15:76871e578c10 293 // Setup SAI Block configuration register.
shorie 15:76871e578c10 294 // Block A : RX
shorie 15:76871e578c10 295 // Block B : TX
shorie 15:76871e578c10 296
shorie 15:76871e578c10 297 // Block B is sync to Block A. So, Block B first.
shorie 15:76871e578c10 298 SAI1_Block_B->CR1 |=
shorie 15:76871e578c10 299 1 << 16 ; // SAIXEN : 0, Disable, 1, Enable. Disable at this moment
shorie 15:76871e578c10 300 // Now, Block A and B start together
shorie 15:76871e578c10 301 SAI1_Block_A->CR1 |=
shorie 15:76871e578c10 302 1 << 16 ; // SAIXEN : 0, Disable, 1, Enable. Disable at this moment
shorie 15:76871e578c10 303
shorie 0:5ac19c994288 304 }
shorie 0:5ac19c994288 305
shorie 2:6613e62da521 306 IRQn_Type hal_get_i2s_irq_id(void)
shorie 0:5ac19c994288 307 {
shorie 15:76871e578c10 308 return SAI1_IRQn;
shorie 0:5ac19c994288 309 }
shorie 0:5ac19c994288 310
shorie 0:5ac19c994288 311
shorie 2:6613e62da521 312 IRQn_Type hal_get_process_irq_id(void)
shorie 0:5ac19c994288 313 {
shorie 15:76871e578c10 314 return SPI6_IRQn; // STM32F746 SPI6 is killed. This interrupt is assigned for signal processing in Unzen
shorie 0:5ac19c994288 315 }
shorie 0:5ac19c994288 316
shorie 2:6613e62da521 317
shorie 2:6613e62da521 318 // The returned value must be compatible with CMSIS NVIC_SetPriority() API. That mean, it is integer like 0, 1, 2...
shorie 2:6613e62da521 319 unsigned int hal_get_i2s_irq_priority_level(void)
shorie 0:5ac19c994288 320 {
shorie 15:76871e578c10 321 // STM32F746 has 4 bits priority field. So, heighest is 0, lowest is 15.
shorie 3:707608830793 322 // But CMSIS NVIC_SetPriority() inverse the priority of the interupt ( F**k! )
shorie 15:76871e578c10 323 // Then, 15 is heighest, 0 is lowerest in CMSIS.
shorie 15:76871e578c10 324 // setting 12 as i2s irq priority allows, some other interrupts are higher
shorie 2:6613e62da521 325 // and some others are lower than i2s irq priority.
shorie 15:76871e578c10 326 return 12;
shorie 2:6613e62da521 327 }
shorie 2:6613e62da521 328
shorie 2:6613e62da521 329
shorie 2:6613e62da521 330 // The returned value must be compatible with CMSIS NVIC_SetPriority() API. That mean, it is integer like 0, 1, 2...
shorie 2:6613e62da521 331 unsigned int hal_get_process_irq_priority_level(void)
shorie 2:6613e62da521 332 {
shorie 15:76871e578c10 333 // STM32F746 has 4 bits priority field. So, heighest is 0, lowest is 15.
shorie 3:707608830793 334 // But CMSIS NVIC_SetPriority() inverse the priority of the interupt ( S**t! )
shorie 15:76871e578c10 335 // Then 15 is heighest, 0 is lowerest in CMSIS.
shorie 15:76871e578c10 336 // setting 4 as process priority allows, some other interrupts are higher
shorie 2:6613e62da521 337 // and some other interrupts are lower then process priority.
shorie 15:76871e578c10 338 return 4;
shorie 0:5ac19c994288 339 }
shorie 0:5ac19c994288 340
shorie 15:76871e578c10 341 // STM32F746 transferes 2 words ( left and right ) for each interrupt.
shorie 2:6613e62da521 342 unsigned int hal_data_per_sample(void)
shorie 0:5ac19c994288 343 {
shorie 0:5ac19c994288 344 return 2;
shorie 0:5ac19c994288 345 }
shorie 0:5ac19c994288 346
shorie 0:5ac19c994288 347 // return true when the sample parameter is ready to read.
shorie 0:5ac19c994288 348 // return false when the sample is not ready to read.
shorie 2:6613e62da521 349 void hal_get_i2s_rx_data( int & sample)
shorie 0:5ac19c994288 350 {
shorie 15:76871e578c10 351 // RX is SAI1_BlockA. See the comment on top of this file
shorie 15:76871e578c10 352 sample = SAI1_Block_A->DR;
shorie 0:5ac19c994288 353 }
shorie 0:5ac19c994288 354
shorie 0:5ac19c994288 355 // put a sample to I2S TX data regisger
shorie 2:6613e62da521 356 void hal_put_i2s_tx_data( int sample )
shorie 0:5ac19c994288 357 {
shorie 15:76871e578c10 358 // TX is SAI1_Block_B. See the comment on top of this file
shorie 15:76871e578c10 359 SAI1_Block_B->DR = sample;
shorie 0:5ac19c994288 360 }
shorie 0:5ac19c994288 361 }
shorie 0:5ac19c994288 362
shorie 0:5ac19c994288 363