Firmware bypass using 2 i2c ports

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: barthess, RoccoMarco

jslee
Posts: 9
Joined: Thu Jun 11, 2020 9:54 am
Has thanked: 1 time

Firmware bypass using 2 i2c ports

Postby jslee » Fri Sep 10, 2021 3:39 am

Hello.
I'm working on FW byapss process implementation.
Below is my environment.
- Board : STM32F4 DISCOVERY
- OS : ChibiOS
- process block
[Test board] ←communication: I2CD1 port→ [stm32f4 disc] ←communication: I2CD2 port→ [sensor module]

In my case, how to set 2 I2C Ports?
I can't feel it yet. help please.

User avatar
Giovanni
Site Admin
Posts: 13807
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 934 times
Been thanked: 796 times
Contact:

Re: Firmware bypass using 2 i2c ports

Postby Giovanni » Fri Sep 10, 2021 8:14 am

Hi,

I am not sure to understand your use case. Note that there is no official slave I2C support in ChibiOS, there could be modified drivers in the community directory.

Giovanni

jslee
Posts: 9
Joined: Thu Jun 11, 2020 9:54 am
Has thanked: 1 time

Re: Firmware bypass using 2 i2c ports

Postby jslee » Mon Sep 13, 2021 5:47 am

It means chibiOS's I2C master, slave setting.

System configuration :
[Main Chip] ←(1)→ [STM32F4/Chibios/I2CD1]
(1) Main Chip : I2CD1 Master mode
STM32F4 : I2CD1 Slave mode
[STM32F4/Chibios/I2CD2] ←(2)→ [sensor]
(2) STM32F4: I2CD2 Master mode
sensor : I2CD2 Slave mode

Main chip transmits register address(including set value).
STM32F4 receives the address and transmits it to sensor.
STM32F4 receives(=read) sensor value from sensor's specific address and transmit the value to Main Chip.
Finally, Main chip receives(read) the value and use it.
I said 'Firmware bypass using 2 i2c ports' about above.

'(2)' is not difficulty.
'i2cMasterTransmitTimeout', 'i2cMasterReceiveTimeout' functions are implemented, already.
'(1)' is main problem to me.
In this case, how can I implement I2C Slave mode on ChibiOS?

User avatar
Giovanni
Site Admin
Posts: 13807
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 934 times
Been thanked: 796 times
Contact:

Re: Firmware bypass using 2 i2c ports

Postby Giovanni » Mon Sep 13, 2021 5:57 am

As I explained, there is no I2C slave support in ChibiOS. You need to implement that at register level or to import code from ST low level libraries.

Giovanni

jslee
Posts: 9
Joined: Thu Jun 11, 2020 9:54 am
Has thanked: 1 time

Re: Firmware bypass using 2 i2c ports

Postby jslee » Mon Sep 13, 2021 6:21 am

Aright, I will try.
Thank you Giovanni.

User avatar
FXCoder
Posts: 369
Joined: Sun Jun 12, 2016 4:10 am
Location: Sydney, Australia
Has thanked: 170 times
Been thanked: 125 times

Re: Firmware bypass using 2 i2c ports

Postby FXCoder » Mon Sep 13, 2021 8:08 am

Hi,
This might give you a head start on your own implementation..
viewtopic.php?t=3544

--
Bob

jslee
Posts: 9
Joined: Thu Jun 11, 2020 9:54 am
Has thanked: 1 time

Re: Firmware bypass using 2 i2c ports

Postby jslee » Tue Oct 12, 2021 11:01 am

FXCoder wrote:Hi,
This might give you a head start on your own implementation..
viewtopic.php?t=3544


Thank you, Bob.
I'm trying that. But, It's still not easy.
I will keep doing

steved
Posts: 776
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 10 times
Been thanked: 123 times

Re: Firmware bypass using 2 i2c ports

Postby steved » Tue Oct 12, 2021 5:33 pm

There's an alternative I2C slave, originally written by genosensor, and modified by me for the later I2C ports, if you search

jslee
Posts: 9
Joined: Thu Jun 11, 2020 9:54 am
Has thanked: 1 time

Re: Firmware bypass using 2 i2c ports

Postby jslee » Wed Oct 20, 2021 10:37 am

steved wrote:There's an alternative I2C slave, originally written by genosensor, and modified by me for the later I2C ports, if you search


I tried I2C master, slave test from link: viewtopic.php?t=3544

I used 2 boards
- Board-1(I2C Master)
- Board-2(I2C Slave)

Print receive data on Board-2(I2C Slave)
Push user switch in Board-1(I2C master) -> I2C master transmit one time

Board2 stop when I push user switch 5 times on Board-1(I2C master).
I couldn't find reason that Board-2(I2C Slave) stop.

