- Posts: 46
Porting Deviation to F3/F4 MCU, new LCD, etc
- cstratton
- Topic Author
- Offline
Rationale: With the exception of the Devo 7e and the x9d, current platforms are fairly pricey. The Devo 7e is extremely limited in program flash. And even an affordable transmitter is not a great development platform, since one wants to keep something in flying condition...
New CPU: The STM32F103 is not a bad processor, but has a couple of limitations:
- no cheap eval board with the pins broken out
- USB bootloader is an aftermarket add on, and susceptible to corruption
- limited memory options
Moving to an F3 or F4 provides some improvements:
- cheap Disovery eval boards ($10 F3, $15 F4) though they are too big for an existing TX enclosure unless one removes the pins
- permanent USB dfu bootloader already in the chip from the factory
- faster CPU
- outrageous amounts of memory available (f4)
- USB host mode for talking to older android phones, flash sticks (F4)
LCD possibilities:
- 1.8" SPI color LCD ($10 from adafruit, $20 /w breakout)
- 320x240 touchscreen LCD's (~$25, but parallel interface)
Please Log in or Create an account to join the conversation.
- cstratton
- Topic Author
- Offline
- Posts: 46
- F3 or F4 CPU. F3 is slightly cheaper but that's trivial compared to the work involved. Currently port to F3 is further along. F4 attempt was abandoned in the mistaken belief F3 API would be closer to F1 - it isn't, it's just nearly pin compatible. I suspect that when F3 port is done, making an F4 port from it will be trivial. But will F4 consume more power? What if it's not run at maximum clock speed?
Currently I'm using the F3, and since it is nearly pin-compatible, keeping the Devo10 pin assignments, at least until I find any conflicts (alternate function not available on current pin, etc)
(Incidentally, these chips are not hard to solder - you do one corner, check alignment with a 10x loupe, do the opposite corner, check alignment. Then you use surface tension and flux and an iron tip much bigger than the pins to solder them all. Finally, fine desoldering braid to clear any shorts which will not resolve by fluxing and reheating alone)
- LCD choices. Probably going with the 1.8" first because it is SPI and fits on smaller transmitters
- Storage options: sst25vf032 is cheap and easy, even to add on a breakout. But many of the LCD's have micro SD slots, which gives more space and the option of removing the card to initialize it / back it up. The F4 has a version with enough internal flash one could have a small filesystem without any external device.
- Physical packaging - try to squeeze into an existing TX? LCD/buttons/processor module which can be glued on the outside lower front? Discovery-based prototoypes probably have to go in ugly project boxes though.
- Remove existing TX PCB? Just tap out the stick pot wipers and leave the old CPU there? Force old CPU into reset? (easy if it's a known part like an ATmega). What about capturing PPM trainer output instead of using ADCs on sticks?
Please Log in or Create an account to join the conversation.
- HappyHarry
- Offline
- Posts: 1136
Please Log in or Create an account to join the conversation.
- cstratton
- Topic Author
- Offline
- Posts: 46
- Need to update to newer libopencm3 to have support for F3
- F3 determines SPI 8 vs 16 bit transfers by the size of SFR access, not by a configuration. So have to use the spi_read8() and spi_write8() functions instead of the implicitly 16-bit plain ones. There's no spi_xfer8() in libopencm3, so have to make our own (easy).
- GPIO API is vastly different, but a fairly simple fix, only it's everywhere. Add an abstraction layer?
- Who knows what the story on timers is... to be addressed
- Who knows what the story on interrupts is... to be addressed
- USB API seems different. This breaks mass storage, HID, etc. Have read-only mass storage almost working, but finally modified libopencm3 cdcacm example into a small firmware which can be used to bulk erase the flash and then dd a filesystem image to it before flashing deviation port (hack!)
- LCD is issues are next to be addressed.
(Some of the LCD breakouts have micro SD slots. That's an interesting alternative to an SPI flash, though it means the LCD and disk share an SPI, wonder if that will have any complications other than needing to abstract out the utilized SPI?)
Please Log in or Create an account to join the conversation.
- PhracturedBlue
- Offline
- Posts: 4402
The F4 should be very similar to the F2, and should be easy to port from the X9D driver. The F2 is quite different from the F1 as it uses a completely different mechanism to initialize ports (among other things)
Please Log in or Create an account to join the conversation.
- PhracturedBlue
- Offline
- Posts: 4402
Please Log in or Create an account to join the conversation.
- PhracturedBlue
- Offline
- Posts: 4402
Please Log in or Create an account to join the conversation.
- cstratton
- Topic Author
- Offline
- Posts: 46
Finally some progress with the lcd. It had done nothing as the code I started from checked that writes are within the screen size. And the screen size is 0 by 0 until you set the rotation!
Not sure why it's taking up only part of the screen though. It's a devo10 filesystem, so it should be the same resolution as my screen?
And that would be a "No". Devo10 is (used as) 128x64, and I'm 160x128.
Guess I have a lot of room for extra debug info, at least unless I feel like recreating all the images...
Please Log in or Create an account to join the conversation.
- PhracturedBlue
- Offline
- Posts: 4402
devo8 is 320x240x16
devo12 is 480x320x32
I don't know what screen that is, but it doesn't look like a 128x64 b&w screen
Please Log in or Create an account to join the conversation.
- cstratton
- Topic Author
- Offline
- Posts: 46
I got the devo10 gui centered on it for now.
How would you feel about a build where bitmaps got flipped upside down before storage on disk? The LCD only has one efficient write direction.
Right now I have the LCD controller flipping the LCD over from where it actually is, so I can invert the Y coordinates in software and have bulk writes of bitmaps occur in file direction efficiently. As far as I can tell, there's nothing which writes in the other direction which has per-pixel (monochrome/)color data such that it would be messed up be having it come out in the wrong order...
Please Log in or Create an account to join the conversation.
- PhracturedBlue
- Offline
- Posts: 4402
Please Log in or Create an account to join the conversation.
- cstratton
- Topic Author
- Offline
- Posts: 46
Now that I see it's not, I can deal with a letterboxed display for my own testing at this stage, and I think my "driver thinks it's upside down" hack is workable with the current graphics.
I'm more concerned with trying to get the access speed up, though I may actually live with that for a while and try to get the rest of core functionality working.
Please Log in or Create an account to join the conversation.
- cstratton
- Topic Author
- Offline
- Posts: 46
Fixing that means my screen draw time seems almost acceptable. If I can figure out why the flash fails when I try to go above 6 MHz or move the display to it's own SPI I should be able to go even faster. I also need to see if I can get away with not cycling /CS between pixel data words. For some reason using the 16-bit spi capability fails, while writing 16 bits as two 8-bit writes works. Even if it were and endian issue, I'd think it would just create goofy colors... more stuff to debug.
It occurs to me that the bitmap problem, even without the upside down display hack, need only mean setting coordinates at the start of each line, not per-pixel.
I see deviation is using a modification of the Adafruit graphics library which was originally meant to backend to this display (amongst others) anyway, so it's a decent fit in terms of access scheme.
Please Log in or Create an account to join the conversation.
- cstratton
- Topic Author
- Offline
- Posts: 46
I was able to get an infinite loop around the initial GUI_DrawScreen(); - which is a full clear, a large bitmap, and the version string - up to 10 frames per second by experimentally introducing a notification method to let the display driver know it will have exclusive use of the SPI. That permits leaving the chip select low between pixels, and programming the SPI for a faster baud rate. During screen clear, the whole screen can be written without touching chip select. During bitmap drawing, only a line at the time, as the file on flash may be accessed over SPI between lines. At this point, it's actually the time between the bytes where it's slow, not the bytes themselves, so looking into flattening the structure or even trying to use DMA or something (at least for clears and large areas) might help.
I still have half a mind to move the display to SPI3 on some ports of GPIOC currently used for switches. But I'm not sure long term if I'm going to have the storage necessarily sharing the SPI with the display (ie, if it's a micro SD on an LCD carrier board). So it seems the choices are:
A ) Different SPI for flash and LCD
B ) Introduce mechanisms to optionally lock the SPI to one peripheral or another, allowing it to change baud rate and leave it's chip select active between lowest level access calls.
A is private to this target, B would affect all targets, but could be as simple as a macro that is empty for other platforms. Premature to worry about it much, as I don't plan to make further LCD optimizations for a while.
I'm now on to trying to get ADCs and interrupts working - right now they crash the system. STM32 work I've done in the past has been against the ST standard peripheral library instead of libopencm3, so there's being a learning curve. Lots of frustration last night chasing down a false problem that was a simple misreading of the vector table structure on my part. I think I know where to look for the real problems now though...
Please Log in or Create an account to join the conversation.
- cstratton
- Topic Author
- Offline
- Posts: 46
- The DMA register map for F3 in (github official) libopencm3 is wrong. It doesn't even match the correct comment immediately preceding it. I figure out the correction, and discover there's a mere 14-hour pull request from stm32f3_paparazzi already correcting it, so I'm using their branch until it goes mainstream.
- As soon as I enable systick, it crashes. But I have a systick handler, something I wasted most of last night proving.
AHA! These chips can have the vector table in RAM or in FLASH... and according to ARM they default to 0x00000000 - no wonder any interrupt causes a runaway. In the ST lib, the command to enable the flash vectors would be:
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
But that's full of undefines. So for the moment I'm doing it like this with info from the ARM manual:
*((uint32_t*)0xE000ED08) = 0x8000000; /* Set vectors register to start of flash */
Please Log in or Create an account to join the conversation.
- PhracturedBlue
- Offline
- Posts: 4402
SCB_VTOR = VECTOR_TABLE_LOCATION;
For the F2, I don't need to set it, since the default is at 0x0000 which is where we put it. You should be able to use it there as well I'd think.
Please Log in or Create an account to join the conversation.
- cstratton
- Topic Author
- Offline
- Posts: 46
If I might trouble you for a minute, what's the current scheme for timing the triggering and collecting of the ADC reads? I see some dma completion interrupt stuff commented out, and quite old forum threads related to it.
I suspect I'm going to have to jump over to the ST examples, get a compact ADC proof of concept for the F3 going (I've done it before for the similar F372, but the F303 is slightly different), figure out what it is actually doing at a register level and then do the same in the deviation codebase against libopencm3. The libopenmc3 usage examples for F3 tend to be the most trivial cases only, such as single ADC software triggered.
On the positive side, I found an F1-F3 migration document which seems to imply that the existing F1 USB mass storage code might just work. Though I don't need mass storage working at present as I have a cruder way of loading the flash.
Please Log in or Create an account to join the conversation.
- PhracturedBlue
- Offline
- Posts: 4402
The ADC runs off DMA on a continuous loop storing data into the adc_array_oversample array (it will store multiple iterations of each value depending on the size of this array)
ADCFilter() is called once every 5msec to average and copy the results into adc_array_raw.
ADC_Filter is actually called by an interrupt (exti1) which is manually set in the clock timer loop (because I wanted it to have its own priority)
Please Log in or Create an account to join the conversation.
- cstratton
- Topic Author
- Offline
- Posts: 46
PhracturedBlue wrote: The ADC runs off DMA on a continuous loop storing data into the adc_array_oversample array (it will store multiple iterations of each value depending on the size of this array)
ADCFilter() is called once every 5msec to average and copy the results into adc_array_raw.
ADC_Filter is actually called by an interrupt (exti1) which is manually set in the clock timer loop (because I wanted it to have its own priority)
Thanks for the explanation.
Am I right in thinking then, that the filling of the oversampling array by the DMA engine, and it's reading by ADCFilter() is entirely asynchronous? Or is there a read of a DMA status flag somewhere I'm missing.
I did look at the x9d adc code a bit last night, but the F2 seems to be a different interface as well.
I'm thinking my best bet right now is to get the ADC working in a small stand alone program before integrating that into deviation. In part, that will let me do some reading noise tests which feed into PCB design efforts, to see if the ADC inputs will need special handling, or if just wiring the sticks to the pins on the discovery board (or a comparatively simple compact eventual replacement) will be enough.
(At the cost of changing vendors and peripheral libraries while staying with an ARM Cortex core, the Freescale-based Teensy 3.1 board might be small enough for retrofits using off the shelf parts if paired with an SPI LCD/uSD card breakout)
Please Log in or Create an account to join the conversation.
- PhracturedBlue
- Offline
- Posts: 4402
You can also see the ADC_ScanChannels() function which I throw into main (in a tight debug loop) to do ADC debugging. That lets me verify the channels are mapped correctly and play with either direct read or DMA coding. I found it really helpful in getting this stuff working.
Please Log in or Create an account to join the conversation.
- Home
- Forum
- Development
- Development
- Porting Deviation to F3/F4 MCU, new LCD, etc