Возникла некоторая сложность в запуске внешнего аудио ЦАПа.
Настроил порты, разрешил тактирование периферии, настроил интерфейс.
Пробую установить старт бит, но как показывается в отладчике, работать всё это устройство отказывается.
Просматривая лапы на чипскопе с дискретизацией 5 МГц, увидел короткие проседания линий, практически одновременно, сразу после сброса (возможно это реакция инициализации портов), однако они отличаются по длине.
Тактовая 16 МГц от PLL и там всё отлично работает, другая периферия работает как часы.
Ниже привожу текст программы:
CODE
RCC->APB1ENR |= (1<<21); // I2C1 clock enable
GPIOD->ODR |= (1<<4); // PD4 RESET AUDIO DAC disable set 1
/* Set I/O mode for GPIOB */
GPIOB->MODER = 0x55696A95; // port B OUT PB3 - PB5 PB6 PB9 and PB10 how to alternative function
GPIOB->OSPEEDR = 0x55555555; // 25 MHz speed
GPIOB->OTYPER |= (1<<9); // PB9 open-drain
GPIOB->OTYPER |= (1<<6); // PB6 open-drain
GPIOB->PUPDR = 0x00200280; // pull-down PB10 PB4 and PB3
GPIOB->AFR[0] |= (0x5<<12); // PB3 how to alternative function AF5 SPI1_SCK
GPIOB->AFR[0] |= (0x5<<16); // PB4 how to alternative function AF5 SPI1_MISO
GPIOB->AFR[0] |= (0x5<<20); // PB5 how to alternative function AF5 SPI1_MOSI
GPIOB->AFR[1] |= (0x5<<8); // PB10 how to alternative function AF5 I2S2_CK
GPIOB->AFR[1] |= (0x4<<4); // PB9 how to alternative function AF4 I2C1_SDA
GPIOB->AFR[0] |= (0x4<<24); // PB6 how to alternative function AF4 I2C1_SCL
//Тут приведена настройка всего порта В, других периферийный модулей
/* I2C1 configuration set */
I2C1->CR2 |= (0x10<<0); // I2C1 clock mode set 16 MHz
I2C1->CCR |= (0x50<<0); // I2C1 speed mode set 100 kHz
I2C1->TRISE |= (0x2<<0); // I2C1 rise time set 250 nc
I2C1->CR1 |= (1<<10); // I2C1 acknowledge enable
I2C1->CR1 &= ~(1<<9); // I2C1 no stop generation set
I2C1->CR1 &= ~(1<<8); // I2C1 no start generation set
I2C1->CR1 &= ~(1<<6); // I2C1 general call disable
I2C1->CR1 &= ~(1<<1); // I2C1 mode set
I2C1->CR1 |= (1<<0); // I2C1 On
I2C1->CR1 |= (1<<8); // I2C1 START On
for(;((I2C1->SR1 & 0x1) == 0x0)
// delay while flag SB will be set
{
}
I2C1->SR1 &= ~(1<<0); // clear flag SB
I2C1->DR = 0x94; // address value transmit and write command
for(;((I2C1->SR1 & 0x2) == 0x0)
// delay while ended address transmission
{
}
I2C1->SR1 &= ~(1<<1); // clear flag ADDR
for(;((I2C1->SR2 & 0x4) == 0x0)
// delay while data bytes transmitted
{
}
I2C1->DR = 0x02; // I2C1 Powered register address
for(;((I2C1->SR1 & 0x80) == 0x00)
// delay while data register not empty
{
}
Это примитивное начало самого кода. Но даже в самом начале старт не показывается.GPIOD->ODR |= (1<<4); // PD4 RESET AUDIO DAC disable set 1
/* Set I/O mode for GPIOB */
GPIOB->MODER = 0x55696A95; // port B OUT PB3 - PB5 PB6 PB9 and PB10 how to alternative function
GPIOB->OSPEEDR = 0x55555555; // 25 MHz speed
GPIOB->OTYPER |= (1<<9); // PB9 open-drain
GPIOB->OTYPER |= (1<<6); // PB6 open-drain
GPIOB->PUPDR = 0x00200280; // pull-down PB10 PB4 and PB3
GPIOB->AFR[0] |= (0x5<<12); // PB3 how to alternative function AF5 SPI1_SCK
GPIOB->AFR[0] |= (0x5<<16); // PB4 how to alternative function AF5 SPI1_MISO
GPIOB->AFR[0] |= (0x5<<20); // PB5 how to alternative function AF5 SPI1_MOSI
GPIOB->AFR[1] |= (0x5<<8); // PB10 how to alternative function AF5 I2S2_CK
GPIOB->AFR[1] |= (0x4<<4); // PB9 how to alternative function AF4 I2C1_SDA
GPIOB->AFR[0] |= (0x4<<24); // PB6 how to alternative function AF4 I2C1_SCL
//Тут приведена настройка всего порта В, других периферийный модулей
/* I2C1 configuration set */
I2C1->CR2 |= (0x10<<0); // I2C1 clock mode set 16 MHz
I2C1->CCR |= (0x50<<0); // I2C1 speed mode set 100 kHz
I2C1->TRISE |= (0x2<<0); // I2C1 rise time set 250 nc
I2C1->CR1 |= (1<<10); // I2C1 acknowledge enable
I2C1->CR1 &= ~(1<<9); // I2C1 no stop generation set
I2C1->CR1 &= ~(1<<8); // I2C1 no start generation set
I2C1->CR1 &= ~(1<<6); // I2C1 general call disable
I2C1->CR1 &= ~(1<<1); // I2C1 mode set
I2C1->CR1 |= (1<<0); // I2C1 On
I2C1->CR1 |= (1<<8); // I2C1 START On
for(;((I2C1->SR1 & 0x1) == 0x0)

{
}
I2C1->SR1 &= ~(1<<0); // clear flag SB
I2C1->DR = 0x94; // address value transmit and write command
for(;((I2C1->SR1 & 0x2) == 0x0)

{
}
I2C1->SR1 &= ~(1<<1); // clear flag ADDR
for(;((I2C1->SR2 & 0x4) == 0x0)

{
}
I2C1->DR = 0x02; // I2C1 Powered register address
for(;((I2C1->SR1 & 0x80) == 0x00)

{
}
Может кто-то пробовал запустить этот ЦАП или знает, какие в нём есть тонкости...
В документации вроде все понятно описано, однако где-то я всё-таки ошибся...