could you check my code?

I2C master code :
Off Topic
#include "ch.h"
#include "hal.h"
#include "chprintf.h"

static const SerialConfig serialCfgMst = {
115200,
0,
USART_CR2_STOP1_BITS,
0
};
BaseSequentialStream* chp_mst = (BaseSequentialStream*)&SD2;

static const I2CConfig i2ccfg_mst = {
OPMODE_I2C,
100000,
STD_DUTY_CYCLE,
};
static i2cflags_t errors = 0;

static uint8_t txbuf[2] = {0x00, 0x00};

/*
* This is a periodic thread that does absolutely nothing except flashing
* a LED.
*/
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {

(void)arg;
chRegSetThreadName("blinker");
while (true) {
palSetPad(GPIOD, GPIOD_LED6); // Blue
chThdSleepMilliseconds(500);
palClearPad(GPIOD, GPIOD_LED6); // Blue
chThdSleepMilliseconds(500);
}
}

#define I2C_SLAVE_ADDR 0x18
#define I2C_TEST_VAL_1 0x23
#define I2C_TEST_VAL_2 0x45

/*
* Application entry point.
*/
int main(void) {

halInit();
chSysInit();

palSetPadMode(GPIOA, 2, PAL_MODE_ALTERNATE(7)| PAL_STM32_OSPEED_HIGHEST | PAL_STM32_OTYPE_PUSHPULL);
palSetPadMode(GPIOA, 3, PAL_MODE_ALTERNATE(7)| PAL_STM32_OSPEED_HIGHEST | PAL_STM32_OTYPE_PUSHPULL);
sdStart(&SD2, &serialCfgMst);
chprintf(chp_mst, "Master Driver Start : Serial\n");

//i2c pin set
palSetPadMode(GPIOB, GPIOB_PIN8, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUPDR_PULLUP);
palSetPadMode(GPIOB, GPIOB_SDA, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUPDR_PULLUP);
i2cStart(&I2CD1, &i2ccfg_mst);
chprintf(chp_mst, "Master Driver Start : I2C\n");

// master
msg_t status = MSG_OK;
txbuf[0] = I2C_TEST_VAL_1;

/*
* Creates the example thread.
*/
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
chprintf(chp_mst, "LED Thread start\n");

chprintf(chp_mst, "Master I2C transmit repeat start\n");
while (true) {
if (palReadPad(GPIOA, GPIOA_BUTTON))
{
i2cAcquireBus(&I2CD1);
status = i2cMasterTransmitTimeout(&I2CD1, 0x18, txbuf, 1, NULL, 0, TIME_INFINITE);
i2cReleaseBus(&I2CD1);
if (status != MSG_OK)
{
errors = i2cGetErrors(&I2CD1);
chprintf(chp_mst, "Master MSG is not OK(%d)\n", status);
}
else
{
chprintf(chp_mst, "Master MSG is OK(%d)\n", status);
}
}

chThdSleepMilliseconds(100);
}

i2cStop(&I2CD1);
}


I2C slave code :
Off Topic
#include "ch.h"
#include "hal.h"
#include "chprintf.h"

static const SerialConfig serialCfgSlv = {
115200,
0,
USART_CR2_STOP1_BITS,
0
};
BaseSequentialStream* chp_slv = (BaseSequentialStream*)&SD2;

static const I2CConfig i2ccfg = {
OPMODE_I2C,
100000,
STD_DUTY_CYCLE,
};

uint8_t txBuff[4] = {0x00, 0x00, 0x00, 0x00};
uint8_t rxBuff[4] = {0x00, 0x00, 0x00, 0x00};

void onI2CSlaveReceive(I2CDriver *i2cp, const uint8_t *rxbuf, size_t rxbytes)
{
(void)i2cp;
(void)rxbuf;
(void)rxbytes;

}

void onI2CSlaveRequest(I2CDriver *i2cp)
{

i2cSlaveStartTransmission(i2cp, txBuff, 2);

i2cSlaveOnReceive(&I2CD2, onI2CSlaveReceive, rxBuff, 2);

txBuff[0]++;
txBuff[1]++;
}

/*
* Receiver thread.
*/
static THD_WORKING_AREA(thread1_wa, 256);
static THD_FUNCTION(thread1, arg) {
(void)arg;
chRegSetThreadName("Print");
chprintf(chp_slv, "Start...\n\r");
while(true) {

chThdSleepMilliseconds(10);
chprintf(chp_slv, "slave Receive %x, %x \n\r", rxBuff[0], rxBuff[1]);
}
}

