Ram. (translation errors)
If their original attempts (STLIB?) looked like they might have been written by a summer intern
I tend to agree; fewer problems with Cube v10.
Still suffers from the "can't insert breakpoints" even though you have not reached the max 5. Exit Cube and restart... Fortunately I manage most debugging with 1 or 2.
I find deleting the breakpoints is good practice. I don't mean deactivate either. Double clicking the breakpoint icon on the line just deactivates that breakpoint, the breakpoint itself is remembered
They seem to be continually working on their development environment
typedef struct {
GPIO_TypeDef *port;
GPIO_InitTypeDef init;
} GPIO_Init_t;
typedef struct {
GPIO_TypeDef *port;
uint8_t pin;
uint8_t af;
} GPIO_AFInit_t;
const GPIO_AFInit_t GPIOAF_cfg[] = {
{ GPIOC, GPIO_PinSource5, GPIO_AF_2 }, // SPI SCK
{ GPIOC, GPIO_PinSource6, GPIO_AF_2 }, // SPI MOSI
{ GPIOD, GPIO_PinSource7, GPIO_AF_4 }, // TIM2 CH1 CCP INPUT
};
const GPIO_Init_t GPIO_cfg[] = {
{ GPIOA, { GPIO_Pin_3, GPIO_Mode_OUT, GPIO_Speed_10MHz, GPIO_OType_PP }}, // LED
{ GPIOB, { GPIO_Pin_4, GPIO_Mode_OUT, GPIO_Speed_10MHz, GPIO_OType_PP }}, // OLED CS
{ GPIOC, { GPIO_Pin_5, GPIO_Mode_AF, GPIO_Speed_10MHz, GPIO_OType_PP }}, // OLED SCK
{ GPIOC, { GPIO_Pin_6, GPIO_Mode_AF, GPIO_Speed_10MHz, GPIO_OType_PP }}, // OLED MOSI
{ GPIOC, { GPIO_Pin_3, GPIO_Mode_OUT, GPIO_Speed_10MHz, GPIO_OType_PP }}, // OLED DC
{ GPIOC, { GPIO_Pin_4, GPIO_Mode_OUT, GPIO_Speed_10MHz, GPIO_OType_PP }}, // OLED RST
{ GPIOD, { GPIO_Pin_4, GPIO_Mode_OUT, GPIO_Speed_10MHz, GPIO_OType_PP }}, // DEBUG SIGNAL
{ GPIOD, { GPIO_Pin_7, GPIO_Mode_AF, GPIO_Speed_10MHz, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_Schmit_Enable }}, // TIM2 CH1 CCP INPUT
};
for(uint8_t i=0; i < sizeof(GPIO_cfg) / sizeof(GPIO_Init_t); i++) // GPIO init
GPIO_Init(GPIO_cfg[i].port, (GPIO_InitTypeDef*) &GPIO_cfg[i].init);
for(uint8_t i=0; i < sizeof(GPIOAF_cfg) / sizeof(GPIO_AFInit_t); i++) // GPIO AF init
GPIO_PinAFConfig(GPIOAF_cfg[i].port, GPIOAF_cfg[i].pin, GPIOAF_cfg[i].af);
“Memory frames”?? What’s that?
/// SPI4
gpio_one_pin(zap_gpio.E.pin02.v_af05_spi4_sck.speed4.pull_up.lock_on); /// spi4_sck
gpio_one_pin(zap_gpio.E.pin04.out.speed4.lock_on); /// spi4_nss
gpio_one_pin(zap_gpio.E.pin05.v_af05_spi4_miso.speed4.pull_up.lock_on); /// spi4-mo
gpio_one_pin(zap_gpio.E.pin06.v_af05_spi4_mosi.speed4.pull_up.lock_on); /// spi4_mi
They are quite handy but I would not have done it that way if I was starting bare-metal. I would work through every page of the RM and use a table. But that's ~2000 pages and you can see why this is impractical.
void Configure_GPIO(GPIO_TypeDef *port, uint32_t pin, GPIO_PinState pin_state, uint32_t mode, uint32_t pull, uint32_t slew)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = pin;
GPIO_InitStruct.Mode = mode;
GPIO_InitStruct.Pull = pull;
GPIO_InitStruct.Speed = slew;
HAL_GPIO_Init(port, &GPIO_InitStruct);
HAL_GPIO_WritePin(port, pin, pin_state);
}
/**
* @brief Initializes the GPIOx peripheral according to the specified parameters in the GPIO_Init.
* @param GPIOx where x can be (A..K) to select the GPIO peripheral for STM32F429X device or
* x can be (A..I) to select the GPIO peripheral for STM32F40XX and STM32F427X devices.
* @param GPIO_Init pointer to a GPIO_InitTypeDef structure that contains
* the configuration information for the specified GPIO peripheral.
* @retval None
*/
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
{
uint32_t position;
uint32_t ioposition = 0x00U;
uint32_t iocurrent = 0x00U;
uint32_t temp = 0x00U;
/* Configure the port pins */
for(position = 0U; position < GPIO_NUMBER; position++)
{
/* Get the IO position */
ioposition = 0x01U << position;
/* Get the current IO position */
iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition;
if(iocurrent == ioposition)
{
/*--------------------- GPIO Mode Configuration ------------------------*/
/* In case of Alternate function mode selection */
if((GPIO_Init->Mode == GPIO_MODE_AF_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_OD))
{
/* Check the Alternate function parameter */
assert_param(IS_GPIO_AF(GPIO_Init->Alternate));
/* Configure Alternate function mapped with the current IO */
temp = GPIOx->AFR[position >> 3U];
temp &= ~(0xFU << ((uint32_t)(position & 0x07U) * 4U)) ;
temp |= ((uint32_t)(GPIO_Init->Alternate) << (((uint32_t)position & 0x07U) * 4U));
GPIOx->AFR[position >> 3U] = temp;
}
/* Configure IO Direction mode (Input, Output, Alternate or Analog) */
temp = GPIOx->MODER;
temp &= ~(GPIO_MODER_MODER0 << (position * 2U));
temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2U));
GPIOx->MODER = temp;
/* In case of Output or Alternate function mode selection */
if((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) ||
(GPIO_Init->Mode == GPIO_MODE_OUTPUT_OD) || (GPIO_Init->Mode == GPIO_MODE_AF_OD))
{
/* Configure the IO Speed */
temp = GPIOx->OSPEEDR;
temp &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2U));
temp |= (GPIO_Init->Speed << (position * 2U));
GPIOx->OSPEEDR = temp;
/* Configure the IO Output Type */
temp = GPIOx->OTYPER;
temp &= ~(GPIO_OTYPER_OT_0 << position) ;
temp |= (((GPIO_Init->Mode & GPIO_OUTPUT_TYPE) >> 4U) << position);
GPIOx->OTYPER = temp;
}
/* Activate the Pull-up or Pull down resistor for the current IO */
temp = GPIOx->PUPDR;
temp &= ~(GPIO_PUPDR_PUPDR0 << (position * 2U));
temp |= ((GPIO_Init->Pull) << (position * 2U));
GPIOx->PUPDR = temp;
/*--------------------- EXTI Mode Configuration ------------------------*/
/* Configure the External Interrupt or event for the current IO */
if((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE)
{
/* Enable SYSCFG Clock */
__HAL_RCC_SYSCFG_CLK_ENABLE();
temp = SYSCFG->EXTICR[position >> 2U];
temp &= ~(0x0FU << (4U * (position & 0x03U)));
temp |= ((uint32_t)(GPIO_GET_INDEX(GPIOx)) << (4U * (position & 0x03U)));
SYSCFG->EXTICR[position >> 2U] = temp;
/* Clear EXTI line configuration */
temp = EXTI->IMR;
temp &= ~((uint32_t)iocurrent);
if((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT)
{
temp |= iocurrent;
}
EXTI->IMR = temp;
temp = EXTI->EMR;
temp &= ~((uint32_t)iocurrent);
if((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT)
{
temp |= iocurrent;
}
EXTI->EMR = temp;
/* Clear Rising Falling edge configuration */
temp = EXTI->RTSR;
temp &= ~((uint32_t)iocurrent);
if((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE)
{
temp |= iocurrent;
}
EXTI->RTSR = temp;
temp = EXTI->FTSR;
temp &= ~((uint32_t)iocurrent);
if((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE)
{
temp |= iocurrent;
}
EXTI->FTSR = temp;
}
}
}
}
/**
* @brief Sets or clears the selected data port bit.
*
* @note This function uses GPIOx_BSRR register to allow atomic read/modify
* accesses. In this way, there is no risk of an IRQ occurring between
* the read and the modify access.
*
* @param GPIOx where x can be (A..K) to select the GPIO peripheral for STM32F429X device or
* x can be (A..I) to select the GPIO peripheral for STM32F40XX and STM32F427X devices.
* @param GPIO_Pin specifies the port bit to be written.
* This parameter can be one of GPIO_PIN_x where x can be (0..15).
* @param PinState specifies the value to be written to the selected bit.
* This parameter can be one of the GPIO_PinState enum values:
* @arg GPIO_PIN_RESET: to clear the port pin
* @arg GPIO_PIN_SET: to set the port pin
* @retval None
*/
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
{
if(PinState != GPIO_PIN_RESET)
{
GPIOx->BSRR = GPIO_Pin;
}
else
{
GPIOx->BSRR = (uint32_t)GPIO_Pin << 16U;
}
}
HAL Libraries are 100% useless if you have to spent as long working out how to use it as it would have taken to read the datasheet and set the resisters yourself.