lgt8fx icon indicating copy to clipboard operation
lgt8fx copied to clipboard

Counter TCNT3 of Timer3 is not defined

Open dbuezas opened this issue 5 years ago • 12 comments

The core has the low and high bytes declared, but not the 16 bit uint, which e.g. the Timer1 counterpart has (TCNT1)

#define TCNT3L	_SFR_MEM8(0x94)
#define TCNT3H	_SFR_MEM8(0x95)

Defining it as #define TCNT3 _SFR_MEM16(0x94) works fine for me. Anything I'm missing?

dbuezas avatar Oct 11 '20 16:10 dbuezas

ADT0 - Auto-monitoring underflow threshold register pair #define ADT0 _SFR_MEM16(0xA5)

ADT1 - Auto-monitoring overflow threshold register pair #define ADT1 _SFR_MEM16(0xAA)

OCR3C - TC3 output compare register C ( defined, but not with _SFR_MEM16 ) #define OCR3C _SFR_MEM16(0x9E)

DTR3 - TC3 dead time register #define DTR3 _SFR_MEM16(0x9C)

DTR3 - TC3 dead time register low and high defined as wrong. Better definiton is: #define DTR3L _SFR_MEM8(0x9C) #define DTR3H _SFR_MEM8(0x9D)

OCR3B - TC3 output compare register B ( defined, but not with _SFR_MEM16 ) #define OCR3B _SFR_MEM16(0x9A)

OCR3A - TC3 output compare register A ( defined, but not with _SFR_MEM16 ) #define OCR3A _SFR_MEM16(0x98)

ICR3 - TC3 capture register #define ICR3 _SFR_MEM16(0x96)

DTR1 - TC1 dead time register #define DTR1 _SFR_MEM16(0x8C)

DTR1 register is present in LGT8F328D too, so file lgtx8e.h must be edited.

LaZsolt avatar Oct 12 '20 20:10 LaZsolt

OCR3A - TC3 output compare register A ( defined, but not with _SFR_MEM16 ) #define OCR3A _SFR_MEM16(0x98)

Now it finally makes sense! This was driving me crazy, that I couldn't count beyond 255 in CTC mode using OCR3A as TOP. It is defined as a char currently.

dbuezas avatar Oct 14 '20 13:10 dbuezas

I found an issue. Weird but true. When accesssing a 16-bit register and an interrupt occured between reading low and high bytes and interrupt routine is accessing another 16-bit register, then high byte lock will be cleared. eg. a timer interrupt occured in the middle of ADCread. So recommended to disable interrupt while accessing 16-bit registers.

LaZsolt avatar Oct 27 '20 20:10 LaZsolt

@LaZsolt - while reading documentation of Timer3 I saw that writing/reading a register may require specific order. E.g. "If write to 16-bit TCNT3, must write TCNT3H firstly. If read 16-bit TCNT3, must read TCNT3L first." Perhaps that's linked to your issue?

Something else - Just in case you ever want to support analogWrite for PWM using Timer 3: While adding Timer3 support to my FastPwmPin library I had some troubles getting the pin output working on my QFP32 board. After days of reading documentation, much trying and testing I finally found it. If you want to use any PORTF pin for output, you first need to disable the shared pin on the other port. So for OC3B to work on pin PD2, DDRD:2 needs to be set low (input) and DDRF:2 needs to be set high (output).

maxint-rd avatar Jan 12 '21 20:01 maxint-rd

@maxint-rd All 16-bit register read or write operations using the same temporary register for the high byte lock. So care must be taken that there will be no other 16-bit read or write operation in an interrupt, or interrupt must be disabled at a 16-bit register access. A 16-bit register read or write require a specific order, but C++ compiler for AVR MCUs will handle this order. uint16_t tc3result = TCNT3; But in the actual release of LGT8Fx package has no appropriate definition of TCNT3 or any LGT specific 16-bit register. You need to correct your copy of lgtx8p.h file.

LaZsolt avatar Jan 12 '21 21:01 LaZsolt

@LaZsolt - thank you for the swift reply. Good to know how to deal with 16-bit registers in an interrupt.

