Channels ▼
RSS

Design

Programmable Systems-On-Chips

Source Code Accompanies This Article. Download It Now.


Jan04: Programmable Systems-on-Chips

Al is a writer and consultant. He is also the editor of the Dr. Dobb's Journal Java newsletter. You can contact Al at alw@ al-williams.com.


Microcontrollers—as opposed to microprocessors—greatly simplify system design because they incorporate RAM, ROM (usually flash memory), clock circuitry, and I/O devices such as UARTs, A/D converters, and similar peripherals. A complete design only adds a voltage regulator, crystal, and any related real-world parts (LEDs, LCDs, motor drivers, or sensors).

The resulting designs are inexpensive and compact, but at a price: You have to select a processor that has the features you need. Consequently, the most common approach for vendors is to produce microcontroller families (like the Microchip PIC or Zilog Z8) that have many members, so you can select a chip with the right combination of memory and I/O. Of course, this approach assumes that you know your requirements ahead of time and that they won't change. In addition, multiple designs might require different parts, adding to inventory requirements.

A recent trend is the introduction of programmable systems-on-chip (PSoC) devices that are similar to ordinary microcontrollers. Instead of dedicated I/O devices, however, PSoCs contain components that you can configure into different I/O devices. For instance, one product might require two serial transmitters. Then, for a different product, you could use the same processor, but select one UART, a timer, analog amplifier, and two A/D converters.

If you think this sounds like programmable logic (see my article "Programmable Logic & Hardware," DDJ, May 2003), you're right. However, there are two big differences:

  • PSoC blocks are not as general purpose as a typical programmable logic block. Certain blocks have very specific functions (including analog functions).

  • PSoC blocks only interconnect via very specific pathways.

Inside the Cypress PSoC

Keep in mind that a PSoC isn't just a single processor. The part is available in a variety of footprints ranging from an 8-pin DIP to larger 48-pin packages. In this article, I focus on the 28-pin CY8C26443 from Cypress (http://www.cypress.com/), a PSoC Designer IDE tool that provides point-and-click design capability. The PSoC Designer IDE, which is freely downloadable, includes preconfigured, peripheral functions, and tools for configuring the PSoC. An In-Circuit Emulator (ICE) is also available. Officially called a "Configurable Mixed-Signal Array with On-board Controller," the PSoC CY8C2xx family of PSoCs replace multiple MCU-based system components with a single configurable device. The same basic architecture applies to the entire family. Other family members may have a different number of blocks, but the concepts remain the same.

Other than the configurable blocks, the CY8C26443 has all the modern features you expect—an 8051 instruction set, internal 48-MHz clock (the processor runs at 24 MHz), and hardware multiply/accumulate unit. There's even a switch mode pump that lets the processor run off low-battery voltages (the pump boosts the voltage to an acceptable level).

Figure 1 shows the screen you view when laying out blocks on the IC. Notice that pins line up around the edges. The top cluster of blocks are digital blocks that you can use for timers, UARTS, and other digital functions. The bottom cluster contains different types of analog blocks. Some of these blocks are amplifier blocks while others implement advanced features using a switched capacitor circuit. These blocks often require digital blocks to realize a specific function (in other words, an A/D converter might require a digital and an analog block).

In addition, both types of blocks may rely on software to perform some functions. A particular wide counter, for example, may put the lower 8 bits in a digital block and have that block interrupt on overflow. An interrupt handler in your program would simulate the upper bits of the counter. This saves using multiple digital blocks (which is another possibility). The Cypress Designer IDE adds the appropriate code to handle these cases, so the process is mostly transparent (except, of course, for the time it steals from your main program).

In fact, the Designer adds an entire API for each component so that you don't deal directly with the PSoC's registers. The API (callable from C or assembly) lets you write code like:

ADC_GetSamples(0); // get continuous samples

This is handy, but it does mean the actual datasheet for the part is almost useless since it deals with low-level connections that the IDE handles for you. However, Designer has a PDF datasheet for each of the virtual components you can create. This datasheet provides the specifications and documents of the API for the various amplifiers, A/D converters, UARTs, and other components you need to use.

