Sunday, February 21, 2016

Hacking my own Arduino Mega

At Interlock, I was handed the old controller board for a gutted 3D printer that was being rebuilt. "Do whatever you want with this." A close inspection of the board showed that it had a main microcontroller of the ATmega 1280, which is the chip used in older Arduino Megas.  The interface to USB however was an ATmega 8u2, which is the chip used in newer Arduino Megas, and you may also know it from older Arduino Unos... modern Uno R3s use a 32u4.

This board had custom firmware on it so that it didn't look like an Arduino, or any sort of serial connection to the host computer it's plugged into... so as-is, it was useless for general use as an Arduino; taking advantage of the GUI and clicky-clicky programmer interface.

So my thought was, it might be nice to have my own 'Mega for testing and such.  Could this board be set up in a way that might make this process and outcome easy?  Turns out it mostly was.

The original board got its power from a power terminls on the board, 24V.  It needed to power the stepper motors, and such so it needed to be beefy.  This was dropped down to 5 and 3.3 on the board itself.

There is a USB B jack for connecting this to a host computer, which did not have its 5V connected, so my thought was, what if i hooked up this 5V to the USB jack.  would that be enough to power the chips?

I added this jumper, which connects the +5 on the USB jack to the 5v bus on the board, and plugged it in, and sure enough, it beeped and came to life without its host power supply.

Next up would be reprogramming the micros to have the arduino bootloader and code on them.

I hooked up my fairly cheesy Arduino D-15 (hacked stepper motor controller) ISP to the 6 pin header, which thankfully was already populated and labelled on the board!  I plugged it into the port labelled "1280 ISP", selected the Arduino Mega, with 1280 micro from the Arduino 1.6.6 menus, selected Arduino ISP for the programmer, then selected "load bootlader".  In about a minute, it seemed to have completed successfully.... if something didn't jive, it would spew out sync or device errors to the screen.  Seemed good so far!

Next, was hooking it up to the jack labelled 8u2 ISP.  This was a little trickier because I wasn't installing the bootloader (which the Arduino IDE makes REALLY easy to do), but rather the secondary micro's firmware, which basically was just a USB-Serial interface driver.

Long story short, I grabbed the 8u2 code from github, "MEGA-dfu_and_usbserial_combined.hex", and used the following command line (using a mixture of the code on that page, with the parameters that my system used via the arduino IDE on my Mac:

    ./avrdude -p at90usb82 -F -cstk500v1 -P/dev/cu.usbserial-A800czia -b19200 -U flash:w:8u2.hex  -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m -U efuse:w:0xF4:m -U lock:w:0x0F:m -C/Users/me/Library/Arduino15/packages/arduino/tools/avrdude/6.0.1-arduino5/etc/avrdude.conf

In short, it sets the CPU to at90usb82, uses the stk500v1 communications protocol over the /dev/cu.usbserial driver, at 19200 baud.... it programs the file 8u2.hex, sets fuses and sets other avrdude configuration stuff.

After lots of text scrolling by from running that, I was able to drop a program I was working on, onto it via the Arduino IDE directly, without any problems at all! I set the port to the serial Mega, set the board to "Arduino Mega", cpu set at "Mega 1280", clicked 'upload' and bam, fully functional serial communications from the serial montior down through to the '1280 on the board.

Whoo! Free Arduino Mega for me!

Edit: Here's the pinouts of stuff I beeped out.

 * 4 - Piezo +
 * 6 - heat
 * 7 - fan
 * 24 - A Dir
 * 25 - A Step
 * 26 - A Enable
 * 27 - A Pot
 * 28 - B Dir
 * 29 - B Step
 * 36 - debug 2
 * 37 - debug 3
 * 38 - (nc)
 * 39 - B Enable
 * 40 - debug 4
 * 41 - PG0
 * 42 - TP33 / Z-MAX
 * 43 - TP32 / Z-MIN
 * 44 - Extra +/R85
 * 45 - bp heat
 * 46 - TP31 / Y-MAX
 * 47 - TP30 / Y-MIN
 * 48 - TP29 / X-MAX
 * 49 - TP28 / X-Min
 * A0 - X Dir
 * A1 - X Step
 * A2 - X Enable
 * A3 - X Pot
 * A4 - Y Dir
 * A5 - Y Step
 * A6 - Y Enable
 * A7 - Y Pot
 * A8  - Z Dir
 * A9  - Z Step
 * A10 - Z Enable
 * A11 - Z Pot
 * A12 - PK4 / JP7
 * A13 - PK5 / JP7
 * A14 - PK6 / JP6
 * A15 - TP27 / HBP Therm

The molex switch connectors seem to have the pinout: (signal) (ground) (ground) (+5v)

Monday, February 1, 2016

A (mostly) Finished 6502 LlamaCalc(ulator) (RC2016/1 Post-Mortem)

February 1st sees the end of RetroChallenge RC2016/1.  My entry for this month was to create a calculator for the Commodore/MOS KIM-1, by way of 6502 and the KIM-Uno emulation project.  I wanted to have a working somewhat-calculator running on the system, but more importantly, I wanted to learn 6502 assembler.

So let's see what my goals were for this RetroChallenge, as I set them out at the beginning of the project:
Starting today, I'm going to attempt to better learn 6502 asm in my copious amounts of free time for the  RC2016/01 Retrocmputing Competition.  To prepare for this, over the past year I've gotten into working with Oscar Vermeulen's awesome KIM Uno kit, as well as pushing out my own updated firmware for it in the form of my Kim Uno Remix project on github. 
For the challenge, I want to use this system to make a simple integer programmer's calculator which I can run on the KIM Uno itself.  Press keys to shift in the nibbles, then switch it into a mode where i can affect the data.  Convert hex to decimal, do bitshifts, add, multiply, etc.
In short, even though I didn't accomplish everything I outlined here, I feel like I was completely successful in the project.  The calculator application is incomplete according to the above feature set, but that wasn't really the goal of this whole thing. I wanted to learn 6502 Asm, which I did. (I didn't finish the BCD to HEX conversions, nor did I implement multiply/divide math functions.)

What were my problems?

I think that one thing that held me back was getting my head around doing multibyte math with only a carry bit. For some reason I got it into my head that this wasn't enough, which of course it is.

Another thing that kept me from getting everything done was that I spent a lot of time to understand the BCD/Hex algorithms.  The code that I used was ultimately very similar to sample code online, but I decided that I really wanted to understand how it worked, so I didn't put it in until that was true.

And of course, just the general lack of time because of various other things including: my daytime job, playing with my kid, two contracts to work on at home, being sick, etc.

What did I achieve?

Over the course of the month, I learned a lot about how to work with such a limited set of registers.  I came from Z80 world where you have a bunch of 16 bit registers.  6502 has one 8 bit accumulator (A), two 8 bit indexing registers (X,Y) which each can only be used for certain operations.

Most everything, seemingly, is done by interacting with memory locations, specifically those in the "zero page". The 6502 has this idea where the 16 byte address's top byte is the "page" of memory.  the memory in the zero page would be bytes from $0000 through $00FF.  This is generally used for OS and general use variables, etc since there are small opcodes specifically for working with them.

I'm getting into too much detail. I'll instead outline all of my accomplishments for the month...

  • Learned 6502 ASM
  • Improved the "KIM Uno Remix" Desktop application (QT for portability)
    • Added a memory snooper
    • Better graphics palette
    • More speed support
  • Learned indexing (using X and Y registers)
  • Wrote the LlamaCalc input routine 3 times, learning 6502 opcodes better each time
  • Came up with a decent user interface for LlamaCalc that's somewhat learned-intuitive
  • LlamaCalc features implemented:
    • Display/UI states for LlamaCalc (Splash, Result, Menu, Error)
    • centralized interface for doing math functions, error handling, etc
    • 8 level stack of numbers to be used (changeable at build time)
    • Push/Pop stack functions
    • Hexadecimal to BCD conversion
    • bit shift left by one bit
    • bit shift right by one bit
    • 24 bit addition
    • 24 bit subtraction
  • Designed an RLE compression scheme for graphics
  • Added RLE decompressor to the source code projects
  • Played with optimizing screen display
  • Oh yeah, created a full repository for 6502 code, with libraries etc. on github
  • Every time I learned something new, I created another project in the Projects6502 repo

So yeah. I feel like i was successful...

I will soon have a walkthrough of using LlamaCalc using a KIM-Uno device.

Here's the source code for everything: