aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/includes/Audio/audio.h2
-rw-r--r--src/glutt-o-logique/audio.c45
-rw-r--r--src/glutt-o-logique/i2c.c38
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()