EEVblog Electronics Community Forum

Electronics => Microcontrollers => Topic started by: SirNick on September 26, 2014, 10:16:41 pm

Title: LPC from scratch
Post by: SirNick on September 26, 2014, 10:16:41 pm
In a similar vein to the 1$/1M and ghetto ARM threads, here's my work-in-progress attempt at minimal C development on NXP's LPC Cortex M series.

What are you doing, and why?
This is part learning opportunity, and part practical project.  My "dev board" is a prototype 8-port remote serial console box, intended to provide access via Ethernet, USB, or local DB-9 RS-232, to (up to) 8 serial devices, such as a managed network device like a router or switch.  I come from a telecom background, and this is usually the kind of job where one would use an older Cisco router with an async serial card, or a dedicated serial concentrator appliance.  Both options are easily >$1,000 devices, and I figure I could build something cheaper that is "good enough" nearly all of the time.

However, all that is purely to illustrate my motivation for learning ARM -- the hardware is not particularly relevant to this discussion.  The point of this thread is to document the process of learning how to build an ARM Cortex M device of your own.  This can be as simple as a breakout board exposing only power, reset, UART0, and the ISP_Enable pin; or it can be some pet project like mine.  As long as you have TTL serial access to an LPC with a boot ROM providing ISP-over-UART support, it's all good.

About the hardware
I'm tackling a complicated PCB design as well, which is probably not a great way to begin, but I'm stubborn like that.  Hopefully, my errors can serve as a useful lesson in basic hardware implementation as well.  Someone asked for reference designs recently, which are relatively difficult to find (compared to, say, AVR.)  I'll publish relevant parts of my design (don't want to muddy the waters with extraneous detail), where hopefully anyone more experienced can point out potential problems along the way.  Anything I publish here is free to use however you want.  Use it as a reference, copy it verbatim, whatever.

OK... In my case, the dev board's main CPU is an LPC4078 -- a Cortex M4F (it actually has a second M0 core, but nevermind that for now.)  It will also have one LPC812 (Cortex M0+) per downstream serial port (they ended up being cheaper than dedicated UART ICs, and allow programmable TX/RX LED control for free), so there's a bonus goal of having the main CPU flash the secondary CPUs as well.  The datasheets for these two parts (well, part families actually) seem to have 100% compatible boot ROM implementations, so I'm hoping that's the case across the product line, but I don't make any guarantees.  The 812 looks like a neat little chip on paper, and it's inexpensive, so if you're wondering where to begin, that would be as good a place to start as any.  (NOTE: It does not have an onboard ADC, if that matters to you.)

As for the software...
The only assumption is that the code will compile with GCC.  I would prefer the code to be as cross-platform as possible, and so I also have IAR Embedded Workbench installed for compatibility testing.  My preferred coding environment is Kate (KDE's multi-document, syntax-highlighting, general-purpose editor), Make, and GCC.  Anyone should be able to follow along with their choice of editor, and the GNU toolchain.  I'll provide info on how to set all that stuff up when I figure out for myself.  ;)  (In the past, I have leaned on Gentoo's automated cross-compiling framework to compile for non-native architectures, but I would like to learn more about how to set up a build environment that isn't tied to a specific distro.)

What's next?
Step one is to establish communications from a PC to the LPC's boot ROM using a standard FTDI TTL serial cable.  There are existing tools to upload HEX images, but I said "from scratch" and I mean it, so I'm brewing a DIY implementation that should compile and run in any POSIX-compliant environment.  This is where things get complicated for Windows users, as it's not particularly well suited to POSIX applications...  If I can, I'll try to write a Windows console application port as well.  In theory, OS X should be able to use the POSIX version.  I'll try to verify this.

It's up to you to provide a the TTL serial interface.  I use a standard FTDI USB-to-TTL cable.  It has a 5-pin 0.1" female header on the end with Gnd, +5v (USB Vbus), and 5v-tolerant 3.3v signalling lines for TX, RX, CTS, and RTS.  AVR fans should be familiar with how avrdude uses RTS to reset the MCU.  I'm going to try to duplicate this behavior.  Take it or leave it.  My software will happily wait for you to manually reset the MCU if you prefer.

OK, but why?
None of this is a practical, low-effort, time-to-market driven approach.  It's 100% wheel-reinventing, for the purpose of learning how to make your own wheel.  A typical complaint from ARM newbies is "where do I start?"  This guide comes from a fellow ARM newbie wondering where to start.  I don't know, so I'm figuring it out, and sharing what I learn along the way.  I'll make mistakes, and I'll do things in an unnecessarily difficult and time-consuming way.  At least I hope so.  Be patient and point it out if you see me leading others astray.  Once I have a more or less workable solution, I'll condense the material and post it on the web.

Alright, here we go. 8)

EDIT: I'll try to keep a section here up-to-date with links to pertinent topics and files.

