How to change stm32 PLL parameters in uboot device tree? - c

I'm new to u-boot and I have a custom board based on the Waveshare CoreH7 board. my crystal(HSE) frequency is 8MHz and I want to have a 400MHZ core frequency using the PLL1. according to this documentation I should add the below code to my board.dts file.
rcc {
vco1#58024430 {
#clock-cells = <0>;
compatible = "stm32,pll";
reg = <0>;
st,clock-div = <4>; // 8MHz divided by 4 = 2MHz
st,clock-mult = <400>; // (2MHz * 400)/2 = 400MHz
st,frac-status = <0>;
st,frac = <0>;
//st,vcosel = <1>;
st,pllrge = <1>;
};
};
so, now my frequency should be 400MHz. but it's not!
I set the uboot logging level to 8 to see all logs. and after checking the output logs on the serial terminal, I realized that u-boot even won't care about those "vco1" parameters in my device tree. so I dicided to take a look at the rcc driver, and when I saw the code, I realized that pll parameters are defined in the driver itself, and the driver even won't care about those parameters that I wrote them in my device tree.
this is a part of stm32h7 driver at 329th line:
/*
* OSC_HSE = 25 MHz
* VCO = 500MHz
* pll1_p = 250MHz / pll1_q = 250MHz pll1_r = 250Mhz
*/
struct pll_psc sys_pll_psc = {
.divm = 4,
.divn = 80,
.divp = 2,
.divq = 2,
.divr = 2,
};
I can't understand what's happening here! As I know, the driver should read these parameters from device tree. So, if the user should write these parameters in the device tree, why the driver has these values in it when it can read them from device tree?

Related

Microchip PIC24FJ SPI writes correctly but only reads zeros

