SI5338 frequency synthesizer I2C timing problem

Post here first, or if you can't find a relevant section!
Post Reply
Nawfal
Posts: 26
Joined: Tue Aug 29, 2017 2:57 pm

SI5338 frequency synthesizer I2C timing problem

Post by Nawfal » Tue Sep 05, 2017 2:36 pm

Hi,
I’m trying to communicate with a frequency synthesizer (Si5338) using a generic STM32F103CBT6 through I2C2. (PB10, PB11 pins).
So far, with no success.
After checking the clock line with an oscilloscope, It appears that the I2C2 is not initialized correctly since the line shows a constant voltage of 3.3V.
I’m wondering if there is some conflict situation with usart3.
The pull-up resistors are also added to both data and clock llines.
I’ve tried the same code with a mini-maple clone and it is not working neither.
Same symptoms using software wire.

Board selected: Generic STM32F103C Series
Variant: STM32F103CB (20k RAM, 128k flash)
CPU Speed :72MHz
Download: ST-LINK

Any help???

Here is the code I’m using:

Code: Select all

#include <Wire.h>
#include "register_map.h"

HardWire HWire(2, I2C_FAST_MODE); // I2c2 instance


#define SLAVE_ADDR 0x71

void I2C_ByteWrite (uint8_t addr, uint8_t dat);
uint8_t I2C_ByteRead (uint8_t addr);

void setup() {

  HWire.begin();
  pinMode(PC15, OUTPUT);

  I2C_ByteWrite(246, 2); //soft reset
  I2C_ByteWrite(241, 0x65); //DIS_LOL = 0

  }
void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(PC15, HIGH);   
  delay(500);              
  digitalWrite(PC15, LOW);    
  delay(500);             
}

void I2C_ByteWrite (uint8_t addr, uint8_t dat) {
  HWire.beginTransmission(SLAVE_ADDR);
  HWire.write(addr);
  HWire.write(dat);
  HWire.endTransmission();
}

uint8_t I2C_ByteRead (uint8_t addr) {
  HWire.beginTransmission(SLAVE_ADDR);
  HWire.write(addr);
  HWire.endTransmission();

  HWire.requestFrom(SLAVE_ADDR, (uint8_t)1);
  uint8_t data = HWire.read();
  HWire.endTransmission();
  return data;
}

edogaldo
Posts: 263
Joined: Fri Jun 03, 2016 8:19 am

Re: STM32F103CBT6 I2C2 problem

Post by edogaldo » Wed Sep 06, 2017 8:31 am

Hi Nawfal, just a suggestion: as I can see you do I2C stuff (write 2 bytes) in the setup and nothing more.
Isn't it you just miss that activity as it's done only once?
Try doing something also in the loop so that you can better check I2C activity.

Best, E.

Nawfal
Posts: 26
Joined: Tue Aug 29, 2017 2:57 pm

Re: STM32F103CBT6 I2C2 problem

Post by Nawfal » Thu Sep 07, 2017 3:46 pm

Hi,

The Si5338 only needs to be set up once...That's why I used the Wryte_Byte() only on the setup part.
I'll check writing some dumb data on the while_loop and let you know

Nawfal
Posts: 26
Joined: Tue Aug 29, 2017 2:57 pm

Re: STM32F103CBT6 I2C2 problem

Post by Nawfal » Thu Sep 07, 2017 5:56 pm

No sign of life on the clock line :x

zmemw16
Posts: 1414
Joined: Wed Jul 08, 2015 2:09 pm
Location: St Annes, Lancs,UK

Re: STM32F103CBT6 I2C2 problem

Post by zmemw16 » Thu Sep 07, 2017 6:37 pm

run the i2cscanner sketch and could you try on both i2c1 and i2c2 without any remapping ?
then again with the remapping.

anything else plugged in on i2c ?
anything else i2c that you could test with by itself ?

stephen

Nawfal
Posts: 26
Joined: Tue Aug 29, 2017 2:57 pm

Re: STM32F103CBT6 I2C2 problem

Post by Nawfal » Thu Sep 07, 2017 8:20 pm

Yes, I'll try it tomorrow with some breakout board (Pressure or 9DOF) and let you know

Nawfal
Posts: 26
Joined: Tue Aug 29, 2017 2:57 pm

Re: STM32F103CBT6 I2C2 problem

Post by Nawfal » Fri Sep 08, 2017 3:51 pm

Hi,

Today, I was able to read/write to the device registers.....but I have no clue why no output (waveform generated) from the chip is appearing.
Has somebody worked on the Si5338C???
Here is the code that I'm using; it is from the application note available at: https://www.silabs.com/documents/public ... /AN428.pdf

Code: Select all

#include <Wire.h>
//#include <HardWire.h>
#include "register_map.h"


TwoWire HWire(PB10, PB11, SOFT_STANDARD);//SOFT_FAST
//HardWire HWire(2, I2C_FAST_MODE); // I2c2
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
// Device address (7 bools) for slave target
// 0x70 is default for the Si5338
#define SLAVE_ADDR 0x71


#define LOCK_MASK 0x15
#define LOS_MASK 0x04
//-----------------------------------------------------------------------------
// Global VARIABLES
//-----------------------------------------------------------------------------
uint8_t test = 1;


//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void I2C_ByteWrite (uint8_t addr, uint8_t dat);
uint8_t I2C_ByteRead (uint8_t addr);