/*
* This is a periodic thread that does absolutely nothing except flashing
* a LED.
*/
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {

(void)arg;
chRegSetThreadName("blinker");
while (true) {
palSetPad(GPIOD, GPIOD_LED4); // Green
chThdSleepMilliseconds(500);
palClearPad(GPIOD, GPIOD_LED4); // Green
chThdSleepMilliseconds(500);
}
}

/*
* Application entry point.
*/
int main(void) {

halInit();
chSysInit();

sdStart(&SD2, &serialCfgSlv);
palSetPadMode(GPIOA, 2, PAL_MODE_ALTERNATE(7)| PAL_STM32_OSPEED_HIGHEST | PAL_STM32_OTYPE_PUSHPULL);
palSetPadMode(GPIOA, 3, PAL_MODE_ALTERNATE(7)| PAL_STM32_OSPEED_HIGHEST | PAL_STM32_OTYPE_PUSHPULL);
chprintf(chp_slv, "Slave Driver Start : Serial\n");

//i2c pin set
palSetPadMode(GPIOB, 10U, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUPDR_PULLUP);
palSetPadMode(GPIOB, 11, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUPDR_PULLUP);
i2cStart(&I2CD2, &i2ccfg);
chprintf(chp_slv, "Slave Driver Start : I2C");

i2cSlaveOnRequest(&I2CD2, onI2CSlaveRequest);
i2cSlaveOnReceive(&I2CD2, onI2CSlaveReceive, rxBuff, 2);
i2cSlaveMatchAddress(&I2CD2, 0x18);

/*
* Creates the example thread.
*/
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
chprintf(chp_mst, "Thread start : LED\n");
chThdCreateStatic(thread1_wa, sizeof(thread1_wa), NORMALPRIO, thread1, NULL);
chprintf(chp_mst, "Thread start : I2C Receive\n");

while (true) {
if (palReadPad(GPIOA, GPIOA_BUTTON))
{

}
chThdSleepMilliseconds(50);
}
}

jslee
Posts: 9
Joined: Thu Jun 11, 2020 9:54 am
Has thanked: 1 time

Re: Firmware bypass using 2 i2c ports

Postby jslee » Fri Oct 22, 2021 3:54 am

steved wrote:There's an alternative I2C slave, originally written by genosensor, and modified by me for the later I2C ports, if you search


I tried I2C master, slave test from link: viewtopic.php?t=3544

I used 2 boards
- Board-1(I2C Master)
- Board-2(I2C Slave)

Print receive data on Board-2(I2C Slave)
Push user switch in Board-1(I2C master) -> I2C master transmit one time

Board2 stop when I push user switch 5 times on Board-1(I2C master).
I couldn't find reason that Board-2(I2C Slave) stop.

could you check my code?

I2C master code :

Code: Select all

#include "ch.h"
#include "hal.h"
#include "chprintf.h"

static const SerialConfig serialCfgMst = {
  115200,
  0,
  USART_CR2_STOP1_BITS,
  0
};
BaseSequentialStream* chp_mst = (BaseSequentialStream*)&SD2;

static const I2CConfig i2ccfg_mst = {
  OPMODE_I2C,
  100000,
  STD_DUTY_CYCLE,
};
static i2cflags_t errors = 0;

static uint8_t txbuf[2] = {0x00, 0x00};

/*
* This is a periodic thread that does absolutely nothing except flashing
* a LED.
*/
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {

  (void)arg;
  chRegSetThreadName("blinker");
  while (true) {
    palSetPad(GPIOD, GPIOD_LED6); // Blue
    chThdSleepMilliseconds(500);
    palClearPad(GPIOD, GPIOD_LED6); // Blue
    chThdSleepMilliseconds(500);
  }
}

#define I2C_SLAVE_ADDR 0x18
#define I2C_TEST_VAL_1 0x23
#define I2C_TEST_VAL_2 0x45

