0

Hello Stack Exchangers!

I am currently working on a project which requires me to use PSOC4 - 049's to scan a series of inputs, and feed this data back to an arduino over I2C.

The arduino, or in this case a teensy 3.5, is the main unit which hosts a UI and retains key system variables. I wish to have the teensy send a few unsigned bytes to the arduino, and when user input is detected have the PSOC act as the master and send relevant information back to the arduino.

Unfortunately I've been trying for about a week now to no avail.

Currently I have 2 Teensy 3.5s sitting on my I2C bus and 1 PSOC4. I send the first teensy a 'H' or 'L' character from a terminal over USB and it turns an LED high or low respectively,

This teensy then relays this character over the I2C Bus to the other teensy at address 0x10, which also toggles an LED.

The idea is that the first teensy then also forwards a value to the PSOC at address 0x11 but this simply isn't working for me!

I can't seem to get a single byte over to the PSOC let alone set up the full MMMS system I need!

Does anyone see what I'm doing wrong or have a good simple example of a PSOC project using Multi Master Multi Slave?

=-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-= ARDUINO MASTER CODE (Might be doing something wrong) =-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-= (Note that this function is part of a much larger project and is just being called from main at this time, much of the project is removed here but should not effect this code in any way)

#include <Wire.h>
void setup()
{
     Wire.begin();
     Serial.begin(9600);
}

void loop()
{checkCommand();}


byte I2CTargetAddr[8] = {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17}; //       Declares the addresses of the PSOCs

void checkCommand() // Reads Serial Commands H or L, sets an LED, then     relays the instruction (hopefully) to the PSOC to do the same thing. 
{
  static int CCFR = 1;

  if (CCFR == 1)
  {
    pinMode(36, OUTPUT);  // Debug LED 
    digitalWrite(36,HIGH);
    CCFR = 0;
  }

  char c;
  static char previousC = 'L';

  static byte low = 0;
  static byte high = 255;

  Wire.setClock(100000); // Set to 100kHz

  while(Serial.available())
  {
    c = Serial.read();

    if(c == 'H')
    {
      Wire.beginTransmission(I2CTargetAddr[0]);
      Wire.write('H');
      Wire.endTransmission();
      digitalWrite(36, HIGH);
    }

    else if(c == 'L')
    {
      Wire.beginTransmission(I2CTargetAddr[0]);
      Wire.write('L');
      Wire.endTransmission();
      digitalWrite(36, LOW);      
    }
  }



if(c == 'H')
{
  Wire.beginTransmission(I2CTargetAddr[1]);
  Wire.write(high);
  Wire.endTransmission();
  //digitalWrite(high, HIGH);
}

else if(c == 'L')
{
  Wire.beginTransmission(I2CTargetAddr[1]);
  Wire.write(low);
  Wire.endTransmission();
  //digitalWrite(low, LOW);      
}


  previousC = c;
}

=-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=--=-= ARDUINO TEST SLAVE CODE (Seems to be totally fine) =-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=--=-=

#include <Wire.h>
#define LED_1 23  // PWM Capable LED Pin

void setup() 
{
  Wire.begin(0x10); 
  Wire.onReceive(receiveEvent); // Calls the receiveEvent function when     something happens to the I2C bus
  pinMode(LED_1,OUTPUT);
  digitalWrite(LED_1, HIGH);
}

void loop() 
{
}

void receiveEvent(int howMany)
{
  while(Wire.available())
  {
    char c = Wire.read();

    if (c == 'H'){digitalWrite(LED_1, HIGH);}
    if (c == 'L'){digitalWrite(LED_1, LOW) ;}
  }
}

=-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-= PSOC 4 Code =-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-=-=-=-==-=--==-=-=-=-=-=-=

The topdesign includes a bootloadable component, a pin for LED Extern and LED Local, and an i2c block set as multi slave/ multi master at 100kb/s

-------------------------------MAIN.C---------------------------------

#include <project.h>
#include <main.h>

