Skip to main content
Eugenia Suarez
Associate III
April 25, 2017
Solved

Accessing HAL TIM struct fields pointers inside other structs correctly.

  • April 25, 2017
  • 4 replies
  • 3433 views
Posted on April 25, 2017 at 12:21

I have the following structs (from a library I'm using) with some fields and I would like to assign with OR operation a new value. But I'm debugging and I can't see how anything is writing there:

typedef struct { 
TIM_TypeDef *Instance; /*!< Register base address */ 
TIM_Base_InitTypeDef Init; /*!< TIM Time Base required parameters */ 
HAL_TIM_ActiveChannel Channel; /*!< Active channel */ 
DMA_HandleTypeDef *hdma[7]; /*!< DMA Handlers array This array is accessed by a @ref DMA_Handle_index */
HAL_LockTypeDef Lock; /*!< Locking object */ 
__IO HAL_TIM_StateTypeDef State; /*!< TIM operation state */
}TIM_HandleTypeDef; 
typedef struct
{ 
__IO uint32_t CR1; /*!< TIM control register 1, Address offset: 0x00 */
__IO uint32_t CR2; /*!< TIM control register 2, Address offset: 0x04 */
__IO uint32_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */ 
__IO uint32_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */ 
__IO uint32_t SR; /*!< TIM status register, Address offset: 0x10 */ 
__IO uint32_t EGR; /*!< TIM event generation register, Address offset: 0x14 */ 
__IO uint32_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */ 
__IO uint32_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */ 
__IO uint32_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */ 
__IO uint32_t CNT; /*!< TIM counter register, 
 ... 
} TIM_TypeDef;

I have a part of code where I defined:

 TIM_HandleTypeDef TIMER_Struct;

And I would like to access the field 'CR1' of TIM_TypeDef struct that is '*Instance' field of TIM_HandleTypeDef. So I have done it by this way in a function:

 void DRV_TIMER_init(void) 
{ 
... 
TIMER_Struct.Instance = TIMx;//TIM7
TIMER_Struct.Init.Period = 100 - 1; 
TIMER_Struct.Init.Prescaler = uwPrescalerValue; 
TIMER_Struct.Init.ClockDivision = 0; // these accesses work 
TIMER_Struct.Instance -> CR1 |= 0x01 << 3; // this no works 
... 
}

Even if I write directly:

 TIMER_Struct.Instance -> CR1 = 0xFFFFFFFF; 

It stills without having effect.

I think It could be a fact that I'm not controlling appropiately the pointer access or similar. But I don't see how can I access and modify the content of the commented field. Since I can see (debug mode) how the rest of struct fields updates are writen correctly.

Any correction suggested here?

TIMER_Struct.Instance -> CR1 = 0xFFFFFFFF; 

I try different ways to get it with no success. I need new ideas. How would you do if you want write there?

Thanks in advance.

#pointers #hal-tim-structs
This topic has been closed for replies.
Best answer by waclawek.jan
Posted on April 25, 2017 at 17:58

TIMER_Struct.Instance -> CR1 |= 0x01 << 3; // this no works 


How do you know that 'this no works'?

Has that timers' clock been enabled in its respective RCC_APBxENR?

JW

4 replies

waclawek.jan
waclawek.janBest answer
Super User
April 25, 2017
Posted on April 25, 2017 at 17:58

TIMER_Struct.Instance -> CR1 |= 0x01 << 3; // this no works 


How do you know that 'this no works'?

Has that timers' clock been enabled in its respective RCC_APBxENR?

JW

Eugenia Suarez
Associate III
April 26, 2017
Posted on April 26, 2017 at 09:58

Jan, thanks for your attention. Timer runs, hence, the only thing I can't get and it's so weird is: writing CR1 register (config register) before initialize the peripheral with HAL_xxx_init(). And I can't update this MCU register, obviously due I'm not able to update my desired value in the 

TIMER_Struct struct I have declared.

How can I see this: I'm debugging and watching TIMER_struct fields after passing write CR1 lines; it has no effect. Timer runs, but now I would like to see how my timer works with some config changes, but I can't change config values coding. That's the question.

I hope you understood me. 

waclawek.jan
Super User
April 26, 2017
Posted on April 26, 2017 at 10:17

How can I see this: I'm debugging and watching TIMER_struct fields after passing write CR1 lines; it has no effect.

In that very same moment, in the debugger, have a look at the relevant RCC_APBxENR register. Is the relevant TIMxEN bit set?

JW

Max
ST Employee
April 26, 2017
Posted on April 26, 2017 at 04:49

Hello,

When you are having troubles with a peripheral hardware register, you should first read its description in the reference manual of the product you are using.

Hardware registers often have constraints due to their specific implementations.

Also check for examples of this register usage in the library, it will show you how to properly access the register when there are constraints (like for reserved bits, data width constraints, handling of r_w0/

r_w

1, access order constraints ...) 

BR,

Max

Eugenia Suarez
Associate III
April 26, 2017
Posted on April 26, 2017 at 10:09

Hi Max I haven't problems exactly with the 'real' registers, so I have problems with struct pointers fields structs accesses. They don't update what I'm writing on.

These structs are provided by st libraries. I guess more people has used them and set config bits more than once.

The fact is that I have read every Tim7 register and other datasheet parts related with this basic timer. URS bit is read/write bit at CR1. However, it doesn't matter, because this register will be updated after a first steep that is: inizialize your struct and then a second: passed it to a function call HAL_xxx_init(). If my struct doesn't have the values I want at desired fields (one of them is call CR1), obviously the real or physical CR1 will not be writen with them. 

Before

HAL_xxx_init()

, when I was debugging I can see how CR1 field of the struct has not experienced any effect. 

regards.

Max
ST Employee
April 26, 2017
Posted on April 26, 2017 at 10:18

the 

TIMER_Struct

.

Instance 

is a pointer to the hardware register, so you are indeed accessing the timer peripheral registers with the code above.

And there are restrictions on this specific register usage.

Eugenia Suarez
Associate III
April 26, 2017
Posted on April 26, 2017 at 10:37

Thanks for your attention, Max. Where can I find them? I was readig at tim chapter. At register description there is nothing about restrictions on URS bit. I'm not accessing reserved bits.

Cr1 has 16 bits, and CR1 field in the struct has a 32b type. Even I also tried with cast the value to uint_32b due manual said at TIM6/TIM7 register chapter: '

peripheral registers can be written by half-words (16 bits) or words (32 bits)'.

But, no effect. 

David.Yves
Associate
April 27, 2017
Posted on April 27, 2017 at 12:27

I think there is precedence involved:

your instruction could be    TIMx->CR1 =(TIMx-> CR1 |  0x1) <<3;

or it could be                      TIMx->CR1 =TIMx-> CR1 |  (0x1 <<3);

I believe you want the latter one  and since 1<<3 is 8

try this      TIMx->CR1 |=8;       in your case   

Instance

->

CR1

|=

8

;

if this works  let me know

if not sorry for wasting your time

Yves

Eugenia Suarez
Associate III
April 27, 2017
Posted on April 27, 2017 at 15:13

Hi David, Yes second one. I think you are all right and your idea is more exact than the first one. When you have a register with a concret value and you don't want modify the rest of bits except one, the best solution is your second one. The first one only will be correct if I have all 0x00. If not I will be shifting the rest of bits and I don't want this. 

Am I wrong?