I have a PIC24FJ256GA702 communicating with a AD5724RBREZ quad DAC with a SPI link.
The DAC works fine, writing is no problem, but I am stuck on reading back the control register from it.
I get the correct waveform on the PIC pin that I am expecting, and the read routine runs, but it always returns zeros. The waveform is clearly not zero- the waveform on the scope is correct for the 4 channels and the internal reference being enabled.
Scope view of waveforms - blue = clock, yellow = data input from DAC at PIC pin
(The excessive ringing on the scope image is probably caused by a long distance ground connection- in practice these chips are about 25mm apart.)
I thought that the input pin was configured as an analogue, but it was correctly a digital input.
I connected it to a counter based on Timer1, and that counter does count if I try to read the DAC. This suggests that the PPS is working, the pin is not bust, and the the input signal is clean enough to use.
I think it may be a problem with the code or the decode timing of the SPI module, but as shown in the image the data is stable during the clock cycle so I cannot see what is wrong.
I have searched the forums, and it seems most with this problem trace it to analogue functions being enabled but that is not the case here.
Would anyone like to suggest something else to try, or post some working SPI read code if my code is not looking correct?
The code follows-
void AOUT_init(void)
{
//assume PPS is unlocked (it is on reset) - see note below
//setup SPI1 itself
SPI1CON1L = 0x0160; //TX work read 0
//SPI1CON1L = 0x0060; //TX not work
//SPI1CON1L = 0x0120; //TX work, read 0
//SPI1CON1L = 0x0020; //not tried
SPI1CON1H = 0x3000;
SPI1CON2L = 0x0017; //word length (17 hex = 24 bits)
//BRG
SPI1BRGL = 0x0000; //default = no divisor
//PPS - assume unlocked at this point
ANSBbits.ANSB13 = 0;
TRISBbits.TRISB13 = TRIS_INPUT;
//##########################################################################
RPINR20bits.SDI1R = 13; //set SDI1 data input to PIC to RB13
//##########################################################################
TRISBbits.TRISB15 = TRIS_OUTPUT;
RPOR7bits.RP15R = 8; //RB15 to SDI1 clock out from PIC
TRISBbits.TRISB14 = TRIS_OUTPUT;
RPOR7bits.RP14R = 7; //RB14 to SDI1 data out from PIC
//AD5724R has additional lines - not all used in practice
//setup and set initial level here
//AOUT-/LDAC
TRISBbits.TRISB6 = TRIS_OUTPUT;
LATBbits.LATB6 = 1;
//AOUT-/SYNC
TRISBbits.TRISB7 = TRIS_OUTPUT;
LATBbits.LATB7 = 1;
//AOUT-/CLR
TRISBbits.TRISB12 = TRIS_OUTPUT;
LATBbits.LATB12 = 1;
//turn SPI on
SPI1CON1Lbits.SPIEN = 1;
SPI1CON1Lbits.MSTEN = 1; //included in definition above
//now setup the AD chip
//output range set
AOUT_TX(0x0C00,0x0100); //all channels to 10V
//control
AOUT_TX(0x1900,0x0500);
//power control - enable DACs
AOUT_TX(0x1000,0x1F00);
}
The comms routine below is included for completeness- it just controls the other DAC lines. The /SYNC line is doing a chip select function.
static void AOUT_Comms(bool bSync, bool bLDAC, bool bClr)
{
//AOUT-/LDAC
LATBbits.LATB6 = bLDAC;
//AOUT-/SYNC
LATBbits.LATB7 = bSync;
//AOUT-/CLR
LATBbits.LATB12 = bClr;
}
This is write routine which works fine.
void AOUT_TX(uint16_t dataH, uint16_t dataL)
{
//AOUT uses 24 bit data
//this routine handles /SYNC line
//relies on AD chip having much faster response than chip cycle time
//AD chip limits at about 38MHz so much quicker than PIC.
AOUT_Comms(0,1,1);
SPI1BUFL = dataL;
SPI1BUFH = dataH;
while(SPI1STATLbits.SPIBUSY) //wait until sent
{
;
}
AOUT_Comms(1,1,1);
//
}
This is the read routine, which uses the routines above.
void AOUT_read_control(uint16_t ReadH, uint16_t ReadL)
{
uint16_t temp;
//to read, transmit the register to be read, then transmit a dummy command "NOP" to clock the data out.
//send register
AOUT_TX(0x9000,0x0000);
//read out- this is similar to write but reads the received buffer at the end.
//clear buffer
while (SPI1STATLbits.SPIRBF)
{
temp = SPI1BUFL;
temp = SPI1BUFH;
}
AOUT_Comms(0,1,1);
SPI1BUFL = 0;
SPI1BUFH = 0x1800; //nop operation via control register
while(SPI1STATLbits.SPIBUSY) //wait until sent
{
;
}
while (!SPI1STATLbits.SPIRBF)
{
; //hold until something received
}
ReadH = SPI1BUFH;
ReadL = SPI1BUFL; //these read zero
AOUT_Comms(1,1,1);
//
//dummy so can check counter also connected to same pin
temp = TMR1;
temp = TMR1;
}
Update-
I checked the SPI read decode by sending the received words directly to a display as suggested by the comments. I get 0000 for both words.
Also as suggested I connected a logic analyser at the PIC pins, and it decodes both read and write correctly.Logic Analyser view- Ch1/Blue/MOSI writing 0x180000, Ch2/Green/MISP reading 0x00001F, both correct

Using DCMI Interface but only receiving 0xA603A603 before hard fault

