What is PSoC?

PSoC (Programmable System-on-Chip) is developed by Cypress company, the world's first programmable embedded design platform that integrates discrete analog and programmable logic along with memory and a microcontroller. Cypress released four different types of PSoC: PSoC1, PSoC3, PSoC4, and PSoC5. It comes in four MCU options for 8-bit and 32-bit applications, ranging from the 8-bit M8C to the high-performance ARM Cortex-M3. These PSoC families and their respective characteristics are shown in Table 1.

Table 1: Cypress PSoC Family Lists
  PSoC 1
CY8C29
PSoC 3
CY8C38
PSoC 4
PSoC 4200
PSoC 5
CY8C58LP
CPU Core M8C 8-bit CPU 8051 8-bit CPU ARM Cortex-M0 32-bit CPU ARM Cortex-M3 32-bit CPU
Max. CPU Frequency 24MHz 67Mhz 48Mhz 80MHz
Flash Memory 32KB 64KB 32KB 256KB
EEPROM N/A 2KB N/A 2KB
SDRAM 2KB 8KB 4KB 64KB
I/Os   28 to 72 I/Os
(62 GPIOs, 8 SIOs, 2 USBIOs)
  28 to 72 I/Os
(62 GPIOs, 8 SIOs, 2 USBIOs)

PSoC Creator

Cypress provides an easy and useful software tool – PSoC Creator. PSoC Creator is an Integrated Design Environment (IDE) that allows concurrent hardware and application firmware design of PSoC 3, PSoC 4 and PSoC 5 systems. PSoC Creator includes over 100 pre-verified, production-ready PSoC Components, so the developers can drag-and-drop the component into a design and configure to suit a broad array of application requirements. PSoC Creator also will generate API libraries for each component; hence the user can directly access components and easily perform reconfiguration during the run-time.

The Problem during the System Development

PSoC Creator provides a wide array of components, which can handle the low hardware layer for the developers. However, the developers still need to design the interface code between the PSoC components and the sensors/devices that are used in their systems (e.g. gyroscope sensor, temperature sensor, etc.) Usually, developers spend a lot of time focusing on the interfacing sensors for their application projects:

  1. Carefully learning the datasheet specifications for each individual sensor.
  2. Fully understanding the communication protocols, such as I2C, SPI, UART.
  3. Writing a small test code for each of the sensors to verify the datasheet and application requirements.
  4. Integrating all the code into the application project.

If any sensor is changed during the development period, the developer may need to modify all the sensor interfacing code. Is it possible to reduce the amount of code and speed up the system development stage in order to allow developers to primarily focus on the application function requirements? The answer is yes.

What is EZ-PSoC LIB (Library)?

EZ-PSoC LIB offers solutions for all the developers. It fills the gap between the user application and PSoC components.

Think about how you want to design the hardware. After you select all of the required sensors and devices, you will connect each sensor through its appropriate communication interface with the microcontroller. If any sensor changes, you can simply replace the sensor, and reconnect it to the supported communication interface. How about the software design? Is it similar to the hardware design?

Figure 1 shows the architecture of EZ-PSoC LIB. EZ-PSoC LIB included three layers: Hardware Interface Layer, Sensor Driver Layer, and Application Layer. Developers only need to connect the Application Layer Object with the Sensor Layer Objects, and also connect the Sensor Layer Objects with Hardware Interface Layer Object, and all the objects will automatically configure within each other. The developers can pay more attention to their application function design.

EZ-PSoC LIBs

Figure 1: The Architecture of EZ-PSoC LIB

 

Easy and Simple to use EZ-PSoC LIB

So, how will the user include the EZ-PSoC LIB into their existing project?

  • First, add the EZ-PSoC LIB (libEZPSoC5.a) to the project.
    In the PSoC Creator, go to the Build Settings and scroll down to Linker. Click on Addtional Libraries and select libEZPSoC5.a library.
  • Second, add the directory of EZ-PSoC LIB to the project.
    Click on Application Library Directories and then add the directory of the library into your project.

InclusionEZPoCLIBs
Figure 2:
Inclusion of EZ-PSoC LIB to Project

 

After you add the EZ-PSoC LIB into your project, you must include all of the proper header files relevant to the sensors used at the top of the main.c file. Then follow the next 5-step process to use the library API in order to interface the sensor with the EagleSoC board.

  1. Declare the Objects
  2. Create the Hardware Interface Objects and connect them with PSoC Creator Components
  3. Create the Sensor Objects and connect them with Hardware Interface Objects.
  4. Create Application Interface Objects. Retrieve interface information from Sensor Objects.
  5. Create Application Objects. Provide sensor interface to Application Objects.

Here, I want to use one example project to show you the all steps of using EZ-PSoC LIB in your project.

Project Purpose Using IMU to detect the orientation of the Robot
Sensor SparkFun 9 Degrees of Freedom - MPU-9150 (3-axis Accelerometer, Gyroscope, and Magnetometer)
Communication Protocol I2C
Application Algorithm DCM Algorithm (Direction Cosine Matrix IMU)

 

Example: MPU-9150 9-DOF Sensor

The sensor in the project is SparkFun 9DOF MPU-9150. It is a 9-axis Motion Tracking MEMS device, which contains a 3-axis gyroscope, a 3-asix accelerometer, and a 3-asix magnetometer in a signal chip. The MPU-9150 uses I2C protocol to communicate with microcontroller, the maximum I2C frequency is 400KHz, and the I2C address can be set by AD0 pin. You can click [Datasheet] and [RegisterMap] to get more detailed information about the MPU-9150.

MPU 9150s
Figure 3: MPU-9150 Board

Connect the MPU-9150 signals (VCC, GND, SDA, SCL) with EagleSoC board on Port 2, and change the VDDIO2 voltage setting to 3.3V. The default connection of AD0 pin on the board is GND. After we connect the sensor with the EagleSoC Board, then we can move on to the software design.