Scattered around Figure 1 are various multiplexers that let you route signals from the blocks to other parts of the chip. Blocks can usually connect to adjacent blocks, or they can connect to these limited global routing resources.

Digital Blocks

There are two types of digital blocks—basic and communications. There are four of each on the CY8C26443. Each block has a separate interrupt system and they can be used as timers or counters. Naturally, the communication blocks are the only ones that support UARTs, SPI communications, and similar functions. DBA2 and DBA6 have special features designed to help certain types of A/D converters and DBA3 can broadcast its output to all other digital blocks (handy for a system clock divider).

The point to all of this is that while the chip can support a myriad of digital functions, it may not be able to handle them all at the same time. The IDE shows you where you can place certain blocks—you can't put a block in the wrong place. However, if the only choices are already in use, you'll have to try something different. If the existing block is something simple, you may be able to move it to a different basic block. On the other hand, if the block can't move, you have a problem. You'll either need to rethink your design or, in some cases, you can reconfigure the design at runtime.

Keep in mind that some functions (wide counters, for example) require multiple blocks. Also, some components include required software. In fact, a few components are purely software. Included among the digital components available from the IDE are counters and timers, CRC generation, I2C (master or slave), SPI (master or slave), infrared receiver, RS-232 transmit/receive/both, PWM output, random-number generators, and inverters.

In addition, the IDE's library contains components that simulate EEPROM in flash memory and drive an LCD display. These are software-only components—they don't consume any digital blocks. The IDE shows a gauge of how many resources you've used (see Figure 2). Keep in mind that some analog functions require digital blocks in addition to one or more analog blocks.

Analog Blocks

The analog blocks (12 organized as four columns of three blocks each) work using op amps and switched-capacitor technology. By controlling the capacitor switching, a number of analog functions are possible, including analog/digital converters, digital/analog converters, analog comparators, amplifiers, bandpass and lowpass filters, and DTMF output.

There are three different kinds of analog blocks: continuous time (CT, the blocks with op amps) and two switched capacitor (SC) blocks. The two different types are known as SC-A and SC-B. Again, the IDE prevents you from misplacing a block, so this is relatively transparent (until you run out of one type of block, of course).

One interesting thing about the analog nature of this chip is the selectable reference. Analog devices usually need a negative supply, but this chip doesn't accept one. Instead, it references the 0 point to a voltage above Vss. For example, you can set the voltage reference to be the midpoint between Vdd and Vss (2.5V in a 5V system). This allows the analog circuits to treat signals as negative without a negative supply. On the other hand, it limits the magnitude of the signals to 2.5V.

The chip also has a built-in bandgap reference that you can use to restrict the voltage reference. This is useful since the analog circuits can't handle signals at the supply rails. So by moving the extreme ends of the scale away from the rails, you can ensure full range operation. Depending on how you set the chip's registers, you can select a range of 1.2 to 3.8V or 1.3 to 3.9V (with the virtual ground in the center of either range). You can also select your own external high and low references, if you prefer.

Reconfiguration

One of the most interesting features about the PSoC is that you can reconfigure the blocks at runtime. This provides some additional flexibility when you start running out of blocks. For example, you might configure several A/D converters and a serial transmitter to connect to an external device and collect data. At a predetermined time, the IC could change the configuration so a UART connects to a modem in place of the simple serial receiver. After sending the data, the program can return to the original configuration.

The IDE lets you build multiple configurations and provides API calls that let you switch between them. You can reconfigure pin connections, or completely change the block functions if necessary.

An Example

As an example, consider the production-line tester in Figure 3 that has the following features:

  • The tester generates an output voltage that is fed to the device under test.
  • A technician adjusts a control until a measured test point is within range (the tester indicates the proper value with an LED and serial output).

  • The tester then changes the output voltage and measures the test point to ensure the output is correct.

  • The tester issues a pass/fail message and waits to test another device.

This is a straightforward project (you can simulate the device under test with a potentiometer). Instead of reinventing the wheel, I used an off-the-shelf TTL-to-RS-232 converter, so the actual circuit is little more than the PSoC chip and an LED.

