Skip to content

Instantly share code, notes, and snippets.

@prnthp
Last active June 10, 2020 03:06
Show Gist options
  • Save prnthp/fe6326fdcdae32f63423685c8a4d9438 to your computer and use it in GitHub Desktop.
Save prnthp/fe6326fdcdae32f63423685c8a4d9438 to your computer and use it in GitHub Desktop.
Minimum example for setting up I2C Slave using EZI2C on ModusToolbox

How to setup EZI2C Slave with Cypress ModusToolbox for PSOC6

Finally we can develop PSOC on *nix and macOS! But Cypress' documentation sucks. With PSOC Creator, you could just drag some components around and the codegen worked perfectly - then only a few lines of code were required to get EZI2C working. Now it's this crap.

You actually don't have to do all of that!

This guide assumes you have a bit of knowledge of both PSOC Creator and ModusToolbox, and I2C.

Device Configurator: Peripherals Plane

Device Configurator Window EZI2C is one of the components of the Serial Communication Block (SCB). Each SCB has its own set of SDA/SCL pins. Here, we're using the P6.4 and P6.5 pins for the CY8CPROTO-63-BLE that is already connected to the KitProg's I2C bus, so we need SCB 6. How do we know which one to use? I don't know either.

You only need to set the Clock, SCL and SDA items here. Set the data rate and address according to your needs. You can leave everything else alone (in the other panes) and hit ⌘ + S.

Hit build once to get the "Generated Source" for your project.

Example Code

Here's the minimal amount of code to implement the EZI2C component for SCB6. Please read the inline comments.

#include "cy_pdl.h"
#include "cyhal.h"
#include "cybsp.h"
#include "cycfg.h" // ADD THIS

#define I2CBUFFERSIZE 10 // Obviously up to you

cy_stc_scb_ezi2c_context_t ezI2cContext; // ADD THIS

// Define this interrupt function
void EZI2C_Isr(void)
{
    Cy_SCB_EZI2C_Interrupt(SCB6, &ezI2cContext);
}

int main(void)
{
    uint8 i2c_buffer[I2CBUFFERSIZE] = {0}; // Initialize the buffer
  
    // Boilerplate from Cypress
    cy_rslt_t result;

    /* Initialize the device and board peripherals */
    result = cybsp_init() ;
    if (result != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }
    // End boilerplate
  
    init_cycfg_all(); // Add this
    
    Cy_SCB_EZI2C_Init(SCB6, &scb_6_config, &ezI2cContext); // Set SCB6 to your SCB number
    Cy_SCB_EZI2C_SetBuffer1(SCB6, i2c_buffer, I2CBUFFERSIZE, 0, &ezI2cContext); // Third parameter is the read/write boundary (see documentation)
    const cy_stc_sysint_t ezI2cIntrConfig =
    {
        .intrSrc      = scb_6_interrupt_IRQn,
        .intrPriority = (7u)
    };
  
    (void) Cy_SysInt_Init(&ezI2cIntrConfig, EZI2C_Isr);
    NVIC_EnableIRQ(scb_6_interrupt_IRQn);

    Cy_SCB_EZI2C_Enable(SCB6);
  
    __enable_irq();

    uint8 counter = 0;
    for (;;)
    {
        NVIC_DisableIRQ(scb_6_interrupt_IRQn);
        // Update your buffer!
        for (int i = 0; i < I2CBUFFERSIZE; i++)
        {
            i2c_buffer[i] = counter;
            counter++;
            if (counter >= 255)
            {
                counter = 0; // Rollover
            }
        }
        NVIC_EnableIRQ(scb_6_interrupt_IRQn);
    }
}

That's it! Enjoy!

@prnthp
Copy link
Author

prnthp commented Jun 10, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment