#avr Logs

Aug 11 2020

#avr Calendar

02:56 PM Smashcat: Can anyone see what I'm doing wrong here? Changed some working code from timer1 to timer0, and now it's just ticking at 125hz instead of 250hz: https://pastebin.com/2SKkADA9
03:02 PM Smashcat: Seems like the timer count register OCROA isn't used at all by timer0.
03:03 PM Smashcat: s/2 PORTS/2 SPI ports/
03:04 PM LeoNerd: Ahyes, if you need two UARTs there aren't many chips in that category :/
03:05 PM LeoNerd: Why two SPI ports though? That's one thing I've never really needed
03:05 PM LeoNerd: Two I²Cs I can just about imagine, if you need both 100kHz and 400kHz chips and you want the faster ones to be fast as possible
03:06 PM Smashcat: LeoNerd: I'm both sending and receiving SPI data, and it's just easier to use the 2 SPI ports to maximise through-put
03:06 PM LeoNerd: Ah
03:07 PM Smashcat: (this device is part of a daisy-chained setup, where each device receives SPI data, and after buffering the first x bytes, it passes the rest on to the next device)
03:07 PM LeoNerd: Mmm I see.. yeah, for that sort of full-duplex I guess you would need both
03:09 PM Smashcat: Yeah makes it easy, as after it gets its data, it just uses an interrupt to bang the data from the input SPI buffer into the output buffer in the background while processing its buffer :)
03:10 PM LeoNerd: I use the 328PB on my "isolated application board" product.. having two SPI ports makes it easy to put one locally and one on the digital isolator,..
03:11 PM LeoNerd: Plus same for I²C controllers
03:18 PM Smashcat: Cool yeah. I've been doing some work with DMX recently, lots of isolation needed on stage equipment - especially when different sockets are on different generators :)
03:21 PM LeoNerd: Mmyeah DMX is fun. I use these for that now -- https://www.tindie.com/products/leonerd/rs-485-isolated-application-board/
03:21 PM LeoNerd: I wrote up a little DMX offload firmware,.. so it acts as an SPI slave chip
03:38 PM Smashcat: Cool. I'm making a product that runs DMX animations, also plays audio, (the DMX channels can animate using a timeline, or some channels can be linked to audio bandwidths, so can react to the sound), with built in 20W x 2 amplifier on the PCB, and GPIO, along with ArtNet, web interface and Bluetooth for a little over double that price - :) It's using the ESP32, so the DMX output, and audio output to the i2c DAC is all
03:38 PM Smashcat: DMA driven. Also making a DMX display tool - it shows the DMX channels on a screen, in various ways (grid, graphs etc), and can record DMX sessions, and replay them.
03:39 PM Smashcat: This is mostly for the event/charity industry - which is mostly what I work on, but I wanted to productise something for a change as so many people ask me for similar things - hehe!
03:39 PM LeoNerd: Mmm nice
03:44 PM cehteh: Smashcat: resetting tcnt manually sounds wrong
03:51 PM Smashcat: cehteh: Yep it's CTC mode, but doesn't auto-reset it. Resetting in the interrupt works though, so meh :)
03:52 PM cehteh: Smashcat: iirc it should reset as well
03:52 PM Smashcat: Timer1 does, but not Timer0. I can't use Timer1 though, as I'm using that for PWM output on dedicated pins on the PCB.
03:53 PM cehteh: mhm i am using timero in normal mode, that resets at least
03:54 PM cehteh: moment CTC stands for Clear Timer on Compare Match (CTC) Mode
03:54 PM cehteh: that *must* clear :D
03:54 PM cehteh: but note that timer0 is 8 bit only, do you have some weird overflow/size mismatch?
03:55 PM Smashcat: The int fires when TCNT0==OCR0A but then TCNT just continues until it wraps around again. So doesn't get cleared :)
03:55 PM Smashcat: In my case OCR0A is set to 125, so shouldn't be an overflow
03:56 PM cehteh: it should lear, but check iirc you need to configure if its OCR0A or OCR0B
03:56 PM cehteh: possibly you have it set for ocr0b
03:57 PM Smashcat: Just checked, OCR0B does the same. It fires but doesn't reset the counter
03:57 PM * cehteh would need to re-read the docs
03:58 PM cehteh: i am pretty sure it should reset, there must be some bug
03:58 PM Smashcat: cehteh: Yeah I tried lots of things, but ended up just resetting the counter in the interrupt in the end and it worked, so kind of left it :)
03:59 PM cehteh: sounds very wrong, because interrupt may be delays, timer still spinning, you get inprecise timing
03:59 PM cehteh: i am almost sure there is a bug on your side and it should/must reset
04:00 PM Smashcat: cehteh: It doesn't matter too much for this, it's just controlling an animation, which isn't synced to anything
04:00 PM cehteh: still i hate such things .. working just by chance but maybe sometime later, maybe when you reuse the code for another project it bites you
04:01 PM cehteh: and of course when it doesnt work as it should it means there is some bug you overseen
04:03 PM Smashcat: cehteh: Yeah, maybe something overlooked, but it's no big deal at the moment - it's working well within the accuracy I need, and is stable enough. It's on a /256 prescaler, so pretty slow really :)
04:03 PM cehteh: in some modes OCR0A is latched btw
04:03 PM Smashcat: The 2 clock cycles to reset it are within a "tick" :)
04:04 PM cehteh: huh?
04:04 PM Smashcat: It's a /256 prescaler, so it only ticks every 256 clock cycles. The command to reset the counter in the interrupt takes much less than that :)
04:05 PM cehteh: the interrupt can be delay whatever time other parts block interrupts or higher pri ISR's are running, plus 6 clock cycles interrupt latency generally plus the register save/restore overhead and anything else unless you use a naked isr
04:06 PM cehteh: usually it should be 'in time'
04:09 PM cehteh: bzw setting the prescaler starts the timer, you should enable the isr first, not that it matters here
04:10 PM Smashcat: I disable interrupts until everything is setup here. As you say that really makes no difference though.
04:12 PM cehteh: but you already start the timer there
04:12 PM cehteh: usually starting it should be the last action after setting everything up including enabling its interrupts
04:12 PM Smashcat: Yeah I set everything up, then enable interrupts, then it all starts as normal.
04:13 PM cehteh: yeah i am talking about the last 2 lines you pasted
04:14 PM cehteh: do you stop and restart the timer sometimes or is that once only initialization?
04:14 PM Smashcat: It's only set up once at boot.
04:15 PM Smashcat: Should note that the bit about 16 bit timers was left in accidentally, as I was using timer1
04:15 PM Smashcat: (in the comments)
04:15 PM cehteh: ok otherwise usually one clear the pending interupt flag firstm but not necessary then, still starting the timer should be done after enabling interrupts, its just by chance that it doesnt do harm here becase your timer is so slow, but reversing the order of those 2 lines wont hurt either
04:18 PM Smashcat: Yep, changed it around, so sei() is before those lines, makes no difference - it just seems that timer0 doesn't clear that timer. This is an ATMega328PB by the way. I have noticed a bug with the PORTE on these chips too...
04:18 PM cehteh: ah lol i see your bug :D
04:18 PM Smashcat: Really? What's up with it? :)
04:18 PM cehteh: you set wgm mode 4 which is undefined/reserved CTC is wgm mode 2
04:19 PM Smashcat: I am setting mode 2, aren't i?
04:19 PM cehteh: TCCR0A |= (1<<WGM01);
04:20 PM cehteh: dont touch WGM02 in TCCR2
04:20 PM cehteh: dont touch WGM02 in TCCR0B
04:20 PM Smashcat: Ahhh! Thanks! Yeah I don't need to clear it now.
04:21 PM cehteh: see .. such bugs are always somewhat fishy, one should put some effort into fixing them because otherwise something strange may happen eventually
04:21 PM Smashcat: That was weird, as setting TCCR0B seemed to be working.
04:22 PM cehteh: its just something undefined/reserved. initialized the timer in some undocumented way done strange things
04:27 PM Smashcat: Interesting, checking another project here, and I was initialising Timer1 CTC mode using TCCR1B |= (1 << WGM12); and that did actually work :)
04:28 PM cehteh: lolwhat?
04:28 PM cehteh: must be TCCR0A
04:28 PM cehteh: err completely messed up
04:28 PM cehteh: C and type safety
04:28 PM Smashcat: No, just checked an I never set TCCR0A.
04:29 PM cehteh: yes but WGM01 you need to set is in TCCR0A not in TCCR0B
04:30 PM cehteh: there is not type safety in these defines
04:31 PM cehteh: thats really a bit ugly
04:32 PM cehteh: would be nice to have something like TC0WGM = 2; or some macro magic that makes this typesafe
04:33 PM Smashcat: Yeah
04:33 PM cehteh: i made such errros before as well :)
04:33 PM Smashcat: :)
11:30 PM day_ is now known as day