There aren't many raycasters on AVR... - Page 1
Forum section: electronics / general

author: T3sl4co1l
author_rank: Super Contributor
timestamp: June 17, 2018, 01:54:14 am
content: So here, have one:The full screen (320x240 16 bit) fill rate isn't too terrible, maybe 4 or 5 FPS equivalent. The full render loop, maybe 2 or 3 FPS.Doesn't look like there's much to save on the drawing routines, unless faster SPI is acceptable. The compiler output (at -Os -flto) is pretty clean.Ah, just poked a register, faster SPI does seem to behave at the moment.And shrunk down to a 160 x 120 window, it's quite presentable. Still not quite FMV rate, but quite competitive with a lot of early FPSs.What amazes me more is, I took almost no effort to clean up the inner render loop -- there's, uh, about 20 + 2N FLOP per column (where N is the number of grid squares "cast" over, average maybe ~10). I'm getting about 25kFLOP/s here, plus all the logic and memory handling around that. Which I suppose is still pretty typical of an 8-bit integer machine (give or take the hardware multiply, which helps out a lot here!), and it's running at nearly 30MHz too. Still, it kicks the crap out of a poor old PC-XT, even with math co...Tim

author: KE5FX
author_rank: Super Contributor
timestamp: June 17, 2018, 02:47:10 am
content: That's pretty cool.What AVR chip runs at 30 MHz, though?I once implemented a panadaptor with a 16 MHz Arduino:https://youtu.be/sPlBv77Uunc

author: ajb
author_rank: Super Contributor
timestamp: June 17, 2018, 04:02:28 am
content: Neat! Do you have an application for this, or just for fun?Quote from: KE5FX on June 17, 2018, 02:47:10 amThe XMEGA parts run at 32MHz. They tend to pack some much nicer peripherals (and more of them) than the tiny/mega parts as well, but they came onto the market a bit too late and at a bit too high of a price to really establish themselves against the ride of the low end ARMs. Even within Atmel's product line they didn't make much sense as soon as the SAM-D and similar lines came out unless you were really tied down to the AVR core for some reason.

author: KE5FX
author_rank: Super Contributor
timestamp: June 17, 2018, 05:09:09 am
content: Quote from: ajb on June 17, 2018, 04:02:28 amFor fun (or were you talking to Tim?) The 'panadaptor' built into the ESM-500A receiver uses a small CRT, and by the time you find one on the surplus market the CRT is usually shot. There are only a few other devices that use them, such as the NLS MiniScope, which are themselves becoming extremely rare. The only way to get a replacement CRT is to cannibalize one of those devices, but the Adafruit 1.8" display is an almost perfect match.QuoteI've never used an XMEGA but the people who have all seem to consider them to be great chips. I don't think of them as "AVRs," though, since they're such a big upgrade from the original 8-bit parts.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: June 17, 2018, 12:12:42 pm
content: You're kidding right, graphics demos have no practical application.XMEGA have a lot of interesting features: more ways to control the IO ports (passive pullup/down, set/clear/toggle registers, control regs, slight peripheral remapping, virtual port registers in the low IO space, etc.), much more powerful timers (4 x 16b compare/capture registers for each 16b counting register, more waveform modes, an 8x clock option, pulse generation suited to motor control and probably SMPS applications), an event system (timers and IOs can trigger timer and ADC actions), faster ADCs (apparently still worse than the competition, as they need pipelining -- in the A version chips -- to claim Ms/s rates), USARTs with vernier baud rate control, IrDA, PLL, and still other stuff. The CPU core is the same basic thing, it's almost too much stuff for the poor thing to manage. It's also a shame that you're only ever going to use 5 or 10% of the peripheral functionality in a given application. But such is the fate of pretty much any MCU or FPGA.Tim

