AVR standard I2C, SPI, USART, USB drivers? - Page 1
Forum section: electronics / general

author: frasdoge
author_rank: Contributor
timestamp: August 21, 2021, 05:47:59 am
content: I'm trying to get a project up and running quickly and I can't find a full set of AVR drivers for these standard interfaces. I'm using an ATmega32U4.I suppose I could make my own, but I have to assume someone has done a far better job than I ever would.There was some hope with the application note avr315, but I cannot find the code it promises anywhere, as with the other interfaces.

author: westfw
author_rank: Super Contributor
timestamp: August 21, 2021, 08:04:20 am
content: The usual suggestion for USB is Dean Camera's LUFA (http://www.fourwalledcubicle.com/LUFA.php)The others tend to be pretty trivial, and I think most people just write them from scratch. I've heard reasonably good things about Peter Fleury's code:http://www.peterfleury.epizy.com/avr-software.htmlNote that there can be considerable variation in AVR peripherals depending on "generation" of device. For example, the 32u4 has one USART, but for some reason it is "USART1" instead of "USART0"

author: T3sl4co1l
author_rank: Super Contributor
timestamp: August 21, 2021, 08:47:51 am
content: Quote from: westfw on August 21, 2021, 08:04:20 amFor my part, I use this often enough for one USART:https://github.com/T3sl4co1l/Reverb/blob/master/bufserial.cMost functions of which are pretty straightforward and generally usable, while the string functions are kinda take-it-or-leave-it. (The fixed-length interface probably isn't worthwhile on the whole, it just happens to be the form I chose when writing it.)(If you're just starting with MCUs, and probably C by association, probably better to stick with library string functions. If you're experienced with C, you're already aware of the issues of fixed vs. variable length strings.)So, you might not want to use this directly in the first place, but it's an alright example of how to do the things you typically need with serial -- interrupts, buffering, shortcut functions.Even more beginner-oriented, can always start with the Arduino ecosystem; drivers are provided as a matter of course.As for SPI, that's pretty much trivial, usually just inlined. No need for a whole framework / API to use it (but you can find such, if you like). I2C and USB, I don't know much offhand.QuoteThey tend to type peripherals; for example, Timer/Counter 0/1 are typically reasonably-functioned 16 bit units (plus more advanced features, and associations with other peripherals (AWeX, Hi-Res, Events, etc.), in later e.g. XMEGA, AVR0, etc.), and TC2+ are typically stripped-down 8-bit counters.Though I don't recall offhand if there's supposed to be a difference between USARTs. (The XMEGA that I'm most familiar with, peripherals are enumerated by the port they're associated with, and there's simply as many identical USARTs, as ports equipped with them.)Or maybe, what used to be "USART0", got absorbed by the USB hardware; but the two systems are so different, that's probably a very long shot.Tim

author: westfw
author_rank: Super Contributor
timestamp: August 21, 2021, 10:32:05 pm
content: QuoteIt was about the XMEGA timeframe that Atmel got better at "standardizing" their peripherals, I think.QuoteFor example. Timer0 (and timer 2) on an ATmega328 or ATmega8 is an 8bit timer. On m328 it has two compare outputs. On m8 it doesn't have any. That sort of "small improvement" from one family to another was pretty common. I guess with xMega you get TC0/TC1/TC2 as TYPES of timer, and each associated with a PORT. On the Mega0 and AVRDx, you have timer types TCA, TCB, and TCD, and back to numbering each instance.QuoteATmega8 and ATmega328 have slightly different UARTs, in particular WRT setting the BRG register. Some AVR UARTs have LIN or IRDA or autobaud or half-duplex support. (This is one of the things that causes vendor libraries to get bloated - they want to support ALL of the features of every peripheral, whether you're using them or not.) Not to mention the design issues you run into if you want to support multiple UARTa vs just one.And all of that is pretty easy, compared to the switch from individual-register-addressed peripherals in the older AVRs, vs structure based blocks in the newer AVRs:Code:data = UDR0; // read data from UART0, ATmega328data = UART0.RXDATAL; // read data from UART0, ATmega4809

author: T3sl4co1l
author_rank: Super Contributor
timestamp: August 22, 2021, 05:52:44 am
content: Oh yeah that's right, TC0/2 were the 8-bitters on MEGAs.And, I haven't looked very much at ATSAMs but I think they have a similar scheme -- at generally higher complexity, given the bus size and process speed (i.e. 32 bit registers standard)?Quote from: westfw on August 21, 2021, 10:32:05 pmNot to be overlooked -- this is one of the, at least potential wins (disclaimer, I haven't checked for myself) of ecosystems like Arduino. It's designed in C++ and, as long as all the CPU/device specific junk is resolved statically on compile (via defines, templates, classes, whatever), you get executable code tailored specifically for the target: all the extra features either aren't available at all, or being unused, get optimized out (particularly with -flto?).You still have a lot of overhead for stuff like, okay they want this pin, which maps to these bits in this collection of registers; there's a lot hidden by a simple GPIO write or what have you. But it knows exactly which bits and registers to use.It's not like having a truly general binary that can be written to any platform, recognizing its host at run-time; likely such a program would be so big as to strain the Flash of even the largest AVRs, being completely impossible to write to most models, hah. Put another way: if literally all functionality written in the source, were compiled into the binary, it would be truly massive; it's stripped down, at compile time, by necessity.Though there are compromises due to the libraries being static, so I may be overstating the advantage, heh. Like I said, I don't know any implementation details of these ecosystems.Tim