Forum: Mikrocontroller und Digitale Elektronik Externer DAC am STM32F4 DISC1


von Uwe (Gast)


Lesenswert?

Hallo zusammen,

an einem STM32F4 DISC1 habe ich einen externen DAC (pcm1774) am I2S2 
dran, aber leider bekomme ich den I2S nicht zum laufen. Könnte 
vielleicht jemand bitte über den Code zum initialisieren des I2S2 
schauen?
Vielen Dank!
1
#define CODEC_I2S SPI2
2
#define I2S2_WS_PIN   GPIO_Pin_12   //port B
3
#define I2S2_MCLK_PIN   GPIO_Pin_6   //port C
4
#define I2S2_SCLK_PIN   GPIO_Pin_13  //port B
5
#define I2S2_SD_PIN   GPIO_Pin_15  //port B
1
void codec_init()
2
{
3
4
  GPIO_InitTypeDef PinInitStruct;
5
  GPIO_StructInit(&PinInitStruct);
6
7
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOB, ENABLE);
8
9
10
  I2S_InitTypeDef I2S_InitType;
11
  //enable I2S clocks
12
  RCC_I2SCLKConfig(RCC_I2S2CLKSource_PLLI2S);
13
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
14
  RCC_PLLI2SCmd(ENABLE);
15
16
  // I2S pins
17
  PinInitStruct.GPIO_OType = GPIO_OType_PP;
18
  PinInitStruct.GPIO_Pin = I2S2_SCLK_PIN | I2S2_SD_PIN | I2S2_WS_PIN;
19
  GPIO_Init(GPIOB, &PinInitStruct);
20
21
  PinInitStruct.GPIO_Pin = I2S2_MCLK_PIN;
22
  GPIO_Init(GPIOC, &PinInitStruct);
23
24
25
  //prepare output ports for alternate function
26
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_SPI2);
27
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
28
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);
29
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource6,  GPIO_AF_SPI2);
30
31
  // configure I2S port
32
  SPI_I2S_DeInit(CODEC_I2S);
33
  I2S_InitType.I2S_AudioFreq = I2S_AudioFreq_48k;
34
  I2S_InitType.I2S_MCLKOutput = I2S_MCLKOutput_Enable;
35
  I2S_InitType.I2S_DataFormat = I2S_DataFormat_16b;
36
  I2S_InitType.I2S_Mode = I2S_Mode_MasterTx;
37
  I2S_InitType.I2S_Standard = I2S_Standard_Phillips;
38
  I2S_InitType.I2S_CPOL = I2S_CPOL_Low;
39
40
  I2S_Init(CODEC_I2S, &I2S_InitType);
41
  //I2S_Cmd(CODEC_I2S, ENABLE);
42
43
}

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Uwe schrieb:
> I2S_InitTypeDef I2S_InitType;
>   //enable I2S clocks
>   RCC_I2SCLKConfig(RCC_I2S2CLKSource_PLLI2S);
>   RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
>   RCC_PLLI2SCmd(ENABLE);

Stelle zuerst mal sicher, das die PLL auch wirklich mit der gewünschten 
Frequenz läuft (dabei den Kommentar zu Jitter im Ref. Manual beachten):
1
void I2S_PLL_Config(uint16_t N,uint16_t R) {
2
    // Set PLL Clock for I2S
3
    RCC_PLLI2SCmd(DISABLE);
4
    RCC_I2SCLKConfig(RCC_I2S2CLKSource_PLLI2S);
5
//    RCC->CFGR &= ~RCC_CFGR_I2SSRC;
6
    /* Configure PLLI2S */
7
    RCC_PLLI2SConfig(N,R);
8
    /* Enable PLLI2S */
9
    RCC_PLLI2SCmd(ENABLE);
10
    /* Wait till PLLI2S is ready */
11
    while (RCC_GetFlagStatus(RCC_FLAG_PLLI2SRDY)==RESET){};
12
//     BlinkLED(1);
13
}
14
// Aufruf fürs Disco F4 und 48 kHz Samplefrequenz. 
15
 I2S_PLL_Config(129,3);
Dann scheint es ein Problem in CMSIS zu geben, das die Masterclock nicht 
einschaltet. Ich habe das so gelöst:
1
/* Definitions for the I2S2 ADC Input Port
2
 * for Port C from setup.h */
3
#define I2S2_MCLK_PIN      GPIO_Pin_6
4
#define I2S2_MCLK_SOURCE    GPIO_PinSource6
5
#define I2S2_MCLK_PORT      GPIOC
6
/* for Port B */
7
#define I2S2_WS_PIN        GPIO_Pin_12
8
#define I2S2_WS_SOURCE      GPIO_PinSource12
9
#define I2S2_SCK_PIN      GPIO_Pin_13
10
#define I2S2_SCK_SOURCE      GPIO_PinSource13
11
#define I2S2_SD_PIN        GPIO_Pin_15
12
#define I2S2_SD_SOURCE      GPIO_PinSource15
13
#define I2S2_DATA_GPIO_PORT    GPIOB
14
15
#define I2SDIV 0x0103;  // Korrekt value for 48kHz * 256 MCLK
16
// now in main.c
17
void MS_I2S2_Init(void) {
18
/* Setup the ADC Input I2S2 for 48 kHz */
19
  GPIO_InitTypeDef GPIO_InitStructure;
20
  I2S_InitTypeDef I2S_InitStructure;
21
     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
22
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
23
      RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE);