For my master thesis I am trying to receive data over DCMI with the STM32H742. As an image sensor I am using the NOIV2SN1300A. It sends data over 10 data lines, this data differs (so not always 0xA603A603). To reduce data size I have activated binning and subsampling.
I am using DMA to transfer the data received by DCMI into the internal SRAM at address 0x24000000. After a few telegrams (of 0xA603A603) the uC goes into hard fault and infinite loop. I am not sure why this error occurs. Here is my config for DMA and DCMI:
/* DCMI DMA Init */
/* DCMI Init */
hdma_dcmi.Instance = DMA1_Stream0;
hdma_dcmi.Init.Request = DMA_REQUEST_DCMI;
hdma_dcmi.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_dcmi.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_dcmi.Init.MemInc = DMA_MINC_ENABLE;
hdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;//WORD;
hdma_dcmi.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_dcmi.Init.Mode = DMA_DOUBLE_BUFFER_M0;
hdma_dcmi.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_dcmi.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma_dcmi.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_dcmi.Init.MemBurst = DMA_MBURST_SINGLE;
//hdma_dcmi.Init.PeriphBurst = DMA_PBURST_SINGLE;
if (HAL_DMA_Init(&hdma_dcmi) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hdcmi,DMA_Handle,hdma_dcmi);
HAL_NVIC_SetPriority(DCMI_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DCMI_IRQn);
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
hdcmi.Instance = DCMI;
hdcmi.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
hdcmi.Init.PCKPolarity = DCMI_PCKPOLARITY_FALLING; //Todo:???
hdcmi.Init.VSPolarity = DCMI_VSPOLARITY_HIGH;
hdcmi.Init.HSPolarity = DCMI_HSPOLARITY_HIGH;
hdcmi.Init.CaptureRate = DCMI_CR_ALL_FRAME;
hdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_10B;
hdcmi.Init.JPEGMode = DCMI_JPEG_DISABLE;
hdcmi.Init.ByteSelectMode = DCMI_BSM_OTHER;//DCMI_BSM_ALL;
hdcmi.Init.ByteSelectStart = DCMI_OEBS_ODD;
hdcmi.Init.LineSelectMode = DCMI_LSM_ALL;
hdcmi.Init.LineSelectStart = DCMI_OELS_ODD;
if (HAL_DCMI_Init(&hdcmi) != HAL_OK)
{
Error_Handler();
}
uint32_t DataSizeImageSensor = 0xB160;
DMA_BUFFER uint32_t AddressFrameBuffer[0xB160];
HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_SNAPSHOT, (uint32_t)AddressFrameBuffer, DataSizeImageSensor);
void MPU_Config (void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* Disable the MPU */
HAL_MPU_Disable();
/* Configure the MPU attributes for SDRAM */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x24000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; //Cache is incoherent with CPU for DMA usage
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
Any idea why this error occurs? Like I said, I receive data, I am sure the sensor sends viable data (so something else then 0xA603A603), but I get only the same data by DCMI before hard fault. At this current setup I transfer 64 telegrams, then the hard fault occurs. Furthermore I disabled the cache for the SRAM1, as there are problems regarding cache/DMA/CPU coherence. I am not quite sure how to proceed, as it looks to me like it is a setup error. Maybe an overrun by DCMI?
Note: The code above doesn't actually occur in this order. That are just the relevant parts (at least from what I expect to be relevant).
I found other posts about this problem, where the error was a slow system clock. As my system clock is 475 MHz and the HCLK3 Clock (which is used by DCMI for sampling) is 237.5 MHz I can rule out a Clock problem. The datasheet says the HCLK Clock has to be 2.5 times faster then DCMI Clock (which is set by the image sensor with 62 Mhz).

How to use I2C GPIO expander's pin instead of RTS to control the RS485 direction, in Linux AUART kernel driver?

I'm creating an embedded system based on i.MX287 processor from NXP(Freescale). I'm using a core processing board which is connected to my evaluation board via a mini PCIe connector.
UARTs 0,3,4 are used as RS232 and UARTs 1,2 as RS485. The core board does not provide the RTS signals in its pinout, so I have to use pins from an I2C GPIO expander to control the RS485 direction. The GPIO expander module is also used for controlling some other devices on the board.
In user-space, I can control the direction pin using libi2c, but my client asked me to put the direction pin control in the UART driver.
Questions:
1- how can I interact with an i2c device inside the auart driver? (is it possible)
2- if it is possible, then how to prevent the i2c-0 bus from being blocked by the kernel? (I also need the userspace calls to the libi2c to work properly)
I googled a lot, but most cases are about how to use the I2C driver or how to activate GPIO pins in the sysfs, and I was able to do all of those.
The libi2c is for userspace so I cannot call it here. I also know that opening a file(/dev/i2c-0) in kernel and reading or writing to it is not a good idea. I am trying to understand what is the best way to handle this problem, without causing any concurrent access issues.
I would appreciate any ideas
P.S. - I don't have a deep understanding of how Linux kernel works, so sorry if my question is a little vague.
Edit 1:
based on #0andriy 's suggestion, I edited the DTS file and added the following to /arch/arm/boot/dts/my_dts_file.dts:
/dts-v1/;
#include "imx28.dtsi"
/ {
// some definitions
apbx#80040000 {
i2c0: i2c#80058000 {
pca8575: gpio#20 {
compatible = "nxp,pca8575";
reg = <0x20>; // PCA8575PW Address -0-0-0
gpio-controller;
#gpio-cells = <2>;
};
};
auart1: serial#8006c000 {
pinctrl-names = "default";
pinctrl-0 = <&auart1_2pins_a>;
linux,rs485-enabled-at-boot-time;
rs485-rts-delay = <0 0>; // in milliseconds
rts-gpios = <&pca8575 4 GPIO_ACTIVE_LOW>;
rs485-rts-active-low;
status = "okay";
};
auart2: serial#8006e000 {
pinctrl-names = "default";
pinctrl-0 = <&auart2_2pins_b>;
linux,rs485-enabled-at-boot-time;
rs485-rts-delay = <0 0>; // in milliseconds
rts-gpios = <&pca8575 5 GPIO_ACTIVE_LOW>;
rs485-rts-active-low;
status = "okay";
};
};
// some definitions
};
and then rebuilt the kernel. I also edited the mxs_auart_init_gpios function in the mxs-auart.c driver to print out the pin description of all the auart GPIOs at boot time. but gpiod = mctrl_gpio_to_gpiod(s->gpios, i) is always NULL.
the pca8575 GPIO controller is not added under /sys/class/gpio/
root# ls /sys/class/gpio
export gpiochip128 gpiochip64 unexport
gpiochip0 gpiochip32 gpiochip96
Edit 2:
auart1_2pins_a and auart2_2pins_b from the imx28.dtsi file :
auart2_2pins_b: auart2-2pins#1 {
reg = <1>;
fsl,pinmux-ids = <
MX28_PAD_AUART2_RX__AUART2_RX
MX28_PAD_AUART2_TX__AUART2_TX
>;
fsl,drive-strength = <MXS_DRIVE_4mA>;
fsl,voltage = <MXS_VOLTAGE_HIGH>;
fsl,pull-up = <MXS_PULL_DISABLE>;
};
auart1_2pins_a: auart1-2pins#0 {
reg = <0>;
fsl,pinmux-ids = <
MX28_PAD_AUART1_RX__AUART1_RX
MX28_PAD_AUART1_TX__AUART1_TX
>;
fsl,drive-strength = <MXS_DRIVE_4mA>;
fsl,voltage = <MXS_VOLTAGE_HIGH>;
fsl,pull-up = <MXS_PULL_DISABLE>;
};
I'm using kernel 4.14.13
the figure below demonstrates what I'm trying to achieve :
I'm not familiar at all with your board so take this answer with a pinch of salt, but I've noticed some funny things on your files.
First off, you need to define the I2C pin you want to use for toggling the direction inside the UART pinmux:
auart2_2pins_b: auart2-2pins#1 {
reg = <1>;
fsl,pinmux-ids = <
MX28_PAD_AUART2_RX__AUART2_RX
MX28_PAD_AUART2_TX__AUART2_TX
MX28_PAD_I2C0_SCL__I2C0_SCL
>;
fsl,drive-strength = <MXS_DRIVE_4mA>;
fsl,voltage = <MXS_VOLTAGE_HIGH>;
fsl,pull-up = <MXS_PULL_DISABLE>;
};
Make sure you double-check the pin name you want to use, I cannot be sure that is the right one.
Then, you seem to be missing the pinctrl for the I2C controller:
i2c0: i2c#80058000 {
pinctrl-names = "default";
pinctrl-0 = <&i2c0_pins_a>;
status = "okay";
pca8575: gpio#20 {
compatible = "nxp,pca8575";
reg = <0x20>; // PCA8575PW Address -0-0-0
gpio-controller;
#gpio-cells = <2>;
};
};
I could not confirm your reg and your pin numbers but I'm assuming you took it from your board's documentation. If you didn't, make sure you find a reliable source for your hardware.
Finally, I'm not sure why you want to have the RTS line active low, most transceivers have a DE/~RE input, which means you need to have the line active high to drive the bus. Maybe your driver is different...
What you are trying to do is documented to be working for other boards so I guess unless there is a bug you should be able to make it work.

