I've been quiet for too long... and I need to publish some more tuts on the NetDuino and other things I have been up to, but in the mean while check this out:
I picked up this fully functional valve based scope for R200 ( < $30 ). It was dirty as all hell, but I spent the last few evenings cleaning it up and now its shiny :) What a piece of old skool awesome! I think this is over 40 years old...
Don't make 'em like they used to!
-(e)
Friday, October 22, 2010
Wednesday, September 22, 2010
The NetDuino and some 74HC574's
If you live in South Africa, you may remember these (ComCrypt 4000 MNET decoder):
Well a collegue found one, ripped it apart and found this little display board inside:
The board was soldered vertically onto the main board but with some judicious use of a de-soldering pump and some flux I got it free. My collegue gave it to me to have a look at.
This is how I reverse engineered it and connected it to the NetDuino:
If we look at the wiring on the Green LED, we can see that the positive pin is permanently connected to a shared 5V power line (shared with the flip-flops etc.) but the negative pin is connected to a GPIO pin on the NetDuino. So how do we switch the LED on? Well we need to write false to the respective output port:
Writing false to the pin sets the GPIO port LOW i.e. brings the pin to GROUND, thereby completing the circuit and causing electricity to flow through the LED, lighting it up.
The data lines (D0-D7) are also active low, and it seems that the registration of the clock pulse occurs on the low edge of the clock. If you imagine the following (as a badly drawn square wave) then when the clock pin goes from HIGH to LOW (falling edge) the flip-flop reads the states of the input pins and transitions that state to the output pins:
Okay, so I made that up, I THINK that is how it works :) If anyone can explain this better then... great!
These decoders are dirt cheap (you can pick one up for around R50-R100 (<$15) ) and they have tons of excellent bits to harvest so go and GET EM! (The newer decoders also have bits and pieces but you have to make sure it is not a new tiny one. They are all SMD and pretty useless for our purposes). Have a look in your garage for old electronics, there is tons of stuff to harvest lying around... :) Here is the code:
Well a collegue found one, ripped it apart and found this little display board inside:
The board was soldered vertically onto the main board but with some judicious use of a de-soldering pump and some flux I got it free. My collegue gave it to me to have a look at.
This is how I reverse engineered it and connected it to the NetDuino:
- First off, look at the chips on the board: we have two 74HC574 chips. A brief Google returns these as “Octal D-type flip-flop, positive edge trigger, 3-state”... at which point I went “WTF?” and had a good read on Wikipedia: http://en.wikipedia.org/wiki/Flip-flop_(electronics), then found the data sheet: http://www.datasheetcatalog.org/datasheet/philips/74HC_HCT574_CNV_2.pdf
- Which didn’t help too much so I read that all again :)
- The data sheet yielded the pinout above, and so I began tracing the connector pins to the chips and reading what the pins did. Here is a picture of the underside of the board
- So.. All of the OE pins are tied to ground. This is good, it seems OE is “Output Enable”. Counting from left to right the pins are traced as:
- NC (not connected)
- Red LED GND
- NC
- GND
- Clock pin (right hand flip-flop)
- 5V (Vin)
- Clock pin (left hand flip-flop)
- Green LED GND
- GND
- INPUT 7
- INPUT 6
- INPUT 5
- INPUT 4
- INPUT 3
- INPUT 2
- INPUT 1
- INPUT 0
- GND
- 5V
- The input lines are connected to both flip-flops on pins D0-D7. The way the flip-flop works is that you set these lines high or low and then pulse the clock to transfer the state of the inputs to the flip-flop outputs i.e. the pins connected to the 7-segment LEDs. Basically between clock pulses the flip-flops will hold their output values thus keeping the relevant bits of the 7-segment display lit.
- From here it was a case of wiring this up to the NetDuino. I connected D0-D7 to the corresponding D0-D7 pins on the NetDuino. Clock pins went to D8 and D9, the LEDs (red and green) went to D10 and D11 and 5V and GND went to the respective 5V and GND lines on the NetDuino. (Notice above that the two 5V pins are bridged, as are the GND pins. The GND pin for one of the chips is not tied to ground and if you omit this you will get weird values on one of the 7-segment displays. I believe this is called a “floating ground” and is the source of much evil...)
If we look at the wiring on the Green LED, we can see that the positive pin is permanently connected to a shared 5V power line (shared with the flip-flops etc.) but the negative pin is connected to a GPIO pin on the NetDuino. So how do we switch the LED on? Well we need to write false to the respective output port:
// Set up the pin
OutputPort _greenLed = new OutputPort( Pins.GPIO_PIN_D11, true );
// Set the pin low
_greenLed.Write( false );
Writing false to the pin sets the GPIO port LOW i.e. brings the pin to GROUND, thereby completing the circuit and causing electricity to flow through the LED, lighting it up.
The data lines (D0-D7) are also active low, and it seems that the registration of the clock pulse occurs on the low edge of the clock. If you imagine the following (as a badly drawn square wave) then when the clock pin goes from HIGH to LOW (falling edge) the flip-flop reads the states of the input pins and transitions that state to the output pins:
Okay, so I made that up, I THINK that is how it works :) If anyone can explain this better then... great!
These decoders are dirt cheap (you can pick one up for around R50-R100 (<$15) ) and they have tons of excellent bits to harvest so go and GET EM! (The newer decoders also have bits and pieces but you have to make sure it is not a new tiny one. They are all SMD and pretty useless for our purposes). Have a look in your garage for old electronics, there is tons of stuff to harvest lying around... :) Here is the code:
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
namespace Decoder
{
public class Program
{
private readonly OutputPort _clockPin1;
private readonly OutputPort _clockPin2;
private readonly OutputPort _redLed;
private readonly OutputPort _greenLed;
private readonly OutputPort[] _digitPins;
private readonly byte[] _digitBits = new byte[]
{
1 + 2 + 8 + 16 + 32 + 64,
1 + 64,
2 + 1 + 4 + 16 + 32,
2 + 1 + 4 + 64 + 32,
8 + 4 + 1 + 64,
2 + 8 + 4 + 64 + 32,
2 + 8 + 16 + 32 + 64 + 4,
2 + 1 + 64,
1 + 2 + 4 + 8 + 16 + 32 + 64,
1 + 2 + 8 + 4 + 64,
128
};
public Program()
{
_digitPins = new OutputPort[]
{
new OutputPort( Pins.GPIO_PIN_D0, true ),
new OutputPort( Pins.GPIO_PIN_D1, true ),
new OutputPort( Pins.GPIO_PIN_D2, true ),
new OutputPort( Pins.GPIO_PIN_D3, true ),
new OutputPort( Pins.GPIO_PIN_D4, true ),
new OutputPort( Pins.GPIO_PIN_D5, true ),
new OutputPort( Pins.GPIO_PIN_D6, true ),
new OutputPort( Pins.GPIO_PIN_D7, true ),
};
_greenLed = new OutputPort( Pins.GPIO_PIN_D11, true );
_redLed = new OutputPort( Pins.GPIO_PIN_D10, true );
_clockPin1 = new OutputPort(Pins.GPIO_PIN_D8, true);
_clockPin2 = new OutputPort(Pins.GPIO_PIN_D9, true);
}
private void PulseClock( OutputPort pin )
{
pin.Write( false );
pin.Write( true );
pin.Write( false );
}
private void SetDigitBits( int digit )
{
if( digit < 0 || digit > 10 )
digit = 10;
digit = _digitBits[ digit ];
for( int i = 0; i < 8; i++ )
{
bool on = ( ( digit >> i ) & 1 ) == 1 ? false : true;
_digitPins[ i ].Write( !on );
}
}
private void DisplayValue( int value )
{
int high = value / 10;
int low = value - ( high * 10 );
SetDigitBits( low );
PulseClock( _clockPin2 );
SetDigitBits( high );
PulseClock( _clockPin1 );
}
private void Setup()
{
PulseClock( _clockPin1 );
PulseClock( _clockPin2 );
}
private void Loop()
{
bool greenOn = true;
int value = 0;
while( true )
{
_redLed.Write( greenOn );
_greenLed.Write( !greenOn );
greenOn = !greenOn;
for( int i = 0; i < 10; i++ )
{
DisplayValue( value++ );
Thread.Sleep( 100 );
}
if( value > 99 ) value = 0;
}
}
public static void Main()
{
Program p = new Program();
p.Setup();
p.Loop();
}
}
}
Saturday, August 21, 2010
Zipit Z2 JTAG
So I finally managed to brick my Z2...
Trying to get the sleep / reset cycle working in u-boot (look for a subsequent post) I managed to generate some dodgy assembler and the next thing you know...
Luckily I had a nice JTAG adapter lyining around, an Olimex ARM-USB-OCD. The soldering wasn't too tricky, but here is a detailed picture to help out the weary:
The interesting part was getting OpenOCD to play along nicely. To get OpenOCD working you need some configuration scripts that identify your CPU, JTAG adapter etc.
Here is the Z2 specific script (save this as e.g. z2.cfg):
What is interesting to note in the script above are the jtag_nsrst_delay and jtag_ntrst_delay values. The ARM-USB-OCD has separate lines for SRST and TSRT and the above values were required to get reset halt to work reliably in OpenOCD.
Reflashing u-boot brought the Z2 back to life and I now have a JTAG debug option. I should have done this years ago!
HTH
-(e)
edit: stupidly I forgot to thank the original JTAG legend GPSFan for his help and pictures and G1PowerMac for his site.
Trying to get the sleep / reset cycle working in u-boot (look for a subsequent post) I managed to generate some dodgy assembler and the next thing you know...
Luckily I had a nice JTAG adapter lyining around, an Olimex ARM-USB-OCD. The soldering wasn't too tricky, but here is a detailed picture to help out the weary:
The interesting part was getting OpenOCD to play along nicely. To get OpenOCD working you need some configuration scripts that identify your CPU, JTAG adapter etc.
Here is the Z2 specific script (save this as e.g. z2.cfg):
And the ARM-USB-OCD configuration (save this as e.g. arm-usb-ocd.cfg):# config for ZipitZ2
jtag newtap pxa270 cpu -irlen 7 -ircapture 0x1 -irmask 0x7f -expected-id 0x49265013 -expected-id 0x79265013
target create pxa270.cpu xscale -endian little -chain-position pxa270.cpu -variant pxa27x
# maps to PXA internal RAM.
pxa270.cpu configure -work-area-phys 0x5c000000 -work-area-size 0x10000 -work-area-backup 0
#flash
flash bank pxa270.flash cfi 0x00000000 0x1000000 2 2 pxa270.cpu
#
# Olimex ARM-USB-OCD
#
# http://www.olimex.com/dev/arm-usb-ocd.html
#
interface ft2232
ft2232_device_desc "Olimex OpenOCD JTAG"
ft2232_layout "olimex-jtag"
ft2232_vid_pid 0x15BA 0x0003
jtag_nsrst_delay 0
jtag_ntrst_delay 200
reset_config trst_and_srst separate
What is interesting to note in the script above are the jtag_nsrst_delay and jtag_ntrst_delay values. The ARM-USB-OCD has separate lines for SRST and TSRT and the above values were required to get reset halt to work reliably in OpenOCD.
Reflashing u-boot brought the Z2 back to life and I now have a JTAG debug option. I should have done this years ago!
HTH
-(e)
edit: stupidly I forgot to thank the original JTAG legend GPSFan for his help and pictures and G1PowerMac for his site.
Tuesday, July 27, 2010
[Dingux] OpenTyrian Save and High Score entry
I've started adding code for a limited kind of virtual keyboard.
This should allow save games names and high score entry in OpenTyrian.
So far it seems to be working for save games but I need to clean it up a bit and get it to work as a generic text entry mechanism.
Stay tuned, hopefully this will be finished before I depart overseas for a week.
-(e)
This should allow save games names and high score entry in OpenTyrian.
So far it seems to be working for save games but I need to clean it up a bit and get it to work as a generic text entry mechanism.
Stay tuned, hopefully this will be finished before I depart overseas for a week.
-(e)
Sunday, July 25, 2010
Dingux OpenTyrian release
Here is an optimised build of OpenTyrian that plays full speed with sound. This archive ONLY contains the executable: opentyrian.dge, please overwrite your old tyrian executable or get the datafiles if you do not have them from:
OpenTyrian @ GoogleCode
Other changes:
- Key mapping now works (segfault in code fixed)
- Key mapping now swaps keys if an in-use key is chosen
- SDL mouse cursor removed
- Soft mouse cursor removed from upgrade etc. screens
- Display is centred
Get it from the GP2X.com archive.
-(e)
Sunday, January 10, 2010
sweetlilmre's tips to make your dev life suck less, part #1
Disclaimer: The title might suggest that I invented or this originated this stuff in some way. I certain DID NOT :) Just some good reading I have done lately. And thanks to JonH for some of the links and discussion.
Dependency Injection:
JonH (a mate of mine from work) and I have been having some very interesting chats on Dependency Injection, Inversion of Control and other bits and pieces.
What this had made me realize is that there are some very simple development concepts (dressed up in frightening terms like Dependency Injection!) that really make your life easier if you practice them. Some of this stuff you pick up as a dev as you go along but formalizing the concept as soon as possible is only going to help you.
So start off by reading this:
http://stackoverflow.com/questions/130794/what-is-dependency-injection
Then ask yourself if you understand what Design by Contract means and how using interfaces applies and to and works with DI to make your life easier. Then have a look at this:
http://googletesting.blogspot.com/2008/07/how-to-think-about-new-operator-with.html
Which gives a nice round off to the DI discussion. This also seems like a great blog to follow generally.
This is all building up to unit testing and mocking, but we'll get to that later :)
-(e)
Dependency Injection:
JonH (a mate of mine from work) and I have been having some very interesting chats on Dependency Injection, Inversion of Control and other bits and pieces.
What this had made me realize is that there are some very simple development concepts (dressed up in frightening terms like Dependency Injection!) that really make your life easier if you practice them. Some of this stuff you pick up as a dev as you go along but formalizing the concept as soon as possible is only going to help you.
So start off by reading this:
http://stackoverflow.com/questions/130794/what-is-dependency-injection
Then ask yourself if you understand what Design by Contract means and how using interfaces applies and to and works with DI to make your life easier. Then have a look at this:
http://googletesting.blogspot.com/2008/07/how-to-think-about-new-operator-with.html
Which gives a nice round off to the DI discussion. This also seems like a great blog to follow generally.
This is all building up to unit testing and mocking, but we'll get to that later :)
-(e)