Hallo! Ich benutze auf einem Customboard einen STM32F103RET6, der an einen PCM3168A Audio Codec angebunden ist. Der DAC (Slave) ist dabei angebunden über den I2S2 (Master Tx) und der ADC (Master) über I2S3 (Slave Rx). Beide I2S-Schnittstellen werden über den jewiligen DMA (DMA1 Channel 5 (Tx) und DMA2 Channel 1 (Rx)) angesteuert. Die Ausgabe von Daten über I2S2 und den DAC (zum Testen einfache sinusförmige Signale) funktioniert einwandfrei. Das Problem ist der Empfang von Daten von I2S3 bzw. dem ADC... der DMA Transfer Complete Interrupt löst einfach nicht aus. Ich habe meine Konfiguration zichfach kontrolliert. Auch die Takt- und Datensignale auf allen I2S Leitungen sind in Ordnung. Hat jemand auf Anhieb eine Idee, wo das Problem sein könnte? :) Vielen Dank für die Mühe! Peter Hier die entsprechenden Teile meines Programmcodes: main():
1 | int main(void) |
2 | {
|
3 | /* System clocks configuration */
|
4 | BOARD_RCC_Configuration(); |
5 | |
6 | /* GPIO configuration */
|
7 | BOARD_GPIO_Configuration(); |
8 | |
9 | /* NVIC configuration */
|
10 | BOARD_NVIC_Configuration(); |
11 | |
12 | /* SPI1 configuration */
|
13 | BOARD_SPI1_Configuration(); |
14 | |
15 | /* DDS configuration */
|
16 | DDS_BuildSineTable(); |
17 | DDS_SetFrequency(DDS0, 1000); |
18 | DDS_SetFrequency(DDS1, 2000); |
19 | |
20 | /* I2S2 and DMA1 (DAC) configuration */
|
21 | BOARD_I2S2_DMA1_Configuration(); |
22 | |
23 | /* I2S3 and DMA2 (ADC) configuration */
|
24 | BOARD_I2S3_DMA2_Configuration(); |
25 | |
26 | /* PCM3168A configuration */
|
27 | PCM3168A_Init(); |
28 | |
29 | // ---------------------------------------
|
30 | // ------------ INFINITE LOOP ------------
|
31 | // ---------------------------------------
|
32 | while(1) { |
33 | |
34 | LED_Toggle(LED0); |
35 | }
|
36 | |
37 | return 0; |
38 | }
|
GPIO-Config:
1 | /* I2S2 (SPI2) */
|
2 | #define PORT_I2S2_WS GPIOB
|
3 | #define PIN_I2S2_WS GPIO_Pin_12
|
4 | |
5 | #define PORT_I2S2_CK GPIOB
|
6 | #define PIN_I2S2_CK GPIO_Pin_13
|
7 | |
8 | #define PORT_I2S2_SD GPIOB
|
9 | #define PIN_I2S2_SD GPIO_Pin_15
|
10 | |
11 | #define PORT_I2S2_MCK GPIOC
|
12 | #define PIN_I2S2_MCK GPIO_Pin_6
|
13 | |
14 | /* I2S3 (SPI3) */
|
15 | #define PORT_I2S3_WS GPIOA
|
16 | #define PIN_I2S3_WS GPIO_Pin_15
|
17 | |
18 | #define PORT_I2S3_CK GPIOB
|
19 | #define PIN_I2S3_CK GPIO_Pin_3
|
20 | |
21 | #define PORT_I2S3_SD GPIOB
|
22 | #define PIN_I2S3_SD GPIO_Pin_5
|
23 | |
24 | #define PORT_I2S3_MCK GPIOC
|
25 | #define PIN_I2S3_MCK GPIO_Pin_7
|
26 | |
27 | void BOARD_GPIO_Configuration(void) |
28 | {
|
29 | GPIO_InitTypeDef GPIO_InitStructure; |
30 | |
31 | /* ... */
|
32 | |
33 | /************************************************/
|
34 | /* Pins for I2S2 (SPI2) */
|
35 | /************************************************/
|
36 | |
37 | GPIO_InitStructure.GPIO_Pin = PIN_I2S2_WS; |
38 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
39 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; |
40 | GPIO_Init(PORT_I2S2_WS, &GPIO_InitStructure); |
41 | |
42 | GPIO_InitStructure.GPIO_Pin = PIN_I2S2_CK; |
43 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
44 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; |
45 | GPIO_Init(PORT_I2S2_CK, &GPIO_InitStructure); |
46 | |
47 | GPIO_InitStructure.GPIO_Pin = PIN_I2S2_SD; |
48 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
49 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; |
50 | GPIO_Init(PORT_I2S2_SD, &GPIO_InitStructure); |
51 | |
52 | GPIO_InitStructure.GPIO_Pin = PIN_I2S2_MCK; |
53 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
54 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; |
55 | GPIO_Init(PORT_I2S2_MCK, &GPIO_InitStructure); |
56 | |
57 | /************************************************/
|
58 | /* Pins for I2S3 (SPI3) */
|
59 | /************************************************/
|
60 | |
61 | GPIO_InitStructure.GPIO_Pin = PIN_I2S3_WS; |
62 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
63 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; |
64 | GPIO_Init(PORT_I2S3_WS, &GPIO_InitStructure); |
65 | |
66 | GPIO_InitStructure.GPIO_Pin = PIN_I2S3_CK; |
67 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
68 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; |
69 | GPIO_Init(PORT_I2S3_CK, &GPIO_InitStructure); |
70 | |
71 | GPIO_InitStructure.GPIO_Pin = PIN_I2S3_SD; |
72 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
73 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; |
74 | GPIO_Init(PORT_I2S3_SD, &GPIO_InitStructure); |
75 | |
76 | GPIO_InitStructure.GPIO_Pin = PIN_I2S3_MCK; |
77 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
78 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; |
79 | GPIO_Init(PORT_I2S3_MCK, &GPIO_InitStructure); |
80 | }
|
NVIC-Config:
1 | void BOARD_NVIC_Configuration(void) |
2 | {
|
3 | NVIC_InitTypeDef NVIC_InitStructure; |
4 | |
5 | /* Set the Vector Table base location at 0x08000000 */
|
6 | NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); |
7 | |
8 | /* Ensure that all 4 interrupt priority bits are used as the pre-emption priority. */
|
9 | NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); |
10 | |
11 | /* DMA1 channel 5 (I2S2 Tx) IRQ Channel configuration */
|
12 | NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn; |
13 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // TODO Priorität anpassen? |
14 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // TODO Priorität anpassen? |
15 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; |
16 | NVIC_Init(&NVIC_InitStructure); |
17 | |
18 | /* DMA2 channel 1 (I2S3 Rx) IRQ Channel configuration */
|
19 | NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel1_IRQn; |
20 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // TODO Priorität anpassen? |
21 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // TODO Priorität anpassen? |
22 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; |
23 | NVIC_Init(&NVIC_InitStructure); |
24 | }
|
I2S- und zugehörige DMA-Config:
1 | #define PERIPH_BASE_ADDR_I2S2_SPI2_DATA_REGISTER (0x40003800 + 0x0C) /* stm32f103ret6 datasheet p. 40 and ref. manual p. 749 */ |
2 | #define PERIPH_BASE_ADDR_I2S3_SPI3_DATA_REGISTER (0x40003C00 + 0x0C) /* stm32f103ret6 datasheet p. 40 and ref. manual p. 749 */ |
3 | |
4 | /**
|
5 | * Configures I2S2 (Master).
|
6 | */
|
7 | void BOARD_I2S2_DMA1_Configuration(void) |
8 | {
|
9 | I2S_InitTypeDef I2S_InitStructure; |
10 | DMA_InitTypeDef DMA_InitStructure; |
11 | |
12 | SPI_I2S_DeInit(SPI2); |
13 | I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips; |
14 | I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_32b; |
15 | I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable; |
16 | I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_32k; |
17 | I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low; |
18 | I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx; |
19 | I2S_Init(SPI2, &I2S_InitStructure); |
20 | |
21 | DMA_DeInit(DMA1_Channel5); |
22 | DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)PERIPH_BASE_ADDR_I2S2_SPI2_DATA_REGISTER; |
23 | DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&MAIN_DACOutputDataBufferA; |
24 | DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; |
25 | DMA_InitStructure.DMA_BufferSize = FRAMESIZE*4; |
26 | DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; |
27 | DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; |
28 | DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; |
29 | DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; |
30 | DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; |
31 | DMA_InitStructure.DMA_Priority = DMA_Priority_High; |
32 | DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; |
33 | DMA_Init(DMA1_Channel5, &DMA_InitStructure); |
34 | |
35 | /* Enable DMA Tx request */
|
36 | SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE); |
37 | |
38 | /* Enable DMA channel transfer complete interrupt */
|
39 | DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE); |
40 | |
41 | /* SPI2 enable */
|
42 | I2S_Cmd(SPI2, ENABLE); |
43 | |
44 | /* DMA1_5 enable */
|
45 | DMA_Cmd(DMA1_Channel5, ENABLE); |
46 | }
|
47 | |
48 | /**
|
49 | * Configures I2S3 (Slave).
|
50 | */
|
51 | void BOARD_I2S3_DMA2_Configuration(void) |
52 | {
|
53 | I2S_InitTypeDef I2S_InitStructure; |
54 | DMA_InitTypeDef DMA_InitStructure; |
55 | |
56 | SPI_I2S_DeInit(SPI3); |
57 | I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips; |
58 | I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_32b; |
59 | I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable; |
60 | I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_32k; |
61 | I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low; |
62 | I2S_InitStructure.I2S_Mode = I2S_Mode_SlaveRx; |
63 | I2S_Init(SPI3, &I2S_InitStructure); |
64 | |
65 | DMA_DeInit(DMA2_Channel1); |
66 | DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)PERIPH_BASE_ADDR_I2S3_SPI3_DATA_REGISTER; |
67 | DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&MAIN_ADCInputDataBufferA; |
68 | DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; |
69 | DMA_InitStructure.DMA_BufferSize = FRAMESIZE*4; |
70 | DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; |
71 | DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; |
72 | DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; |
73 | DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; |
74 | DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; |
75 | DMA_InitStructure.DMA_Priority = DMA_Priority_High; |
76 | DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; |
77 | DMA_Init(DMA2_Channel1, &DMA_InitStructure); |
78 | |
79 | /* Enable DMA Rx request */
|
80 | SPI_I2S_DMACmd(SPI3, SPI_I2S_DMAReq_Rx, ENABLE); |
81 | |
82 | /* Enable DMA channel transfer complete interrupt */
|
83 | DMA_ITConfig(DMA2_Channel1, DMA_IT_TC, ENABLE); |
84 | |
85 | /* SPI3 enable */
|
86 | I2S_Cmd(SPI3, ENABLE); |
87 | |
88 | /* DMA2_1 enable */
|
89 | DMA_Cmd(DMA2_Channel1, ENABLE); |
90 | }
|