Design of the 8052 SBC

With the schematics finished, I set out to program the PLD for address decoding. I had ordered some ATMEL AT89S52’s off eBay. The ATMEL version of the 8052 has some extra features. Among them is the ability to ISP program the parts. I found that even though the current version of AVRDUDE does not support the AT89S52, that someone had figured out how to configure AVRDUDE to program them. I added the extra configuration into the AVRDUDE config file and used my oscilloscope to check for an active high reset signal, which was correct.

The schematic is shown below.  Click here for a PDF of the schematic.

8052 SBC Schematic

Since I wanted to have an external reset button on the SBC, I used the PLD to gate either the ISP reset signal or the hardware switch reset signal to the AT89S52. 8052_BASIC also uses an ALE_DIS signal to latch the lower 8-bits of the address bus and hold it stable during EEPROM writes. I wanted to be able to use the EA pin of the AT89S52 to access the ROM or RAM at memory address 0x0000 to 0x1FFF (or 0x7FFF for the RAM). I also wanted to access the RAM or ROM at 0x8000 to 0xDFFF (or 0xAFFF for the ROM). I decoded the state of the EA pin to switch the address decodes accordingly. Since the memory at 0x8000 needs to apprea in both the PROG and DATA spaces, I used PSEN and RD as the RAM or ROM OE pin. This way, I can program code into the RAM or EEPROM while at 0x8000 and then set the EA pin low to map the program in in RAM or ROM into address 0x0000. After verifying the decoding logic worked properly, I set out to define PCB footprints for the various parts.

USB-to-TTL bridge (before and after mod)

I did not want to use an external USB-to-TTL dongle and I had a few eBay modules that used the CH340 parts. However, all these eBay dongles that are CH340, PL2303 or CP2102 based have a TYPE-A USB connector soldered to them. I could have simply soldered the module to the PCB but a USB extended cable must be used to interface with that connector and I did not want to use it. I desoldered the USB connector and the right-angle BERG-STIK pins and removed them. I then added BERG-STIK pins to the USB connections and the TTL I/O pins then created a PCB footprint for the module. The USB connector pads are less than 0.1 inch spacing but they were close enough that I could force-fit the BERG-STIK pins into the pads without damaging the board. I have not used my PCB layout program in about a year, so it took me a few hours to get back into “memory recall mode” to be able to use it efficiently.

Most of the layout was done within 2 hours. There are 187 connections on this board. I was originally thinking to hand-wire the PCB but with this many connections, it did not warrant the cost in time to do so, not to mention the possible wiring errors and subsequent desolder and re-soldering required to correct them.

Below is the CUPL code for the address decoder PLD.

Name 8052SBC_IOdecode-1V00;
Partno 8052SB_PLD;
Revision 01;
Date 10/26/2016;
Designer Quest, Johnny;
Company JQ;
Assembly 8052 SBC;
Location U1;
Device g20v8a;

 *              ______________
 *             |8052SBC_IOdeco|
 *         x---|1           24|---x Vcc 
 *    wr_l x---|2           23|---x ale_h 
 *    rd_l x---|3           22|---x IO1_CS 
 *     a15 x---|4           21|---x IO0_CS 
 *     a14 x---|5           20|---x RAM_OE 
 *     a13 x---|6           19|---x RAM_CS 
 *     a12 x---|7           18|---x ROM_OE 
 *    ea_l x---|8           17|---x ROM_CS 
 *  psen_l x---|9           16|---x ALE_EN 
 * rst_isp x---|10          15|---x RST_H 
 *  rst_sw x---|11          14|---x ale_dis 
 *     GND x---|12          13|---x 
 *             |______________|
/* This device generates chip select signals for two */
/* 32Kx8 static RAMs. */
/* It also drives the system WAIT line to insert a */
/* wait-state of at least one cpu clock for all memory */
/* accesses. 1 wait-state is internally generated by */
/* the Z80 for I/O accesses */