/*
* Application entry point.
*/
int main(void) {

  halInit();
  chSysInit();

  palSetPadMode(GPIOA, 2, PAL_MODE_ALTERNATE(7)| PAL_STM32_OSPEED_HIGHEST | PAL_STM32_OTYPE_PUSHPULL);
  palSetPadMode(GPIOA, 3, PAL_MODE_ALTERNATE(7)| PAL_STM32_OSPEED_HIGHEST | PAL_STM32_OTYPE_PUSHPULL);
  sdStart(&SD2, &serialCfgMst);
  chprintf(chp_mst, "Master Driver Start : Serial\n");

  //i2c pin set
  palSetPadMode(GPIOB, GPIOB_PIN8, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUPDR_PULLUP);
  palSetPadMode(GPIOB, GPIOB_SDA, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUPDR_PULLUP);
  i2cStart(&I2CD1, &i2ccfg_mst);
  chprintf(chp_mst, "Master Driver Start : I2C\n");

  // master
  msg_t status = MSG_OK;
  txbuf[0] = I2C_TEST_VAL_1;

  /*
  * Creates the example thread.
  */
  chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
  chprintf(chp_mst, "LED Thread start\n");

  chprintf(chp_mst, "Master I2C transmit repeat start\n");
  while (true) {
    if (palReadPad(GPIOA, GPIOA_BUTTON))
    {
      i2cAcquireBus(&I2CD1);
      status = i2cMasterTransmitTimeout(&I2CD1, 0x18, txbuf, 1, NULL, 0, TIME_INFINITE);
      i2cReleaseBus(&I2CD1);
      if (status != MSG_OK)
      {
        errors = i2cGetErrors(&I2CD1);
        chprintf(chp_mst, "Master MSG is not OK(%d)\n", status);
      }
      else
      {
        chprintf(chp_mst, "Master MSG is OK(%d)\n", status);
      }
    }

    chThdSleepMilliseconds(100);
  }

  i2cStop(&I2CD1);
}


I2C slave code :

Code: Select all

#include "ch.h"
#include "hal.h"
#include "chprintf.h"

static const SerialConfig serialCfgSlv = {
  115200,
  0,
  USART_CR2_STOP1_BITS,
  0
};
BaseSequentialStream* chp_slv = (BaseSequentialStream*)&SD2;

static const I2CConfig i2ccfg = {
  OPMODE_I2C,
  100000,
  STD_DUTY_CYCLE,
};

uint8_t txBuff[4] = {0x00, 0x00, 0x00, 0x00};
uint8_t rxBuff[4] = {0x00, 0x00, 0x00, 0x00};

void onI2CSlaveReceive(I2CDriver *i2cp, const uint8_t *rxbuf, size_t rxbytes)
{
  (void)i2cp;
  (void)rxbuf;
  (void)rxbytes;

}

void onI2CSlaveRequest(I2CDriver *i2cp)
{

  i2cSlaveStartTransmission(i2cp, txBuff, 2);

  i2cSlaveOnReceive(&I2CD2, onI2CSlaveReceive, rxBuff, 2);

  txBuff[0]++;
  txBuff[1]++;
}

/*
* Receiver thread.
*/
static THD_WORKING_AREA(thread1_wa, 256);
static THD_FUNCTION(thread1, arg) {
  (void)arg;
  chRegSetThreadName("Print");
  chprintf(chp_slv, "Start...\n\r");
  while(true) {

    chThdSleepMilliseconds(10);
    chprintf(chp_slv, "slave Receive %x, %x \n\r", rxBuff[0], rxBuff[1]);
  }
}

/*
* This is a periodic thread that does absolutely nothing except flashing
* a LED.
*/
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {

  (void)arg;
  chRegSetThreadName("blinker");
  while (true) {
    palSetPad(GPIOD, GPIOD_LED4); // Green
    chThdSleepMilliseconds(500);
    palClearPad(GPIOD, GPIOD_LED4); // Green
    chThdSleepMilliseconds(500);
  }
}

/*
* Application entry point.
*/
int main(void) {

  halInit();
  chSysInit();

  sdStart(&SD2, &serialCfgSlv);
  palSetPadMode(GPIOA, 2, PAL_MODE_ALTERNATE(7)| PAL_STM32_OSPEED_HIGHEST | PAL_STM32_OTYPE_PUSHPULL);
  palSetPadMode(GPIOA, 3, PAL_MODE_ALTERNATE(7)| PAL_STM32_OSPEED_HIGHEST | PAL_STM32_OTYPE_PUSHPULL);
  chprintf(chp_slv, "Slave Driver Start : Serial\n");

  //i2c pin set
  palSetPadMode(GPIOB, 10U, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUPDR_PULLUP);
  palSetPadMode(GPIOB, 11, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUPDR_PULLUP);
  i2cStart(&I2CD2, &i2ccfg);
  chprintf(chp_slv, "Slave Driver Start : I2C");

  i2cSlaveOnRequest(&I2CD2, onI2CSlaveRequest);
  i2cSlaveOnReceive(&I2CD2, onI2CSlaveReceive, rxBuff, 2);
  i2cSlaveMatchAddress(&I2CD2, 0x18);

/*
* Creates the example thread.
*/
  chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
  chprintf(chp_slv, "Thread start : LED\n");
  chThdCreateStatic(thread1_wa, sizeof(thread1_wa), NORMALPRIO, thread1, NULL);
  chprintf(chp_slv, "Thread start : I2C Receive\n");

  while (true) {
    if (palReadPad(GPIOA, GPIOA_BUTTON))
    {

    }
  chThdSleepMilliseconds(50);
  }
}


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 6 guests