24
     RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE);
25
     SPI_I2S_DeInit(SPI2);
26
     /* Connect pins to I2S peripheral  */
27
    GPIO_PinAFConfig(I2S2_DATA_GPIO_PORT, I2S2_SCK_SOURCE, GPIO_AF_SPI2);
28
    GPIO_PinAFConfig(I2S2_DATA_GPIO_PORT, I2S2_SD_SOURCE, GPIO_AF_SPI2);
29
    GPIO_PinAFConfig(I2S2_DATA_GPIO_PORT, I2S2_WS_SOURCE, GPIO_AF_SPI2);
30
    GPIO_PinAFConfig(I2S2_MCLK_PORT, I2S2_MCLK_SOURCE, GPIO_AF_SPI2);
31
/* Configure I2S Pins */
32
/* CODEC_I2S2 pins configuration: WS, SCK and SD pins */
33
    GPIO_InitStructure.GPIO_Pin = I2S2_WS_PIN | I2S2_SCK_PIN;
34
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
35
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
36
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
37
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
38
    GPIO_Init(I2S2_DATA_GPIO_PORT, &GPIO_InitStructure);
39
/* Configure MCLK on diff. Port */
40
    GPIO_InitStructure.GPIO_Pin = I2S2_MCLK_PIN ;
41
    GPIO_Init(I2S2_MCLK_PORT, &GPIO_InitStructure);
42
/* Configure SD as Input */
43
    GPIO_InitStructure.GPIO_Pin = I2S2_SD_PIN;
44
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
45
    GPIO_Init(I2S2_DATA_GPIO_PORT, &GPIO_InitStructure);
46
     SPI_I2S_DeInit(SPI2);
47
/* now set the parameters for the I2S Interface itself */
48
    I2S_StructInit(&I2S_InitStructure);
49
    I2S_InitStructure.I2S_Mode = I2S_Mode_MasterRx;
50
    I2S_InitStructure.I2S_Standard = I2S_STANDARD;
51
    I2S_InitStructure.I2S_MCLKOutput = ENABLE;
52
    I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_48k;
53
    I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
54
    I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
55
    I2S_Init(SPI2,&I2S_InitStructure);
56
    // set the MCLK Output enable bit and prescaler , cause the initfunction is bugged
57
    SPI2->I2SPR = I2S_MCLKOutput_Enable | I2SDIV;
58
   // Configure the I2S Rx not empty IRQ
59
   NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
60
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0b;
61
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
62
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
63
    NVIC_Init(&NVIC_InitStructure);
64
    SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE,ENABLE);
65
    I2S_Cmd(SPI2,ENABLE);
66
}
Der Mode und die Richtung der Datenpins ist bei mir Input, weil ich 
einen Audio ADC dranhängen habe und kein DAC, aber der Rest sollte 
eigentlich klappen. Es schadet nicht, den Masterclock mal zu messen, 
weil zumindest bei mir da eine viel zu niedrige Frequenz dran war, weil 
SystemInit() die PLL nicht brauchbar konfigurierte.
Die entscheidene Zeile für den Masterclock ist
> SPI2->I2SPR = I2S_MCLKOutput_Enable | I2SDIV;

Bei mir holt der IRQ neue Daten aus dem ADC, das kannst du aber 
natürlich machen, wie du es brauchst und auch ganz ohne IRQ.

: Bearbeitet durch User
von Uwe (Gast)


Lesenswert?

Hi Matthias,

Danke für deinen Beitrag. Ich werde mal schauen, ob der pll für i2s auch 
wirklich anläuft.
Mein Problem ist das ich an keinem i2s2 Pin am LA etwas zappeln sehe. 
Das kann doch nicht so sein, oder?

von Bülent C. (mirki)


Lesenswert?

Uwe schrieb:
> Mein Problem ist das ich an keinem i2s2 Pin am LA etwas zappeln sehe.
> Das kann doch nicht so sein, oder?

Wie denn auch?, oder glaubst Du Dein STM32 hat 'nen Interface zu einer 
Glaskugel?!?!??
1
// I2S pins
2
  PinInitStruct.GPIO_OType = GPIO_OType_PP;
3
  PinInitStruct.GPIO_Pin = I2S2_SCLK_PIN | I2S2_SD_PIN | I2S2_WS_PIN;
4
  GPIO_Init(GPIOB, &PinInitStruct);
5
6
  PinInitStruct.GPIO_Pin = I2S2_MCLK_PIN;
7
  GPIO_Init(GPIOC, &PinInitStruct);

da fehlt das hier:
1
PinInitStruct.GPIO_Mode = GPIO_Mode_AF;

von Uwe (Gast)


Lesenswert?

Jepp, jetzt zappelt es gewaltig am LA. Danke Bülent.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.