void setup() {
  
  HWire.begin();
  pinMode(PC15, OUTPUT);
  Serial2.begin(9600);
  
  uint8_t curr_chip_val, clear_curr_val, clear_new_val, combined, reg;
  Reg_Data curr;
  uint8_t i; // Temporary counter variable used in for loops


  //EA = 1; // Global interrupt enable****MUST BE LAST****
  //----------------------------------------------------------------
  // See Si5338 datasheet Figure 9 for more details on this procedure
  // delay added to wait for Si5338 to be ready to communicate
  // after turning on
  //counter = 0;
  delay(12);
  I2C_ByteWrite(230, 0x10); //OEB_ALL = 1
  
  test = I2C_ByteRead(230);
  Serial2.print(0x10, HEX);
  Serial2.print("  ,  ");
  Serial2.println(test, HEX);
  
  I2C_ByteWrite(241, 0xE5); //DIS_LOL = 1
  
  test = I2C_ByteRead(241);
  Serial2.print(0xE5, HEX);
  Serial2.print("  ,  ");
  Serial2.println(test, HEX);
  
  //for all the register values in the Reg_Store array
  //get each value and mask and apply it to the Si5338
  for (int i = 0; i < NUM_REGS_MAX; i++) {
    curr = Reg_Store[i];
    if (curr.Reg_Mask != 0x00) {
      if (curr.Reg_Mask == 0xFF) {
        // do a write transaction only
        // since the mask is all ones
        I2C_ByteWrite(curr.Reg_Addr, curr.Reg_Val);
        
        Serial2.print(curr.Reg_Val, HEX);
        Serial2.print("  ,  ");
        test = I2C_ByteRead(curr.Reg_Addr);
        Serial2.println(test, HEX);
      } else {
        //do a read-modify-write
        curr_chip_val = I2C_ByteRead(curr.Reg_Addr);
        clear_curr_val = curr_chip_val & ~curr.Reg_Mask;
        clear_new_val = curr.Reg_Val & curr.Reg_Mask;
        combined = clear_new_val | clear_curr_val;
        I2C_ByteWrite(curr.Reg_Addr, combined);
        
        Serial2.print(combined, HEX);
        Serial2.print("  ,  ");
        test = I2C_ByteRead(curr.Reg_Addr);
        Serial2.println(test, HEX);
      }
    }
  }
  // check LOS alarm for the xtal input
  // on IN1 and IN2 (and IN3 if necessary) -
  // change this mask if using inputs on IN4, IN5, IN6
  reg = I2C_ByteRead(218) & LOS_MASK;
  while (reg != 0) {
    reg = I2C_ByteRead(218) & LOS_MASK;
  }
  I2C_ByteWrite(49, I2C_ByteRead(49) & 0x7F); //FCAL_OVRD_EN = 0
  I2C_ByteWrite(246, 2); //soft reset

    // wait for Si5338 to be ready after calibration (ie, soft reset)

  delay(25);
  
  I2C_ByteWrite(241, 0x65); //DIS_LOL = 0

  //make sure the device locked by checking PLL_LOL and SYS_CAL
  reg = I2C_ByteRead(218) & LOCK_MASK;
  while (reg != 0) {
    reg = I2C_ByteRead(218) & LOCK_MASK;

  }
  //copy FCAL values
  I2C_ByteWrite(45, I2C_ByteRead(235));
  I2C_ByteWrite(46, I2C_ByteRead(236));
  // clear bools 0 and 1 from 47 and
  // combine with bools 0 and 1 from 237
  reg = (I2C_ByteRead(47) & 0xFC) | (I2C_ByteRead(237) & 3);
  I2C_ByteWrite(47, reg);
  I2C_ByteWrite(49, I2C_ByteRead(49) | 0x80); // FCAL_OVRD_EN = 1

  
  I2C_ByteWrite(230, 0x00); // OEB_ALL = 0

        Serial2.print(47, HEX);
        Serial2.print("  ,  ");
        test = I2C_ByteRead(47);
        Serial2.println(test, HEX);
}

void loop() {

  // put your main code here, to run repeatedly:
//  digitalWrite(PC15, HIGH);   // turn the LED on (HIGH is the voltage level)
//  delay(500);              // wait for a second
//  digitalWrite(PC15, LOW);    // turn the LED off by making the voltage LOW
//  delay(500);              // wait for a second
}

void I2C_ByteWrite (uint8_t addr, uint8_t dat) {
  HWire.beginTransmission(SLAVE_ADDR);
  HWire.write(addr);
  HWire.write(dat);
  HWire.endTransmission();
}
uint8_t I2C_ByteRead (uint8_t addr) {
  HWire.beginTransmission(SLAVE_ADDR);
  HWire.write(addr);
  HWire.endTransmission();

  HWire.requestFrom(SLAVE_ADDR, 1);
  uint8_t data = HWire.read();
  HWire.endTransmission();
  return data;

}



zmemw16
Posts: 1414
Joined: Wed Jul 08, 2015 2:09 pm
Location: St Annes, Lancs,UK

Re: STM32F103CBT6 I2C2 problem

Post by zmemw16 » Fri Sep 08, 2017 8:19 pm

i thought i read it as scl/sda with no output pulsation ?

now did the other devices function using the i2cscanner sketch ?
if yes that would isolate your sketch as having an issue.
stephen

Nawfal
Posts: 26
Joined: Tue Aug 29, 2017 2:57 pm

Re: STM32F103CBT6 I2C2 problem

Post by Nawfal » Fri Sep 08, 2017 9:59 pm

zmemw16 wrote:
Fri Sep 08, 2017 8:19 pm
i thought i read it as scl/sda with no output pulsation ?

now did the other devices function using the i2cscanner sketch ?
if yes that would isolate your sketch as having an issue.
stephen
Yes, it does detect the device as 0x71 address.....
I've been reading the forum about the SI5338 on community.silabs.com/t5/Timing/bd-p/Timing_Discussion and it seems that people are facing the same issue and complaining about the incompleteness of the information provided on the datasheet

Post Reply