Boot ROM Serial Flash Code (https://www.eevblog.com/forum/microcontrollers/lpc-from-scratch/msg520251/#msg520251): revision 11 (Thu., Oct. 14, 2014)
Title: Re: LPC from scratch
Post by: SirNick on September 26, 2014, 11:03:41 pm
Here's a shot of the dev board I'm working on.  The LPC4078 is the LQFP-100 package in the middle, next to the DB-9 port.  The FTDI cable connects to a header to the right side.

I've populated one "port" with an LPC812 and the RS-232 level translator.  The 812 is the TSSOP-20 on the far left, above the RJ45 cluster on the bottom.  It's the one oriented top-to-bottom.  The level translator (an Intersil part) is rotated 90-deg (left-to-right) below it.  The main CPU has the ability to selectively trigger ISP mode for each 812, which will be used down the road for IC-to-IC ISP.

Next, I'll explain the boot ROM protocol.
Title: Re: LPC from scratch
Post by: SirNick on September 26, 2014, 11:08:59 pm
The boot ROM expects a connection at 9600 baud, 8 data bits, 1 stop bit, no parity, with software (XON/XOFF) flow control.  If you start a terminal application, you can probe the device to see if communications are working.  Here's the basic flow:

- You reset the device and assert ISP_Enabled.  (Without any user code on the IC, it'll default to the boot ROM w/o having to assert ISP_En.)
- The host (PC) sends '?' repeatedly until the CPU responds with "Synchronized<CR><LF>".
- The host responds "Synchronized<CR><LF>".  The CPU should respond "OK<CR><LF>".
- The host then sends the actual system clock frequency, in kHz, as a decimal number: "12000<CR><LF>".  The CPU should again respond "OK<CR><LF>".
- You are then free to start throwing commands at it.  For example you can turn echo off, or change the baud rate and stop bits to your preference, query the part ID, unique ID, and boot ROM version, or start reading / writing memory.

Now, the docs say you must terminate lines with CRLF, and any spurious CRs and LFs will be ignored.  It also says the CPU will use CRLF to terminate its lines, however, it seems like I only get CR from the device.  That could be something the kernel is doing, but you might expect to deal with CR and/or LF as a matter of course.

To start poking at flash, you need to first unlock flash access.  This requires a code (presumably to prevent line noise from inadvertently sending an unlock command) that you have to get from your part's data sheet.  Flash sectors must also be prepared for writing (basically like turning off a per-sector read-only flag).  Then, you can erase them, copy from RAM to flash, etc.  All flash access is based on sectors, starting at 0.  Flash sectors are not all uniform in size.  It's common to see e.g., 4KB sectors for the first few, then 32KB sectors for the rest.  Check the data sheet.

RAM access is by address rather than sector, and must be word-aligned, or divisible by 4.  There's no way to write directly to flash, so you must pre-stage writes in RAM first.  You then copy from RAM to flash.

There are commands to check flash sectors for blankness (to avoid gratuitous erase cycles), and compare memory (e.g., RAM and flash to confirm valid contents after a write).

All data transfers are UUencoded, resulting in a conversion from 3x 8-bit data bytes to 4x 6-bit chars.  If you have less than three bytes remaining, pad them with 0x00.  The resulting chars are shifted into the 0x21-0x60 character space to avoid conflicting with non-printable control characters (like ESC or XON/XOFF).  Do this by taking the value and adding 0x20, except if the char's value is 0x00 -- then you add 0x60.

Data is sent in lines of up to 45 data bytes (60 chars) with the length of the line (number of 8-bit data bytes) converted to an 8-bit integer, and shifted up by 0x20 (again, to be a printable character.)  This "length" byte is the first byte in each line, immediately followed by the 60 UUencoded characters, and then CRLF.

You can send up to 20 lines at a time, then you must send a checksum.  To generate a checksum, simply add the values of each incoming data byte as it's encoded.  The resulting decimal value (byte[0] + byte[1] + ... + byte[44], for each line, for 20 lines) is sent as an ASCII number (e.g., "25140") followed by CRLF.  You should then get "OK<CRLF>" back from the MCU, or "RESEND<CRLF>" if the checksums don't match.

When you reach the end of the data, your last group will potentially be less than 20 lines, and less than 45 bytes on the last line.  Send a final checksum and watch for "OK<CRLF>".  You tell the boot ROM in advance how many bytes you're going to send, so there's no ambiguity.

Receiving data works the same way, but in reverse.

I'm attaching the code I'm working on.  It's incomplete, and I'll probably change parts of it along the way, so don't take it too seriously yet.  However, it does work so far as establishing communications, and fetching IDs and such.  I'm working on the memory access parts now.

Quick-start:
Code: [Select]
# gcc -o serial uuencode.c intelhex.c unix.c unix-cmds.c
# ./serial -p /dev/ttyUSB0 -c 12000 --verbose

For help:
Code: [Select]
# ./serial --help
EDIT:
REV 10:  Fixed some issues and cleaned up main() a little.  Added revision to version info.  (./serial --version)
REV 11:  Fixed some bugs, added line encode/decode to UUencode library, added Intel Hex library, added tests.
Title: Re: LPC from scratch
Post by: paulie on September 26, 2014, 11:44:03 pm
Judging by the number of LPC fans here this thread should be a great success. Your project board looks very interesting too. It should provide a great minimum development platform partially populated yet extremely powerful end product when completely built up. I can't wait to see how this turns out.

One question though: do you know of any serial flash programming utility that works under winblows similar to the ones from ST? This would be of great help to the majority of users who might like to play on their home desktop.
Title: Re: LPC from scratch
Post by: sca on September 26, 2014, 11:54:02 pm
One question though: do you know of any serial flash programming utility that works under winblows similar to the ones from ST? This would be of great help to the majority of users who might like to play on their home desktop.
http://www.flashmagictool.com/ (http://www.flashmagictool.com/)

sca
Title: Re: LPC from scratch
Post by: paulie on September 27, 2014, 12:05:10 am
Thanks sca. It's quite compact and installed easily. My chips haven't arrived yet but looks like I'll be ready when they do. This is my 4th venture into new ARM parts since starting out a few weeks ago and looks like the only promising one other than ST for cheapo quick start. So far two of the others turned out not to even have a bootloader. Fanboys and datasheets go through some pretty fancy footwork to hide this deficiency. Only $10-$15 loss but mostly it's the wasted time that can be very frustrating. This is looking real good so far.
Title: Re: LPC from scratch
Post by: SirNick on September 27, 2014, 12:59:02 am
You kinda have to try them all and see what speaks to you.  The boot ROM is a pretty big deal to me, as is the ability to crank these things up to like 200MHz (for the 4078, not the 812.)  I really want to like Atmel's stuff, but they're just not all that impressive.  Nice datasheets though.  IMO, ST doesn't have much going for them either, other than cost and ubiquity.  (Although, for some, that's precisely what matters.)

In the end, NXP seemed like the way to go for me.  The handy Xpresso boards were the nail in the coffin.  That said, I will probably dabble outside of brand boundaries once I have my sea legs.  Why not?  They're cheap.
Title: Re: LPC from scratch
Post by: paulie on September 27, 2014, 11:22:22 am
ST doesn't have much going for them either, other than cost and ubiquity.

Admittedly being an ST fanboy at this point I look at it a little differently. Comparing $1 chips (103c to 812) it's 128k to 16k flash, 20k to 4k ram, 3 USART to 1, 16 ADC to none, etc so for my uses ST comes out with a lot more going for it.

If we look at similar features it's probably STM8003 at $.21 vs $1.05 for LPC812M101JD20FP. In this case it almost does boil down to only a cost difference. Except maybe STM8s 5 ADC. Analog interfacing is important to me so that does tip the scales.

The handy Xpresso boards were the nail in the coffin.

Here it does look like mainly a cost issue. Searching on Ebay it's $2-$3 for 003 demo board vs $15-$20 for Xpresso. Or $7 for 103 blue board. Not really significant for me because we are talking pennies in all cases for DIY.

Maybe there are advantages to LPC that I'm not aware of yet. When the chips arrive monday I'll have both up and running for a real hands on comparison and better position to judge. Possibly I'm attached to ST because it was my "first love".  In any case I look forward to soon hitting some "strange". :)
Title: Re: LPC from scratch
Post by: poorchava on September 27, 2014, 11:49:23 am
How are you gonna debug this?

From what I know there's no good free (as in: no code size limit etc) IDE that supports debugging.

For STM32s there's CoIDE which is very good in my opinion (it's just custom compilation of Eclipse with some embedded debug-oriented stuff).
Title: Re: LPC from scratch
Post by: mrflibble on September 27, 2014, 04:01:31 pm
ST doesn't have much going for them either, other than cost and ubiquity.

Admittedly being an ST fanboy at this point I look at it a little differently. Comparing $1 chips (103c to 812) it's 128k to 16k flash, 20k to 4k ram, 3 USART to 1, 16 ADC to none, etc so for my uses ST comes out with a lot more going for it.

If we look at similar features it's probably STM8003 at $.21 vs $1.05 for LPC812M101JD20FP. In this case it almost does boil down to only a cost difference. Except maybe STM8s 5 ADC. Analog interfacing is important to me so that does tip the scales.
Perhaps a better comparison would be LPC812 vs something like an stm32f030. I mean come on, the LPC812 is a shiney cortex-m0 while the stm8s003 is a crusty old 8-bitter that is two registers short of a very small register set. Are those 0.21 danny-bucks? Because surely the lpc can be had for lower prices than $1 if you put some time into it and scour the chinese market place, same as for those 100 stm8s003's. It's either that or compare distributor prices. Which I just did and that looks pretty good for the LPC actually.