linux gpio driver can't export GPIO

I want to use linux GPIO driver to handle one of the GPIO pins of mpc8308 processor as output. so I enabled the GPIO driver and it's debugging in:
Device Drivers ---> GPIO Support ---> /sys/class/gpio/... (sysfs interface)
but when using echo command to export GPIO21, it gives Invalid argument errno:
gpio_request: gpio-21 (sysfs) status -22
export_store: status -22
I used cat /sys/kernel/debug/gpio to see which GPIO pins are reserved by other drivers, but it shows nothing. so this pin is free.
I hacked the kernel for the place of error and found that in beginning of gpio_request function in gpiolib.c it crashes at last line in bellow:
int gpio_request(unsigned gpio, const char *label)
{
struct gpio_desc *desc;
struct gpio_chip *chip;
int status = -EINVAL;
unsigned long flags;
spin_lock_irqsave(&gpio_lock, flags);
if (!gpio_is_valid(gpio))
goto done;
desc = &gpio_desc[gpio];
chip = desc->chip;
if (chip == NULL)
goto done
gpio_desc[gpio] is an entry of an array in driver (static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];) that must be initialized by gpiochip_add function in driver. and this function must be called early as driver says:
/**
* gpiochip_add() - register a gpio_chip
* #chip: the chip to register, with chip->base initialized
* Context: potentially before irqs or kmalloc will work
*
* Returns a negative errno if the chip can't be registered, such as
* because the chip->base is invalid or already associated with a
* different chip. Otherwise it returns zero as a success code.
*
* When gpiochip_add() is called very early during boot, so that GPIOs
* can be freely used, the chip->dev device must be registered before
* the gpio framework's arch_initcall(). Otherwise sysfs initialization
* for GPIOs will fail rudely.
*
* If chip->base is negative, this requests dynamic assignment of
* a range of valid GPIOs.
*/
but gpiochip_add function never is called during boot.
Here is the .dts file:
gpio#c00 {
device_type = "gpio";
compatible = "fsl,mpc8315-gpio";
reg = <0xc00 0x100>; //reg = <0xc00 0x18>;
interrupt-parent = < &ipic >;
};
can anyone help me with this problem?
Edit:
I changed dts file to this:
gpio1: gpio-controller#c00 {
#gpio-cells = <2>;
compatible = "fsl,mpc8308-gpio", "fsl,mpc8349-gpio";
reg = <0xc00 0x100>;
interrupt-parent = <&ipic>;
interrupts = <74 0x8>;
gpio-controller;
interrupt-controller;
#interrupt-cells = <2>;
};
and now it shows gpiochip224 in /sys/class/gpio and this gpiochip has 32 GPIOs. but I don't know what is the mapping between 21 and 224-255?
can anyone tell me what is the relation between PIN numbers in datasheet and GPIO numbers in kernel for MPC8308 PowerPC series processor?I try all numbers 224-255 and none of them works.
You need to use GPIO controller base + GPIO.
If you have gpiochip451 and want gpio 21:
$ ls /sys/class/gpio
export gpiochip451# unexport
Then you need: echo 472 > export

