If you landed on this page, you are likely scratching your head in bewildered wonderment at the Crossbar feature of the Silicon Lab’s Busy Bee 8051 microcontrollers. You are contending with keywords such as priority decoder, skip registers, along with function maps showing the relationship between peripherals and physical I/O pins.
The short answer is to use the graphical configuration tools designed into Silicon Lab’s Simplicity Studio Integrated Development Environment (IDE). This is an excellent tool that will solve many of your needs.
But what if you want to share pin functionality across several devices?
How can the Crossbar be changed dynamically?
For example, how do we configure the Busy Bee (Si Labs 8051) so that LCD control lines may be shared with SPI. This is an important cost saving advantage for designs with relaxed performance requirements. Here relaxed implies that the LCD update and the SPI operation do not occur at the same time and that the update rate is slow enough to accommodate the time-division multiplexing.
To answer this question, we will start at the beginning. We will explore the Crossbar operation and then move to the more complex examples with dynamic configuration allowing pin sharing.
Note that we will focus on the newer members of the Silicon Laboratory 8051 family. One significant upgrade is the inclusion of Crossbar skip registers. This adds considerable pin assignment flexibility when compared to the older devices such as the C8051F000. However, it does add additional programming complexity to an already abstract and at time difficult to understand concept. This may be a good time to review the operation of the older devices Crossbar configuration as described in this application note.
In the long-standing tradition of the 8051, the new features build on the old, with roots all the way back to the Intel parent in 1980.
The Crossbar is used to route peripherals to specific I/O pins. This functionality is handled differently across microcontrollers. Some architectures have little to no flexibility in pin assignment. These minimalist microcontrollers physically route a peripheral such as SPI to a single set of I/O pins. We are then required to work around this limitation as the printed circuit artwork is developed. In the ideal world, peripherals such as the SPI could be routed to any pin. While this is desirable, unrestricted assignment adds cost and complexity. The Crossbar provides a solution somewhere between the two extremes.
The Crossbar is a gateway. Nothing is passed to the lower numbered I/O ports without first passing through the Crossbar. This gateway may be envisioned as a series of multiplexers as shown in the highly simplified Figure 1 representation. An example is the SPI0-SCK signal. It may be routed to any P0 pin or select P1 pins provided the appropriate Priority Crossbar registers are activated.
Figure 1: Simplified section of the Silicon Labs 8051 Crossbar.
One of the most frustrating things about the Crossbar is its abstraction. Observe that we do not explicitly state that peripheral X is connected to I/O pin Y. There is no such command as connect SPI0-SCK to P1.3. Instead, we guide the process based on a given priority scheme.
This priority is defined in two dimensions:
In one dimension, priority is equivalent to pin order with P0.0 assigned the highest position. P0.1 slightly lower and so on until we consume all P0, P1, and depending on the microcontroller, P2 pins.
The other dimension is concerned with the peripherals themselves. Communication devices such as the UART and SPI are deemed more “important” than a PWM or a timer output. As an example, suppose a programmer activated all three peripherals. The UART would be assigned first, then the SPI, and then the PWM.
This list provides a summary of the Crossbar attributes that must be considered for the remainder of this post:
The Crossbar is included in the critical path between a peripheral and I/O pins. Without Crossbar activation there are no microcontroller outputs.
The Crossbar acts as a large priority multiplexer.
The programmer does not have explicit control of the multiplexer. Instead, pins are assigned in priority where priority is defined along two dimensions including peripheral type and the I/O pin. The USART has the highest priority along the peripheral dimension while P0.0 as the highest priority on the pin hierarchy dimension.
The crossbar may be dynamically configured. However, turning off a device by modifying the XBRn registers will change the priority with a resulting change in pin assignments. This may be mitigated using the PxSKIP registers which will be explored later in this post.
It’s important to have a plan in place before attempting to program the Crossbar. You will need to identify and then map all I/O to the microcontroller. At a minimum you will need to identify which peripherals are to be activated.
- SPI (3-wire mode with NSS software controlled for consecutive write operations)
- While not used, we will reserve future use of the UART
- The remainder of pins are reserved for general purpose or non-Crossbar peripherals such as the ADC.
The resulting I/O map is captured in Figure 2. The table on the left is associated with the physical I/O pins with a sketch of the SOIC-16 IC outline included for reference. The table on the right captures the Crossbar matrix. This is an adaptation of the table found in the Busy Bee datasheet that has been truncated to reflect the limited options available with the SOIC-16 device.
Note that the hierarchical table includes the critical priority across two dimensions. Also, unlike the datasheet representation, this table also include the associated XBARx and PxSKIP registers.
Figure 2: I/O Pin mapping and Crossbar support for an 8051 project with SPI and PWM.
Let’s start with the UART. Recall that we wish to reserve this top priority peripheral for future use. Rather than enable the device, we will skip the pin assignment by placing a S in the corresponding locations for P0.4 and P0.5. Later we will need to configure the associated P0SKIP bits.
Next, we map the SPI. We will use the highest priority I/O from P0.0 to P0.2. Observe that this corresponds to physical pins 3, 2, 1, and 16 (chip select) of the SOIC-16 device. This is convenient as all SPI I/O are located on one side of the IC thereby simplifying PCB layout. Later we will need to set the associate XBR0 bits.
The final part of our map involves the PWM which is part of the Programmable Counter Array (PCA0). We could assign the two PWM outputs to P0.6 and P0.7. However, from a board routing perspective it may be better to use pins P1.1 and P1.2 as they are conveniently located on the edge of the SOIC-16 package.
Tech Tip: Pin assignment is an iterative exercise. Having the physical mapping with the given microcontroller package alongside the Crossbar priority map is helpful. Together they point to a desirable PCB layout that may not have been apparent if the ideas were considered independently.
Before moving on please examine Figure 2 and observe:
the black shaded areas are not available for the chosen Busy Bee.
the UART is an exception with a fixed association with pins P0.4 and P0.5.
after the UART exception is complete, we move left to right across the I/O pins either assigning (X) or skipping (S). It’s important to clearly place an X or S into each column as a mistake will result in an undesirable pin shifting to the left. Remember, we do not explicitly state that peripheral X is connected to I/O pin Y. instead we assign priorities and the Crossbar does the actual assignment.
for clarity, we shade in the column below each X or S.
we “walk” a diagonal down the Crossbar table.
for this SOIC-16 device, there are more peripheral than there are available physical I/O pins
Now that we have filled out the Crossbar chart with our desired connections (X) and skips (S), we can assign the appropriate registers. This is done by writing to the associated XBRx registers on the left and the PxSKIP registers on the bottom of the table.
Let’s start with the skip registers. Reading from left to right, we will skip:
- P0.3 (software control of SPI chip-select line)
- P0.4 and P0.5 (reserved in case we want to use the UART in the future)
- P0.6, P0.7, P1.0 (preferred PCB configuration given the SOIC-16 package)
A review of the Busy Bee reference manual shows that a skip is a logic 1. It follows that the values are:
P0SKIP = 0xF8;
P1SKIP = 0x01;
We can now move on to the XBRx assignments. Reading from top to bottom, we will skip:
- all peripherals from SMB0E down to SYSCLK (inclusive)
Again, a review of the Busy Bee reference manual shows that an assignment is a logic 1. It follows that the values are:
XBR0 = 0x01;
XBR1 = 0x02; // Use two of the three PWM outputs
The last step is to configure and enable the peripherals themselves including the SPI and PWM. The various PxMDIN and PxMDOUT registers must also be configured for any general purpose I/O and ADC operations.
That is a topic for another day.
At this point we have code that configures the Crossbar. All we need to do is call the code once before entering the while(1) superloop. That is sufficient for most programs as we set the Crossbar once and then forget about it. Yet, not all programs are equal.
Suppose we wish to add an LCD character display to the microcontroller. The chosen SOIC-16 is a small pin-limited device. It does not have enough pins to support the SPI, LCD, and other meaningful general purpose I/O.
With a bit of creativity and careful programming the external hardware can share I/O pins. In this project, three of the SPI I/O pins may shared with the LCD. This is not a simultaneous operation. Instead, they are time-multiplexed with the understanding that the demands of the SPI and LCD are low enough so that no apparent delay or interference will result. With multiplexing the 8051 will send commands to the LCD and sometime later shift the Crossbar so that it can communicate with the SPI device(s).
Recall that the Crossbar is the gateway to the Busy Bee’s P0 and P1 I/O pins. Also recall that the Crossbar is configured for the SPI pins on P0.0 to P0.3. With this configuration, a write to a port latch such as P0.0 will have no effect on the I/O PIN.
We could disassociate the SPI from the I/O pins by clearing XBR0.URT0E bit. Unfortunately, this action would result in a pin reassignment with the two PWM moving three positions to the left landing in the P0.6 and P0.7 positions.
Let’s restate this essential mechanism:
Dynamically changing the XBRx registers without simultaneously changing the PxSKIP register will result in an undesirable pin reassignment.
To maintain the configuration, we must command the Crossbar to skip the SPI’s P0.0 to P0.3 pins along with the original skipped I/O. This new configuration is shown in Figure 3, and here is the new Crossbar configuration.
XBR2 = 0x00; // Global disable of all I/O cells blocks
P0SKIP = 0xFF;
P1SKIP = 0x01;
XBR0 = 0x00;
XBR1 = 0x02; // Use two of the three PWM outputs
XBR2 = 0x40; // Global enable of all I/O cells blocks
Figure 3: I/O Pin mapping preserving pin spacing with the SPI turned off.
Tech Tip: SPI allows for parallel connection of devices provided each device has an independent select line. This implies that MISO pin for all non-selected devices enter a high impedance state. This allows one device to talk on the line at any given time. While perhaps not recommended, the master microcontroller can use this line for other purposes that is, assuming all other devices are disabled with their MISO drive pins in a high impedance state.
This was a challenging piece to write. In retrospect, the Crossbar is a very simple mechanism. The most difficult part is planning out the I/O in the first place.
My hope is that the post brings you clarity.
Your comments and suggestions are welcome.