Design Flow

When you start the PSoC Designer software, you'll see that it is similar to most modern IDEs. However, it has three distinct modes. Each mode corresponds to a phase of the design flow. The first mode lets you select functional blocks and place them in the IC's free resources.

For this project, I needed to place a PWM module (for voltage output), an amplifier and an A/D converter (for reading the incoming voltage), and UART. In addition, the UART needs a baud-rate clock, so I placed a timer in DB03. The chip generates a 48-MHz clock, which you can divide down in two steps. I selected appropriate dividers so that it would be possible to generate the 8X clock required for the UART (I wanted a 9600-baud rate). Figure 1 is the final result.

In addition to block assignments, this mode also lets you set global options such as clock speed. You can even set the I/O direction of the pins here if you like. Of course, you can do all of this at runtime (even configure blocks) but it is often easier to do it from this screen, especially if you aren't planning on changing the configuration (for example, switching a pin from input to output).

Once you are done, you can "generate the application." This produces the files required to configure the chip as well as the API definitions for both assembly and C. This leads to the second phase of the design—editing the source code.

When you work with the source code, you'll see many source files you didn't create. These are the library files produced for you. For the most part, leave these files alone. However, the interrupt handlers contain clearly marked areas where you can add custom code (for example, you might want to perform particular steps when the UART receives a character).

Unfortunately, the interrupt handlers are in assembly language. It is possible to jump to a C function (you must use a pragma to make the function an interrupt handler, though). Of course, this adds a small bit of latency to the interrupt handling.

In addition to the library code, you'll see a main source file where the program resides. Nearly all programs begin by enabling interrupts and configuring the various blocks. The blocks won't do anything until you explicitly enable them. I always find it disconcerting to have to turn on an amplifier, for example. Listing One includes the tester program (starting with void main()).

After enabling interrupts, the code turns on the input amplifier, ADC, and DAC, and starts both the baud-rate timer and UART. Finally, it asks the ADC to perform continuous conversions and begins its main loop.

The third phase is debugging. Cypress makes its PSoC ICE-4000 available for a reasonable cost. This is a real in-circuit emulator, connecting to your PC's parallel port. It occasionally crashes Windows XP, but other than that it is nice. You can single step, trace, and set complex breakpoints while operating in the real circuit. It is possible to program the chip with a programmer, test it, scratch your head, and repeat. However, the emulator's low cost makes it a great choice for speedy development. Unfortunately, there is no software emulation—if you don't have the ICE-4000, you are on your own for debugging.

