cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407ZGT6 to LTC1859IG read issues

lebies
Visitor

Hi all,

First post here...

I'm fairly new to STM32, working on STM32CubeIDE and have running code on a very well designed and laid out PCB with above components being the main actors.. The project was setup with STM32CubeMX V6.4.0 using STM32Cube FW_F4 V1.26.2. I haven't upgrade it yet (as suggested) because I inherited the project.

Build Id Info: STM32CubeIDE

/*
Version: 1.15.0
Build: 20695_20240315_1429 (UTC)
OS: Windows 10, v.10.0, x86_64 / win32
Java vendor: Eclipse Adoptium
Java runtime version: 17.0.8.1+1
Java version: 17.0.8.1
/*

ADC hooked up to the CPU via SPI, and CPU running at 160MHz.

Here's my problem:

I'm trying to read 5 of the 7 ADC channels sequentially and working exactly according to the LTC1859IG datasheet. If I read 1 or 2 channels only I get very accurate good values back but the minute I add any combination of the other channels (1 or more) I get (typically but not always) garbage values for either the 1st channel (0) or the last channel (4) - or both - and good values for the other channels!

I've gone down various rabbit holes trying different config settings as well as adding delays, in vain ... I'm now stuck and hoping someone can point me to possible errors in my approach/code.

Here's the code I'm trying:

//GPIO_init:
	GPIO_InitTypeDef GPIO_InitStruct = { 0 };

	/* GPIO Ports Clock Enable */
	__HAL_RCC_GPIOA_CLK_ENABLE();
	__HAL_RCC_GPIOB_CLK_ENABLE();
	__HAL_RCC_GPIOC_CLK_ENABLE();

	/*Configure GPIO pin Output Levels */
	HAL_GPIO_WritePin(GPIOA, SPI1_nCS1_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOA, SPI3_nCS1_Pin, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOC, ADC2_CONVST_Pin, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB, ADC1_CONVST_Pin, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB, SPI1_nCS2_Pin | SPI1_nCS3_Pin | SPI1_nCS4_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(SPI2_nCS1_GPIO_Port, SPI2_nCS1_Pin, GPIO_PIN_SET);

	/*Configure GPIO pins : SPI1_nCS1_Pin */
	GPIO_InitStruct.Pin = SPI1_nCS1_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

	/*Configure GPIO pin : ADC2_CONVST_Pin */
	GPIO_InitStruct.Pin = ADC2_CONVST_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

	/*Configure GPIO pins : ADC1_CONVST_Pin SPI2_nCS1_Pin SPI1_nCS2_Pin SPI1_nCS3_Pin SPI1_nCS4_Pin */
	GPIO_InitStruct.Pin = ADC1_CONVST_Pin | SPI2_nCS1_Pin | SPI1_nCS2_Pin | SPI1_nCS3_Pin | SPI1_nCS4_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

	/*Configure GPIO pins : ADC1_BSY_Pin /
	GPIO_InitStruct.Pin = ADC1_BSY_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

	/*Configure GPIO pins : ADC2_BSY_Pin */
	GPIO_InitStruct.Pin = ADC2_BSY_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

	/* EXTI interrupt init*/
	HAL_NVIC_SetPriority(EXTI1_IRQn, 0, 0);
	HAL_NVIC_EnableIRQ(EXTI1_IRQn);


//SPI1_init:
	hspi1.Instance = SPI1;
	hspi1.Init.Mode = SPI_MODE_MASTER;
	hspi1.Init.Direction = SPI_DIRECTION_2LINES;
	hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
	hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
	hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
	hspi1.Init.NSS = SPI_NSS_SOFT;
	hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;	(RCC_OscInitStruct.PLL.PLLN = 160; ie 160MHx)
	hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
	hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
	hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
	hspi1.Init.CRCPolynomial = 10;


//BUSY PIN Interrupt callback:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
	if(GPIO_Pin == ADC1_BSY_Pin) {
		haveADC1 = 1;
	}


void ADCM_ConvertStart()  {
	unsigned long st;

	// start conversion
//	while( hspi1.State != HAL_SPI_STATE_READY );  				// wait xmission complete
	HAL_GPIO_WritePin(GPIOB, ADC1_CONVST_Pin, GPIO_PIN_SET);	// ADC1_CONVST HI
	st = DWT->CYCCNT;											// 8 (+50ns)
	while(DWT->CYCCNT - st < ADC_CONV_CYCLE_COUNT);
//	delayC = (DWT->CYCCNT - st);
	HAL_GPIO_WritePin(GPIOB, ADC1_CONVST_Pin, GPIO_PIN_RESET);	// ADC1_CONVST LO
}


void ADCM_Start1()  {
	HAL_StatusTypeDef err;
	unsigned long st;
	uint16_t res = 0;

	chSelect = 0;
	HAL_GPIO_WritePin(GPIOA, SPI1_nCS1_Pin, GPIO_PIN_RESET);									// !SPI1_nCS1 (RD) = LO
	st = DWT->CYCCNT;
	while(DWT->CYCCNT - st < ADC_READ_CYCLE_COUNT);				// 3 cycles
	err = HAL_SPI_TransmitReceive(&hspi1, (uint8_t*)&RD_CH0, (uint8_t*)(&res), 2, 50);				// setup LA1_ADC1_IN1
	HAL_GPIO_WritePin(GPIOA, SPI1_nCS1_Pin, GPIO_PIN_SET);										// SPI1_nCS1 (RD) = HI
//	while( hspi1.State != HAL_SPI_STATE_READY );  												// wait xmission complete
	if( err != HAL_OK )
		doSPI_Error(err);

	chVals[0] = res;
	// start conversion
	ADCM_ConvertStart();
}


ADC_Read():
//	while( hspi1.State != HAL_SPI_STATE_READY );  				// wait xmission complete
	HAL_GPIO_WritePin(GPIOA, SPI1_nCS1_Pin, GPIO_PIN_RESET);	// nCS1 (RD) = LO
	st = DWT->CYCCNT;
	while(DWT->CYCCNT - st < ADC_READ_CYCLE_COUNT);				// 3 cycles
	err = HAL_SPI_TransmitReceive(&hspi1, (uint8_t*)&RD_CH1, (uint8_t*)(&res), 2, 50);
	HAL_GPIO_WritePin(GPIOA, SPI1_nCS1_Pin, GPIO_PIN_SET);
//	while( hspi1.State == HAL_SPI_STATE_READY );  				// wait xmission complete
	if( err != HAL_OK )
		doSPI_Error(err);
	chVals[0] = res;
//	st = DWT->CYCCNT;
//	while(DWT->CYCCNT - st < ADC_READ_CYCLE_COUNT);
	ADCM_ConvertStart();										// start next conversion


Algorithm:
	//call ADCM_Start1() before main.while( true )
	//onInturrupt (CONV_BSY HI+EDGE), set flag to read and save result of conversion (haveADC1)
	
	ADCM_Start1();
	while (loopcount < 100)
		{
			if( 1 == haveADC1 )		// wait for CONV_done
			{
				switch (chSelect) {
					case 0:
						chVals[0] = 0;
						ADCM_ReadChannel(0);							// gets result of previous conversion and sets up next channel
						TransmitDataPacket.M_HALL_LA1 = chVals[0];		// send packet
						TransmitDataPacket.time = timeSinceStartup_ms;
						dumpAsciiPacket_ToWIFI();
						chSelect = 1;									// select next channel to read
						haveADC1 = 0;									// set semaphore (used to wait for CONV done)
						ADCM_ConvertStart();							// start CONVersion (toggle CONV GPIO)
						break;
				...
					//for all channels

 

0 REPLIES 0