STM32 odd timer1 behavior in Master-Slave Configuration - mb code issue

I'm currently working on an embedded system which is meant to output a specific pulse sequence at equidistant timings. Therefore, I use the STM32 - DISCO board with the FreeRTOS kernel, as a first test.
I configured TIM3 as Master triggering TIM1. TIM1 is triggered with a frequency of 1Hz or every second. TIM3 then generates a pulse sequence on it's output.
I configured the TIM3 output to PB4, and TIM1 to PA9. This configuration works as expected, but now I wanted to change the configuration on the fly with a structure that stores my settings and can be passed as pointer to a function that configures both timers.
As a first step, I generated a data structure and initialized it in my timer function to configure TIM3.
PG_ERR TIM_Master_Init(void){
PG_HandleTypeDef hPG_timer;
hPG_timer.PLS.Prescaler = 139;
hPG_timer.PLS.Period = 60000;
hPG_timer.PLS.DutyCycle = 30000;
hPG_timer.PLS.RepetitionCounter = 5;
hPG_timer.PLS.PercentChange = 0;
/* Timer3 handler declaration: Master */
TIM_HandleTypeDef TimMasterHandle;
/* Master configuration structure */
TIM_MasterConfigTypeDef sMasterConfig;
/* Output compare structure */
TIM_OC_InitTypeDef sOCConfig;
__TIM3_CLK_ENABLE();
PG_ERR xPGERR = PG_ERR_NONE;
/* Compute the prescaler value to have TIM3 counter clock equal to 60 KHz */
/* Set TIMx instance */
TimMasterHandle.Instance = MASTER_TIM;
/* Master configuration: TIM3 */
TimMasterHandle.Init.Period = 60000 - 1;
TimMasterHandle.Init.Prescaler = 1399;
TimMasterHandle.Init.ClockDivision = 0;
TimMasterHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
if (HAL_TIM_PWM_Init(&TimMasterHandle) != HAL_OK){
xPGERR = PG_ERR_TIM;
}
/* Configure the PWM_channel_1 */
sOCConfig.OCMode = TIM_OCMODE_PWM1;
sOCConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
sOCConfig.OCFastMode = TIM_OCFAST_ENABLE;
sOCConfig.Pulse = 30000;
if (HAL_TIM_PWM_ConfigChannel(&TimMasterHandle, &sOCConfig, TIM_CHANNEL_1) != HAL_OK){
xPGERR = PG_ERR_TIM;
}
/* Configure TIM3 as master & use the update event as Trigger Output (TRGO) */
sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1REF;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
if(HAL_TIMEx_MasterConfigSynchronization(&TimMasterHandle, &sMasterConfig) != HAL_OK){
xPGERR = PG_ERR_TIM;
}
/* Start PWM Timer3*/
if(HAL_TIM_PWM_Start(&TimMasterHandle, TIM_CHANNEL_1) != HAL_OK){
xPGERR = PG_ERR_TIM;
}
if(HAL_TIM_Base_Start_IT(&TimMasterHandle) != HAL_OK){
xPGERR = PG_ERR_TIM;
}
return xPGERR;
}
1) With this configuration i get some really odd behaviour. After including the data structure:
PG_HandleTypeDef hPG_timer;
hPG_timer.PLS.Prescaler = 139;
hPG_timer.PLS.Period = 60000;
hPG_timer.PLS.DutyCycle = 30000;
hPG_timer.PLS.RepetitionCounter = 5;
hPG_timer.PLS.PercentChange = 0;
After that code snipped, I don't get any output on PIN PB4 (Master - TIM3) which should still be toggled at 1Hz.
2) To get even more confusing, when I substitute the code block with a handle:
PG_HandleTypeDef hPG_timer;
PG_HandleTypeDef *hPG_timer;
hPG_timer = &hPG_timer_config;
hPG_timer.PLS.Prescaler = 139;
hPG_timer.PLS.Period = 60000;
hPG_timer.PLS.DutyCycle = 30000;
hPG_timer.PLS.RepetitionCounter = 5;
hPG_timer.PLS.PercentChange = 0;
Now I can see the output on PB4 (Master - TIM3) with 1Hz but the output polarity of PA9 (Slave - TIM1) is reversed.
I tried to investigate the problem, I focused on the stack/heap of the FreeRTOS. I tested the system with large heap/stack = (uint32_t) 65535; I couldn't observe any changes in the behaviour.
I hope somebody came across a similar problem or has an idea how to resolve this. I'm thankful for any input in this, I'm at the end of my knowledge unfortunately.
Edit:
I spend some more time with the problem, and I think I can be more specific. In case of the pointer use, the TimMasterHandle is locked right after the initialization. If I unlock the handle TimMasterHandle.lock = HAL_UNLOCK; all works well, but that is just masking the problem and i would like to know where this is coming from.
It some how looks still like an heap or stack problem. Is there any way, I can check for heap or stack overflow. I am using Keil uVision 5.10.
Thank you for your time and help,
eimer
So I contacted the E-Mail support of ST.
The rather simple answer I got was -
Initialize your timer handles e.g.:
PG_HandleTypeDef hPG_timer = {0};
Seems to resolve the odd behaviour.
I hope somebody finds this usefull.
enjoy your day
eimer

Resources