cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F05x SPI clk single bit

aoleon
Associate II
Posted on May 14, 2014 at 17:07

Hi,

I have a PCB with a STM32F051 connected to 3 ADCs (

http://datasheets.maximintegrated.com/en/ds/MAX11166-MAX11pdf

) in daisy chain. Page 29 Figure 14 of the datasheetshows the schematic I implemented andPage 21 shows how to configure the chips.... My problem is (page 21): ''The load process is enabled on the falling edge ofCNVST when SCLK is held high. '' The SPI is normally in LowPolarity and Falling Edge, But in order to create the situation above I switch on the fly the polarity and Edge of the system to get the CLK high while CNVST falls... (I attached a screenshot...) Very dirty way.. and I'm not sure if the ADCs are not upset by the extra clk falling edge at the end of the communication when I go back to the normal polarity.

void
ADCs_init(
void
)
{
uint16_t tmpreg = 0;
SPI_Cmd(SPI1, DISABLE); 
tmpreg = SPI1->CR1;
tmpreg &= 0xFFFC;
tmpreg |= (SPI_CPHA_1Edge | SPI_CPOL_High); 
SPI1->CR1 = tmpreg ; 
/* Write to SPIx CR1 */
GPIO_SetBits(ADC_CNVST_PORT,ADC_CNVST_PIN); 
SPI_Cmd(SPI1, ENABLE);
GPIO_ResetBits(ADC_CNVST_PORT,ADC_CNVST_PIN); 
/* Drop CNVST to enable the load process */
Send_Receive_Byte(0xC0); 
// Daisy Chain Mode with busy indicator, Reference mode 0, Normal mode.
Send_Receive_Byte(0xC0); 
// Daisy Chain Mode with busy indicator, Reference mode 0, Normal mode.
Send_Receive_Byte(0xC0); 
// Daisy Chain Mode with busy indicator, Reference mode 0, Normal mode.
GPIO_SetBits(ADC_CNVST_PORT,ADC_CNVST_PIN); 
SPI_Cmd(SPI1, DISABLE);
tmpreg = SPI1->CR1;
tmpreg &= 0xFFFC;
tmpreg |= (SPI_CPHA_2Edge | SPI_CPOL_Low); 
SPI1->CR1 = tmpreg ; 
/* Write to SPIx CR1 */
SPI_Cmd(SPI1, ENABLE); 
}
uint8_t Send_Receive_Byte(uint8_t byte)
{
/*!< Send byte through the SPI1 peripheral */
SPI_SendData8(SPI1, byte);
while
(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
while
(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
/*!< Return the byte read from the SPI bus */
return
SPI_ReceiveData8(SPI1);
}

Do you know a nice way to control the CLK level? Thanks, Alex
4 REPLIES 4
Posted on May 14, 2014 at 18:43

> I'm not sure if the ADCs are not upset by the extra clk falling edge at the end of the communication when I go back to the normal polarity.

They shouldn't be, as the shifted-in data are loaded into the ADC's register upon CNVST going high; and the ''extra'' SCK edge happens after that, thus should be ignored by the ADCs.

JW
aoleon
Associate II
Posted on May 15, 2014 at 12:04

Thanks a lot for your reply. That's what I thought too and also ADC IN and OUT seem to show an end of conversion after.The ADCs might not be upset...

Even in this case I don't really like the way I handle the Clock and CNVST... Controlling the Clock independently is also necessary to read the data from my 3 ADCs. I need to read 49 bits (1 busy bit + 3 x 16 bits). There as well I coded it dirty by changing the size of the frame on the fly. I send 4 bits, then 13 bits, 16 bits and 16 bits....

void
MAX1116x_Receive(tst_ADCs_global *ADCs) 
{
uint16_t tmpreg = 0;
/* Clear the DRDY EXTI line pending bit */
EXTI_ClearITPendingBit(EXTI_Line0); 
/* Activate interrupt */
NVIC_EnableIRQ(EXTI0_1_IRQn);
GPIO_SetBits(ADC_CNVST_PORT,ADC_CNVST_PIN); 
// Pull CNVST high to stop acquisition and start Conversion 
osSignalWait (1, osWaitForever); 
/* To be changed for a what the conversion time should be (1.5 - 3uS ) and handle the timeout*/
GPIO_ResetBits(ADC_CNVST_PORT,ADC_CNVST_PIN); 
// Pull CNVST low because we don't need it anymore.
/* Deactivate interrupt */
NVIC_DisableIRQ(EXTI0_1_IRQn);
/* Get the SPIx CR2 value */
tmpreg = SPI1->CR2;
/* Clear DS[3:0] bits */
tmpreg &=(uint16_t)~SPI_CR2_DS;
/* Configure SPIx: Data Size */
tmpreg |= (uint16_t)SPI_DataSize_4b;
/* Write to SPIx CR2 */
SPI1->CR2 = tmpreg;
SPI_SendData8(SPI1, 0x00);
while
(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
ADCs->Temperature = (SPI1->DR << 15);
/* Get the SPIx CR2 value */
tmpreg = SPI1->CR2;
/* Clear DS[3:0] bits */
tmpreg &=(uint16_t)~SPI_CR2_DS;
/* Configure SPIx: Data Size */
tmpreg |= (uint16_t)SPI_DataSize_13b;
/* Write to SPIx CR2 */
SPI1->CR2 = tmpreg;
Send_Receive_16_bits(0x00);
while
(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
ADCs->Temperature |= SPI1->DR;
/* Get the SPIx CR2 value */
tmpreg = SPI1->CR2;
/* Clear DS[3:0] bits */
tmpreg &=(uint16_t)~SPI_CR2_DS;
/* Configure SPIx: Data Size */
tmpreg |= (uint16_t)SPI_DataSize_16b;
/* Write to SPIx CR2 */
SPI1->CR2 = tmpreg;
Send_Receive_16_bits(0x00);
while
(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
ADCs->NH_Value = SPI1->DR;
Send_Receive_16_bits(0x00);
while
(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
ADCs->PH_Value = SPI1->DR;
}

I end-up with small delays between each packets, which once again might not upset the ADCs but I would like to find a nicer way to do it... Would anyone have an idea on how to make the STM32 and the MAX11166 talk nicely? Alex
Posted on May 15, 2014 at 12:43

49 = 7 x 7

JW

aoleon
Associate II
Posted on May 16, 2014 at 12:52

That would avoid me changing the data frame size on the fly indeed. But I find it still quite intense... 7 frames when there should only be 3.

The only other way I can think of to just generate a single clock pulse is to switch the SPI off, change the Clk GPIO to output, toggle it to flush the busy bit and turn the SPI back on in 16 bits mode....