Sunday, October 09, 2022

STM32 HAL API functions (1) - basic

HAL stands for  Hardware Abstraction Layer.  It's generic API by ST Microtronics to program their MCUs.


/* delay */

HAL_Delay(1000);


/* GPIO */

HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);    // set HI

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET);     // set LO


/* UART */

HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);


/* I2C */     // example: TMP102

HAL_StatusTypeDef   ret;       // expect HAL_OK if operation is successful

// set request argument in buf[0], then:

ret = HAL_I2C_Master_Transit(&h12c1, TMP102_ADR, buf, 1, HAL_MAX_DELAY);

ret = HAL_I2C_Master_Receive(&h12c1, TMP102_ADR, buf, 2, HAL_MAX_DELAY);


/* ADC */

HAL_ADC_Start(&hadc1);

HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);

uint16_t     raw;

raw = HAL_ADC_GetValue(&hadc1);


Labels: ,

Saturday, October 08, 2022

FreeRTOS Cheatsheet

/* basic - why RTOS? want tasks for concurrency */
#include "FreeRTOS.h"
#include "task.h"
TaskHandle_t    myTask1Handle = NULL;
void myTask1 (void *p) {
    while (1) {
    }
}
// then in main.c
  // create task
  vTaskStartScheduler ();    // won't return
  while (1) {
  }

//-------------------------------------------------
/* Task */
xTaskCreate ( myTask1, "task1", 200 /*stacksize*/, (void*)0, 
                    tskIDLE_PRIORITY, &myTask1Handle);
vTaskSuspend ( myTask1Handle );
vTaskSuspendAll();
vTaskResume ( myTask1Handle );

curTaskHandle = xTaskGetCurrentTaskHandle();
vTaskDelete ( curTaskHandle );  // delete oneself

taskName = pcTaskGetName ( myTask2Handle );
taskHandle = xTaskGetHandle ( "dog" );  // find handle by name

eTaskState myState;
myState = eTaskGetState ( myTaskHandle );   // return enum, 1 is eReady

char myTaskList[300];
vTaskList ( myTaskList );

uxTaskGetNumberOfTasks()
xTaskGetTickCount()             // do NOT use in ISR
xTaskGetTickCountFromISR()      // ISR version

//-------------------------------------------------
/* prefix */
https://www.freertos.org/FreeRTOS-Coding-Standard-and-Style-Guide.html#NamingConventions
// fcns:
v   void
x   return code or handle   // ux  eg. UBaseType_t
// vars:
ul  uint32_t    u   uint16_t    uc  uint8_t
c   char        l   long        s   short
e   Enumerated variables
pc  char *

//-------------------------------------------------
/* delay */
vTaskDelay ( 1000 ); // only if at default Hz; still slightly > 1000 ms
vTaskDelay ( 1000 * configTICK_RATE_HZ / 1000 ); // independent from Hz
  // precise version:
TickType_t  myLastUnblock;
myLastUnblock = xTaskGetTickCount ();
vTaskDelayUntil ( &myLastUnblock, 1000 * configTICK_RATE_HZ / 1000 );

//-------------------------------------------------
/* interrupt */
void myIntTask(void *p) {
    while (1) {
        vTaskSuspend( NULL );  // suspend right away once started
        // do work
    }
}
// in default IRQ Handler
BaesType_t xYieldRequired;
xYieldRequired = xTaskResumeFromISR ( myIntTask ); // resume my int fcn
portYIELD_FROM_ISR( xYieldRequired );  // require context switch

//-------------------------------------------------
/* Queue */     LIFO - add to back(tail), get from front(head)
#include "queue.h"
QueueHandle_t   myQueue;
char buf[30];
myQueue = xQeuueCreate ( /*len*/5, sizeof(txBuf) );
// task 1
xQueueSend ( myQueue, (void*) txBuf, (TickType_t) 0);  // block time 0 (no block)
xQueueSendToFront (..)  // reverse order
xQueueOverwrite (..)    // default send not overwrite
// task 2
if( xQueueReceive ( myQueue, (void*) rxBuf, (TickType_t) 5 )) {
    // "Receive" blocked to read
    // xQueuePeek (..)
    // ..
}

uxQueueMessageWaiting ( myQueue ); // wait until ready
uxQueueSpaceAvailable ( myQueue );
xQueueReset ( myQueue );           // dump all unread message

//-------------------------------------------------
/* Notification */
/*task1*/ xTaskNotifyGive ( myTask2Handle ); // 'Give' to increment by 1 // default 0
/*task2*/ notifiedValue = ulTaskNotifyTake ( pdFALSE,
                                        (TickType_t) portMAX_DELAY );
    // decrement if false, reset to 0 if true

// task1
xTaskNotify ( myTask2Handle, 0, eNoAction );
    // eSetBits, eIncrement, eSetValueWithOverwrite, eSetValueWithoutOverwrite
    // eg. xTaskNotify ( myTask2Handle, (1<<2) | (1<<1), eSetBits );
xTaskNotifyAndQuery ( myTask2Handle,
                      (1<<2),
                      eSetValueWithOverwrite, 
                      &ulNotifiedValue ); // store last value before inc
xTaskNotifyStateClear ( myTask2Handle ); // cancel send, value remains
// task2
if ( xTaskNotifyWait(0, 0, &ulNotifiedValue, portMAX_DELAY ) == pdTRUE ) {
    // ..
}

//-------------------------------------------------
/* Semaphore */
#include "semphr.h"
// same handle for mutex & semaphore, up to create fcn
SemaphoreHandle_t   xMutex; 
xMutex = xSemaphoreCreateMutex(); // ... here determine what type
if ( xSemaphoreTake ( xMutex, (TickType_t) 0xFFFFFFFF ) == 1 ) { // LOCK
    // do work
    xSemaphoreGive ( xMutex );  // UNLOCK
}
Read more »

Labels: