In here you can find a toolchain I have built from the sources.
It's based on the latest gcc (4.7.2) and seems to work pretty well building the latest linux kernel.
I'll upload my kernel sources and announce here as soon as they are available (probabbly in some git repository).
Also, expect some new movies.
Enjoy!
sábado, 1 de dezembro de 2012
sábado, 27 de outubro de 2012
Hot News
It's been a while since my last post.
I've been busy with other cool projects and maybe I'll post something about them.
Today I've built a new toolchain for the 68000 with gcc 4.7.2 and a new kernel based on the latest git sources from git.ketnel.org.
And here is the boot log:
It still amazes me everytime I see this "ice age" cpu booting up so gracefully such a shinny new kernel!
As promissed I have started publishing documentation at: http://code.google.com/p/m68k
(schematics can be found at the download section)
I plan to add the toolchain and uClinux-dist sources soon.
I've been busy with other cool projects and maybe I'll post something about them.
Today I've built a new toolchain for the 68000 with gcc 4.7.2 and a new kernel based on the latest git sources from git.ketnel.org.
And here is the boot log:
Alcetronics M68K v0.2 (2012)
Booting in 3...
Booting...
Linux version 3.7.0-rc1-dirty (ljalves@xsys-lnx) (gcc version 4.7.2 (GCC) ) #1 Sat Oct 27 23:09:31 WEST 2012
Alcetronics M68K support by Luis Alves <ljalvs@gmail.com>
uClinux/MC68000
Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne
Built 1 zonelists in Zone order, mobility grouping off. Total pages: 2031
Kernel command line:
PID hash table entries: 32 (order: -5, 128 bytes)
Dentry cache hash table entries: 1024 (order: 0, 4096 bytes)
Inode-cache hash table entries: 1024 (order: 0, 4096 bytes)
Memory available: 7580k/8188k RAM, (1587k kernel code, 361k data)
NR_IRQS:32
Calibrating delay loop... 1.93 BogoMIPS (lpj=9664)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 512
NET: Registered protocol family 16
bio: create slab <bio-0> at 0
Switching to clocksource timer
NET: Registered protocol family 2
TCP established hash table entries: 512 (order: 0, 4096 bytes)
TCP bind hash table entries: 512 (order: -1, 2048 bytes)
TCP: Hash tables configured (established 512 bind 512)
TCP: reno registered
UDP hash table entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1
RPC: Registered named UNIX socket transport module.
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
ROMFS MTD (C) 2007 Red Hat, Inc.
io scheduler noop registered (default)
FTDI 245 USB module serial driver
ttyS0 at MMIO 0xe00000 (irq = 5) is a FTDI 245 serial usb module
console [ttyS0] enabled
uclinux[mtd]: RAM probe address=0xb00000 size=0xbc000
uclinux[mtd]: set ROMfs to be root filesystem
Creating 1 MTD partitions on "RAM":
0x000000000000-0x0000000bc000 : "ROMfs"
alce-eth Ethernet Driver, V0.01
ENC28J60: Probe
net eth0: alce-eth driver registered
TCP: cubic registered
VFS: Mounted root (romfs filesystem) readonly on device 31:0.
mmc0: host does not support reading read-only switch. assuming write-enable.
mmc0: new SDHC card on SPI
mmcblk0: mmc0:0000 SD04G 3.70 GiB
mmcblk0: p1
#
It still amazes me everytime I see this "ice age" cpu booting up so gracefully such a shinny new kernel!
As promissed I have started publishing documentation at: http://code.google.com/p/m68k
(schematics can be found at the download section)
I plan to add the toolchain and uClinux-dist sources soon.
quinta-feira, 3 de maio de 2012
Alcetronics M68K
Alcetronics M68K is the name chosen for the board.
The word 'alce' mean 'moose' in Portuguese and the usage of this name in the board is related to other previous (huge) stories.
So... the huge wire-maze was starting to freak me out. If for some reason a wire got disconnected I could loose hours searching for the problem. Every time my cat climbed to the desk where I had the breadboards I almost had an heart attack... So I've made a decision: Place everything on a PCB.
Since my goal was to run uClinux and make something useful with it I've decided to design the board with the following specs:
CPU:
System memory:
Mass storage:
Peripherals:
To control the system I've used the XC9572 CPLD. It's responsible to generate all the control signals for basic system functionality (chip selects, boot address, /rd's & /wr's, ...).
The same XC4010E FPGA from the breadboard is used to control all the peripherals and assist the CPU with whatever signals it needs (almost all CPU pins are available at the FPGA).
Since I didn't want to waist much money with the PCB, I've designed all to fit in a 2 layer PCB, within the minimum area I could use.
And here is a photo of the final PCB produced at Eurocircuits (using their proto PCB service)
From left to right and top to bottom you can see: Flash, SRAM, 68000, FPGA, CPLD, RTC, microSDcard, ftdi245 and ethernet.
In the bottom side there is more FLASH/SRAM, the ADC, 40MHz oscilattor, 5v to 3.3v level converter for the SDcard and the voltage regulators.
And here it is the populated PCB:
On the next post I'll talk about the system bring-up, the FPGA contents and current progress in uClinux.
The word 'alce' mean 'moose' in Portuguese and the usage of this name in the board is related to other previous (huge) stories.
So... the huge wire-maze was starting to freak me out. If for some reason a wire got disconnected I could loose hours searching for the problem. Every time my cat climbed to the desk where I had the breadboards I almost had an heart attack... So I've made a decision: Place everything on a PCB.
Since my goal was to run uClinux and make something useful with it I've decided to design the board with the following specs:
CPU:
- 68HC000P8 (overclocked to 20MHz)
System memory:
- 8Mb SRAM
- 4Mb Flash
Mass storage:
- Micro SD card connector
Peripherals:
- FTDI245 - As an USB serial port
- ENC28J60 - Ethernet controller
- MCP3208 - 8 channel 12bit ADC
- DS12887 - Real time clock + NVRAM
- Lots of GPIO
To control the system I've used the XC9572 CPLD. It's responsible to generate all the control signals for basic system functionality (chip selects, boot address, /rd's & /wr's, ...).
The same XC4010E FPGA from the breadboard is used to control all the peripherals and assist the CPU with whatever signals it needs (almost all CPU pins are available at the FPGA).
Since I didn't want to waist much money with the PCB, I've designed all to fit in a 2 layer PCB, within the minimum area I could use.
And here is a photo of the final PCB produced at Eurocircuits (using their proto PCB service)
Alcetronics M68K board (naked PCB) |
From left to right and top to bottom you can see: Flash, SRAM, 68000, FPGA, CPLD, RTC, microSDcard, ftdi245 and ethernet.
In the bottom side there is more FLASH/SRAM, the ADC, 40MHz oscilattor, 5v to 3.3v level converter for the SDcard and the voltage regulators.
And here it is the populated PCB:
Alcetronics M68K board |
On the next post I'll talk about the system bring-up, the FPGA contents and current progress in uClinux.
segunda-feira, 30 de abril de 2012
uClinux - Hello world!
Hello World!
Usually this represents the very basic program someone can compile. In this case it's a true salutation to the whole world - The Internet.
With the FPGA around, connecting a simple ethernet controller from Microchip (the enc28j60) was a piece of cake. The chip interface is a simple SPI slave port that even provides 5V tolerant IO's.
An experimental linux driver for kernel 2.4 is easily found here: http://elinux.org/Enc28j60 (linux kernel 3.x tree already has support fot this chip). So, all I had to do was to rewrite the SPI function calls, and that was it...
My kernel image size has grown significantly with the addition of network support, so memory limitation is (again!) my greatest pain.
Here is a small video showing the system running the 'boa' web server (it show nice comments during playback):
Having reached this far, and starting to struggle with low memory issues, I've lost my mind and decided to put all this stuff on a PCB!
On the next post I'll show the specifications, peripherals and the PCB itself.
quarta-feira, 18 de abril de 2012
uClinux - Part II
More wires
Having a working kernel image and a serial port is just not enough! I needed peripherals...
Old peripheral chips are hard to find and I din't have any around, but I had in my junk box some old FPGA from Xilinx. It's a XC4010E in a PGA package with 191 pins and it runs from 5V... perfect!
Also, since I need to add more features to the system I also need more ram and flash. I've brought 4x 512Kb cheap (around 3€ each) SRAM and replaced all the ram in the breadboard. Also bought 2x512Kb FLASH and replaced the old (smaller) FLASH chips.
Ended up with 2Mb RAM and 1Mb FLASH memory. This should be enough to start porting kernel 2.4.x. for the board.
After some long hours of coding and re-coding it finally booted!
I've used the latest pre-compiled GCC toolchain (4.2.4) and the latest (at that moment) uClinux-dist (20111111). Re-used most of the code from the Motorola Dragonball family (MC68328).
So, having a nicer and newer kernel booting and running up, I decided to wire up that old FPGA.
My first attempts were just to see if that thing was still alive. The big headache was to wire all those ground and vcc pins. After finally finished, I've coded up a very simple verilog counter and programmed that old silicon piece using the JTAG port. And there it was, counting up (like it was supposed to be).
The FPGA can be programmed as if it is a simple 8-bit parallel peripheral. I've wired up the 8 data bits directly to the cpu databus, the address decoded feeds the FPGA chip select pin and the write/read pins are connected to the respective pins in the system (provided by one of the GALs). This way, the FPGA is seen by the CPU as a 1 byte memory location.
To program the FPGA all that is needed it so send byte by byte the generated bitstream. If everything ok, the DONE led goes bright.
4GB SDHC card
Mass storage memory is so cheap these days. Having a large amount of memory available in my system will allow me to move most of the romfs contents to the sdcard and more important at the moment, whenever I want to try new stuff, simply compile in the laptop and copy to the SDcard.
The new cards are 3.3V parts. I needed a voltage converter to wire the sdcard to the system so I used a simple 5V to 3.3V converter. Only the signals that go to the SDcard get converted because the FPGA can nicely handle 3.3V signals (just set the voltage thresholds to TTL in the FPGA config).
Having everything wired up, I wrote a simple verilog SPI master module.
The module when receiving a byte from the CPU, dumps the byte to the SPI mosi pin while at the same time, samples the miso pin. When reading the FPGA the CPU gets the last sampled byte.
The clock source for the FPGA is an oscilator module I had around rated at 35MHz.
I divide the clock by 2 in the FPGA and feed the CPU with a magnificent 17.5MHz clock! (remember that this is a 8MHz rated CPU). I've also tried using a 40MHz module, but if I sneeze or take a deeper breath, the system hangs!
Here is a video showing the kernel boot, mounting the sdcard and running some shell commands.
Next step is to add connectivity to the world: the internet!
terça-feira, 20 de março de 2012
uClinux - Part I
Resurrection
A few months ago I was dumping out some old things to the trash when accidentally stumbled into those old yellowish breadboards still holding tight the magnificent 68000 cpu. I stood there for about 5 minutes admiring all the patience I had a decade ago wiring up all those pins. Suddenly a nostalgic feeling had taken over my mind, and all I could think at that moment was "I really need 5 volts".
I was about to know if the mighty 68breadboard000 was still rock n' rolling. I've connected the serial port and applied power and there it was, the system was up and running ready to accept commands from the serial port!
After playing some time with it, doing some memory dumps and tests, the same old question came back: "What the hell am I going to do with this?".
For a few days the whole system was left untouched in my desk... as usual. And one day I was googling around when the word "uClinux" made a spark in my brain. I looked to the 68000, looked back to the word "uClinux" and its fate was obvious: "Run some linux code in that old
I've had an experience with uClinux in the past with a Coldfire microcontroller although I hadn't done much back in that time since I used a pre-compiled kernel image.
Dressing up for the party
The system was far from being able to run such operating system. It had a small amount of ram, the serial port and was slow and I had no timer for periodic interrupt. The flash memory was enough for the boot, but userland binaries had to be cut to the minimum.
SRAM: The system only had 128k SRAM (4x32Kb) and I had four old 128Kb around. What I didn't have was room to place those huge chips so I've wired them up in two extra breadboards (I had to dismantle a Z80 to get those!). Once wired up it was time to connect that half megabyte of ram to the 68k totaling 640KBytes of ram.
Memory upgrade: Check!
Serial port: The system had a USART chip (from the 8051 microcontroler series) wired up. It only had a 1byte buffer and without hardware flow control, buffer overruns occurred frequently. Since a uClinux kernel + romfs can be significantly large, I needed to have a way to upload the image to the system, fast!
I had this spare USB module where the interface is an 8-bit parallel bus, with 4 control signals (/rd, /wr, txe, rxf). Wired it up to the cpu upper half of the databus and connected the control signals with basic logic ports. When connected to the PC USB port it is seen as a standard (fast) serial port.
Fast serial port: Check!
Bootloader: The way I always used the system was loading to the ram and running code from there. Since I needed the ram available fot the kernel, I had to write the image directly in the flash so I've coded a simple bootloader in that beautiful assembly language (no kidding, it is really beautiful!). The working principle is simple:
- Wait for a key press on the serial port for 3 seconds (not accurate seconds).
- If no keypress, boot from a specific flash address where hopefully kernel code is located.
- If a key is pressed, start the bootloading part.
- Bootloader receives srecord files. If it detects that the destination address is flash, load everything to the ram and at the end of the load cycle, write everything to the flash (and verify). At last boot from flash.
- If the destination of the srecord if ram, load to ram and boot from there.
I was facing some weird behaviour during the flash write, later I realized that the bootloader can't be executed from the flash and write on it at the same time! The solution was simple: When the bootloader starts, it copies itself to the ram and then runs from there.
Bootloader: Check!
Periodic timer interrupt: This final piece of hardware was missing from the system. It is a vital component to enable any multitasking operating system to run. It is responsible to make the cpu enter a 'supervisor' mode and switch between tasks. My first approach was to use a counter and connect one of the upper bits to the interrupt logic with some latch so that I could reset it in the interrupt routine. It was a bad idea... Didn't work well so I just ended up with a simpler solution: a 555 timer! The interrupt interval is set by a resistor and capacitor. It's not accurate but it's good enough to do the job!
Timer interrupt: Check!
Let the compiling begin!
As a first approach I've used as base code the board from Weiss Electronics: SM2010. Apparently that board also uses an 68000 cpu. From the few documentation I could find I know It's some kind of industrial controller board with 6 serial ports and (at least) 2 hardware timers. The guy that ported uClinux to that board did most of the work. He ported kernel 2.0.x and for a start it was good enough. I ended up by adapting the hardware part of the kernel: hardware timer, ftdi245 serial driver and ram/rom locations for the linker.
A few compilations later there it was! The old 68000 up and running uClinux!
I've also made a small video showing the kernel bootup and some commands being issued.
But the job wasn't completed! My ultimate goal is to run kernel 3.x in this old piece of hardware!
So my next step was to make a fully functional kernel 2.4.x. and there was no SM2010 board in the kernel tree!
quarta-feira, 22 de fevereiro de 2012
Project number 2
The year was 2005 and I was a step away from becoming an electronics engineer. There was only one thing missing to finally end my student life: the final project. There were a lot of proposed projects to choose from, but none really caught my attention. Fortunately there was the option to propose your own project, so I came up with something that I thought it would be at the same time useful and really cool to develop: a vnc and rdesktop thin client. When finished it would be a small and simple board where you connect a display, keyboard, mouse and a network cable, then through vnc or remote desktop it would be a remote workstation.
Well, this was the original idea and the proposed project would divide in 3 major tasks:
So, after brought back to earth by my project coordinator it ended up being just the first part (the 2D GPU). The issue here was time... It was a one man project and it needed to be ready in less than 3-4 months (and it was not a full time job).
One Xilinx Spartan3 (XC3S200) was used to develop the GPU. The spartan3 kit that was available had on board memory to go up to 800x600x16bit and enough I/O to pull out a dedicated parallel bus for the cpu interface.
So the remaining question was: "What will control the GPU?" For demonstration purposes I could just interface the GPU with a serial port or some cheap 8-bit microcontroller using spi or i2c. But since the initial idea was to connect a coldfire to the gpu that question had a simple answer: "The dusty 68000!" And there I was again... cleaning up all the dust from those breadboards!
The spartan3 kit already had a VGA connector but it was a simple 3-bit 'resistor DAC'... Yuck! So one expansion connector was used to interface a 24-bit DAC and another one for the cpu interface (the pins were enough for a full 16-bit I/O port).
The GPU ended up working pretty nice. It was modular so that the available functions could be included/removed from the top module, depending in purpose of the application was for. And these were the functions I have developed:
I remember that I had more fun than work during the whole project.
When I had the GPU almost finished I played a lot with the 68k and coded several small programs, things like a simple clock, image loading, mathematic function tracing, a simple 3d wiremaze game and 3D raytracing...
Too bad I didn't had enough time to play with it a bit more (and maybe finish the initial idea).
And this was the last project where my 68000 system was used...
A few months ago and after several years later I decided to play with it that 'spaghetti board' again!
And this is where uClinux comes in...
Well, this was the original idea and the proposed project would divide in 3 major tasks:
- Develop a FPGA based 2D GPU (with dedicated functions for networ display).
- Build a prototype pcb for the main controller and GPU interface (it would be a mcf5407 with 32Mb SDRAM and 8Mb FLASH).
- Develop the code for the microcontroller.
So, after brought back to earth by my project coordinator it ended up being just the first part (the 2D GPU). The issue here was time... It was a one man project and it needed to be ready in less than 3-4 months (and it was not a full time job).
One Xilinx Spartan3 (XC3S200) was used to develop the GPU. The spartan3 kit that was available had on board memory to go up to 800x600x16bit and enough I/O to pull out a dedicated parallel bus for the cpu interface.
The Diligent Spartan3 Starter Kit used for the GPU development |
So the remaining question was: "What will control the GPU?" For demonstration purposes I could just interface the GPU with a serial port or some cheap 8-bit microcontroller using spi or i2c. But since the initial idea was to connect a coldfire to the gpu that question had a simple answer: "The dusty 68000!" And there I was again... cleaning up all the dust from those breadboards!
The spartan3 kit already had a VGA connector but it was a simple 3-bit 'resistor DAC'... Yuck! So one expansion connector was used to interface a 24-bit DAC and another one for the cpu interface (the pins were enough for a full 16-bit I/O port).
24-bit DAC board: top view. |
24-bit DAC board: bottom view |
The GPU ended up working pretty nice. It was modular so that the available functions could be included/removed from the top module, depending in purpose of the application was for. And these were the functions I have developed:
- putpixel, getpixel (the most basic functions for anything that display graphics). These functions have several working modes: A window could be defined and then post-increment or pre-decrement pixel manipulation methods could be used to fill the window (among other features).
- clrscr (clears screen, filling with a pre-selected color)
- poly (draws a polygon, points passed as arguments)
- circle (draws a circle, center and radius as parameters)
- text (places text in the display)
- copyrect (copies a rectangle from a place to another).
- save / load. (the remaining on board memory was used for a save and load function).
Development (at my parents house during christmas season). |
I remember that I had more fun than work during the whole project.
When I had the GPU almost finished I played a lot with the 68k and coded several small programs, things like a simple clock, image loading, mathematic function tracing, a simple 3d wiremaze game and 3D raytracing...
One of the the few pictures I've took during development showing a clock and some text in the upper left corner. |
"Faculdade de Engenharia da Universidade do Porto" logo loaded from a .bmp file. |
Too bad I didn't had enough time to play with it a bit more (and maybe finish the initial idea).
And this was the last project where my 68000 system was used...
A few months ago and after several years later I decided to play with it that 'spaghetti board' again!
And this is where uClinux comes in...
quinta-feira, 16 de fevereiro de 2012
Project number 1
There I was in the year of 2002. The music was spreading all over the place in the form of digitally compressed bits and portable CD players were starting to be a thing from the past. Standalone MP3 players were already in the market, but the cost was very high and their capacity was very small. The very first mp3 player only had 32 Mb to store music. That's about the same an audio CD can handle...
Googling around I've stumbled in a forum where some people were posting about their mp3 player projects. Some guys were just stiffing a whole PC in some custom made enclosure to have in the living room, others would even attach an alphanumeric lcd to the printer port so they could have a sort of visual interface.
What caught my attention were the projects were you could use these hard-to-get-mp3-decoder-chips.
So that's when I decided: "I'll build a standalone MP3 player!"
At that time I remember only having two options as decoder chips: Micronas MAS3507D or VLSI Solution VS1001K and independently of which one I choose I wouldn't find one in a 2000 Km radius...
Suddenly I had 4 quests in my life:
Quest number one turned out to be easy. I was living with a cousin at that time (we both were studying electronics engineering out of hometown) and he was dating a girl that had her father in Germany near a local shop where they actually had the mas3507d. Great! Her dad bought us 2 Micronas chips and sent by mail (and also 2 Micronas audio DACs). (My cousin also ended up joining the mp3 player adventure, which without him I would stuck in the first quest for some time!).
While waiting for the package to arrive, I started quest number two.
The MAS3507D datasheet had this reference design, so I took it, ripped of some unneeded stuff (like auxiliary audio inputs) and used it in my board. The scary thing was that the chips were SMD. Developing a home-made pcb for smd was something I had never done, but after about 3 or 4 tries I was able to etch an almost perfect double sided PCB using UV sensitive boards.
Soldered all the components and the there I was, with a perfect mp3 decoder board that was just missing the... mp3 decoder! The chips arrived some days after, soldered them and I was ready to provide my ears with some music.
Quest number three was about to start: feed the beast!
The beautiful thing of this decoder board was the simplicity to make it work.
The board is fed with the mp3 bitstream in a 'crippled' 2 wire SPI interface (mosi, clk) and a "i'm busy" signal telling that the chip buffer is full. The output are two stereo connectors: line out and speaker out.
To test the board all I has to do was connect the 3 wires to a computer parallel port and code a simple program that grabbed an mp3 and bit-streamed it in the parallel port.
And... well, I can say that it did work! A sort of something that I can call half-second music, half-second silence was flowing in the air.
What was happening was the mp3 that I selected to be the One, had a high bitrate encoding and the computer plus the parallel port couldn't handle the job. Maybe if I did some assembly coding it would play higher bitrate mp3s but that was not the point. I just simply searched eMule for a small and low bitrate mp3 and tested it. Funny that the first hit was the theme song from a Portuguese TV show named "Batatoon". And there it was, playing perfectly in the mp3 decoder board (as perfect as it could get with only 96kbps bitrate)!
The board also has a second connector for an I2C interface. It allows to control internal registers of the mas3507 like volume, treble, bass, balance, ... (and really needed in a latter chip revision to start the decoder! I know this because after some days a badly connected power supply destroyed the first mas3507 and when using the second one (and I'm glad I had a second one!), the music was gone! so after reading through the datasheet and setting a specific bit in some register, the board was back to life).
Having a working mp3 decoder board, all that was left was the last quest: Have a full working system with space to store a bunch of music.
This is where the 68000 comes in. I grabbed my 68000 system, cleaned all the dustin it and attached an IDE harddisk.
I think I've aged about 2 years just for cutting the 40 pin IDE cable and connecting each signal to the 68000 bus (in breadboards). One word: tedious!
"Let the coding start"!
For who never programmed 68k assembly this can sound weird, but the truth is that it is pleasure to code those lines! The instruction set is so vast and there are a lot of addressing modes!
And so I've codded the IDE driver, partition and FAT32 reader. I could soon play some tunes!
When it came to the part of connecting the mp3 decoder board, problems appeared! How the hell am I going to send the bitstream?
Ideia number 1: Serialize the bitstream in software and send it bit by bit through some sort of parallel port (and I've wired a simple 8-bit latch).
Result: The 68k running at 8MHz didn't have horsepower to do the IDE access and send bit by bit clock by clock the bitstream. And to make things worst I wasn't using any kind of interrupts, so the bigger the buffer was, the longer the pauses were.
This is understandable because the cpu is not intended to do SPI with its 16-bit wide databus!
> FAIL <
Ideia number 2: Use the same setup but using the 'busy' pin from the mas3507d to interrupt the CPU for data.
Result: It worked... better, but not good! The main loop would just fill in the buffer while the interrupt routine dumped it to the mp3 board. It was almost smooth playing, but time to time I could hear the music stop. High bitrate mp3 (320kbps) still didn't play...
> FAIL <
Idea number 3: Send 1 or more bytes of data to 'something' that could serialize it and then send to the mp3 decoder.
Result: The 'something' was the big question mark. It could be a 8-bit shift register, clocked at some frequency, being fed by the 68k with some glue logic. But I wanted something that I had at that time in my junkyard, so I picked this little PIC16F84A and thought "this thing has enough pins for a 68k 8-bit data transfer plus 2 for spi and its fast enough to serialize the data!".
The connection was pretty simple: one pic interrupt pin for a write signal from the 68k, the 'busy' signal was directly connected to the 68k to request data and pic port B was used to receive the data from the 68k.
At that time I thought in wire up two 8-bit shift registers and have a 16-bit serial shifter (or use a PIC with more pins). Sending 16-bit at time would reduce in half the effort needed by the cpu to feed the data, but...
> SUCCESS <
But the full working system was already a monster (in size)... It was working good but it was way far from a portable mp3 player.
After some time playing around with this thing I had shifted away from my main goal so I decided to go back on track.
The main goal was to have a portable mp3 player and from what I had at that moment was failing in some important aspects: It was huge it was heavy and it was consuming lots of amp's!
Trying to figure a way to solve all of these issues I came up with some ideas:
So the ultimate goal was making a small board with the max size of a laptop harddisk.
And then I stated to develop the prototype board for the PIC18F455. The final board had the following specifications:
I coded everything up in C (IDE driver, FAT32 access functions, LCD driver and IR driver).
When I had the code practically finished, I placed everything in 'small' acrylic box.
That box was part of my car about 2 years in a row! At that time the first car mp3 CD players were becoming cheap, but why would one carry a bunch of CD's when all would fit in a single harddisk? It was something that caught attention and the remote control was something I really loved in it.
The good points were: huge capacity, fast and easy user interface (custom made!) and a sweet universal remote control.
There were also disadvantages, starting by the fact that when I needed to add music I had to connect the harddisk to the computer. The initial idea was to use that expansion port to to the transfer interface (possibly using the parallel port), but that never got completed.
In summary, the final board never got made... And I gave up also because flash memory prices were dropping fast, while available memory capacities were rising faster.
A few years later the mp3 players industry exploded! I ended up buying a car radio with a USB connector where I could just plug anything with mass storage...
In the next post I'll talk about the other real big project where the 68000 was the king!
Googling around I've stumbled in a forum where some people were posting about their mp3 player projects. Some guys were just stiffing a whole PC in some custom made enclosure to have in the living room, others would even attach an alphanumeric lcd to the printer port so they could have a sort of visual interface.
What caught my attention were the projects were you could use these hard-to-get-mp3-decoder-chips.
So that's when I decided: "I'll build a standalone MP3 player!"
At that time I remember only having two options as decoder chips: Micronas MAS3507D or VLSI Solution VS1001K and independently of which one I choose I wouldn't find one in a 2000 Km radius...
Suddenly I had 4 quests in my life:
- Get my hands on one of these mp3 decoder chips.
- Build a board with the mp3 chip + audio DAC.
- Feed the mp3 decoder board with some music (and enjoy the beautiful sound).
- Build some controller board with some heavy mass storage (I really mean heavy when I say it! the main goal was to use a laptop IDE hard disk but all I had back then was a heavy 3.5'' hard disk).
Quest number one turned out to be easy. I was living with a cousin at that time (we both were studying electronics engineering out of hometown) and he was dating a girl that had her father in Germany near a local shop where they actually had the mas3507d. Great! Her dad bought us 2 Micronas chips and sent by mail (and also 2 Micronas audio DACs). (My cousin also ended up joining the mp3 player adventure, which without him I would stuck in the first quest for some time!).
While waiting for the package to arrive, I started quest number two.
The MAS3507D datasheet had this reference design, so I took it, ripped of some unneeded stuff (like auxiliary audio inputs) and used it in my board. The scary thing was that the chips were SMD. Developing a home-made pcb for smd was something I had never done, but after about 3 or 4 tries I was able to etch an almost perfect double sided PCB using UV sensitive boards.
Soldered all the components and the there I was, with a perfect mp3 decoder board that was just missing the... mp3 decoder! The chips arrived some days after, soldered them and I was ready to provide my ears with some music.
The finished mp3decoder board! Left is MAS3507D, right is DAC3550; Top connectors: I2C, SPI, Power supply; Right connectors: Lineout and Speaker out. |
Quest number three was about to start: feed the beast!
The beautiful thing of this decoder board was the simplicity to make it work.
The board is fed with the mp3 bitstream in a 'crippled' 2 wire SPI interface (mosi, clk) and a "i'm busy" signal telling that the chip buffer is full. The output are two stereo connectors: line out and speaker out.
To test the board all I has to do was connect the 3 wires to a computer parallel port and code a simple program that grabbed an mp3 and bit-streamed it in the parallel port.
And... well, I can say that it did work! A sort of something that I can call half-second music, half-second silence was flowing in the air.
What was happening was the mp3 that I selected to be the One, had a high bitrate encoding and the computer plus the parallel port couldn't handle the job. Maybe if I did some assembly coding it would play higher bitrate mp3s but that was not the point. I just simply searched eMule for a small and low bitrate mp3 and tested it. Funny that the first hit was the theme song from a Portuguese TV show named "Batatoon". And there it was, playing perfectly in the mp3 decoder board (as perfect as it could get with only 96kbps bitrate)!
The board also has a second connector for an I2C interface. It allows to control internal registers of the mas3507 like volume, treble, bass, balance, ... (and really needed in a latter chip revision to start the decoder! I know this because after some days a badly connected power supply destroyed the first mas3507 and when using the second one (and I'm glad I had a second one!), the music was gone! so after reading through the datasheet and setting a specific bit in some register, the board was back to life).
Having a working mp3 decoder board, all that was left was the last quest: Have a full working system with space to store a bunch of music.
This is where the 68000 comes in. I grabbed my 68000 system, cleaned all the dustin it and attached an IDE harddisk.
I think I've aged about 2 years just for cutting the 40 pin IDE cable and connecting each signal to the 68000 bus (in breadboards). One word: tedious!
"Let the coding start"!
For who never programmed 68k assembly this can sound weird, but the truth is that it is pleasure to code those lines! The instruction set is so vast and there are a lot of addressing modes!
And so I've codded the IDE driver, partition and FAT32 reader. I could soon play some tunes!
When it came to the part of connecting the mp3 decoder board, problems appeared! How the hell am I going to send the bitstream?
Ideia number 1: Serialize the bitstream in software and send it bit by bit through some sort of parallel port (and I've wired a simple 8-bit latch).
Result: The 68k running at 8MHz didn't have horsepower to do the IDE access and send bit by bit clock by clock the bitstream. And to make things worst I wasn't using any kind of interrupts, so the bigger the buffer was, the longer the pauses were.
This is understandable because the cpu is not intended to do SPI with its 16-bit wide databus!
> FAIL <
Ideia number 2: Use the same setup but using the 'busy' pin from the mas3507d to interrupt the CPU for data.
Result: It worked... better, but not good! The main loop would just fill in the buffer while the interrupt routine dumped it to the mp3 board. It was almost smooth playing, but time to time I could hear the music stop. High bitrate mp3 (320kbps) still didn't play...
> FAIL <
Idea number 3: Send 1 or more bytes of data to 'something' that could serialize it and then send to the mp3 decoder.
Result: The 'something' was the big question mark. It could be a 8-bit shift register, clocked at some frequency, being fed by the 68k with some glue logic. But I wanted something that I had at that time in my junkyard, so I picked this little PIC16F84A and thought "this thing has enough pins for a 68k 8-bit data transfer plus 2 for spi and its fast enough to serialize the data!".
The connection was pretty simple: one pic interrupt pin for a write signal from the 68k, the 'busy' signal was directly connected to the 68k to request data and pic port B was used to receive the data from the 68k.
At that time I thought in wire up two 8-bit shift registers and have a 16-bit serial shifter (or use a PIC with more pins). Sending 16-bit at time would reduce in half the effort needed by the cpu to feed the data, but...
> SUCCESS <
But the full working system was already a monster (in size)... It was working good but it was way far from a portable mp3 player.
After some time playing around with this thing I had shifted away from my main goal so I decided to go back on track.
The main goal was to have a portable mp3 player and from what I had at that moment was failing in some important aspects: It was huge it was heavy and it was consuming lots of amp's!
Trying to figure a way to solve all of these issues I came up with some ideas:
- Get rid of the 68000 - Ended up using a 40pin PIC18F452. It had lots of IOs and I2C and SPI port.
- Get rid of the 3.5'' IDE harddisk - These disks need two power supplies: +12V and +5V. Final goal was to use a laptop harddisk that only require +5V. The interface is the same so when the time comes I could simple switch disks.
- Make everything smaller - The prototype mp3decoder board ended up being bigger than expected (well, its a prototype!).
- Add a display and some buttons!
So the ultimate goal was making a small board with the max size of a laptop harddisk.
And then I stated to develop the prototype board for the PIC18F455. The final board had the following specifications:
- PIC18F452 as main controller.
- 32Kb SRAM as buffer.
- 64Kb serial eeprom for settings and other stuff.
- RS232 port for firmware upgrade/development.
- LCD port (ended up using a 4x20 alphanumeric LCD)
- Infrared port (used an universal IR remote as controller, so there were only two push-buttons: reset and bootloader entry).
- 40 Pin Parallel ATA (IDE port)
- 8 bit expansion port.
- SPI and I2C connectors (to mp3decoder board)
- IR led, harddisk led
I coded everything up in C (IDE driver, FAT32 access functions, LCD driver and IR driver).
When I had the code practically finished, I placed everything in 'small' acrylic box.
That box was part of my car about 2 years in a row! At that time the first car mp3 CD players were becoming cheap, but why would one carry a bunch of CD's when all would fit in a single harddisk? It was something that caught attention and the remote control was something I really loved in it.
The good points were: huge capacity, fast and easy user interface (custom made!) and a sweet universal remote control.
There were also disadvantages, starting by the fact that when I needed to add music I had to connect the harddisk to the computer. The initial idea was to use that expansion port to to the transfer interface (possibly using the parallel port), but that never got completed.
In summary, the final board never got made... And I gave up also because flash memory prices were dropping fast, while available memory capacities were rising faster.
A few years later the mp3 players industry exploded! I ended up buying a car radio with a USB connector where I could just plug anything with mass storage...
The full system connected. Almost 10 years later I've connected the player. |
In the next post I'll talk about the other real big project where the 68000 was the king!
terça-feira, 31 de janeiro de 2012
I'm Alive
So, there I was with the CPU in my hand and the first thing it came to my mind was "maybe this thing is broken! maybe that's why the boards were thrown away..."
Well, fortunately for me this CPU has what is called "freerun" mode. In a few worlds, this CPU can work with no memory and no peripherals just by forcing the pins to vcc or gnd... perfect!
Having a clock source, the control signals all tied to the proper level and all data bus grounded I powered up the board and there it was, this greed led connected to one of the upper address lines, blinking, like if it was telling me "I'm alive!".
Technically all 0's in the data bus matches the opcode 'ORI.B #0,D0' this means that the CPU is reading and Immediate Byte value '#0' and making a boolean OR with the contents of the internal register D0. After that, another equal instruction follows in the address bus, making it sweep all the 16Mb addresses making it a beautiful... counter!
Having the proof that it was (apparently) working, I decided to gather some sram from those same boards (I needed at least two of them for the 16-bit data bus). Too bad the biggest sram's on that board was only of 2Kbytes (and there were a lot of them!).
Back in that time huge sram chips didn't exist an the ones that did exist were very expensive.
With everything connected, all I was missing was a way to get some code in that ram. At first I thought in burning some roms since I had a lot of uveprom's from the boards. But when I really though about it, developing code would be painful... I needed a way to develop code and test it fast...
After some time thinking about it I had this idea of using the parallel port to program the srams, and it worked like a charm! Using shift registers, latches and buffers I was able to program the full 4KBytes with the parallel port. The address was loaded into the serial registers, then I could read or write data in the data bus. I wrote a small program that could write or read the sram (in turbo pascal at that time).
Now I had a fast way to test and debug code, and there I started making little assembly programs that the only thing they did was to manipulate bytes in the sram (that I could read with the parallel port interface). I do remember that the first piece of assembly code I've tested was as simple as loading two registers with some numbers and them saving the multiplication result in some memory location that after reading with the parallel port I could check that, after spending some days (or even months) under the sun and in the rain, this guy could still do some real math!
Later I've put my hands on a USART (a M82C51A) and finally had a door to the world! I then started the development of a serial bootloader that when finished would go into 2 ROMs and allow me to remove all the parallel port to sram circuitry.
Some time passed and these new things called programmable logic devices appeared.
I've build a GAL (Generic Array Logic) programmed and programmed some GAL's which replace many of the original glue logic. I guess these devices have died meanwhile (or better, evolved into CPLDs).
Meanwhile I've made a few more improvements. The most significant were the upgrade of the available RAM to 128Kb (4x 32Kb SRAMs from an old PC motherboard, used as cache memory) and the migration from uvprom to flash memory (two brand new W29C020).
And that it was, my single (bread)board computer! With 512Kb flash memory and 128Kb RAM.
And when I thought everything going good I was wrong... In one minute I had million ideas and in the next minute I had zero ideas to do with the board... the year was around 2001 and for some time the only thing that was developed in that board were layers and layers of dust...
But then it came a day when...
(in next post I'll talk about two major projects I used this board for)
Well, fortunately for me this CPU has what is called "freerun" mode. In a few worlds, this CPU can work with no memory and no peripherals just by forcing the pins to vcc or gnd... perfect!
Having a clock source, the control signals all tied to the proper level and all data bus grounded I powered up the board and there it was, this greed led connected to one of the upper address lines, blinking, like if it was telling me "I'm alive!".
Technically all 0's in the data bus matches the opcode 'ORI.B #0,D0' this means that the CPU is reading and Immediate Byte value '#0' and making a boolean OR with the contents of the internal register D0. After that, another equal instruction follows in the address bus, making it sweep all the 16Mb addresses making it a beautiful... counter!
Having the proof that it was (apparently) working, I decided to gather some sram from those same boards (I needed at least two of them for the 16-bit data bus). Too bad the biggest sram's on that board was only of 2Kbytes (and there were a lot of them!).
Back in that time huge sram chips didn't exist an the ones that did exist were very expensive.
2x UM6116K-2 - 2KByte SRAM from the original boards. |
With everything connected, all I was missing was a way to get some code in that ram. At first I thought in burning some roms since I had a lot of uveprom's from the boards. But when I really though about it, developing code would be painful... I needed a way to develop code and test it fast...
After some time thinking about it I had this idea of using the parallel port to program the srams, and it worked like a charm! Using shift registers, latches and buffers I was able to program the full 4KBytes with the parallel port. The address was loaded into the serial registers, then I could read or write data in the data bus. I wrote a small program that could write or read the sram (in turbo pascal at that time).
Now I had a fast way to test and debug code, and there I started making little assembly programs that the only thing they did was to manipulate bytes in the sram (that I could read with the parallel port interface). I do remember that the first piece of assembly code I've tested was as simple as loading two registers with some numbers and them saving the multiplication result in some memory location that after reading with the parallel port I could check that, after spending some days (or even months) under the sun and in the rain, this guy could still do some real math!
Later I've put my hands on a USART (a M82C51A) and finally had a door to the world! I then started the development of a serial bootloader that when finished would go into 2 ROMs and allow me to remove all the parallel port to sram circuitry.
My version of the famous Willem programmer used to burn... well, everything! |
Some time passed and these new things called programmable logic devices appeared.
I've build a GAL (Generic Array Logic) programmed and programmed some GAL's which replace many of the original glue logic. I guess these devices have died meanwhile (or better, evolved into CPLDs).
Meanwhile I've made a few more improvements. The most significant were the upgrade of the available RAM to 128Kb (4x 32Kb SRAMs from an old PC motherboard, used as cache memory) and the migration from uvprom to flash memory (two brand new W29C020).
My GAL programmer. Made from a single side pcb version from this source. |
And that it was, my single (bread)board computer! With 512Kb flash memory and 128Kb RAM.
And when I thought everything going good I was wrong... In one minute I had million ideas and in the next minute I had zero ideas to do with the board... the year was around 2001 and for some time the only thing that was developed in that board were layers and layers of dust...
But then it came a day when...
(in next post I'll talk about two major projects I used this board for)
quarta-feira, 25 de janeiro de 2012
Origins
And this all started about twelve years ago when I've spotted these two huge pcb boards dumped on a sideroad near some other uninteresting trash. These two boards had a lot of eproms (uv erasable) easily identifiable by the stickers on them covering the UV window and identified by the letters "ROM1 ODD" "ROM1 EVEN" and so on up to ROM32 or so. There was also these big population of small chips all over the boards. (later I've realized that this boards probably belonged to some arcade machine)
And in the middle of one board there it was, this huge chip named MC68000P8.
Back in that time my knowledge in electronics was pretty limited, so I didn't have a clue of what that huge chip was. After some quick research I've found out that it was a 32-bit CPU! I remember there were some websites with a lot of information and a few schematics on how to connect this big chip. The other chips lying around where mostly buffers, latches, glue logic a Yamaha chip (for sound effects) and some other unattractive 8-bit CPU (the 6502 if I remember correctly, maybe used to deal with the sound).
So, there I was with with the 68k in my hand and very enthusiastic in getting that thing up and running!
In the next post I'll talk about from the first sign of life to the fully functional board with serial bootloader.
And in the middle of one board there it was, this huge chip named MC68000P8.
The original CPU scavenged from the original PCB |
Back in that time my knowledge in electronics was pretty limited, so I didn't have a clue of what that huge chip was. After some quick research I've found out that it was a 32-bit CPU! I remember there were some websites with a lot of information and a few schematics on how to connect this big chip. The other chips lying around where mostly buffers, latches, glue logic a Yamaha chip (for sound effects) and some other unattractive 8-bit CPU (the 6502 if I remember correctly, maybe used to deal with the sound).
So, there I was with with the 68k in my hand and very enthusiastic in getting that thing up and running!
In the next post I'll talk about from the first sign of life to the fully functional board with serial bootloader.
Subscrever:
Mensagens (Atom)