Skip to main content
Manojkumar Subramaniam
Associate III
October 3, 2018
Question

Removing delay for escaping blocking in my code

  • October 3, 2018
  • 6 replies
  • 1031 views

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 
			}
	}

    This topic has been closed for replies.

    6 replies

    Tesla DeLorean
    Guru
    October 3, 2018

    Run a state-machine via the SysTick interrupt.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Manojkumar Subramaniam
    Associate III
    October 3, 2018

    @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 ?

    Tesla DeLorean
    Guru
    October 3, 2018

    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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Manojkumar Subramaniam
    Associate III
    October 3, 2018

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

    Tesla DeLorean
    Guru
    October 3, 2018

    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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
    T J
    Senior III
    October 4, 2018

    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");		 
    	 }
     }
     }
    }