Hi Everyone and thank you for your time.
I have been working on interfacing the STM32f446RE Nucleo board with the TLV5628 8 Bit Octal Serial DAC. I have ran into multiple issues, but the current issue has been one of two things:
1) The data and clock lines showing the exact same information
or
2) The data line showing information, but nothing on the clock line.
Regardless, the information coming out is completely incorrect.
Here is my setup code:
void SPI_INIT(void){
// Enable clocks for C
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
// SPI GPIO
GPIOC->MODER |= 2 << 3*2; // PC3 data pin
GPIOC->MODER |= 2 << 7*2; // PC7 clock pin
GPIOC->MODER |= 1 << 2*2; //pc2 load
GPIOC->MODER |= 1 << 4*2; //pc4 ldac - probably set low permanently
// Pins default to push-pull
// set all to high speed
GPIOC->OSPEEDR |= (3 << 2*2) | (3 << 3*2) | (3 << 4*2) | (3 << 7*2);
GPIOC->AFR[0] |= 5<< 6*2; // Alt func 5 pc3 - SPI2
GPIOC->AFR[0] |= 5 << 7*2; // Alt func 5 pc7 - SPI2
// SPI Setup
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; // Enable SPI Clock
RCC->APB1RSTR |= RCC_APB1RSTR_SPI2RST; // reset SPI2
RCC->APB1RSTR &= ~RCC_APB1RSTR_SPI2RST;// clear the reset
// Control Register 1
SPI2->CR1 &= ~SPI_CR1_SPE; // Disable SPI
SPI2->CR1 |= SPI_CR1_MSTR; // master mode
SPI2->CR1 &= ~SPI_CR1_RXONLY; // transmit, 0 == full duplex
SPI2->CR1 &= ~SPI_CR1_DFF; // 8 bit format
SPI2->CR1 &= ~SPI_CR1_LSBFIRST; // MSB first
SPI2->CR1 &= ~SPI_CR1_CPOL;// low polarity, so 0 when idle
SPI2->CR1 |= 4 << 3; // (180M/4)/32 = 1.41 MHz
SPI2->CR1 |= SPI_CR1_CPHA; // first edge, look in data sheet
//Questionable settings
// Biderectional data line
SPI2->CR1 |= SPI_CR1_BIDIMODE; // 1/17/2019 --> Check to see if this fixes something
SPI2->CR1 |= SPI_CR1_BIDIOE; // idk if i need this
// CRC Polynomial Register
SPI2->CRCPR = 10;
// Control Register 2
SPI2->CR2 |= 1<<2; // SS output enabled
SPI2->CR1 |= SPI_CR1_SPE; // enable, has to be last
}
And here is my SPI Write code:
void SPI_Write(int dacSelect, int adcData){
while((SPI2->SR & SPI_SR_TXE) != 0);
GPIOC->ODR |= 1 << 2; // load set high to read data
SPI2->DR = dacArray[dacSelect]; // send address
SPI2->DR = adcData; // send adc data
while((SPI2->SR & SPI_SR_BSY) == SPI_SR_BSY);
GPIOC->ODR &= ~(1 << 2); // Send load low to load data
Delay(10); // short delay
GPIOC->ODR |= 1 << 2;
}
You can use STMCubeMX to generate codes for STM microprocessors and boards. Following code blocks are generated from STM32ubeMX for STM32F4. You should change baudrate for your sensor.
SPI_HandleTypeDef hspi;
SPI_HandleTypeDef SpiHandle;
void Spi_Initialize(void)
{
/*##-1- Configure the SPI peripheral #######################################*/
/* Set the SPI parameters */
SpiHandle.Instance = SPI2;
SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
SpiHandle.Init.Direction = SPI_DIRECTION_2LINES;
SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE;
SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT;
SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
SpiHandle.Init.TIMode = SPI_TIMODE_DISABLE;
SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
SpiHandle.Init.CRCPolynomial = 7;
SpiHandle.Init.NSS = SPI_NSS_SOFT;
SpiHandle.Init.Mode = SPI_MODE_MASTER;
if(HAL_SPI_Init(&SpiHandle) != HAL_OK)
{
while(1){};
}
}
void Spi_Read(void )
{
uint8_t SpiData[2];
uint8_t tempmessage = 8;
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,RESET); // CS pin
HAL_SPI_TransmitReceive(&hspi,&tempmessage,SpiData,2,5000); // Read Data
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,SET); // CS Pin
}
void Spi_Write(uint8_t *Data, uint8_t size)
{
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,RESET); // CS pin
HAL_SPI_Transmit(&hspi, Data, size, 5000); // Write Data
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,SET); // CS Pin
}