Recently, I have been helping a reader sort out some code that makes strings of WS2812 LEDs work.  Specifically, this code takes data from a frame buffer inside of the PSoC 6 and drives it out a SPI port via the MOSI pin. I have written about this a couple of times, but,  the new wrinkle in our code is that it allows you to use any combination of SPI port/pins on the chip.  Instead of using the configurators to setup the SPI to GPIO connection, I setup the connection using PDL to talk directly to the PSoC 6 configuration the registers.

Perhaps it is obvious to everyone how a connection from a peripheral to a GPIO works, but I thought that I would write about it anyway.  In this article I am going to show you a bunch of the documentation for PSoC as well as the PDL source code which implements the documentation.  Specifically, I will show you the PSoC 6

  1. Architecture TRM
  2. Register TRM
  3. Datasheet
  4. PDL

Architecture TRM

In the picture below, which I copied from the PSoC 6 Architecture TRM, you can see how an individual GPIO works.  Starting  at the Pin of the chip you can see that there are three connections from/to the pin (look at the green box).

  • A set of switches to/from the Analog Mux Bus which enable CapSense or Analog peripherals to talk to the Pin
  • A connection from the pin to the Analog peripherals (some Analog peripherals can attach directly to a pin and not though the Analog Mux Bus
  • A connection to the High Speed I/O Matrix (HSIOM) – for the digital peripherals

Notice that all of the signals coming into the green box from the top are DIGITAL.  All of the signals coming into the box from the bottom are Analog and the line coming into the middle of the box controls the behavior of the I/O.

For my case the SPI is one of the “Fixed Function Digital Peripherals”.  In order to get it to connect to the pin I will beed to pick out the right signal in the multiplexer that is in the HSIOM Matrix box.

When you scroll down a little bit further in the Architecture TRM, the next diagram is a more detailed description of the GPIO.  Notice that there are a bunch of configuration register bits which setup different parts of the I/O like slew rate, interrupts, drive mode etc.  Notice that the multiplexer that is connected to “out”
and “out_en” has a bunch of different possible signals.  Including “GPIO_PRTx_OUT[OUTy]” which is a register bit which is can be used for “digital write”.  For instance GPIO_PRT0_OUT[2] would be P0_2.  The other interesting thing going on here is you can see that there are really three classes of signals attached to the mutiplexer

  • The digital output pin
  • Active signals – which work while the chip is not in deep sleep
  • Deep Sleep signals – which work while the chip is in deep sleep.

On the output side you can see the two pullup and pulldown resistors, as well as the two transistors which pullup and pull down.  All of these can be configured to be connected… or not.

And finally at the bottom of the I/O you can see the analog signals.


If you look a little bit further down in the Architecture TRM you will find this table which describes how each of the actual pins on the multiplexer work.

PSoC 6 Register TRM

If you want to start to make specific configurations for specific pins you will need to look into the PSoC 6 Register TRM.  In that document you will find that the

Register TRM

Register TRM

PSoC 6 Datasheet

But what are all of the active and deep sleep signals?  Well if you look in the PSoC 6 data sheet you can find all of those connections.  For instance on P0.1 active signal 8 is the SCB 0 SPI Select signal 2.


But really all of these register reads and writes are not really that fun.  So, Cypress provides other, less painful ways of getting things going.  Specifically,

  • void Cy_GPIO_SetHSIOM(GPIO_PRT_Type* base, uint32_t pinNum, en_hsiom_sel_t value)


  • Cy_GPIO_Pin_Init(GPIO_PRT_Type *base, uint32_t pinNum, const cy_stc_gpio_pin_config_t *config)

When you call both of these function you need to provide the value for the multipler either directly in the Cy_GPIO_SetHSIOM or indirectly in the Cy_GPIO_Pin_Init case where you provide it as a member of the cy_stc_gpio_pin_config_t *config structure called “hsiom”

Depending on which package you have selected you will have a file like gpio_psoc6_01_124_bga.h which will have both the generic definitions for the HSIOM multiplexer select (like this)

As well as the pin by pin definitions… like this for P0_2

If you look at the Cy_GPIO_Pin_Init function you will see that on line 96 it sets the register which picks the correct pin mux.

And finally the Cy_GPIO_SetHSIOM actually writes to the register.


Finally, it may seem obvious, but there is a limited set of connections to each GPIO in PSoC 6.  This means that any given SCB can only connect its SPI pins to a specific set of pins on the chip.  But, what are they?  You can either look at the data sheet, or you can search the file which you will find the pin definitions which will all be in the form of Px_y_SCBz_SPI_MOSI and this will give you a complete map.

Recommended Posts

No comment yet, add your voice below!

Add a Comment

Your email address will not be published. Required fields are marked *