extern uint8 I2CSlaveIn[BUFFER_SIZE];
extern uint8 I2CSlaveOut[BUFFER_SIZE];
extern uint8 I2CMasterIn[BUFFER_SIZE];
extern uint8 I2CMasterOut[BUFFER_SIZE];


/* Fast BootLoad ISR */
CY_ISR_PROTO(bootloadISR_Handler);

CY_ISR(bootloadISR_Handler)
{
    Bootloadable_1_Load();   // Forces a restart of the bootloader,     triggered by the onboard button. 
}


int main(void)
{
    BootLoadSys_Start(); // Initialise easy bootloader tool
    bootloadISR_ClearPending();
    bootloadISR_StartEx(bootloadISR_Handler);

    initI2C(); // Initialised i2c

    CyGlobalIntEnable; /* Enable global interrupts. */


    uint8 transferredIn[BUFFER_SIZE]; 
    uint8 byteCount;
    uint8 lastVal = 0;

    LED_Local_Write(0);
    int i;

    for(;;)
    {   
        if (0u != (MYI2C_I2CSlaveStatus() & MYI2C_I2C_SSTAT_WR_CMPLT)) //     Wait for master to complete Write
        {
            byteCount = MYI2C_I2CSlaveGetWriteBufSize();
            MYI2C_I2CSlaveClearWriteStatus();             // Take a wild guess    

            for (i =0; i<byteCount; i++)
            {transferredIn[i] = I2CSlaveIn[i];} // Copy data from the buffer          

            MYI2C_I2CSlaveClearWriteBuf();           
        }


        if (transferredIn[0] != lastVal)
        {
            if (transferredIn[0] == 255u){LED_Local_Write(1);}
            if (transferredIn[0] == 0u  ){LED_Local_Write(0);}
        }

        lastVal = transferredIn[0];       




    }
}

----------------------------------I2C.C------------------------------------

#include "project.h"
#include "i2c.h"
#include "main.h"

uint8 I2CSlaveIn[BUFFER_SIZE];
uint8 I2CSlaveOut[BUFFER_SIZE];
uint8 I2CMasterIn[BUFFER_SIZE];
uint8 I2CMasterOut[BUFFER_SIZE];

void initI2C()
{    
    MYI2C_I2CSlaveSetAddress(MY_SLAVE_ADDR);

    MYI2C_I2CSlaveInitReadBuf( (uint8 *)I2CSlaveOut  , BUFFER_SIZE);
    MYI2C_I2CSlaveInitWriteBuf((uint8 *)I2CSlaveIn  , BUFFER_SIZE);



    MYI2C_Start();  // Calle after buffer setup 
}

----------------------------------I2C.h----------------------------------

#define BUFFER_SIZE 1u // Sets Buffers size
#define MY_SLAVE_ADDR 0x11u


void initI2C(); 
4
  • You need to get your slaves communicating properly first. I would strongly suggest dropping multi-master and have the PSoC use a GPIO line to signal the Teensy master to read it, instead of swapping masters. Much simpler implementation. Commented Jan 22, 2018 at 17:17
  • This won't work due to the needs of the system architecture. Arduino -> PSOC commands will be only issued very occasionally, whereas the the PSOC(s , there are 8 of them) Will be sending information whenever the user interacts with the hardware. It's important that I minimise the amount of time spent communicating
    – GigaJoules
    Commented Jan 22, 2018 at 17:23
  • Design-wise you should consider keeping the drivers separate from the rest of the application. Your current design is so-called "spaghetti", where all files are died together with global variables. This will quickly become unmanageable as the program size grows.
    – Lundin
    Commented Jan 23, 2018 at 14:30
  • @lundin Yeah, it's just a test programme so I'm not too worried about that at the moment, just want to get it working. Also, I love having a dangerous amount of globals, puts a little bit of excitement in my life ;)
    – GigaJoules
    Commented Jan 23, 2018 at 14:42

1 Answer 1

1

So it turns out I'm an idiot. At some point in the last day or so I must have accidentally changed the pins that the I2C component is assigned to.

This code (or at least code very similar to this, after a couple of minor changes) works perfectly for the slave side.

Feel free to make use of it if you need it!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.