/** Inputs **/
PIN 2 = wr_l; /* 8052 WR (active low) */
PIN 3 = rd_l; /* 8052 RD (active low) */
PIN [4..7] = [a15..a12]; /* upper 4 address bits */ 
PIN 8 = ea_l; /* 8052 EA (active low) */
PIN 9 = psen_l; /* 8052 PSEN (active low) */
PIN 10 = rst_isp; /* ISP reset line (active high) */
PIN 11 = rst_sw; /* Reset Switch input (active low) */
PIN 14 = ale_dis; /* 8052 ALE_dis [P1.3] (active high) */
PIN 23 = ale_h; /* 8052 ALE (active high) */

/** Outputs **/
PIN 22 = IO1_CS; /* I10 CS (active low) */ 
PIN 21 = IO0_CS; /* IO0 CS (active low) */ 
PIN 20 = RAM_OE; /* 32Kx8 RAM OE (active low) */ 
PIN 19 = RAM_CS; /* 32Kx8 RAM select (active low) */ 
PIN 18 = ROM_OE; /* 8Kx8 EEPROM OE (active low) */ 
PIN 17 = ROM_CS; /* 8Kx8 EEPROM select (active low) */ 
PIN 16 = ALE_EN; /* ALE enable (active high) */
PIN 15 = RST_H; /* 8052 RST (active high) */

/** Declarations and Intermediate Variable Definitions **/
FIELD address = [a15..12]; /* upper 5 addresses */ 
FIELD banksel = [rd_l,psen_l,ea_l]; /* RAM/ROM Bank switching inputs */

bank0 = address:[0XXX..7XXX]; /* Lower 32KB bank */
bank1 = address:[8XXX..DXXX]; /* Upper 24KB bank */

io0 = address:[EXXX..EXXX]; /* IO0 address decode */
io1 = address:[FXXX..FXXX]; /* IO1 address decode */

dataspc = psen_l; /* DATA space address */
progspc = !psen_l; /* PROG space address */

io0_eqn = io0 & dataspc; /* IO0 decode in DATA space */
io1_eqn = io1 & dataspc; /* IO1 decode in DATA space */

ram_cs_eqn = ((dataspc & ea_l) & bank0) /* EA=1, RAM chip select in DATA space (active low) */
 # ((dataspc & !ea_l) & bank1) /* EA=0, RAM chip select in DATA space (active low) */
 # ((progspc & !ea_l) & bank1); /* EA=0, RAM chip select in PROG space (active low) */

ram_oe_eqn = ea_l & !rd_l & ram_cs_eqn /* EA=1, RAM read in DATA space (active low) */
 # !ea_l & progspc & ram_cs_eqn; /* EA=0, RAM read in PROG space (active low) */
/*ram_oe_eqn = !rd_l & ram_cs_eqn; */ /* RAM read in PROG or DATA space (active low) */

rom_cs_eqn = ((progspc # !ea_l) & bank0)
 # (dataspc & ea_l & bank1); /* EEPROM chip select in PROG space (active low) */

rom_oe_eqn = (progspc # !rd_l) & rom_cs_eqn; /* EEPROM read in PROG or DATA space (active low) */

/** Logic Equations **/
ale_en_eqn = ale_dis & ale_h; /* 74HC573 Latch Enable (active high) */ 
rst_h_eqn = rst_isp # !rst_sw; /* 8052 reset signal */

/* Memory select outputs */
RAM_CS = !ram_cs_eqn; /* RAM_CS (active low) */
RAM_OE = !ram_oe_eqn; /* RAM_OE (active low) */
ROM_CS = !rom_cs_eqn; /* ROM_CS (active low) */
ROM_OE = !rom_oe_eqn; /* ROM_OE (active low) */

IO0_CS = !io0_eqn; /* IO0 address decode (active low) */
IO1_CS = !io1_eqn; /* IO1 address decode (active low) */

ALE_EN = ale_en_eqn; /* ALE enable (active high) */
RST_H = rst_h_eqn; /* 8052 RST (active high) */

2 thoughts on “Design of the 8052 SBC

  1. Hi Rando:
    I had not thought about it. The design needs a few PCB fixes and I am not using any “free” PCB layout packages, so all I could provide are the GERBER and drill files.

    WORDPRESS does not really allow any files other than graphic images, so there’s that issue as well and I don’t have a web-server or “cloud” system that I want to upload them to.

    I’ll post them when I have time.

    Peace and blessings,
    Johnny Quest


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s