diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/includes/Audio/audio.h | 2 | ||||
-rw-r--r-- | src/glutt-o-logique/audio.c | 45 | ||||
-rw-r--r-- | src/glutt-o-logique/i2c.c | 38 |
3 files changed, 43 insertions, 42 deletions
diff --git a/src/common/includes/Audio/audio.h b/src/common/includes/Audio/audio.h index 573c157..a3c70fd 100644 --- a/src/common/includes/Audio/audio.h +++ b/src/common/includes/Audio/audio.h @@ -35,6 +35,8 @@ void audio_stop_dma(void); void audio_initialize(int plln,int pllr,int i2sdiv,int i2sodd, int rate); // Power up and down the audio hardware. +void audio_put_codec_in_reset(void); +void audio_reinit_codec(void); void audio_on(void); void audio_off(void); diff --git a/src/glutt-o-logique/audio.c b/src/glutt-o-logique/audio.c index 0576d30..6ef992f 100644 --- a/src/glutt-o-logique/audio.c +++ b/src/glutt-o-logique/audio.c @@ -72,8 +72,33 @@ void audio_initialize_platform(int plln, int pllr, int i2sdiv, int i2sodd, int _ GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_SPI3); - // Reset the codec. + audio_reinit_codec(); + + // Disable I2S. + SPI3 ->I2SCFGR = 0; + + // I2S clock configuration + RCC ->CFGR &= ~RCC_CFGR_I2SSRC; // PLLI2S clock used as I2S clock source. + RCC ->PLLI2SCFGR = (pllr << 28) | (plln << 6); + + // Enable PLLI2S and wait until it is ready. + RCC ->CR |= RCC_CR_PLLI2SON; + while (!(RCC ->CR & RCC_CR_PLLI2SRDY )) + ; + + // Configure I2S. + SPI3 ->I2SPR = i2sdiv | (i2sodd << 8) | SPI_I2SPR_MCKOE; + SPI3 ->I2SCFGR = SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SCFG_1 + | SPI_I2SCFGR_I2SE; // Master transmitter, Phillips mode, 16 bit values, clock polarity low, enable. + +} + +void audio_put_codec_in_reset(void) { GPIO_ResetBits(GPIOD, GPIO_Pin_4); +} + +void audio_reinit_codec(void) { + audio_put_codec_in_reset(); for (volatile int i = 0; i < 0x4fff; i++) { __asm__ volatile("nop"); } @@ -98,24 +123,6 @@ void audio_initialize_platform(int plln, int pllr, int i2sdiv, int i2sodd, int _ audio_write_register(0x1a, 0x0a); // Adjust PCM volume level. audio_write_register(0x1b, 0x0a); - - // Disable I2S. - SPI3 ->I2SCFGR = 0; - - // I2S clock configuration - RCC ->CFGR &= ~RCC_CFGR_I2SSRC; // PLLI2S clock used as I2S clock source. - RCC ->PLLI2SCFGR = (pllr << 28) | (plln << 6); - - // Enable PLLI2S and wait until it is ready. - RCC ->CR |= RCC_CR_PLLI2SON; - while (!(RCC ->CR & RCC_CR_PLLI2SRDY )) - ; - - // Configure I2S. - SPI3 ->I2SPR = i2sdiv | (i2sodd << 8) | SPI_I2SPR_MCKOE; - SPI3 ->I2SCFGR = SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SCFG_1 - | SPI_I2SCFGR_I2SE; // Master transmitter, Phillips mode, 16 bit values, clock polarity low, enable. - } void audio_on() { diff --git a/src/glutt-o-logique/i2c.c b/src/glutt-o-logique/i2c.c index cc784f4..08861c1 100644 --- a/src/glutt-o-logique/i2c.c +++ b/src/glutt-o-logique/i2c.c @@ -24,6 +24,7 @@ #include "GPIO/i2c.h" #include "Core/common.h" +#include "Audio/audio.h" #include "stm32f4xx_conf.h" #include "stm32f4xx_i2c.h" @@ -61,37 +62,26 @@ static void i2c_device_init(void); * pulses. The device that held the bus LOW should release it sometime within * those nine clocks. If not, then use the HW reset or cycle power to clear the * bus. + * + * The only device on the i2c bus is the audio codec. */ +static int i2c_recover_count; static void i2c_recover_from_lockup(void) { usart_debug_puts("ERROR: I2C lockup\r\n"); - I2C_SoftwareResetCmd(I2Cx, ENABLE); - - // Configure I2C SCL and SDA pins. - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = GPIOB_PIN_SCL | GPIOB_PIN_SDA; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(GPIOB, &GPIO_InitStructure); - - const TickType_t delay = pdMS_TO_TICKS(5); - - GPIO_SetBits(GPIOB, GPIOB_PIN_SDA | GPIOB_PIN_SCL); - vTaskDelay(delay); - - for (int i = 0; i < 10; i++) { - GPIO_ResetBits(GPIOB, GPIOB_PIN_SCL); - vTaskDelay(delay); - GPIO_SetBits(GPIOB, GPIOB_PIN_SCL); - vTaskDelay(delay); + i2c_recover_count++; + if (i2c_recover_count > 3) { + trigger_fault(FAULT_SOURCE_I2C); } + I2C_SoftwareResetCmd(I2Cx, ENABLE); + audio_put_codec_in_reset(); + for (int i = 0; i < 0x4fff; i++) { + __asm__ volatile("nop"); + } I2C_SoftwareResetCmd(I2Cx, DISABLE); - - i2c_device_init(); + audio_reinit_codec(); } static void i2c_device_init(void) @@ -127,6 +117,8 @@ static void i2c_device_init(void) // enable I2C1 I2C_Cmd(I2C1, ENABLE); + + i2c_recover_count = 0; } void i2c_init() |