#Noe's Thread
1 messages · Page 1 of 1 (latest)
What an absolute headache
Do you know what crystal I should use at 3.3V?
Also I'd be interested to see where you saw that on the datasheet @rigid fractal
Noe's Thread
"29.4 Clock Characteristics"
a one-time calibration procedure is described at https://ww1.microchip.com/downloads/en/appnotes/atmel-2555-internal-rc-oscillator-calibration-for-tinyavr-and-megaavr-devices_applicationnote_avr053.pdf
Ah yeah, I was reading that
there is a more involved calibration with temperature corrections at https://www.microchip.com/content/dam/mchp/documents/OTH/ApplicationNotes/ApplicationNotes/doc8384.pdf which is meant for the 32U4, but could probably also work on the 328P (the 328P also has an on-chip thermometer readable via ADC)
I realize this implies an Atmel-ICE just comes with a calibration utility
yeah, some of the Atmel-branded programmers have oscillator calibration support
I might just do that and run at something like 300 baud rate
Since I transfer such little data at a time, I really don't need speed
it's also possible to use a watch crystal to calibrate the RC oscillator. that might be suitable for occasional live recalibration in a lower-power application, especially if you shut down the watch crystal when not doing calibration https://ww1.microchip.com/downloads/en/Appnotes/doc8002.pdf
Yeah I don't wanna interrupt the other guy asking for help
I just have no idea what to do here
I got my hands on this 10 MHz clock but the fuses are just killing my brain @rigid fractal
I can't interpret what's going on in this datasheet
first of all, what kind of clock is it?
when you say you might have bricked the chip, what exactly happened?
So I have more chips, I can bail it if I need to, but
I was modifying the options with my Atmel-ICE, and it just has a drop-down of all the possibilities
I chose one which looked right, but totally forgot to record what I'd done so I could find a way to reverse it if it was a mistake maybe
It's just this
I chose an option, but forgot to record my changes, and now I can't communicate with that chip
I think I chose something like ext low-freq crystal, and I know it said +65 ms at the end too
But right now, I just have no idea what the differences between these options are
Datasheet is not helping explain
so you can't communicate with the chip at all? via ISP?
Yeah it fails to enter programming mode
Can't read the signature or anything, it's gone
if you had written down the hex values, that would help a lot in troubleshooting
you're pretty sure your selection included "ext" and "low-freq crystal"?
Yes
And +65 ms at the end
But I have no idea what the 1K CK, 32K CK, 14 CK stuff means
oscillator cycles, i think. it gives it time to stabilize the oscillation
oscillators take time to start up and become stable
"low-freq" typically means a 32.768kHz watch crystal, so the electrical configuration will be way off for a 10MHz crystal
you don't have to use "full-swing"; i think there's an option for low-power crystal that isn't low-frequency
Page 26
Ah
On page 27, I think I'd like "Crystal oscillator, slowly rising power"
so i think you can apply an external clock at approximately the expected frequency to XTAL1, and you'll be able to talk ISP to the chip (slowed down to 1/4 the actual clock speed)
Why just XTAL1?
I'm gonna be honest with you, I actually have no idea how crystal oscillators work as discrete components, and I don't know what XTAL1 and XTAL2 each mean independently
because XTAL1 is the input, and XTAL2 is the output, of an inverting amplifier configured as an oscillator, according to the datasheet
yeah, the oscillator might not start up properly for a crystal that's almost 1000 times as fast as what it's configured for
I honestly don't have a problem letting that chip go
For now, anyway. I want to see this configured properly, then maybe I'll think of saving him later
But I have more chips
I just have to be careful...
yeah. you might be able to recover this chip eventually, but it might not be worth the trouble, depending on your priorities
So what I'm seeing here is this
It looks promising
So I need to have CKSEL3..1 set for a low-power crystal, right?
And then configure CKSEL0 and SUT1..0 for that option
i think so? make sure you're configured for the correct frequency range, or it might not start up
Because to me it seems page 27 figure 8-4 is describing the sub-options when CKSEL3..1 are set for low-power oscillator?
Right
yeah
What really is the difference between low-power and full-swing
Oh, I guess it's better for "noisy environments" (I do not know what that means)
environments that are noisy enough to disrupt the oscillator or clock subsystem, i guess. also, it'll consume more power
What's "rail-to-rail swing on the XTAL2 output"
i assume it means that the oscillator's inverter swings all the way from ground to positive supply voltage
Ah okay
i guess if you wanted to see for yourself, try both options and hook up a scope to XTAL2 (assuming that its probe doesn't disrupt the oscillator in the low-power mode!)
picture here so I can look back in a second
Hmmm
How does 0xFF look?
I think I want 0xFF
No CKDIV8, no CKOUT, CKSEL3..1 = 111 for 8-16 MHz, and this option set for "crystal oscillator, slowly rising power"
It's 0b11111111
It didn't brick!!!
I think I got it!
yay
note you linked the automotive datasheet. i think the regular datasheet is https://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061B.pdf
Yes I know
The automative sheet has this info, the regular one I found did not
Maybe I'd found a summary sheet
Why are there different sheets? Something about temperature grades I'd heard?
yeah, you might have found a summary sheet
different temperature grades, electrical specs, etc. the higher-level architecture is probably fairly similar
you could single-frame the video around transitions and check the time stamps, assuming you trust the time base on your camera 😁
Could I ask you what's the deal with capacitors?
Why does the crystal need that feedback from the caps
i don't remember exactly. i think it has to do with the particular way the crystal's impedance rapidly changes near its resonant frequency
I'd like to understand this more
Never mind, it barely derails
I just ran the timer for about 5 minutes, and the gap between the seconds and the light stayed pretty much exactly the same
That is great
Okay there's...quite a problem here
So I'm using my ICE to debug the program
When I send it something, I can see down there what it got
I have an Arduino hooked to the chip's receive line
And a serial terminal open to send things to the chip manually this time
If I send the same individual character at a time, it always shows the same character number, which seems like a good sign
But when I send things as a block, it's very inaccurate
what do you mean? i can guess that you might be expecting UART input to be queued while your debugger is stopped, but that's probably not what's actually happening
No, no, I have it stopped and waiting for input on that very program
When I send an input, it breaks on the line that's yellow in the picture, and shows me the byte it just read
you have set a breakpoint on that yellow line?
Yes
If I send the same exact text character on my terminal, the same number always shows up, which I guess is a good sign
so when you're sending multiple bytes, that breakpoint triggers, the processor stops, and any bytes after that will likely be lost
But if I send, say, the text, "123", it doesn't seem to read "1", "2", "3", it reads 2 arbitrary-looking numbers
the rest of the world doesn't stop just because your debugger hit a breakpoint
I thought there was a buffer kind of thing here
even if there were, i think interrupts are disabled while stopped at a breakpoint. like the processor clock is effectively frozen
Ah okay
i think you're going to have to read in multiple bytes, then set a breakpoint after that, if you want to see what your program is doing when receiving multiple bytes at once
sometimes a microcontroller can have peripherals continue to run while stopped at a breakpoint, but they're typically more advanced ones that have DMA capability
I've hooked up TX
Got a loopback, no breakpoint
More efficient
Okay, I've confirmed
It doesn't even understand what I'm saying
void loop()
{
if (Serial.available())
{
Serial.write(Serial.read());
}
}
I'm running this in the chip now
Blue is sent, purple is received
Wow, I am completely lost.....
All I can think of right now is that maybe the Arduino library just isn't affected by the F_CPU being set by me, and is just statically designed to be run at 16MHz. What do you think of that theory?
the Arduino core's hardware serial does some internal buffering, i think, and Serial.read() might return -1 on error (but maybe that doesn't fully explain what you're seeing)
how are you capturing the numbers you're printing out?
Cross-linked TX/RX @rigid fractal
I'm just running this program within the chip
so those numbers are coming from the debugger? which way did you set that up?
Now I'm not using the debugger breakpoints
I'm just running that code
Communicating with the chip with an arduino and a serial monitor
those numbers in blue and purple… what exactly is printing them?
and that terminal program is connected to a USB UART adapter connected to your chip?
An arduino middle-man yes
This is my theory
are you setting F_CPU in your sketch or in compiler flags?
also if you hardwire a loopback to your USB UART "adapter", do you see the expected result?
By that do you mean connecting TX and RX together in one wire?
Also, just in the sketch on top
WHAAAAAT??!?!
What is going on here.....
What. Is. Going. On. Here
This can't be. I plugged a 16MHz clock into the ATmega instead of the 10MHz...just to see if it would change anything
And it seemed my theory is correct
The Arduino API is hardcoded in 16 MHz, and it does not like running in 10 MHz
I don't understand...why is the 16MHz clock working? I'm running on 3V3, so why is the 16MHz clock working. This is against the datasheet
It's perfect now on 16MHz
yes
it's outside of the specified operating conditions but might happen to work
So what does it even mean to not be recommended to run it
What's supposedly going to go wrong
no, it's parameterized off F_CPU, which is currently probably being set inconsistently. the source code files for the hardware serial API are compiled separately from your sketch file
Interesting....and HardwareSerial's impl files have F_CPU in them?
Oh you're telling me I have to recompile this all
I get it
Somehow...because the preprocessor already went through the HardwareSerial impl files in an environment where F_CPU was something else. Is that it?
could be anything could go wrong, if the datasheet doesn't say explicitly. but i imagine it would be stuff like different components might not consistently keep up with a 16MHz CPU clock at 3.3V, and you could get all kinds of corruption or incorrect behavior
F_CPU is normally set as a build parameter (actually usually a command-line predefine like -DF_CPU=1000000) or something by the Arduino build system
are you using the Arduino IDE or something else?
i dunno how Atmel Studio handles it. it might use the boards.txt from an Arduino install, or it might keep its own versions of things around just to be difficult
Oh wait
It does ask me for the path of the Arduino IDE
When I created the project, it did
Wait, oh my gosh
It asked me for the Arduino path AND what board I used
ok, you'll probably have to locate the boards.txt in the Arduino IDE library files, and create a boards.local.txt in the same directory. and make a new board definition with a different F_CPU, maybe copied from the Uno
I said a nano
I'm already here
I'll copy from the nano since when Atmel Studio asked me what board I said nano
Arbitrarily
I just wanted the standard lib
So I didn't care
i'd have to look up exactly what the nano is, but it does look like a 16MHz board
it looks like 328 instead of 328P, so maybe some subtle dfiferences
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
I'm running a 328 right now actually
oh, i thought you were running a 328P for some reason
Well, I was
Remember I murdered him
I have a collection of mixed m328s and m328ps
but yeah, copy the nano section into a boards.local.txt and rename it to something different, set the f_cpu correctly, and try again?
you'll have to update the board choice in Atmel Studio after that
Everything between the large rows of asterisks right?
they're hash marks ### in my version, but yeah, probably. there might be something more clever you can do by adding a menu item to the existing nano.menu stuff, but i'm less familiar with how that works
and you might have to explicitly delete build directories to force a rebuild
done
IT WORKED
THAT WORKED
GAHAHA
WHAT
yay
yeah, you're basically rolling your own custom Arduino board by using parameters that are substantially different from the standard boards
hey, it's a learning experience!
Time to clean up my room....
What a mess
How much you go through vs how messy the desk gets. Linear relationship
weird. apparently the Arduino Nano is a 3.3V ATmega328 board clocked at 16MHz. so it's a production dev board that's technically overclocking the chip
oh sorry, i misread something and it's v3.3 (hardware revision) in the datasheet
What does that mean
it means my brain scrambled something when i read it and saw 3.3V instead of v3.3. i checked again and elsewhere in the Nano datasheet it seems to say the MCU is powered at 5V
Ah
@rigid fractal Now that I got it working with Arduino standard library
I'm...tempted to go raw
how raw? avr-libc? AVR assembly language?
rolling your own C code to use the UART module is probably doable. you'll need to read the datasheet very carefully, of course, and programming ISRs is its own kind of special adventure
I've been all around the ISR ballpark (I kinda cheated with the library), no worries on that one. I once used the timer/counter control registers with overflow interruption from the datasheet entirely
And I know for sure that made me better at datasheet reading
So I can go through pain again
Oh hey I found it
ISR(TIMER0_OVF_vect)
{
static uint8_t currentFrame;
if (++currentFrame == TOTAL_FRAMES)
currentFrame = 0;
setActiveFrame(currentFrame);
}
int main()
{
DDRB |= 0b00001111; // Prepare all outputs
DDRD = 0xff;
TCCR0B = (1 << CS02) | (1 << CS00); // 1024 prescaler. ISR active
TIMSK0 = (1 << TOIE0);
sei();
while (1)
{
for (uint8_t layer = 0; layer < 3; layer++)
{
clear();
draw(layer);
}
}
}
@rigid fractal I wanna thank you again for your patience with me