Regarding analog, I just looked it up for the lpc812 and am a bit confused. This here page (http://www.nxp.com/products/microcontrollers/cortex_m0_m0/) and a few other ones seem to suggest the lpc8xx series has an ADC in it, but the datasheets I could find do not show any ADC. It only looks to have a comparator. Only lpc1100 and up has an adc in it. Or I am looking at the wrong datasheet? Because I was actually sortof expecting the lpc800 series to have an 12-bit sar adc in it like the competition. But apparently all you get is this lousy comparator, and off you go implementing your own delta-sigma. Yeah, maybe not...

Incidentally, the stm8s only has 1 adc in it. One single 10-bit adc with an analog mux (aka 5 channels). If only it had 5 adc's, that would have made my choice a whole lot more difficult interesting. ;D

Besides cost and ubiquity ST also has nice hardware, shit vendor libraries and very nice indeed chibios going for it. Then again, NXP also makes nice chippies so maybe the LPC series is even better.

Anyways, looking forward to reading the rest of SirNick's adventures in LPC country.  :-+
Title: Re: LPC from scratch
Post by: nctnico on September 27, 2014, 04:07:47 pm
How are you gonna debug this?

From what I know there's no good free (as in: no code size limit etc) IDE that supports debugging.
Eclipse works very well for debugging. But then again debugging is not really mandatory.

Regarding the LPC800 series: they have no ADC :palm:
Title: Re: LPC from scratch
Post by: paulie on September 27, 2014, 04:32:29 pm
Perhaps a better comparison would be LPC812 vs something like an stm32f030.

As mentioned before I dont see the F030 being in the running since F103 is much superior in every respect and costs less. Lots more F103 out there too. So you can compare the LPC with that one dollar for dollar or with the 003 feature for feature (except no ADC) in which case we can buy 4x more.

Are those 0.21 danny-bucks?

No, "paulie-bucks":

(https://www.eevblog.com/forum/microcontrollers/lpc-from-scratch/?action=dlattach;attach=110565;image)

Apparently this seller bumped up 2 cents since I purchased monday and probably another 1 or 2 cents by the time I finish typing. I suspect a couple hours spent searching over the next few days can get it back down there. No matter what less than a quarter each regular price. Note that the numbers mentioned previously are for similar quantities for both chips being compared. Either 100 to 100 or 10 to 10.

Because surely the lpc can be had for lower prices than $1 if you put some time into it and scour the chinese market place, same as for those 100 stm8s003's.

From what I can tell LPC does not exist on the Chinese market. I would love to be corrected.

Incidentally, the stm8s only has 1 adc in it.

My 003s have 5 channels. We can argue endlessly about what is an ADC and what is a channel but this level of discussion tells me I've made my point. No matter what the ST has INFINITELY more ADCs.  :)

I do think SirNick is on the right track and all of the chips being discussed here stand out head and shoulders from the rest of the ARM crowd. If you are designing cell phones or just pushing a favorite oddball part due to romantic attachment then maybe not.
Title: Re: LPC from scratch
Post by: mrflibble on September 27, 2014, 05:11:19 pm
Edit: never mind, might possibly come across as a wee bit argumentative. :P

Question remaining after edit would be: since you say F103 costs less than F030.. I can get 10 STM32F030's for $7.00. I would love to get 10 STM32F103's for $6.99 or less, but cannot find anything even close. Got any link where I can buy F103's for roughly $0.70 a piece at moderate quantities (5, 10, 20)?

Anyways, I'll shut up and let SirNick get back to it.
Title: Re: LPC from scratch
Post by: legacy on September 28, 2014, 10:42:04 am
good project, great thread  :-+
Title: Re: LPC from scratch
Post by: paulie on September 28, 2014, 01:30:18 pm
Edit: never mind, might possibly come across as a wee bit argumentative. :P

Got any link where I can buy F103's for roughly $0.70 a piece at moderate quantities (5, 10, 20)?

You can't get F030 for that either. They are actually 90 cents (70+20) as can be seen in your link:

http://www.ebay.com/itm/STM32F030F4P6-IC-MCU-ARM-16K-FLASH-20TSSOP-10pcs-Lot-/291245778302 (http://www.ebay.com/itm/STM32F030F4P6-IC-MCU-ARM-16K-FLASH-20TSSOP-10pcs-Lot-/291245778302)

The truth is all chips mentioned so far, including the LPC, hover around a dollar. None are half the other, none 2x more. Pennies difference. So it really boils down to features and availability. Only two stand out there and F0 is not one.

BTW Arguments are how we learn which does not happen when everybody agrees. But this does drift off topic so moved here:

https://www.eevblog.com/forum/microcontrollers/one-dollar-one-minute-arm-development/msg520941/#new (https://www.eevblog.com/forum/microcontrollers/one-dollar-one-minute-arm-development/msg520941/#new)
Title: Re: LPC from scratch
Post by: Brutte on September 28, 2014, 04:56:33 pm
Perhaps a better comparison would be (..) the LPC812 is a shiney cortex-m0 while the stm8s003 is a crusty old 8-bitter (..). Are those 0.21 danny-bucks? (..)Regarding analog (..)Incidentally, the stm8s only has 1 adc in it. (..) Besides cost and ubiquity(..)
This "crusty old" 8-bitter is 7 years old and "shiny M0" is 5 years old. Living on the edge?
The volume price is indeed in the range of $0.20-$0.40 for that 8k device. As for analog, in the world of smallest uCs term "5 x ADC" is precise enough.

As for NXP - their (nice) forum was deliberately terminated by NXP staff. Not sure if the forum still exists.
Things you should be LPC-aware of*:
*These are my personal experiences I had with LPC1769/11C12/1114, LPCLink and LPCXpresso.
Title: Re: LPC from scratch
Post by: zapta on September 28, 2014, 05:23:16 pm
One question though: do you know of any serial flash programming utility that works under winblows similar to the ones from ST? This would be of great help to the majority of users who might like to play on their home desktop.

With some LPC's with USB (e.g. LPC11u35), it's even easier. You hook it to your computer, it appears as a disk, you copy/drag your binary to it and you are done.
Title: Re: LPC from scratch
Post by: ehughes on September 28, 2014, 11:45:16 pm
Quote
With some LPC's with USB (e.g. LPC11u35), it's even easier. You hook it to your computer, it appears as a disk, you copy/drag your binary to it and you are done.

The other ones I know of are :

LPC11U68  (M0)
LPC134x   (M3)


Most others have USB DFU and basic serial port  (FlashMagic is a popular tool for the serial port).


I tend to like NXP as the bootloader in ROM can be a lifesaver.
Title: Re: LPC from scratch
Post by: paulie on September 29, 2014, 03:51:41 pm
I was fascinating by the prospect of virtual drive flashing. That is until the $5-$10 per chip price tag came up.

It may be possible to replace the stock bootloader on one of the cheap ones like LPC812 but that would probably require a 12mhz crystal and may not fit. The old V1 Stlink worked like that but those are discontinued.
Title: Re: LPC from scratch
Post by: nctnico on September 29, 2014, 04:19:02 pm
I was fascinating by the prospect of virtual drive flashing. That is until the $5-$10 per chip price tag came up.
I see that as a small price to pay for a bit of luxury and I'm pretty sure you can find these controllers for a lower price in larger quantities. IMHO one of the mistakes people make is just looking at the price of a part instead of looking at the complete package they get. One of the major advantages of the LPC series from NXP is that the peripherals are kept the same between the low end and high end parts so porting or re-using existing code is a piece of cake. In the other thread 'One dollar... ' people mention using ST's library to make existing code compatible between controllers. With the LPC series you don't need that. Ofcourse you could say your spare time is free but if you spend some of it on working in the local super market you can make more money in 1 hour than the price difference between an easy to use chip or an obfustigated chip.
Title: Re: LPC from scratch
Post by: zapta on September 29, 2014, 04:31:52 pm
I was fascinating by the prospect of virtual drive flashing. That is until the $5-$10 per chip price tag came up.
I see that as a small price to pay for a bit of luxury and I'm pretty sure you can find these controllers for a lower price in larger quantities.

Yes, easily half price, and the USB serial is also great for debugging or hooking the mcu to a computer for data, and the lpcxpresso idea/tool chain is easy to install and is os agnostic. Almost beats arduino :)
Title: Re: LPC from scratch
Post by: SirNick on September 29, 2014, 09:20:05 pm
IMO, ST doesn't have much going for them either, other than cost and ubiquity.

OK, in light of the ensuing comments, I should really take that back.  It's just my perception based on the things that were important to me when I was choosing a vendor, and not a qualified opinion in any way.  I also managed to overlook the lack of ADC on the 812.  I didn't have a need for it yet, so failed to notice it wasn't there.  Kind of a set back for general hobbyist use without at least a couple channels.  Oh well.

How are you gonna debug this?

It's not really in the cards, at least for now.  Emphasis on the "minimal C environment".  This is targeted primarily for those wanting to really understand the nuts and bolts of ARM development, from the beginning.  Those that are content to learn an IDE and approach development from a high level, with all the amenities, are probably going to find this primitive, and needlessly archaic.  That's OK.  I follow the evolutionary chart below.

Title: Re: LPC from scratch
Post by: SirNick on September 29, 2014, 09:28:05 pm
It may be possible to replace the stock bootloader on one of the cheap ones like LPC812

AFAIK, it isn't.  It's a boot ROM.  (I am prepared to stand corrected though.)
Title: Re: LPC from scratch
Post by: nctnico on September 29, 2014, 09:51:19 pm
AFAIK it should be possible to replace the boot rom. It seems to be just flash. I recall someone has disassembled the NXP bootloader to find out how the flash is begin programmed at a low level but I never got his code to work.
Title: Re: LPC from scratch
Post by: SirNick on September 30, 2014, 05:28:25 am
Looking at the LPC81x data sheet, the memory map shows this:

Code: [Select]
0x0000 0000 4kB Flash (810), 8kB Flash (811), 16kB Flash (812)
0x0000 4000 reserved
0x1000 0000 1kB SRAM (810), 2kB SRAM (811), 4kB SRAM (812)
0x1000 1000 reserved
...
0x1FFF 0000 8kB Boot ROM
...

The flash sectors, per the ISP section in the manual, show flash sectors:

Code: [Select]
00: 0x0000 0000 - 0x0000 03FF
01: 0x0000 0400 - 0x0000 07FF
...
14: 0x0000 3800 - 0x0000 3BFF
15: 0x0000 3C00 - 0x0000 3FFF

So, no overlap there between flash sectors and the memory region where the boot ROM is located.  You could probably copy the ROM region to flash, and then change it... but AFAIK, you can't copy your changed code back to the ROM region again.

Anyone know if there is a way?
Title: Re: LPC from scratch
Post by: westfw on September 30, 2014, 07:32:42 am
Quote
My "dev board" is a prototype 8-port remote serial console box, intended to provide access via Ethernet, USB, or local DB-9 RS-232, to (up to) 8 serial devices, such as a managed network device like a router or switch. ...  this is usually the kind of job where one would use an older Cisco router with an async serial card, or a dedicated serial concentrator appliance.
Ah, a subject near and dear to my heart.  The early cisco "Terminal Server" code ran in about 512k of memory on a 68000 (RAM, including both data and instructions.  But rather heavily dependent on the all-ram architecture.)   That included IP/TCP/Telnet/rlogin/slip/ppp and probably some other stuff, though it was a tight squeeze...  IMO, it should be relatively easy to fit equivalent code on something like the TI "Connected" Tiva Launchpad (1MB flash, 256k RAM, $20.)   But oh, the amount of infrastructure that needs to be recreated!

Quote
[replacing the boot ROM]
I assume that anything called "ROM" is not eraseable or re-programmable by a user.  However, it should certainly be possible to put a more traditional bootloader in regular flash memory, and have it do whatever you want.  Especially given the ARM ability to redefine the vector table address.
Title: Re: LPC from scratch
Post by: neslekkim on September 30, 2014, 08:36:10 am
One question though: do you know of any serial flash programming utility that works under winblows similar to the ones from ST? This would be of great help to the majority of users who might like to play on their home desktop.

With some LPC's with USB (e.g. LPC11u35), it's even easier. You hook it to your computer, it appears as a disk, you copy/drag your binary to it and you are done.

Same as ST did with Nucleo-boards: http://norwied.wordpress.com/2014/05/07/first-steps-with-my-nucleo-f401re/ (http://norwied.wordpress.com/2014/05/07/first-steps-with-my-nucleo-f401re/)
Title: Re: LPC from scratch
Post by: nctnico on September 30, 2014, 10:18:57 am
I assume that anything called "ROM" is not eraseable or re-programmable by a user.
Ask yourself how they program the bootloader during production. They already have flash on the chip so it doesn't hurt to put a little bit extra on it.
Title: Re: LPC from scratch
Post by: dannyf on September 30, 2014, 11:04:00 am
Quote
Same as ST did with Nucleo-boards

The Nucleo board is interesting. The one I have has a st-link v1 harhdware and st-link v2 software. Totally weird.
Title: Re: LPC from scratch
Post by: SirNick on September 30, 2014, 07:24:03 pm
Ask yourself how they program the bootloader during production. They already have flash on the chip so it doesn't hurt to put a little bit extra on it.
Mask ROM?  I dunno.  I read a forum post somewhere where one of the mods recommended "using a newer chip" to troubleshoot a bootloader issue, because the OP's ROM version was old.  Circumstantial, but indicative that it isn't fixable with a flash update.
Title: Re: LPC from scratch
Post by: nctnico on September 30, 2014, 08:14:09 pm
That is because the tools don't support reprogramming the bootloader flash.
Title: Re: LPC from scratch
Post by: SirNick on September 30, 2014, 10:26:28 pm
Unless you have info the rest of us don't, it doesn't seem to be a limitation of the tools.  It's that the bootloader region isn't an addressable flash sector, if it's flash at all.

From ISP, you should be able to read this area of memory... haven't tried yet, but I will in a bit.  I expect writes (with the write-to-RAM command) to fail since it's not a RAM address.  Likewise, since there's no corresponding sector number, the copy-RAM-to-flash command won't be able to address it.

If there is a way to write to this region, it's not exposed by ISP.  IAP (in-application programming) has a limited set of the same commands -- namely, copy-RAM-to-flash, which still requires a sector number as the destination.  So no-go there either.  Not sure what would happen if you set a pointer to that region in the memory map and tried to write to it.  Maybe a null-op, maybe an exception, who knows?  I doubt the contents would change in a way that persists across power-cycle though.  Curious parties are welcomed to give it a try and report back.
Title: Re: LPC from scratch
Post by: nctnico on September 30, 2014, 10:47:30 pm
You are overthinking things. As I wrote before: many years ago I have read an article from someone who claimed he could overwrite the bootloader in an LPC chip. I just can't find the article. He got that information from disassembling the bootloader. It is easy enough to do. Just write a piece of code which dumps the bootloader area as a hex file to the serial port, save to disk and disassemble it. There is an undocumented peripheral which deals with erasing/writing the flash.
Title: Re: LPC from scratch
Post by: SirNick on October 01, 2014, 01:53:49 am
You are overthinking things.
I don't think I am:

If there is a way to write to this region, it's not exposed by ISP.
Which, so far, is true.  Although maybe with the caveat: "Not exposed by documented ISP commands".

As I wrote before: many years ago I have read an article from someone who claimed he could overwrite the bootloader in an LPC chip. I just can't find the article. He got that information from disassembling the bootloader. It is easy enough to do. Just write a piece of code which dumps the bootloader area as a hex file to the serial port, save to disk and disassemble it. There is an undocumented peripheral which deals with erasing/writing the flash.
Did you really mean "undocumented peripheral"?  Or, did you mean ISP command, or an undocumented instruction used by the bootloader?  Anyway, could be possible, and while slogging through uncommented, symbol-less, disassembled code isn't my idea of fun, it might be possible to find that functionality if it exists.

I just finished writing an Intel Hex library for my flash util, so I'm not too far from implementing read/write functionality.  Or, someone else can use one of the existing tools to do this.  Boot ROM is 8kB at 0x1FFF 0000.
Title: Re: LPC from scratch
Post by: neslekkim on October 01, 2014, 11:27:19 am
Quote
Same as ST did with Nucleo-boards

The Nucleo board is interesting. The one I have has a st-link v1 harhdware and st-link v2 software. Totally weird.

Hm, I thought they all had st-link v2-1? (not sure what differs between v2 and v2-1 though), i have 8 of these now (ok, kinda stupid, but couldn't help myself), and all seem to have exact same design, other than the main chip, wonder if all also are pincompatible?, so that is the criteria to become an nucleo board?
Title: Re: LPC from scratch
Post by: dannyf on October 01, 2014, 02:20:01 pm
They used different chips with the same packaging. So aside from those arduino-like pins, pin out is mostly the same but not identical.

Nucleo boards seem to be mbed designed and st manufactured? There is this online ide/compiler from mbed that sets them apart. But the code can be compiled offline, using mbed library or gcc.

They are good value for the money, particularly vs. the cost of the chips + ebay boards.
Title: Re: LPC from scratch
Post by: neslekkim on October 01, 2014, 07:28:41 pm
yes, about $10 pr board, I can dig that all day long.
Title: Re: LPC from scratch
Post by: zapta on October 01, 2014, 11:45:22 pm
I am spending some time creating my standard LPC based development environment, libraries, etc, similar to what I had with atmega328. The goal is to have C/C++ code line that can easily installed on lpcexpresso, can be shared by multiple projects (hence the library), targets barenone boards with lpc11uxx MCU's and is a easy and practical starting point for arbitrary projects. Currently I  am testing it with  Embeded Artists QSB lpc11u35 which is very minimal (good) but will later cut my own application specific boards.

I chosen LPC because of the OS agnostic Eclipse based IDE and the ability to update the firmware via the USB port, no tools necessary (for debugging I am a using Link 1 board)

So far it is going well and I am happy with lpcxpresso. It is quick, configurable, git friendly, the cross references work great, and it feels like home.

Here is my hello world example (binary size ~5K).

Code: [Select]
#include "ezlpc.h"

#include "usb_serial.h"
#include "system_time.h"

int main(void) {
  // Initialization
  ezlpc::setup();
  usb_serial::setup();

  // Actual program
  for (int i = 0; ; i++) {
    usb_serial::printf("Hello world: %d, %04x, %d\n", i, i, 10000 / i);
    system_time::delay_ms(1000);
  }
}
Title: Re: LPC from scratch
Post by: paulie on October 02, 2014, 09:19:41 am
Unless you have info the rest of us don't, it doesn't seem to be a limitation of the tools.

I suspect that is exactly the situation. Like the ST boot "ROM" which can be altered but only with a special upgrade utility. The upgrade files themselves are highly encrypted. One fellow claimed to have broken it but no evidence this was true. Out of several thousand Baseflight users no single case of corruption. Like with AVR and PIC there are most certainly hardware features available to prevent reading too.
Title: Re: LPC from scratch
Post by: Brutte on October 02, 2014, 01:31:53 pm
One fellow claimed to have broken it but no evidence this was true.
Any reference?
Title: Re: LPC from scratch
Post by: paulie on October 02, 2014, 03:09:25 pm
http://www.taylorkillian.com/2013/01/retrieving-st-linkv2-firmware-from.html (http://www.taylorkillian.com/2013/01/retrieving-st-linkv2-firmware-from.html)

It has been discussed here before. Like a lot of this stuff appears to be typical internet trolling. Some say the chinese clones used it but subtle differences belie that. Versaloon is another attempt that flopped.

I would like to know if there is any more information on programming LPC with STlink. It's not an option in Flashmagic.
Title: Re: LPC from scratch
Post by: SirNick on October 02, 2014, 07:06:21 pm
Via SWD?  No idea.  What would be the point, vs. using the boot ROM or USB disk mode?  Were you thinking the ROM area might be accessible that way?

Minor progress update:

Hoping to have the test harnesses for UUencode and Intel Hex libraries finished today.  (EDIT: This is done.  Added a .tar file -- because tar.gz/bz2 isn't supported by the forum -- to the boot ROM discussion page.  Added an index section on the first post to make it easy to find these things.)

Once they test out to be (presumably) bug-free, I'll start hammering on memory R/W code.  I have a few changes in mind to get more of the session code to be usable both from the PC app and as an IC-to-IC library.  Might add that this time or wait until I start refining it later on.  (It's not terribly elegant code just yet.  First draft never is.)

I would like to get some test code loaded onto the chip and start verifying basic I/O before publishing reference schematics, just to avoid having anyone duplicate mistakes that may not be apparent yet.

Until then, keep up the conversation.  :)
Title: Re: LPC from scratch
Post by: westfw on October 02, 2014, 09:52:00 pm
BTW, I tried reading the STM32F103 boot rom, and it doesn't work (presumably it bus-errors due to protection failure, and uses the same protection mechanism as YOUR code in protected flash would have.)  The flash write mechanism (on ST) has 32 or 64 bits worth of "keys", which doesn't sound promising from a "guess" point of view.  I'd strongly suspect that if the boot "rom" isn't secure, then neither is any code a customer would put in flash...
Title: Re: LPC from scratch
Post by: SirNick on October 02, 2014, 11:02:24 pm
Not necessarily.  LPCs have Code Read Protection support.  You write a certain value to a certain location in flash to set it.  CRP is pretty serious business.

At level 1, you can't write to RAM below a certain address, you can't write to flash sector 0, you can't erase sector 0 unless you erase everything, you can't read memory at all...

At level 2, you can't even write to memory anymore.  You can't execute from arbitrary locations in memory, and you can't access SWD.

At level 3, you can't even get into ISP mode.  They also warn you that no future factory testing can be performed.

If you're worried about someone exploiting the boot ROM by replacing it with less secure code, you can just enable CRP at level 3.  Then, if the vendor hasn't back-doored the code themselves (which is ALWAYS a risk), it probably can't happen.  At least, not in any way that couldn't be used even without the aid of ROM hacks.
Title: Re: LPC from scratch
Post by: SirNick on October 16, 2014, 11:33:38 pm
I added code to start poking around in memory, and ran into something I thought was interesting given the previous discussion about boot ROM.

Code: [Select]
# ./serial --verbose -p /dev/ttyUSB0 -c 12000 -i 47193f47 -l 23130 -t 500 --check 0,30 --prepare 29,1 --copy 0x1fff0000,0x00078000,4096
Serial port /dev/ttyUSB0 opened
Synchronizing...  OK
Setting clock frequency... OK
Disabling echo... OK
Getting part ID... 0x47193f47
Getting unique ID... 0x01011b1e 0x53320000 0x52d1a647 0xf5000003
Getting ROM version... 4.8
Unlocking flash with code 23130... OK
Checking for 30 blank sectors starting at 0
Requsted range is blank
Preparing 1 sectors for write starting at 29
done
Copying 4096 bytes from 0x1fff0000 to 0x00078000
Copy failed: (4) Source address is out of mapped region

OK, you can't copy directly from the boot ROM region to flash.  Wonder if it will let you copy it to SRAM first?

Code: [Select]
# ./serial --verbose -p /dev/ttyUSB0 -c 12000 -i 47193f47 -l 23130 -t 500 --check 0,30 --prepare 29,1 --copy 0x1fff0000,0x10000000,4096
Serial port /dev/ttyUSB0 opened
Synchronizing...  OK
Setting clock frequency... OK
Disabling echo... OK
Getting part ID... 0x47193f47
Getting unique ID... 0x01011b1e 0x53320000 0x52d1a647 0xf5000003
Getting ROM version... 4.8
Unlocking flash with code 23130... OK
Checking for 30 blank sectors starting at 0
Requsted range is blank
Preparing 1 sectors for write starting at 29
done
Copying 4096 bytes from 0x1fff0000 to 0x10000000
Copy failed: (5) Destination address is out of mapped region

Nope.  Can't do that either.  Presumably, you can't copy TO SRAM at all, just from SRAM to flash.

So, now ya know.
Title: Re: LPC from scratch
Post by: Jeroen3 on October 17, 2014, 06:00:10 pm
Bootloader flash is masked in the chip. This cannot be changed.
That's why the first generation of the dual core LPC's have this reset bug when booting from SPIFI memory.
http://www.nxp.com/documents/errata_sheet/ES_LPC43X0.pdf (http://www.nxp.com/documents/errata_sheet/ES_LPC43X0.pdf)
There also is a USB driver api available in some parts. Don't know about this, might be masked as well.

But, there are also a lot of OTP bytes that are not documented, for oscillator trim for example, as well as multiple peripherals (or entire cores) that are turned off.
Some LPC's can also enable or disable features using a specific pattern at a random location in user flash.
Good luck finding those if they're not documented.

If you want to read all the chip's memories, look into the programming algorithms used with your ide. For starters, they execute from ram.
Title: Re: LPC from scratch
Post by: nctnico on October 17, 2014, 06:56:51 pm
No need to mess with programmers. Just create a piece of firmware which dumps the content of the boot rom as a hex file to the serial port. Shouldn't take more than 20 lines of code. From there load the hex file in a dissassembler. One of the remarkable things about machine code is that a dissassembler gets into sync with the code pretty quick even if you start at a completely random address.
Title: Re: LPC from scratch
Post by: paulie on October 17, 2014, 07:17:55 pm
Bootloader flash is masked in the chip.

By that if you mean masked ROM (which is not flash BTW) then it's unlikely. The same claim was recently made for 3 other MCUs (AVR, PIC, STM32) and was demonstrated not to be true. Purposely make difficult to alter for obvious reasons but not bulletproof. Do you have a credible source for your information?
Title: Re: LPC from scratch
Post by: SirNick on October 17, 2014, 07:39:13 pm
Do you happen to know if this area is actually readable during normal execution?  I would think so, since it has to be executable (and thus, readable) during boot.  But, who knows, NXP could protect it from user code.  It's apparently unavailable from the boot ROM interface.

In reality, I don't know if there's anything to gain by looking at the ROM, I'm just curious if it can be done by normal means, or if it takes some kind of ... "persuasion" to accomplish.  :)  I'm just having fun poking at them for now.

Quick status update on the flash code:

I have extracted the platform-specific code from the ISP client interface.  It should now be cross-platform compatible.  The POSIX stuff (basically, main() and the serial interface parts) are in their own module.  I'm working on porting this part to Win32 Console, and providing a lightweight abstraction interface (for the serial calls) for AVR / Arduino, and LPC.

Since starting this project, I've realized that the flash util needs to have a map of flash sectors to memory addresses, since this varies by part; and needs to know where in RAM it can stage incoming data before it gets written to flash.  For now, the CLI exposes the internal commands 1:1, so you have to work this out on your own.  But ideally it should be as simple as choosing a hex file and having the util handle the rest.  In other words, a part database.  Yuck.  Would be nice if this info was available from the boot ROM, since it's inherently going to be device-specific code anyway......

Also:  Windows programming sucks.  FormatMessage() is like strerror() and sprintf() bundled into one, with a little iconv() thrown in for good measure.  But the real surprise was finding that the C99 integer types (intXX_t) don't exist in VS2010.  2010!!  ><  And, while VS2013 finally got around to adding them, at least according to a note on one of the betas, sprintf() works now, but sNprintf() didn't make it because they "ran out of time" implementing it.  So, when it comes down to adding a byte counter in your format loop, or having user code suffer buffer overflows, I guess the choice is obvious.  Oy vey......
Title: Re: LPC from scratch
Post by: paulie on October 17, 2014, 08:47:06 pm
NXP could protect it from user code.

It's SOP for most MCUs to have multiple options for read and write protection. Usually protection from outside access (ISP), protection from inside (user code), and protection from everything except hidden protocols (factory id, serial #, etc). I have intimate knowledge here regarding PIC, AVR, and STM32. Not LPC but I'm guessing with 99.9% probability no different.

Note that masked ROM is very expensive now compared to flash. Just the opposite of how it was back in the old days.

Also:  Windows programming sucks.

Two words: Py... Thon...
Title: Re: LPC from scratch
Post by: Jeroen3 on October 17, 2014, 09:19:08 pm
By that if you mean masked ROM (which is not flash BTW) then it's unlikely. ... Do you have a credible source for your information?
Yes, rom. And I worked with one of the first lpc4350's while I was at nxp for a while. Those with the many bugs.
Title: Re: LPC from scratch
Post by: SirNick on October 17, 2014, 09:21:59 pm
Oh, dear me, no.  I needs muh white space.  Besides, this exercise is part wheel reinventing for the sake of a tutorial (on the protocol, on crossdev...), and part practical library so I can have MCU A flash MCU B.  I could be wrong, but I don't think there's a way to run Python code on a micro.  ;)

(I'm wrong about that, aren't I?  Thinking about it, I have no doubt someone out there has done this...)

Just found out Win32 has no getopt() equivalent.  Of course it doesn't.  Why would it?  :palm:  (getopt_long(), technically.)
Title: Re: LPC from scratch
Post by: Jeroen3 on October 17, 2014, 09:23:40 pm
You should seriously consider opening you Microsoft vendorlock and find Qt.
Title: Re: LPC from scratch
Post by: nctnico on October 17, 2014, 09:44:15 pm
Do you happen to know if this area is actually readable during normal execution?  I would think so, since it has to be executable (and thus, readable) during boot.  But, who knows, NXP could protect it from user code.  It's apparently unavailable from the boot ROM interface.
... because there is no use to read the ROM through the regular programming interface. Years ago I found this nice web page which explained the inner workings of the LPC bootrom in great detail (the author used the route I described to get a boot rom dump and dissassemble from there) but I really can't that web page any more.
Title: Re: LPC from scratch
Post by: SirNick on October 18, 2014, 04:01:22 am
You should seriously consider opening you Microsoft vendorlock and find Qt.

That's one option.  There are many libs out there which appear to help ease the divide ... Boost, Cygwin, etc.  However, for a small utility like this, it seems like overkill.  Most of those are C++, for one, which I don't know very well, and try to avoid unless there's a good reason.  (Afterall, you can always mix C with C++ apps, but not so easily the other way.)

Mostly, I have a hard time justifying dependencies for an app this size.  I am torn what to do about getopt_long() though...  Concede to using a library (and end up with .DLLs), include the .c and .h files necessary to build it within the executable (but then I have to comply with GPL), or re-write it myself (thus reinventing a much less interesting wheel).

Ugh.  How is this kind of thing not part of the standard C library on Windows?
Title: Re: LPC from scratch
Post by: SirNick on October 18, 2014, 04:39:21 am
Hey, while I'm thinking of it...  I haven't looked too closely at Intel Hex files before, so while writing a parser for them, I found out there is addressing info encoded in there too.  Go figure.

AFAIK, raw binary images don't indicate where the data should be located.  I.e., to upload a binary image to flash, you would have to specify where you want the image to be written.  Syntax to write 32KB from the image to flash might look something like this:

Code: [Select]
--write 0x00000000,32768,bin="image.bin"or
Code: [Select]
--write image.bin --address 0x00000000 --size 32768
But then we have Hex images, which DO have this information encoded into them.  In terms of flexibility to do "weird and wonderful things", what would your expectation be, given the examples above, but with a Hex file as the source?  Alternatively, which would be most useful?

A) Write up to 32KB of data, if the file has content that is supposed to be placed at 0x0000 0000.  I.e., obey address and offset from the file, and allow the user to subset this with the CLI options.  If the address isn't found in the source file, it's a no-op.

B) Do not support address and size fields on the command line for Hex files.

C) Use the address given on the command line as a base address and the per-line offsets are relative to that.  BUT-- In this case, what should be done about address fields in the file?  (That is, the record types that set a 16-bit segment address or 32-bit linear address.)  Ignore them?  Keep them relative to the base address?  Set the base address when encountering them, possibly ignoring the CLI?  Stop processing?

D) Ignore all address / offset info and treat the file as raw data.  (This seems dangerous, since there's no guarantee the data is meant to be contiguous.)
Title: Re: LPC from scratch
Post by: zapta on October 18, 2014, 05:08:55 am
A quick update, I uploaded gerber files (2 layers, using Elecrow cam file) and ordered 10 1mm boards from elecrow. Will see how it goes.

https://github.com/zapta/arm/tree/master/mini-pro/eagle
Title: Re: LPC from scratch
Post by: gmb42 on October 18, 2014, 11:44:19 am
Also:  Windows programming sucks.  FormatMessage() is like strerror() and sprintf() bundled into one, with a little iconv() thrown in for good measure.  But the real surprise was finding that the C99 integer types (intXX_t) don't exist in VS2010.  2010!!  ><  And, while VS2013 finally got around to adding them, at least according to a note on one of the betas, sprintf() works now, but sNprintf() didn't make it because they "ran out of time" implementing it.  So, when it comes down to adding a byte counter in your format loop, or having user code suffer buffer overflows, I guess the choice is obvious.  Oy vey......

For the int_XX types try including stdint.h, the header where the C99 standard says they should be defined.  It exists in my copy of VS2010, note that just having this header file doesn't make VS2010 C99 compliant.

For snprintf, use _snprintf, see here (http://"http://msdn.microsoft.com/en-us/library/2ts7cx93(v=vs.100).aspx") for more info.

For getoptlong, first note that it's part of the POSIX standard, and usually on Linux is provided by the GNU C library, e.g. from the GNUC C manual (my added emphasis):

Quote
The getopt and getopt_long functions automate some of the chore involved in parsing typical unix command line options.

Having said that there are getopt libraries for use with Visual Studio, e.g. here (http://"http://www.codeproject.com/Articles/157001/Full-getopt-Port-for-Unicode-and-Multibyte-Microso") and probably many others.


Title: Re: LPC from scratch
Post by: nctnico on October 18, 2014, 01:03:40 pm
Using GCC (mingw32) + Eclipse instead of Visual studio gives you a programming environment which is much more like Linux. For using a serial port in a cross-platform way I suggest to look for a component called wxCTB: https://iftools.com/opensource/ctb.en.php
Title: Re: LPC from scratch
Post by: paulie on October 19, 2014, 02:21:00 am
A quick update, I uploaded gerber files (2 layers, using Elecrow cam file) and ordered 10 1mm boards from elecrow. Will see how it goes. https://github.com/zapta/arm/tree/master/mini-pro/eagle

Are those for your "arm-mini-pro"? Why here?

If so I am quite interested because this looks like a perfect board for that chip. A couple friends might also like to build one and Gerbers would be helpful. Unfortunately I can't get into that page. Would it be possible to zip them up here or better still in the other thread?
Title: Re: LPC from scratch
Post by: SirNick on October 19, 2014, 02:31:40 am
For the int_XX types try including stdint.h, the header where the C99 standard says they should be defined.  It exists in my copy of VS2010, note that just having this header file doesn't make VS2010 C99 compliant.
Ah crap.  I'm speaking from the wrong end again.  You're right, stdint.h IS included.  It's just inttypes.h that doesn't exist.  So, intXX_t are available, but PRIu32, etc, are not.  I had imported my POSIX files directly, saw a bunch of squiggly lines (the IDE's way of saying "can't find this header"), and was surprised to see inttypes.h as one of them, so I started researching and found out it doesn't exist due to incomplete C99 support.  I found the MSIntType project on Google Code that has both stdint.h and inttypes.h, so I've been using those instead.  Totally missed the fact that stdint.h did actually resolve to a valid file.  Sorry about that.

Oh, and yes, I do get that C99 is more than just integer types.  Fun fact I learned recently:  MOST compilers are not fully compliant.  (Just closer than VS.)

For snprintf, use _snprintf, see here (http://msdn.microsoft.com/en-us/library/2ts7cx93(v=vs.100).aspx) for more info.
Hey.. great!  Thanks!

For getoptlong, first note that it's part of the POSIX standard, and usually on Linux is provided by the GNU C library
Yep, understood.  I made it a point to look up native getopt-like CLI processing functions on Win32, and from what I could find via StackOverflow and MSDN, there really is no equivalent.  It seems like a fairly obvious omission.  Even GUI apps often have command-line options, so I figured there would be a built-in API to help with the typical chores associated with parsing them.

Having said that there are getopt libraries for use with Visual Studio, e.g. here (http://"http://www.codeproject.com/Articles/157001/Full-getopt-Port-for-Unicode-and-Multibyte-Microso") and probably many others.
I found a few.  Some are direct ports of the GNU LibC versions, which come with the responsibility to uphold GPL terms, while others are written from scratch (and may or may not have licensing terms.)  Fewer ports of getopt_long(), although I did find at least one -- but again, a port of GNU code.  Hence the thinking-out-loud about whether I want to bother with DLLs, concede to GPL compliance, or go an entirely different direction.

Using GCC (mingw32) + Eclipse instead of Visual studio gives you a programming environment which is much more like Linux.
I looked into MinGW, which I might end up using eventually, but probably not on this.  I don't like Eclipse at all though.  I'm not a huge fan of VS either, although I do want to maintain VS project files.  CMake supposedly helps with that.  Yet another tool to learn... sigh...  ;)

For using a serial port in a cross-platform way I suggest to look for a component called wxCTB: https://iftools.com/opensource/ctb.en.php (https://iftools.com/opensource/ctb.en.php)

That part's already done.  Windows doesn't use POSIX I/O calls, but the native API is close enough that a few light wrappers will do the job.  I have to abstract them anyway, since I want the libraries to work on various microcontrollers as well.
Title: Re: LPC from scratch
Post by: gmb42 on October 19, 2014, 08:50:12 am
For getoptlong, first note that it's part of the POSIX standard, and usually on Linux is provided by the GNU C library
Yep, understood.  I made it a point to look up native getopt-like CLI processing functions on Win32, and from what I could find via StackOverflow and MSDN, there really is no equivalent.  It seems like a fairly obvious omission.  Even GUI apps often have command-line options, so I figured there would be a built-in API to help with the typical chores associated with parsing them.

Unfortunately it has never figured in the Win32 API, so grabbing an external piece of code, or writing your own has always been the way.

I'm not a huge fan of VS either, although I do want to maintain VS project files.  CMake supposedly helps with that.  Yet another tool to learn... sigh...  ;)

CMake does produce good VS solution files (and Makefiles for other platforms) but the learning curve for anything other than a toy project is immense.  Makes ARM toolchain setup on Windows look like a walk in the park.  Their docs are very similar to MSDN, they describe all the functions in detail, but not how to bring it together in a coherent manner.
Title: Re: LPC from scratch
Post by: SirNick on October 21, 2014, 12:27:11 am
Well, new day new problem.  I traded out the LPC4078 dev board for a minimal LPC812 on breadboard setup.  My test app did not synchronize, so I ran through the process in Minicom to see what was happening.

I sent a '?', and got "Synchronized" back, so I sent "Synchronized" in return.  But, instead of getting "OK" from the micro, the cursor just moves back to the beginning of the line (ala carriage-return).  Hm.  I tried sending the clock speed ("12000") anyway.  I get as far as "12" and then each 0 just echoes back garbage characters.  So the session goes like this:

Code: [Select]
>> ?
<< Synchronized
>> Synchronized
>> 12000
<< (garbage after the '2')

I tried swapping between a Prolific USB serial to TTL cable and an FTDI equivalent.  No change.  Pulled out another breakout PCB and a new 812 -- same behaviour.  Just in case it had something to do with line endings, I emerged lpc21isp and it had the same problem my script has (Synchronizing.... timeout).

Any ideas?
Title: Re: LPC from scratch
Post by: paulie on October 21, 2014, 01:05:46 am
Following your description I was able to get all the way to display version and command list. Initially under MSDOS using a turbo C 2.0 program then Python under XP. Both about 100 times easier than my experiences with dot net and C#. It looks like you are doing everything right so IDK. You're shorting the right ISP pin for your version? I know that is different for older chips.
Title: Re: LPC from scratch
Post by: nctnico on October 21, 2014, 11:24:53 am
just moves back to the beginning of the line (ala carriage-return).  Hm.  I tried sending the clock speed ("12000") anyway.  I get as far as "12" and then each 0 just echoes back garbage characters.  So the session goes like this:

Code: [Select]
>> ?
<< Synchronized
>> Synchronized
>> 12000
<< (garbage after the '2')

I tried swapping between a Prolific USB serial to TTL cable and an FTDI equivalent.  No change.  Pulled out another breakout PCB and a new 812 -- same behaviour.  Just in case it had something to do with line endings, I emerged lpc21isp and it had the same problem my script has (Synchronizing.... timeout).
I have had similar problems with lpc21isp and it seems to be an order-of-commands or timing issue. Flashmagic gets it right so I suggest to make a trace of what Flashmagic sends and mimic that.
Title: Re: LPC from scratch
Post by: SirNick on October 21, 2014, 05:58:42 pm
You're shorting the right ISP pin for your version? I know that is different for older chips.

On these breakout PCBs, I have Gnd, Vcc (w/ 1uF), and a 10-47k pull-up on reset.  ISP_En (the pin that has changed since the early silicon) is left floating, so it will (and does seem to) enter ISP when there's no user code in flash, but I can pull it down manually if need be.  There's no external Xtal, it's using the internal RC.

I have had similar problems with lpc21isp and it seems to be an order-of-commands or timing issue. Flashmagic gets it right so I suggest to make a trace of what Flashmagic sends and mimic that.

You're right.  That worked.  It also worked fine when I used Flash Magic's terminal to go through the init process by hand. So there must be some difference with how the port is configured (??), combined with the code differences in the 800-series bootloader.  :-//  It's a start I guess.  Thanks for the suggestion.

On that note, here are some other differences I've found, for the interested:

The 800-series transfers code as binary streams, while the 4078 is UUencoded and uses Xon/Xoff flow control.  The 800 seems to (although the docs are sparse) transfer the entire image wholesale, while the 4078 wants 20 lines at a time, then a block CRC.  The 800 compensates by offering a separate CRC check command.  Finally, the 800 ignores the clock speed sent during init, using the internal RC for the entire session.  The docs say it's still required for "compatibility", presumably with the other versions of the bootloader, although the transfer mechanism has changed so the util needs to know the new protocol regardless.  I assume they intend for the util to work this out after getting the part ID and ROM version, although a different sync string could have easily identified the discrepancy, and intentionally broken unaware utilities from trying to communicate with unsupported ICs.  *shrug*
Title: Re: LPC from scratch
Post by: SirNick on October 21, 2014, 06:29:37 pm
And now it's working from my Linux laptop (where it wasn't before.) :wtf:  I hate intermittent problems.  Sometimes.
Title: Re: LPC from scratch
Post by: cv007 on October 22, 2014, 01:12:51 am
 the host should send the same string "Synchronized<CR><LF>"

maybe its possible you are/were sending only CR or LF instead of CR+LF
can be easy to get wrong (every terminal app can have its own setting, etc)
don't know if the bootloader is fussy about it, but if its looking for both, only sending one of them could cause a problem
just a guess


 
Title: Re: LPC from scratch
Post by: SirNick on October 22, 2014, 11:19:55 pm
I thought that might be the case too, but now I'm pretty sure it wasn't:  The same code worked later; the same code worked on a different series part; I do in fact use /r/n to end lines (I double-checked); and the docs say the ROM should be resilient to CR, LF, or extraneous CR/LFs.

I dunno what the deal was.  I used two different cables, and two different breakout boards, and got (AFAICT) the exact same gibberish back every time.  Awful consistent to be a fluke.  I thought maybe Flash Magic did something magical to the board to make it behave, but I only used it on one of the two PCBs I have, and when I went back to Linux, both worked.

So ... full moon? :-//  I'm at a loss.  I'm hoping I find a bad jumper wire or something so I can get closure.
Title: Re: LPC from scratch
Post by: SirNick on November 04, 2014, 10:41:15 pm
Man, I am really struggling with the data transfer code (for sending firmware images via the ROM bootloader).  It's an easy thing in theory, but I'm having trouble balancing some conflicting goals:

The source file could be raw binary or in one of a few popular ASCII formats, like Intel Hex or Motorola S.  In the raw binary case, things are easy.  Figure out how much RAM is available on the target, read that much, and throw it at the serial port.  Easy.  To determine the segment size (the total data length), just ask the underlying file system how big the file is.

But, in the ASCII-encoded case, there are (potentially) address records that break the file into segments.  The only way to know how large a data segment is going to be (which the target wants to know in advance) is to pre-scan the file and look for EOF or the next address record.  Not a big deal.  But, all the data is encoded in records (lines) of a certain size.  There's also a line checksum, which makes it a bit of a chore to read anything less than a whole line at a time.

The problem with that is twofold:  1) In the case where this library is used on a micro to talk to another micro, it necessitates dealing with buffers between 256 and 512 bytes or so.  If you have only a couple KB of RAM, that's significant, so you have to be as thrifty as possible while still supporting up to the maximum possible record length.  2) It becomes necessary to consider the RAM available on the target device as well, since all data has to be staged in RAM before being copied to flash.

Then, you also have to deal with two transfer mechanisms -- 8-bit binary, and UUencoded.  In the latter case, we have another buffer to worry about (because the source data has to be encoded before being transmitted), it's again line-based, and of course there's the additional requirement of having to track and send a checksum every 20 lines.  The checksum is a real bear, since the micro may tell you "send that last block again please" -- and therefore, you must retain 20 lines of data in a buffer (which puts a lower threshold on the resources required to play) OR retain enough info to seek back to the starting position in the source file.  With all the various file position and memory address counters, the stack size becomes consequential, not to mention the amount of data to track and keep consistent with numerous entry and exit points in the logic.

Things get really fun when you're reading from a line-based file, and have to transfer using a line-based protocol, where the lines are not guaranteed to be the same length.  Again, keeping in mind the size of target RAM available, and how that ties in with line lengths, so as not to put yourself in the position of having to break segments mid-line (thus another data point to track -- offset in the source file buffer.)  UUencoded lines may be up to 45 data bytes in length, and I don't know but I suspect it's OK to send less than this on any line (that is, not just the final line), which is at least a small consolation.

Truly, the easiest way to handle all of this would be to read the entire source file, decode to binary, catalog all the addresses, then transfer the blocks from RAM.  But on a device whose RAM is severely limited in comparison to potential flash image size, this is not even a remote possibility.

None of this even touches on the fact that flash has to be prepared for write and erased before it can be written to.  This means having to map between addresses and sectors (not too bad), and dealing with offsets within sectors, and the rigid flash block copy sizes available.  Furthermore, do you erase all affected sectors in advance (after pre-parsing the whole source file) and then write?  Or erase one-by-one as necessary during the write op?  Imagine what fun it would be to have two separate segments in a file that affect the same flash sector.  A naive routine would erase the former data to prepare for the latter write.  A smarter routine would track that, requiring an in-memory database of previously-written sectors.  I don't suppose there should be retry attempts if the flash verification phase fails?

Sigh.  What a PITA.  There are certainly a few things the bootloader could've done to make this more tidy, although I doubt they were putting much emphasis on resource-constrained platforms as the image source.  When you have 1GB of RAM at your disposal, many of these thorns cease to exist.

I asked for this, though.  I could simply scrap the project and use existing tools.  There are even some that claim to be portable.

Nah.  :-/O
Title: Re: LPC from scratch
Post by: westfw on November 04, 2014, 10:58:19 pm
Quote
the easiest way to handle all of this would be to read the entire source file, decode to binary, catalog all the addresses, then transfer the blocks from RAM.  But on a device whose RAM is severely limited in comparison to potential flash image size, this is not even a remote possibility.
Multiple passes?  I'm not sure why there is a device with limited RAM in the path; if you want to have some intermediate systems ("pocket programmer"), can't you massage the data BEFORE putting it on that intermediate system?

Title: Re: LPC from scratch
Post by: SirNick on November 05, 2014, 12:21:00 am
That may end up being the direction I take.  I would like it to be full-featured enough to read images from external storage (e.g., SD) but it's starting to look like more trouble than it might be worth.

E.g., to optimize delivery over serial would mean bulk transfers as large as possible.  Resource constraints beg for processing data in the smallest increments possible.

The code is more flexible and the API is cleaner if it can allocate memory freely.  Embedded systems appreciate pre-allocated buffers and aggressive re-use of existing memory.

The utility is more useful if it supports large numbers of devices, file formats, and transfer protocols.  The cost being abstraction and a bigger API -- i.e., larger memory footprint and code size.

While I would like for this to run on an ATtiny (arbitrary example), I'm starting to think it may not be realistic.  The smallest host device would have to be capable of holding the image contents in memory, or having enough RAM to support all the overhead of at least being able to locate, seek in, and read from a file on some other medium.  That rules out a whole class of lower-end devices already.


In other news, my 812 has gone unresponsive again.  It seems to be resetting after 15 characters are transmitted to it.  Sending '?' will get the "Synchronized" prompt, but no matter what I enter at this point, after sending 15 characters, it resets.  Sending another '?' or two will prompt another "Synchronized" from the chip.  Sending anything else will throw off the auto-baud routine and return garbage until power-cycled.

Here's an actual transcript, completely repeatable:

Code: [Select]
???Synchronized
ABCDEFGHIJKLMNO??Synchronized

No idea why this is happening.  It's not my day I guess.  ::)