-
GPIO Defaults CANNOT read pin input
07/14/2015 at 06:55 • 0 commentsNOTE:
(Update: Now, if I'da just read Tahmid's intro from the start, as well as all the way through its first section, then I'da saved a LOT of time!)
Summary: Put this early-on in your code!
//Pins which are shared with Analog peripherals default to ANALOG by //default... This causes all READS from PORTx to be 0 //Set ANSELx bits to 0 for PORTx reads to be valid! //Below takes care of PORTA inputs, use ANSELB, etc. for PORTB... ANSELA = 0x0000;
Frankly, the documentation is downright confusing at times. Somewhere I'm sure I read that the defaults result in the GPIO pins defaulting to inputs.
But, no... That's not enough... Because if you're *not* planning on using the ADC, you *still* need to look into it... Because later down-the-line it also says something like GPIO pins that are shared with analog peripherals default to ANALOG mode. Which, apparently, explicitly *disables* PORT [input] reads on those pins... So, even if you're *not* planning to use any analog stuff, and just want to read a pushbutton on a pin, you *still* need to acknowledge (and learn the intricate details regarding) the fact that the pin is shared with an analog peripheral... even though those analog peripherals default to OFF.
It took me two days to figure this one out.
The takeaway, here, I guess, is to make sure that all your inputs are set to digital mode, until you decide to use them otherwise. Just do it: ANSELx = 0; -
wherein we discover with some amount of certainty...
07/12/2015 at 06:41 • 0 comments...that the world doesn't really exist. Or something like that.
Regardless:
Apparently, the trick to getting openOCD to use the fast-writing method is to hack it in two ways.
THESE ARE 'INSTRUCTIONS' TO SPEED UP PIC32 PROGRAMMING
(Without them, it takes nearly 10 MINUTES to flash! With, just a handful of seconds.)
First: Apparently there's a test that determines whether the fast-write data buffer is safe...
This test, apparently, is faulty...
basically it tests: "offset + size", whereas it should test "offset + size -1"
(say the offset/start address is 0, and the size is 8 bytes, then it thinks the *last-used* byte is 8, rather than byte 7...)
Fine, bad-programmer, right? Lucky, I suppose; musta been using some set-up wherein the data-buffer was somehow created not-immediately-after the working-buffer... 'spose it's plausible. Regardless, unless these buffers use 'null-termination' this is a glaring mistake..
Second: After that's fixed, there's a new "register 'a0' not defined" message... which is special... because, apparently, this message... only appears after you fix the above, right...?
But, no, it comes back to haunt us again later...
For now, yeah, apparently the MIPS32 registers are listed as "r0"-"r31", but should be given more-relevent names, one of which is "r7" which should be "a0" (as I recall).
I guess our friend "Serge" fixed this way back in 0.60, but somehow it came back...?
http://sourceforge.net/p/openocd/mailman/message/28333633/
Regardless, this is the weird part...
Fixing that doesn't fix the problem... fast-write still doesn't work. I can't recall the message off-hand, but somehow it led me to look into fixes, wherein we find... wait, just a minute, I gotta point this out: Without Fast-Write mode, it takes TEN MINUTES to flash 64kb... and my program's really only like 2k... so there's that, too... TEN FRIGGIN' MINUTES every time I make a code-change. Yeah, no.
So, the problem, no we're not yet at the "weird part" yet... I'll get to it, Promise...
Anyways, the new weird message leads to this page:
http://openocd.zylin.com/#/c/977/
which says "abandoned" because, apparently "Not needed. We can play with adapter_khz and/or scan_delay in queued mode to make it work nearly safe and faster."
Ohhh, OK, so all's I hads to do's was adjust adapter_khz... apparently it was too fast, the program running on the pic for fast-write was executing too slowly, and my fast 4000khz adapter_khz was too fast, causing polling of whether the program had completed to fail... I think I get it...
Fine, back to the Unhacked version of openOCD-0.90... the freshly-compiled version, straight from the source... this time with adapter_khz of 400, rather'n my old 4000
And, low-and-behold: "falling back to non fast-write" as well as "register 'a0' not defined"
Whoa, now, wait a minute... the 'a0' issue was due to the fact that fast-write is *being executed*, no? That's how I understood it... that 'a0' thing was only happening *because* I fixed the overlapping-memory-test, before... when that overlapping-memory-test failed, it resorted to "non fast write" mode... So, then, when I fixed the overlapping-memory-test, it was then *able* to *attempt* fast-write, wherein we discovered the 'a0' bug in the 'fast-write' algorithm... RIGHT?
So, then, why does changing adapter_khz to 400 somehow *ignore* the overlapping-memory-test failure in the original version, and *go into fast-write mode*?!
Alright, I dunno... So, adapter_khz 4000 works with *slow-writing* on the default 0.90
400 causes the 'a0' issue to appear, on the default 0.90
OK
And in the hacked-version...?
adapter_khz 4000 results in falling-back to non-fast-write, and if I recall, actually fails... No, that ain't right... it results in the 'a0' message... no, that ain't right, either, 'cause I just fixed that... so, what was the weird error that caused me to look into the "zylin" page...? I can't recall, but there was some weird message that caused me to look into the "zylin" page... and that page basically said to try a slower adapter_khz, and my having-done-so resulted in a REALLY FAST WRITE.
So, two changes were necessary, in openOCD's source-code:
First: fix that overlapping-memory-test, so that fast-write can execute (using the memory-buffer tested for overlap)
Second: replace the 'r' registers with their better names... so that, apparently, the code that's supposed to run for "fast-write" mode, can execute *at all*...
Then, of course, the third step is to change adapter_khz to 400 (from 4000)
Fine.
For posterity: Here's where we're at... this world doesn't exist. Logic is irrelevent. Programming is bullshit, code... code only functions when you don't understand *how* it functions. Or something. I'm ready for the next level, so I'm not going to write this up in any easier format, 'cause, frankly, even if I did, this wouldn't help you, because the universe, or whatever it is, would find a completely different path-of-confusion for you.
So, here's the diffs:
diff -x .DS_Store -r openocd-0.9.0_fresh/src/target/mips32.c openocd-0.9.0_hacked/src/target/mips32.c 47a48 > #if 0 163a165,214 > #else > //meh: > // per: > // http://sourceforge.net/p/openocd/mailman/message/28333633/ > static const struct { > unsigned id; > const char *name; > enum reg_type type; > const char *group; > const char *feature; > int flag; > } mips32_regs[] = { > { 0, "zero", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 1, "at", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 2, "v0", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 3, "v1", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 4, "a0", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 5, "a1", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 6, "a2", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 7, "a3", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 8, "t0", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 9, "t1", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 10, "t2", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 11, "t3", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 12, "t4", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 13, "t5", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 14, "t6", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 15, "t7", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 16, "s0", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 17, "s1", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 18, "s2", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 19, "s3", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 20, "s4", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 21, "s5", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 22, "s6", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 23, "s7", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 24, "t8", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 25, "t9", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 26, "k0", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 27, "k1", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 28, "gp", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 29, "sp", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 30, "fp", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 31, "ra", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 32, "status", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 }, > { 33, "lo", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 34, "hi", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, > { 35, "badvaddr", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 }, > { 36, "cause", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 }, > { 37, "pc", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 }, 164a216,285 > { 38, "f0", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 39, "f1", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 40, "f2", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 41, "f3", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 42, "f4", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 43, "f5", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 44, "f6", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 45, "f7", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 46, "f8", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 47, "f9", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 48, "f10", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 49, "f11", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 50, "f12", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 51, "f13", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 52, "f14", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 53, "f15", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 54, "f16", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 55, "f17", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 56, "f18", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 57, "f19", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 58, "f20", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 59, "f21", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 60, "f22", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 61, "f23", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 62, "f24", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 63, "f25", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 64, "f26", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 65, "f27", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 66, "f28", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 67, "f29", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 68, "f30", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 69, "f31", REG_TYPE_IEEE_SINGLE, NULL, > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 70, "fcsr", REG_TYPE_INT, "float", > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > { 71, "fir", REG_TYPE_INT, "float", > "org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG }, > }; > #endif diff -x .DS_Store -r openocd-0.9.0_fresh/src/target/mips_m4k.c openocd-0.9.0_hacked/src/target/mips_m4k.c 1171,1172c1171,1186 < if (address <= fast_data_area->address + fast_data_area->size && < fast_data_area->address <= address + count) { --- > typeof(fast_data_area->address) fd_addr = fast_data_area->address; > > typeof(fd_addr) fd_lastAddr = fd_addr + fast_data_area->size -1; > > typeof(address) lastAddr = address + count -1; > > //meh: > //THE ABOVE CAN'T BE RIGHT, right? > // lastAddr shouldn't be address + count, > // otherwise, we'd have e.g. 0x00 + 0x08 = 0x08 = lastAddr > // but the lastAddress SHOULD be 0x07... No? > > //if ( (address <= (fast_data_area->address + fast_data_area->size)) > // && (fast_data_area->address <= (address + count)) ) > if ( ( address <= fd_lastAddr ) && ( fd_addr <= lastAddr ) ) > { 1176a1191,1194 > LOG_ERROR("fast_data: (0x%8.8"PRIx32"-0x%8.8"PRIx32").", > fd_addr, fd_lastAddr); > LOG_ERROR("address: (0x%8.8"PRIx32"-0x%8.8"PRIx32").", > address, lastAddr);
-
wins! and tcnter!
07/10/2015 at 09:54 • 0 commentsWoot! I won a couple prizes for the Sponsors' contests! Thanks HaD, Microchip, and Freescale!
Finally got the 'heartbeat' code running with the 'tcnter' (on the PIC32)...
'tcnter' implements a long-duration high-accuracy timer without necessitating interrupts. I use it for timing the heartbeat to 8 seconds per fade-in/out cycle and one second per blink. I also use it as the timing-basis for *several* other commonThings, including bit-banging of UARTs, etc.
So, basically, the idea is that once the heartbeat is running with tcnter, it means serial-communication is coming soon.
Embedded-project-development-wise, that's the path... and, in general, going from nada to heartbeat to bit-banged serial, and beyond is a matter of a few hours' work. This time, not so much... There's been a bit of a learning-curve with this PIC32/MIPS system... and, more importantly, a lot of work on #commonCode (not exclusively for AVRs) ... It's that "not exclusively for AVRs" part that's being improved significantly as part of this process. New ideas on how to decouple the system from the architecture even further... Better documentation, whatnot... It's a daunting amount of work, we'll see how it goes.
Basically, as-of little more than a few months ago, I seldom looked at commonCode as a project of its own... it's always been developed/improved as a result of some other project[s] that makes use of it... I'm actually quite amazed at how much I accomplished that way, as looking at it *directly*, now, seems like a *huge* undertaking.
-
It's Alive!
07/04/2015 at 14:40 • 0 comments_commonCode's 'heartbeat' program is now running on the PIC32! Woot!
So... basically... that means the _commonCode *system* now works with the PIC32 and its toolchain, so I guess it's time to start doing some code-abstraction (where necessary).
Actually, there's some learning to be done... The "fade cycle" is supposed to be 8 seconds, so obviously I need to look into the timers. And peripherals in general, and registers... and basically, I know nothing about this chip ;)
...actually, I should probably get the full/functional schematic and pinouts and whatnot documented soon, if not first... Nevermind the procedure/configuration for flashing via JTAG... as it stands, that's a FTDI2232H breakout-board used as a JTAGger. (and, no, /MCLR is not connected to nT/SRST). I'm using openOCD 0.90 (anything above 0.60 should work). Programming the flash takes about 10 minutes, but it's "falling back from bulk-write mode"--ish so there's probably a configuration I could change to make it faster.
Oh, and... there were a few things I had to figure out regarding getting _commonCode to run with xc32-gcc, which required using a separate "fork" (maybe?) resulting in a lot of general compatibility improvements, etc... so that should be merged at some point.
-
MPLAB kills commonCode
07/02/2015 at 08:07 • 0 comments(updated a couple days later... Figured out the problem, but noting that at the end... otherwise: a couple typos fixed)
commonCode has run on well-over a half-dozen different versions of GCC... Apple's from 10.5.8, several different versions of avr-gcc, now gcc on linux... spanning gcc's from 4.0.something (was it 3.something?) through 4.7.2...
but xc32-gcc/cpp seems to be mangling it quite royally. (See the fix at the end)
makefile:
COMDIR = ../../../_commonCode VER_BITHANDLING = 0.95 BITHANDLING_HDR = $(COMDIR)/bithandling/$(VER_BITHANDLING)/ CFLAGS += -D'_BITHANDLING_HEADER_="$(BITHANDLING_HDR)/bithandling.h"'
the end-result (when running gcc with -E -dM) should be:
#define _BITHANDLING_HEADER_ "../../../_commonCode/bithandling/0.95/bithandling.h"
(yes, in quotes)
Then main.c uses:
#include _BITHANDLING_HEADER_
Yeah, it's a little ugly on the makefile side, but there's reason for it.
There's a name for it: "Computed Includes" and there's a whole section in 'info cpp', including mention of using the command-line option -D to do-so...
And, a significant portion of #commonCode (not exclusively for AVRs) relies on this technique, and has for several years.
Instead, with xc32-gcc (Microchip's toolchain) what I get is:
#define _BITHANDLING_HEADER_ ../../../_commonCode/bithandling/0.95
Notice:1) No quotes (where'd they go? BASH didn't mangle 'em, I can compile this on avr-gcc and linux's gcc on the same system, same 'bash', same 'make' without trouble).
2) It completely dropped everything after $(BITHANDLING_HDR) (/bithandling.h"')
No complaints about missing endquotes...
And a few more hacks resulted in even weirder stuff... Including Macros whose closing-parentheses were apparently never reached, and never complained about.. Like this:
CFLAGS += -D'_QUOTETHIS_( x)=\#x' CFLAGS += -D"_BITHANDLING_HEADER_=_QUOTETHIS_($(BITHANDLING_HDR)/bithandling.h)"
which results in:
../../../_commonCode/heartbeat/2.05/heartbeat.h:319:11: error: unterminated argument list invoking macro "_QUOTETHIS_"
#include _BITHANDLING_HEADER_
^which doesn't make an ounce of sense, clearly it's terminated, Even tried ' instead of " and various others...
And, even weirder, the output results in:
#define _BITHANDLING_HEADER_ _QUOTETHIS_(../../../_commonCode/bithandling/0.95 #define _QUOTETHIS_(x) #x
... so, clearly, '/' isn't the problem...... and it seems to be cut-off at the same place... immediately after the *makefile* variable... which shouldn't even appear to any of the xc32 utilities... and is, in fact, the same make used by the other gcc-toolchains that work fine.
Maybe it's because of this crippled ("free license") version, but that's some REALLY WEIRD SHIZZLE.
...right?
--------------
Update a couple days later:
Turns out: xc32-gcc is removing the quotes, *all of them* wherever they lay in the command-line. No, it's not bash's doing, no it's not make's doing... the compiler shouldn't be doing this, right? Maybe it has something to do with its being aimed at Windows rather'n linux?
Anyhow:
The Fix is explained here at stack-overflow, as that's also where I figured out the problem. The end-result is a necessity to:
1) remove ' and replace " with \"
2) replace \" with \\\"
That first bit's just for an alleged portability-increase for the original -D'...="..."' method to -D...=\"...\"
That should be effectively the same as the original in all cases, while also plausibly being compatible with other operating-systems I haven't tried.
The next bit is the oddity of xc32-gcc... apparently the quotes need to be escaped *again* dispite already being escaped...
thus the regular escaped-quote that bash passes into xc32-gcc: \" is removed, unless it's *escaped again* with \\\"
Again, oddly, this isn't a bash-thing, this is definitely an xc32-gcc thing. Weird.
So, now commonCode tests which compiler you're using and extra-escapes if necessary. (ultimately, maybe, there might be a more automatic way of detecting whether this is necessary, regardless of the CC used... TODO)
-
toolchain difficulties
07/01/2015 at 05:41 • 6 commentsI dunno what's wrong with my search-fu, 'cause the signs all point to that *people are doing it*... but all I can seem to find is really low-level weird ways of doing it.
There's more to a toolchain than just the compiler; compiled code can run in many forms... "bare-metal" or as an application atop an OS... Once it's compiled, it's gotta be "linked" appropriately, which in a bare-metal situation means the linker needs to know *where* to put the compiled machine-language on the machine. Interrupts in certain locations, initial boot stuff at the beginning, whatnot. Then there's these newfangled chips with their newfangled abilities to run code from the RAM (WHAT?!)... but that code has to be *stored* in the FLASH, then *relocated* into RAM before it's executed... blah blah blah.
The gist of it is that: Yeah, the Microchip IDE handles all that, specifically for their chips. Of course. And alternatively, yeah, there's a MIPS cross-compiler for gcc, and many other such tools... but basically, it seems, most of the nitty-gritty described above is... beyond my search-fu.
So, it would seem, the way it's done is one of two paths:
A) write your own linker-scripts, header files, etc... for each different chip you work with... or if you're lucky you'll find someone who's done-so already. Then, use mips-gcc... e.g. http://wise-ware.org/wiki/index.php?n=Pic32.Gcc4Pic which is well-written, but a lot of work and a bit incomplete. Or...
B) download and install Microchip's IDE, and get its linker-scripts, header-files, etc. Then plausibly apply them to a more generic build-chain. e.g. http://www.paintyourdragon.com/uc/osxpic32/
Either way seems utterly ridiculous. And neither makes a bit of sense as the way people do it considering how much effort apparently has already gone into supporting these devices at the lower-levels (JTAG/flash-programming via openOCD, etc.).
So, apparently, I just don't know what to search for, right?
Well, as it stands, I'm half-assing option B: I'm downloading MPLAB XC32 from Microchip... there's a Linux version, so who knows. On the plus-side, no need for writing linker-scripts, etc. On the minus-side, it's a bit crippled unless you're willing to pay for a license (I'm not). And it kinda takes away from this being a totally open-source method. But... maybe I'll actually be able to run some code on my chip soon, which'd be a nice improvement over having to dig out the instruction-set reference and create op-codes, uploaded one-by-one by hand ;) (yeah, I didn't get beyond 0x00000000 NOP).
http://www.microchip.com/pagehandler/en-us/devtools/mplabxc/home.html
That's, basically, the equivalent of a regular "tool-chain" except distributed and slightly crippled by Microchip. Allegedly it's got xc32-gcc which is allegedly open-source, as well as the linker-scripts, headers, etc. which are explicitly NOT OPEN SOURCE. This is different from the IDE, it's the toolchain the IDE uses. Again, I'm not too fond of IDEs, in general, so this'll probably be a happy-medium for now. Still, it's 60+MB, which means I've had plenty of time to write this, look at various other links, download documentation, and am still at less than 2/3rds downloaded.
And, again, even if it's not open-source, at least the entry-requirements are free. That's a plus.
-
Hah! Mike's the man!
06/30/2015 at 13:36 • 0 commentsRound ROUND-about way of coming to this HaD article/video of years before from @Mike Szczys himself: http://hackaday.com/2012/09/27/beginners-look-at-on-chip-debugging/#comment-2628854
Having some difficulty with my ancient version of openOCD, so looking through the release-logs of the newer versions led me to that link. Go Mike!
---------
Otherwise... it's connecting, I managed to manually twiddle one byte in the FLASH from "blank" to "nop" and can single-step to verify it works as expected.
So... I found another resource which suggests it should be as simple as typing "program <file.hex>" (as of 0.60). So I'll be compiling 0.90 soon...
Though, I don't yet have a hex-file to program... that'll be the next hurdle, I suppose. Have the mips-cross-compiliing/debugging toolchain from when I worked with the old cable box... but there's a bit more to that, as I understand... need some linker-scripts and some chip header-files...
I'm keeping a pretty wordy log of my progress/results/links, but it's FAR too wordy and round-about for public-consumption... I'll eventually strip it down to the bare-minimum "build instructions"(?) to get it going.
And This Guy: OpenOCD PIC32 Programmer · kinsamanka/PICnc-V2 Wiki actually uses a RaspPi as his JTAGger, but besides that, his script and stuff is quite informative and should turn out to be quite handy...
-
JTAG = GO
06/28/2015 at 20:38 • 0 commentsLots of fiddling, finally got connection with openOCD...
Who knows whether it'd've worked without some of the additional-fiddling (e.g. figuring out where /MCLR should connect, etc.) but it does work now. THE BIG "DUH" was I was *certain* I breadboarded the MX2xx series chip, but apparently had breadboarded the MX1xx series chip, instead. (They've *very slightly* different pinouts). Swapped it out, and it connects.
I'll update the "details" section with better pinout info, and whatnot.
Yesterday's unposted post:
Not sure what's wrong with my setup, but it's not detecting my chip yet...
Had to reinstall openocd, as apparently the last time I used it was on a different (and now defunct) computer. So, thought maybe something was wrong with the setup, but apparently I'm using the exact same version (actually, installed from the same .deb)... And did some searching 'round the web and found that others have had [some amount of] success with even older versions.
A couple useful resources:
This page suggests it's possible, and with my version, and using a configuration-file that exists... (Rather'n having to configure each setting manually)
https://forum.sparkfun.com/viewtopic.php?f=18&t=28623
This page suggests TRST should be connected to pin1 /MCLR
https://github.com/kinsamanka/PICnc-V2/wiki/OpenOCD-PIC32-ProgrammerTried TRST on MCLR, both directly-connected and through a transistor-inverter... Still nogo.
Finally, decided to hook up the ol' Cable Box again, just to make sure the danged FT2232 board still works... It didn't, at first, but then I connected nTRST to VREF and it did. So.... Something to think about, in here... I don't know what, exactly.
-
Necessary Pins
06/26/2015 at 20:36 • 0 commentsFirst, working out which pins/circuitry need to be connected as a bare-minimum. (Reminder: I'm going for JTAG-programming, here... If you're planning to use MPLABX and/or a Microchip programming-dongle, or if you're looking for this to be *correct*, you're probably better-off using someone else's documentation, check out those links suggested in this project's "comments" by @Bruce Land ! Thanks for those! Especially: Tahmid's Introduction To PIC32)
I've documented my overly-wordy thought-process, but I won't bore you with those details here. I'll probably upload those docs at a later-date.
This is, pretty much, "AS I UNDERSTAND" which may be "not at all" or somewhere inbetween. I tried to be rigorous, but I haven't wired anything up yet....
( '#' = MUST BE CONNECTED per section 2.1 ) ( Minimal WITHOUT USB, WITHOUT ANALOG DECOUPLING INDUCTOR ) 3V3 ^ | \ / 10K PIC32 \ MX2xxFxxxB 3V3 / ___________ ^ | 1k | |_| | | .1uF +-/\/\-- /MCLR -|1*# #28|- AVDD -+--||--. | RA0 -|2 #27|- AVSS / AGND -+-> GND ===.1uF RA1 -|3 26|- RB15 | RB0 -|4 25|- RB14 | RB1 -|5 +24|- RB13 | RB2 -|6 (#)23|- VUSB3V3 ---> 3V3 v RB3 -|7 22|- RB11 GND<---- GND/VSS-|8# 21|- RB10 10uF TANT/CER ^ RA2 -|9 #20|- VCAP ----||--. | RA3 -|10 #19|- VSS / GND ---+-> GND ===.1uF RB4 -|11 *18|- RB9/TDO | RA4 -|12 *17|- RB8/TCK +------ V+/VDD -|13# *16|- RB7/TDI | TMS/RB5-|14* *15|- VBUS (N/C OK?) v |___________| (input to detect USB) 3V3
This pinout is pretty much the same for the MX1xxFxxxB, but there are distinct differences:NOTE: 1xx/2xx are mostly pin-compatible
NOTICED DIFFERENCES:
14 TMS (2xx)
15 RB6 vs VBUS
21 5V tolerant vs NOT
22 5V tolerant vs NOT
ALSO NOT TMS (2xx)
23 RB12 vs VUSB3V3JTAG:
I'm having some difficulty figuring out the TRST/SRST scenario... but I'm piecing it together from various sources... I THINK TRST is a N/C, and I THINK SRST is connected to /MCLR. Again, this is not yet tested. FROM PAST-EXPERIENCE with the Freescale part, it was possible to connect openOCD to the Freescale chip with NO reset pin connected... Albiet a bit unweildy. So, I think that'll be my first-attempt.
As It Stands:
FT2232 pinout: (AD#) _______ | | (plausibly: ->VREF) N/C nTRST |1 2| GND (VSS) (AD1) TDI |3 4| GND (VSS) (AD2) TDO |5 6| GND (VSS) (AD3) TMS |7 8| GND (VSS) (AD0) TCK |9 10| GND (VSS) (likely: /MCLR) N/C nSRST |11 (12)| (Index, don't populate) N/C DINT |13 14| VREF N/C |_______| (VREF: PIC32's VDD -> JTAGger?)
... today ... so-far unique amongst most my days... lots-learned, tons outside the realm of electronics... hopefully some of that will stick around.
-
A "page" written on the matter a while back...
06/26/2015 at 12:08 • 0 commentsThis is a repost of some thoughts from my "page" of a few months back: https://hackaday.io/page/884-whats-this-a-page-pic32-contemplations
Mainly a reminder regarding this link: A pretty decent write-up on LD (linker) scripts and PIC32s
Currently contemplating PIC32's...
PICs have always seemed a bit backwards to me... They've so many peripheral-features, come in so many packages, have so many different architectures (8-bit 16-bit...), Yet (if I understand correctly) there's *very little* open-source support for 'em.
I'm sorry, being stuck with Windows for developing for a microcontroller seems utterly-ridiculous to me. And more...
But, there's the PIC32...
And, somewhere, I read it's designed around a MIPS core.
Now somehow that appeals to me...
Maybe it's something to do with a project of a few months back... I tried to see what I could do with an old Cable (TV) Box that had an unknown processor in it. Thought maybe I could install linux on it, if I tried hard enough (apparently no one else has?). Or something, I dunno. But I spent a few weeks (months?) at it, and learned a lot about JTAG and MIPS. At the end I couldn't figure out the memory-mapping stuff, that was a bit beyond my reverse-engineering-skills. But, I was able to blink the two LEDs, and was pretty proud of that. (the UART was a no-go).
I do know that MIPS has been around long enough that certainly I could eventually find a resource that resonates with my learning-style...
Ages and ages ago, as part of my undergraduate-research I developed a system around an Atmel ARM-7...
I'd been doing AVRs for a while at that point, so thought this particular ARM7 (with internal FLASH and RAM) was going to be like working with an AVR... Boy was I wrong.
I got it working... I mean, really, it *worked*... The code I wrote *worked*, on the system I developed.
But even after designing a 4-layer PCB and ordering and soldering all those parts and *running* the system with my code... there was one thing I could never wrap my head around...
Basically, memory-mapping. (again).
That blasted thing was running my code straight off the FLASH memory... which seemed fine to me... That's how AVRs do it! ...Until it came to my attention that the FLASH was slowing my (what was it, 100MHz?) system to slower than my AVR projects. Quite literally, the FLASH embedded in this chip rated for 100MHz was *slower* than the FLASH embedded in AVRs.
Fine, move that code to SRAM!
How?
The Linker, of course!
Right, I fought that danged thing for ages, just *barely* grasping its functionality, let alone its obscure language. In the end, I honestly thought it'd be easier to write the code to do the transfer by hand, in assembly.
A little wiser (probably not much) now, I realize that maybe doing that transfer (from FLASH to SRAM) by hand would be difficult, since all the jumps, etc, (in my C-compiled code, meant to run from FLASH) probably couldn't be guaranteed to be relative, etc.
So, MIPS... no easier, really... Plausibly more complicated with its virtual-memory mapping (does ARM do that? I never got that far).
On the plus side, apparently some dude has a pretty decent write-up on using mips-gcc with PIC32's, including a pretty decent explanation of the linker-script.
It looks to be a *significant* amount of more work to get a PIC32 running than an AVR... no header-files, no linker-script, etc... but at least there's a resource, and a little more learning-experience.
It's a contemplation, anyhow.
OTOH, now that ARMs are everywhere, is this a worthwhile endeavor?
Well, for one thing, some PIC32s (yes 32-bit processors) apparently come in DIP packages, but no 40-pin?!! And *several* variants, to boot. Plausibly even drop-in-replaceable with some of my old AVR projects(?)
And, some of those may only be a handful of bucks ($3 for a 40MHz 32 bit processor/FLASH/RAM?! and it doesn't require fine-pitch soldering?!)
I'm kinda intrigued.
Contemplations forgotten:
How'm I gonna program this thing...? Research suggests OpenOCD via JTAG might be feasible... Took quite a bit of Googling to find anything even *remotely* to the affirmative. (Burried under tons of pages of people *asking* whether it was possible to program via JTAG met with little conclusive besides "there's a brief mention in the data-sheet"... Most of which, apparently, are on microchip's site...) This search reminded me, too, of another reason I'd avoided PICs for so long... I didn't have a programmer, and I certainly wasn't 'bouts to buy one for experimenting with just a handful of chips... but if JTAG'll do it... we'll see!