The debugger works well in assembly or C (the assembler is free, the C compiler isn't). If you find a mistake in your code while debugging, you have to switch modes back to editing before actually changing the file. You repeat these steps until everything is satisfactory. You can even go back to the first steps and change the design of the chip if you like.

Inside the Code

Listing One is unremarkable. The UART provides high-level APIs such as CommPort_PutSHexInt to write a hex number to the output. These functions, combined with the simplicity of C, makes the program straightforward. Of course, most of the work was done during hardware configuration.

Take clock generation, for example. The A/D converter needs a clock. In fact, if the clock is close to an even multiple of 50Hz and 60Hz, it tends to integrate out noise at those frequencies. A 150-kHz clock, therefore, is a good idea. The chip internally generates a 48-MHz, 24-MHz, and 32-kHz clock. It also generates signals known as 24V1 and 24V2. The 24V1 clock is the 24-MHz clock divided by a user-selected denominator (between 1 and 16). The 24V2 clock is the 24V1 clock divided down again (with a denominator between 1 and 16). For this design, I set the 24V1 denominator to 16 (1.5 MHz) and the 24V2 denominator to 10 (150kHz).

The 24V2 clock, then, can directly drive the A/D. The 24V1 clock feeds the baud-rate generator. The UART requires an 8X clock, so for 9600 baud, the clock period should be about 13 (76.8 KHz). The baud-rate generator, then, should be divided by 19.5—not possible with an integer divider. However, dividing by 19 or 20 results in a very small error. I used 19 (by setting 18 into the counter's period register). So without writing any code manually, the entire UART and baud-rate clock—as well as the A/D clock—is done.

About the only I/O operation that isn't handled in the hardware blocks it the indicator LED. The LED is changed by altering the Port 1 data register (PRT1DR):

PRT1DR|=LEDMASK; // turn on LED

I used C in this project. However, the assembler works the same way. The library code is typically assembly language anyway, so there isn't any trouble using the same functions. The assembler is free, and the instruction set is familiar if you've worked with any 80xx-series microcontrollers. The complete source code for the project is available electronically; see "Resource Center," page 7.

The Future

Processors such as the PSoC are the tip of the iceberg. Eventually, you'll be able to buy a complete microprocessor and a fully programmable array in one package. Of course, even now you can get FPGAs that accept a CPU core on the chip, but not at the same low-cost and easy development of something like the PSoC. Besides, FPGAs don't have analog blocks. The analog circuitry is the key to reducing overall system cost—even a less expensive processor can't compete if the PSoC allows you to remove op amps and other analog circuitry from your design.

Customizing a single chip to fit different designs can reduce inventory costs. Using the same exact part in multiple designs also allows you to buy in larger quantities, which should also drive prices down. Being able to reconfigure the chip at runtime is just that much better.

The downside? The current generation of parts leave something to be desired in their analog performance. Inexpensive ICs can outperform many of the analog functions. What's more is the early generation of the PSoC, in particular, which has several nasty bugs when running at full speed (my example runs at 12 MHz to avoid this problem). However, new versions are now available that should fix many of these problems (and hopefully not introduce any new ones). Finally, even though the PSoC tries to be universal, you can still find designs you can't realize because you've run out of a particular resource that is required.

These problems—and they aren't big problems—won't last forever, though. Analog sections will improve, bugs will be squashed, and you can expect to see chips with many more resources (and more interconnections) very soon. In short, programmable I/O on microcontrollers will soon become the standard, not the exception.

DDJ

Listing One

//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------
#include <m8c.h>
#include "PSoCAPI.h"  

// bit of port 1 attached to LED
#define LEDMASK 0x20  
#define LOWPASS 0x100
#define HIGHPASS 0x120
#define LOWPASS2 0x7F
#define HIGHPASS2 0x99

void main()
{
    M8C_EnableGInt;  // turn on global interrupts
    InAmp_Start(InAmp_HIGHPOWER);
    ADC_Start(ADC_HIGHPOWER);
    DAC_Start(DAC_FULLPOWER);
    BaudRate_Start();
    CommPort_Start(CommPort_PARITY_NONE);
    ADC_GetSamples(0);  // get continuous samples
    while (1)
    {
       int v;
       CommPort_CPutString("Start test (space to complete)\r\n");
       DAC_WriteBlind(128);  // 2.5V output
       while (CommPort_cReadChar()==0)
       {
          while (ADC_fIsData()==0);
          v=ADC_iGetData()+2048;
          ADC_ClearFlag();
          CommPort_PutSHexInt(v);
          if (v>=LOWPASS && v<=HIGHPASS)
          {
            PRT1DR|=LEDMASK;  // turn on LED
            CommPort_PutChar('*');
          }
          else
          {
            PRT1DR&=~LEDMASK;  // turn off LED
          }
         CommPort_PutCRLF();
       }
     // phase 2
      if (v<LOWPASS || v>HIGHPASS)
        CommPort_CPutString("Warning! Device not calibrated\r\n");
      DAC_WriteBlind(64);
      CommPort_CPutString("Testing...\r\n");
      while (ADC_fIsData()==0); // get one sample
      ADC_ClearFlag(); // throw it away
      while (ADC_fIsData()==0);  // get another
      v=ADC_iGetData()+2048;
//  pass/fail logic
     if (v>=LOWPASS2 && v<=HIGHPASS2)
        CommPort_CPutString("Passed");
      else
        {
        CommPort_CPutString("Failed ");
        CommPort_PutSHexInt(v);
        }
      CommPort_CPutString("\r\nPress any key to continue\r\n");
      while (CommPort_cReadChar()==0);
     } 
}


Back to Article


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video