cancel
Showing results for 
Search instead for 
Did you mean: 

Removing delay for escaping blocking in my code

Manojkumar Subramaniam
Associate II

Hi all, i have a function that changes the PWM value over some time.. the issue is it get blocked by HAL_Delay.. what's the way to replace it with some non blocking method ?

void heartBeat_loop(uint8_t initial_val, uint8_t end_val, uint8_t n)
{
		int delayl = 0;
		HAL_GPIO_WritePin(RING_B_GPIO_Port, RING_B_Pin, GPIO_PIN_SET);
	//only run this loop when the initial value max = 40
		if(n==0) // when light ramp down slope
	{
			for(uint8_t x = initial_val; x>=end_val;) // 0- 100 in 2 sec
			{
			TIM16->CCR1= x;
			x = x - 1;
				
			//Detect 13 times 10ms of TIM6 has elapsed.
			delayl = 1000/(initial_val-end_val);
			HAL_Delay(delayl);	
					
			//Create a delay of 130ms
			//loop will end with PWM val = 10 so 25% brightness 
			}
	}

6 REPLIES 6

Run a state-machine via the SysTick interrupt.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Manojkumar Subramaniam
Associate II

@Community member​  maybe a flag in the function... and then check for the flagged in systick and increment if flagged.. is this what u suggesting ?

No, a state-machine, that tracks and sequences progress, and enters/exits quickly if the next stage of operation isn't ready to get done yet. ie you don't block in a loop, but check periodically

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Manojkumar Subramaniam
Associate II

@Community member​  but the it's a for loop... it can't simply exits

You're going to have to free your mind to alternate implementations, where for example you hold the iteration count as a state variable.

If you can't break free of the linear execution mindset, perhaps you need to have multiple threads of execution, but then you'd need to contend with more than one thing happening at once.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
T J
Lead

in main.c

declare the globals:

char mSint,TxDMABufHasData ;
int mS,second;

in Systick add these lines:

  mSint = true; // mSinterrupt is a soft foreground interrupt,
  mS ++;
  if(mS > 999){
    mS = 0;
    second++;
    secondInt = true;  
  }

in main.c

under while(1){

if(mSint){
 
  mSint= false;
  run_StateMachine();  // every mSecond
  }
}

in your code set:

void run_StateMachine(void){  // every mSecond
 
	CheckTxDMABufferProgress();  // non blocking uart Tx DMA
 
	Task2();
	Task3();
 
	if(secondInt){ 
		secondInt = false;
		printf("Secondint has fired");
	}
}
 
void CheckTxDMABufferProgress(void) {
  if (TxDMABufHasData) {
    char uartState = HAL_UART_GetState(&huart7);
    if ((uartState == HAL_UART_STATE_READY) || (uartState == HAL_UART_STATE_BUSY_RX)) {
	  TxDMABufHasData = false;	// sending now
	  if (HAL_UART_Transmit_DMA(&huart7, (uint8_t *)Usart1TxDMABuffer + U1TxBufferPtrOUT, U1TxBufferPtrIN - U1TxBufferPtrOUT) == HAL_OK) {
	    HAL_UART_Transmit_DMA_Status = UartDMAsuccess;
	    U1TxBufferPtrOUT = U1TxBufferPtrIN;  // now empty , can reset pointer to zero here
	  }
	  else {
	  //	_Error_Handler(__FILE__, __LINE__);                 /* Transfer error in transmission process */
	    HAL_UART_Transmit_DMA_Status = UartDMAfailed;
	    char  DMAfailedString[32];
		printf(DMAfailedString, "Usart DMA has Failed\n\r");		  
	  }
    }
  }
}