First, create an new project in the PSoC Creator. Select PSoC 5LP Design, and make sure Device selection is correct. (For EagleSoC Board, it is CY8C5868AXI-LP035. For EagleSoC Mini, it will be CY8C5868LTI-LP039). Then drag one I2C Master component to your TopDesign.cysch as the Figure 4 shown.

 

TopDesign01  TopDesign02
Figure 4: The I2C Master component and configuration in the TopDesign.cysch

The objects used in this project include one I2C component, MPU-9150 sensor, and IMU application. So, we need to include all of the header files that the objects use in the project into the main.c file.

// Header files for EZ-PSoC LIB
#include "ezCOMM.h"
#include "ezI2C.h"
#include "MPU9150.h"
#include "IMU_DCM_Algorithm.h"

Then, we just follow the 5-steps to use EZ-PSoC LIB.

1. Declare the Objects: Declare all objects that are used in your projects, included the Hardware Interface Objects, Sensor Objects, and Application Objects.

// Step 1: Declare all Objects
PEZOBJ_I2C           i2c;       // Hardware Interface Object
PEZOBJ_MPU9150       mpu;       // Sensor Object
PEZOBJ_INTERFACE     intfGyro;  // Application Interface Object
PEZOBJ_INTERFACE     intfAcc;   // Application Interface Object
PEZOBJ_INTERFACE     intfMag;   // Application Interface Object
PEZOBJ_IMUDCM        imu;       // Application Object

 2. Create the Hardware Interface Objects and connect them with PSoC Creator components
Second step requires us to create all hardware interface objects in our project and connect them with the PSoC Creator components. Here we create our hardware interface object called "i2c" (lowercase) and connect it with a PSoC Creator component, named "I2C_1" by default. Then we initialize and start the object.

// Step 2: Create the Hardware Interface Objects and connect them with PSoC Creator components
int main()
{
    i2c = ezI2C_Create();    // Creating new Hardware Interface i2c object
    CONNECT_I2C(i2c, I2C_1); // Connecting Hardware Interface object i2c with the PSoC Creator I2C component
    ezI2C_Start(i2c);        // Starting i2c interface object

 3. Create Sensor Objects and connect them with Hardware Interface Objects
Third step requires us to create sensor objects and connect them with HW interface objects. Here we create our sensor object called "mpu" and connect it with our HW interface object "i2c". We also initialize and start our MPU object.

// Step 3: Create Sensor objects and connect them with Hardware Interface objects
    mpu = MPU9150_Create();         // Creating new Sensor object
    MPU9150_ConnectI2C(mpu, i2c);   // Connecting Sensor object mpu with the Hardware Interface object i2c
    MPU9150_Start(mpu);             // Starting mpu sensor object

 4. Create Application Interface objects, and retrieve interface information from Sensor objects
If your design uses Application object, then Step # 4 requires us to create application interface objects, which will retrieve interface information from the Sensor Objects.

Here, we create Application Interface objects for Gyroscope, Magnetometer, and Accelerometer. Then we retrieve interface information for each one of them from our Sensor object mpu.

// Step 4: Create Application interface objects
    intfGyro = INTERFACE_Create();      // Create Application Interface for Gyroscope
    intfAcc  = INTERFACE_Create();      // Create Application Interface for Accelerometer
    intfMag  = INTERFACE_Create();      // Create Application Interface for Magnetometer 
// Retrieve interface information from Sensor objects
    MPU9150_GetGyroIF(mpu, intfGyro);   // Retrieve information from mpu Sensor to Gyroscope Application Interface
    MPU9150_GetAccIF (mpu, intfAcc);    // Retrieve information from mpu Sensor to Accelerometer Application Interface
    MPU9150_GetMagIF (mpu, intfMag);    // Retrieve information from mpu Sensor to Magnetometer Application Interface

 5. Create Application objects. Provide Sensor Interface to Application objects
Finally, step 5 requires us to create Application objects. Then we will plug-in the Application Interface objects from step 4 into the Application objects. Now we can retrieve information from the sensor via the Application object as all the necessary connections have been established between the layers.

Here, we create Application object IMU and store the information from each of the application interface object. Finally, we initialize and start the application object.

// Step 5: Create Application objects.
    imu = IMUDCM_Create();
// Provide Sensor interface to Application objects
    IMUDCM_PlugGyroIF(imu, intfGyro);  // Provide Gyroscope information to imu Application object
    IMUDCM_PlugAccIF (imu, intfAcc);   // Provide Accelerometer information to imu Application object
    IMUDCM_PlugMagIF (imu, intfMag);   // Provide Magnetometer information to imu Application object
    IMUDCM_Start(imu);                 // Start imu Application object

 Now we are ready to read data from our application object by polling the Euler Angles from each of the onboard sensors.

// Done
    while(1) {
        ...
        if ( !IMUDCM_MeasureCurrentPositions(imu)) {
            ....
	    // Read data from the Application Object
            roll  = imu->roll;
            pitch = imu->pitch;
            yaw   = imu->yaw;
            ....
        }
        ....
    }

Conclusion

To summarize these 5 steps of interface configuration we compare it with a traditional non-library code in terms of code length for the user.

In the Figure 5, on the right hand side you see the functions that the library user will have to call to get his IMU chip working versus all the code user has to account for on the left side and beyond, since it is impossible to fit all the code on one slide.

SummarizeEZPSoCs
Figure 5: Compared with the Traditional Code

The library will already preconfigure required configurations and the user will not need to spend lots of time going through a datasheet in order to test out sensor functions. It would be almost as plug-n-play opportunity with minimal functional calls, which can take a PSoC Creator to another level.