Notifications
Clear all

Setting Timer Interrupt Options (Registers?)

22 Posts
3 Users
5 Likes
982 Views
(@silverstar)
Member
Joined: 3 years ago
Posts: 18
Topic starter  

The timer interrupt expects data to be preset in two registers. I think of a register as an 8-bit special memory location although its really 8 flip-flops. I understand how to to set the timer compare match but I am having trouble understanding the prescaler setting. Timer 1 TCCR1B is established  with the following:

TCCR1B |= (1 << CS12);

Bitwise operations would have be believe that this will OR a "1" (on) in position CS12. I am reading this as

a "1" is shifted left to match the CS12 position which would look like a "100" binary. Am I understanding this correctly? If i wanted the prescaler to be 1024 would I do

       TCCR1B |= (101 << CS12);

                 OR

       TCCR1B |= (1<< CS12);

       TCCR1B |= (1<< CS10);

Thanks for your help.


   
Quote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 7001
 

@silverstar 1024 dec is 1<<10. 

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
(@davee)
Member
Joined: 3 years ago
Posts: 1694
 

Hi @silverstar,

   Sorry, I my have an error in this, as I haven't played with this register in Arduino, but as a first try:

I would aim to zero out (using AND function) the three bits setting the prescalar, leaving the the top 5 bits of the register unchanged, then OR  in the three bits I want, to the bottom three bits, which at first glance is 101 in binary as you mention. (This should guarantee, it doesn't matter what the three bottom bits were set to before.)

Something like:

TCCR1B   &=   248;    // I think that is 1111 1000 in decimal?

TCCR1B   |=   5;    // I think that is 101 in decimal?

I think there are ways of specifying binary, as per my reference below,  in C++, but I am not sure, because it failed when I tried it on a an online C++ compiler, so I have stuck to decimal.

This link might help: https://electronoobs.com/eng_arduino_tut140.php

I would guess you copy the contents of the register into a variable and print ... possibly as a 'before' and 'after' changes, to see if the AND and OR do the right thing. Again, I am assuming the register can be read back, which I haven't checked.

Good luck, sorry this is untested and it is a long time since I last went down this path.

Best wishes, Dave

 


   
ReplyQuote
(@davee)
Member
Joined: 3 years ago
Posts: 1694
 

Hi @silverstar,

  As a late addition. I think this version using binary should also compile .. rest of logic unchanged.

TCCR1B &= 0B11111000;  // I think that in decimal 248  =  1111 1000

TCCR1B |= 0B0101; // I think 5 in decimal is 101

 

Also note: This combination of AND followed by OR, is the classic general approach for updating 1 or more bits in a register.

However, if interrupts are enabled when running this pair of instructions, some thought should be given to check that an interrupt occurring between the two statements cannot give a problem. (In most cases, it won't.) In some cases, it might be advisable to disable interrupts just before the first statement and re-enable them immediately after the second.

 

Best wishes, Dave


   
Ron reacted
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 7001
 

@davee @silverstar How come the OP mentioned 1024? If he only has the 3 low order bits to manipulate, then the largest value is 7 and the largest shift of a single but is 2. Once again I am confused and/or missing something. BTW, am I the only one who does not know what CS10 and CS12 stand for?

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
(@davee)
Member
Joined: 3 years ago
Posts: 1694
 

Hi Ron @zander,

   I Google'd  CS10, etc .., having guessed they were probably related to some register bits in an Arduino microcontroller.

Hence, this link which I included: https://electronoobs.com/eng_arduino_tut140.php

which includes:

image

As I said, I haven't tried this out, nor am I familiar with this particular part of the microcontroller.

However, I think I can make a reasonable guess as to what's happening, and gave a 'standard approach' answer, which I think is worth a try, albeit with a warning that something unexpected might pop up.

Best wishes and take care my friend, Dave


   
Ron reacted
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 7001
 

@davee  @silverstar Ah, now I get it. I sure wouldn't code it that way. Very misleading.

If I wanted to set a prescalar of 1024 then I would OR 0b00000101 with TCCR1B.

As @davee said, in some cases when using  this kind of code you may or may not want to zero the target bit positions first so an AND mask that omits those positions you wish to OR is how that is done.

As @dave has shown you, the TWO lines of code that are often used are 

TCCR1B &= 0b11111000;   // set low order 3 bits to 0

TCCR1B |= 0b00000101;   // set low order 3 bits to the value that selects a divisor of 1024

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 7001
 

@davee I can't remember if you need to totally disable interrupts, or just enclose the two lines of code in a critical section macro. 

I do NOT know for sure in this case but in my experience if you completely disable interrupts you can miss an interrupt but if you use a critical section, the interrupt remains pending and will happen immediately after the critical section completes subject of course to any interrupt prioritization.

I am getting stronger, but I am still too weak to dig out the details and I can't find my copy of the ESP32 documentation but I am fairly certain of my comments.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
(@silverstar)
Member
Joined: 3 years ago
Posts: 18
Topic starter  

@davee Hi Dave,

Many thanks for your response. I will try TCCR1B |= 0b00000101; // set low order 3 bits to the value that selects a divisor of 1024. I should have mentioned that the first thing i did was to stop interrupts and clear TCCR1B to zeros.

Fred


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 7001
 

@silverstar Do you know if 'stopping interrupts' will pend them so they will eventually be handled, or is it something else. BTW, how did you do that.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
(@davee)
Member
Joined: 3 years ago
Posts: 1694
 

Hi Ron @zander,

   As I acknowledged, I am not generally familiar with the deeper secrets of the system, so it is quite possible that a 'weird' problem will arise.

I don't know the general scheme of  the software .. e.g. Is this register set up once near the start of the programme or is it continually modified?

If it is only set up once, then I guess it will probably be fine, but if it is continually happening, then the chance of a  'collision' becomes more plausible.

I presume the application is only for a hobby project, and not safety critical, etc., so I think the simple code I suggested is worth a try and hopefully allows @silverstar to move forward .

Best wishes all, Dave


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 7001
 

@davee We don't know so best to be on the safe side. Since he said he disabled interrupts, I must assume there is some criticality to the project. Also, since it only requires 2 additional lines of code it's no big deal. I am attaching the relevant parts of the documentation and a link to the page.

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos_idf.html#critical-sections

Also remember to store the critical code in high speed ram. For esp32 it's IRAM_ATTR added to the function declaration as in void IRAM_ATTR myFuncToSetScalar(){ stuff }

Screenshot 2023 07 30 at 14.17.11
Screenshot 2023 07 30 at 14.21.17

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
(@silverstar)
Member
Joined: 3 years ago
Posts: 18
Topic starter  

@davee This application is a learning project to become more familiar with interrupts and how they work. I have mainframe interrupt experience so I understand the concept. I agree that with the suggestion to change gow I set the various bits. I issue a Nointerrupts ()when I set up the registers and issue an Interrupts(); when I think I am ready > i have no idea what goes on during the period that I stop interrupts. I am thinking that really nothing happens: counters are not adjusted or tested. When interrupts resume,I assume it picks up where it left off. A guess. Give me a little time to test it a little.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 7001
 

@silverstar I used to be an IBM Software field service rep and at one time was very familiar with hardware (also trained in hardware) and software interrupts.

Perhaps you did not see the following clip form the Arduino manual. Turning off interrupts is for ALL, not just your code so background tasks will also be affected. Maybe use CRITICAL_SECTION macros instead?

Screenshot 2023 07 30 at 18.56.17

 

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 3 years ago
Posts: 7001
 

@silverstar I should have asked first, what board are you using?

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
Sure you can learn to be a programmer, it will take the same amount of time for me to learn to be a Doctor.


   
ReplyQuote
Page 1 / 2