author: chris_leyson
author_rank: Super Contributor
timestamp: June 17, 2018, 01:34:32 pm
content: Nice one Tim. Reminds me of Atari Wayout.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: June 17, 2018, 11:45:42 pm
content: So you can see black pixels along the top of the view. That's kind of weird.Today I've been tweaking the fill routine for speed and accuracy.I've got:Code:void fillRectangle(uint16_t colr, int xStart, int yStart, int width, int height) {uint8_t dh, dl;uint16_t pixels;pixels = width * height;dh = colr >> 8; dl = colr & 0xff;wr_reg(ILI9325_DRCODE, 0);wr_reg(ILI9325_VADDRST, xStart);wr_reg(ILI9325_VADDREN, xStart + width - 1);wr_reg(ILI9325_HGADDR, yStart);wr_reg(ILI9325_VGADDR, xStart);spiSetIndex(ILI9325_GRAM);SPI_CSON();SPI_DATA = ILI9325_START_SETREG;do {SPI_TXWAIT(); SPI_DATA = dh; SPI_DATA;SPI_TXWAIT(); SPI_DATA = dl; SPI_DATA;} while (--pixels);SPI_CSOFF();spiSetIndex(0);}This draws a solid rectangle (as the name suggests), but it seems to not finish the transaction correctly. I'm not writing a black pixel -- yet one ends up on the next row below the rectangle (or, if it fills the screen, at the top, because wrapping).If I make _pixel_ one less, it doesn't draw the last (intentionally colored) pixel, and the last (intended) pixel is sometimes black.That very last call, to spiSetIndex, seems to be the easiest way to fix it. A setReg or wr_reg operation doesn't seem to do it. (I didn't try a lone start byte, maybe that will work too.)Aaaaalso, you can kinda guess what my API is doing here. The function names are kind of a mess, but the register macros at least are pretty coherent and self-explanatory.Tim

author: ajb
author_rank: Super Contributor
timestamp: June 18, 2018, 06:58:37 pm
content: Quote from: T3sl4co1l on June 17, 2018, 12:12:42 pmFair, but for all I know, this could be your first step towards a Wolfenstein clone or something!Quote from: T3sl4co1l on June 17, 2018, 11:45:42 pmIssue with the way the transaction is ended on the SPI bus, like a spurious clock edge before CS comes up that makes the controller thing another pixel's being clocked in maybe? The SPI peripheral doesn't have an overly clever FIFO like some of the STM32s do, does it?Quote from: KE5FX on June 17, 2018, 05:09:09 amOh yeah, I've used XMegas in a couple of projects and they really are nice chips. They just don't make a ton of sense in the current market where you can get similar peripherals with a more powerful (ARM) core that will be better able to make use of those peripherals for the same or less money. I just looked at some prices in a random and completely non-scientific manner, and the cheapest XMEGA parts cost about twice as much as similar (pin count/flash size) SAM-D parts. Actually looks like the SAM D series has really grown up recently and now includes M4s with ethernet MAC, and they cost ~25% less than the same pin count/flash size XMEGA! But for situations where the AVR core will do, or where the XMEGA has a particular peripheral setup you want, and you don't care about spending an extra buck, sure, they're great! No argument there.[EDIT: And obviously, if they're selling them, then people must be buying them, so clearly there are enough applications out there for them.]

author: T3sl4co1l
author_rank: Super Contributor
timestamp: June 18, 2018, 11:26:25 pm
content: Hah nah, I don't think Wolf is in the works, I'd need a texture routine too.Which... I'd need to pass along more data (texture column number, and a few extra bits of column height so it doesn't clamp at full screen size), which really isn't too much. Then devise some way to get a buffer out to the screen quickly.Also, even a 32x32 texture is 1kiB gone, so it wouldn't fit very many textures. More than one or two, and they'd have to go in PROGMEM. Which is fine, but reading it is a few more cycles wasted during the write. Actually...maybe not? Because the SPI write takes a few dozen cycles. Maybe it's free after all?IIRC, the SPI clock ends in the default state (high), as it's supposed to. No FIFO, unfortunately -- I don't think it's worth trying interrupt driven IO in this case, but if I had a FIFO I definitely would.Yeah, XMEGAs really aren't cost effective -- you get several times the peripherals and many times the CPU performance, for less cost, in the low-tier ARMs. For same-cost, you can just about run Doom on the thing (provided you have external RAM, of course).I just happen to have a ~dozen of these from other projects/inheritances, so I thought it would be neat to plop one down here and give it a go.Tim

author: amyk
author_rank: Super Contributor
timestamp: June 19, 2018, 02:27:06 am
content: Not bad.Something more interesting:https://www.linusakesson.net/scene/craft/

author: David Chamberlain
author_rank: Frequent Contributor
timestamp: June 19, 2018, 06:21:53 am
content: Quote from: T3sl4co1l on June 18, 2018, 11:26:25 pmHow about procedural textures? If you have a few spare cpu cycles that is.http://www.upvector.com/?section=Tutorials&subsection=Intro%20to%20Procedural%20Textures

author: T3sl4co1l
author_rank: Super Contributor
timestamp: June 19, 2018, 12:33:49 pm
content: I've got the SPI ticking at half peripheral clock, or 16 CPU cycles per frame (32 per pixel, since two bytes/pixel), so there's not enough time to call a procedure as such, and if it's inlined, it better be very short and streamlined. There's always the XOR texture for instance, but that's just one thing and not very interesting...It is handy to save program space, but you still need a buffer to hold any somewhat complicated texture, which makes them not helpful for embedded demos.Or if you calculate the texture just before you need it, you can maybe put it in a second buffer while the first is still being written to the screen (assuming effective interrupt driven IO -- probably not applicable here). But you're likely to be wasting time inbetween, as there's only so many cycles you can spare.As far as making things more interesting, it would be fairly easy to put a gradient on things, I might try that. Scaling the gradient by wall height, and setting the initial offset, may be tricky (more function parameters, more calculations per line?).Tim