I already fixed my copy of the .h file after your comment in another issue's thread. Thanks. Although it did get me to compile my code and have Timer3 running, at first the pin output wouldn't budge. Only after reading somewhere that OC3B was actually on PF2 instead of PD2, I found out I had to first disable PD2 and set PF2 as output to get my fast PWM output to work on pin 2. So I have it working now! (hooray). BTW: While testing fast PWM on pin 1 (PF1), I also managed to temporarily brick my QFP32 board! Apparently the Holtec USB chip didn't like having 4MHz generated on TX. Fortunately a small cap between pin 1 and 3v3 helped to make the USB recognizable again so then I could flash it...

maxint-rd avatar Jan 12 '21 21:01 maxint-rd

I'm glad I was able to help. Anyway, not easy to handle the LGT's unusual pin sharing. I'm using SPI ethernet module in my project, and it wasn't easy to find out how it is work in the SSOP20 chip.

LaZsolt avatar Jan 12 '21 21:01 LaZsolt

Just faced another "quirk". The OCRnx registers (e.g OCR3A) can only be set to a value > 255 AFTER configuring the WGM bits. Otherwise the high bit is blocked to zero. I guess This is not different in atmega328p but it took me a while to find out why my timings were out of whack

dbuezas avatar May 23 '21 15:05 dbuezas

The OCRnx registers (e.g OCR3A) can only be set to a value > 255 AFTER configuring the WGM bits.

I think it's not an error, but in the databook wasn't mentioned this kind of behaviour. If OCRnA or OCRnB was written before setting of WGM bits, then the OCRn high byte may be cleared during writing of WGM bits.

In my undertanding the reason is maybe that the WGM bits 2 and 3 are not in the same register than bits 0 and 1. Between writing TCCRnA and TCCRnB maybe there a short time when WGM bits sets the fast PWM 8-bit mode which means the upper bytes of OCRnx registers will be cleared.

kép

LaZsolt avatar May 24 '21 18:05 LaZsolt

but in the databook wasn't mentioned this kind of behaviour.

Still, the manual writes something: "Note that when using fixed TOP values the unused bits are masked to zero when any of the OCR1x registers are written."

LaZsolt avatar May 24 '21 18:05 LaZsolt

Oh wow! I didn't see that! What is that datasheet you use? I'm still using the orange one with the broken english.

By the way, I noticed 2 differences between lgt328p and atmega328p timers:

  1. In timer1, FPWM, toggle on compare match is only allowed with WGM1=15 (atmega allows it also with WGM1=14)
  2. In all timers, with FPWM, if COMnX is set to do set or clear, LGT "resets" at MAX, whereas ATM resets at BOTTOM (according to the datasheets).

I'm making a tool to configure and visualise timers so I guess I'll put that to the test soon (I want it to match reality after all hehe)

dbuezas avatar May 24 '21 21:05 dbuezas

What is that datasheet you use?

The quoted text from "ATmega328_P AVR MCU with picoPower Technology Data Sheet"

LaZsolt avatar May 24 '21 21:05 LaZsolt

This issue can be closed and still serve as a reference for others later.

dwillmore avatar Jan 12 '23 19:01 dwillmore

Hello to all friends I'm having trouble reading tcnt3 on the atmega64 micro and it's not giving me the correct value We did all the codes that could be used, but the main problem is that it finds the value of TCNT3L, but the value of TCNT3H gives zero. Examples of the codes I wrote For example this code uint16_t timer3_value = (TCNT3H << 8) | TCNT3L;​ T3=TCNT3; TCNT3 =0; Or tcnt3 = (T3H*256)+T3L; T3=TCNT3; TCNT3 =0; Or T3= TCNT3H 8>>T3; TCNT3 =t3+TCNT3L When you come to zero TCNT3 or TCNT3H and TCNT3L, it's as if the low value is read and the high value is 0. When you change the frequency, it only shows the correct value of TCNT3L

Novin000 avatar Jan 26 '24 19:01 Novin000

You probably have the timer configured so that the top value is 255. The tool doesn't specifically support the atmega64, but this may help you figure out where the problem may lie: https://dbuezas.github.io/arduino-web-timers/#mcu=LGT8F328P&timer=3&topValue=0x00FF&CompareOutputModeA=clear-on-match%2C+set-at-max&OCR3A=85

dbuezas avatar Jan 26 '24 20:01 dbuezas

Thanks mate, I'll check it out Of course, I work with Codevision

Novin000 avatar Jan 27 '24 16:01 Novin000