Duet3D Logo Duet3D
    • Tags
    • Documentation
    • Order
    • Register
    • Login

    I2C on expansion board Duet3HC

    Scheduled Pinned Locked Moved
    Firmware developers
    4
    19
    948
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Nikhilundefined
      Nikhil
      last edited by Nikhil

      Hi @dc42 , I want to use I2C on duet 3hc board. So as per datasheet and hardware IO_0 has serialcom , multiplexed I2C. Was trying to make changes in firmware related to I2C. Want to know even if it'll intialize and start will the hardware allow to use those pins? PA16(PAD[0]) = SDA and PA17 (PAD[1]) = SCL. As I can see PA16 has pull up resistor.

      dc42undefined 1 Reply Last reply Reply Quote 0
      • dc42undefined
        dc42 administrators @Nikhil
        last edited by

        @nikhil, the 3.3beta source code includes an I2C driver although currently it is only enabled in some of the builds for SAMC21-based expansion boards. However, the SERCOM peripherals are almost the same on the SAME51-based EXP3HC board, so it may work on that too. Once difference that you will need to take account of is that the SAMC21 uses a single interrupt line per SERCOM, whereas the SAME51 uses three (but we may only need to use two of them).

        Before you assume that IO0 can do I2C, check section 6.2.6 of the datasheet to make sure that the pins used by IO0 are I2C-capable.

        You will need to bypass the 10K series resistor on IO0_IN with a 470 ohm or lower resistor. The easiest way will be to solder the new resistor on top of it.

        Caution, i2C is very sensitive to capacitively-coupled interference. Use it only over very short distances and keep the i2C wres well away from stepper motor wires. If possible, use SPI in preference to i2C. Many devices support both I2C and SPI. The EXP3HC already provides an SPI connector.

        Duet WiFi hardware designer and firmware engineer
        Please do not ask me for Duet support via PM or email, use the forum
        http://www.escher3d.com, https://miscsolutions.wordpress.com

        o_lampeundefined Nikhilundefined 2 Replies Last reply Reply Quote 0
        • o_lampeundefined
          o_lampe @dc42
          last edited by o_lampe

          @dc42 said in I2C on expansion board Duet3HC:

          The EXP3HC already provides an SPI connector.

          Sorry to bomb in here. David, is there a public access to SPI, like 'm260' is provided for I2C?
          I only found predefined sensors or NeoPixel stuff...

          dc42undefined 1 Reply Last reply Reply Quote 0
          • dc42undefined
            dc42 administrators @o_lampe
            last edited by

            @o_lampe said in I2C on expansion board Duet3HC:

            @dc42 said in I2C on expansion board Duet3HC:

            The EXP3HC already provides an SPI connector.

            Sorry to bomb in here. David, is there a public access to SPI, like 'm260' is provided for I2C?
            I only found predefined sensors or NeoPixel stuff...

            You would need to change the firmware to support a new SPI device. However, something similar to M260 would be possible to add to the firmware.

            Duet WiFi hardware designer and firmware engineer
            Please do not ask me for Duet support via PM or email, use the forum
            http://www.escher3d.com, https://miscsolutions.wordpress.com

            1 Reply Last reply Reply Quote 0
            • Nikhilundefined
              Nikhil @dc42
              last edited by

              @dc42 I went through the datasheet again it does have I2C support on pin 16 & 17 on port A and it is in use by IO_0. So, I've already checked with the beta version and trying to use that. Hardware changes will do once after successful intialisation.

              As the sensor I'm using has only I2C support checked for alternative cannot find. So, will have to use the same may be I'll isolate the sensor wires.

              Que. As SAME51 uses 3 interrupt lines so, the 2 of them will be used for transmission and reception that was I thinking. Is it correct. I was going to use direct code by changing sercom number and handler but may be that will not going to work.

              dc42undefined 1 Reply Last reply Reply Quote 0
              • dc42undefined
                dc42 administrators @Nikhil
                last edited by

                @nikhil I suggest you use the code already written, because it is known to work on the SAMC21. You will need to #define SUPPORT_I2C_SENSORS as 1 in file EXP3CH.h. Setting that should enable the code in Platform.cpp that creates an instance of SharedI2CMaster. Then you will need to create an instance of SharedI2CClient attached to that master for your sensor. Look at the CommandProcessing/AccelerometerHandler files to get an idea of how to use SharedI2CClient.

                Duet WiFi hardware designer and firmware engineer
                Please do not ask me for Duet support via PM or email, use the forum
                http://www.escher3d.com, https://miscsolutions.wordpress.com

                Nikhilundefined 1 Reply Last reply Reply Quote 0
                • Nikhilundefined
                  Nikhil @dc42
                  last edited by Nikhil

                  @dc42 Hi, as you suggested I've made changes in firmware code

                  #if SUPPORT_I2C_SENSORS
                  	{ TcOutput::none,	TccOutput::none,	AdcInput::none,		SercomIo::none,		SercomIo::none,		Nx,	nullptr 		},	// PA16 		I2C SDA
                  	{ TcOutput::none,	TccOutput::none,	AdcInput::none,		SercomIo::none,		SercomIo::none,		Nx,	nullptr			},  // PA17 	    I2C SCL
                  #else
                  	{ TcOutput::none,	TccOutput::none,	AdcInput::none,		SercomIo::none,		SercomIo::sercom1c,	Nx,	"io0.out,uart0.tx" },	// PA16
                  	{ TcOutput::none,	TccOutput::none,	AdcInput::none,		SercomIo::sercom1c,	SercomIo::none,		Nx,	"uart0.rx"		},		// PA17
                  #endif
                  
                  constexpr uint8_t I2CSercomNumber = 4;		//defined I2C serial comm number
                  constexpr Pin I2CSDAPin = PortAPin(16);		//use 16 SDA
                  constexpr GpioPinFunction I2CSDAPinPeriphMode = GpioPinFunction::C;
                  constexpr Pin I2CSCLPin = PortAPin(17);		// use 17 SCL
                  constexpr GpioPinFunction I2CSCLPinPeriphMode = GpioPinFunction::C;
                  
                  #define I2C_HANDLER4		SERCOM4_0_Handler    // changed the handler as it was calling dummy handler and going forever loop
                  

                  And also made changes in respect module file just like CommandProcessing/AccelerometerHandler

                  #  ifndef I2C_HANDLER4    // added this statement as !defined() macro was showing error even after changing handler name.
                  #	error "I2C_HANDLER4"
                  #  endif
                  	void I2C_HANDLER4() noexcept
                  	{
                  		Platform::sharedI2C->Interrupt();
                  
                  	}										// we may need to use 2 handlers for I2C
                  # endif
                  

                  created task using

                  monitorTask->Create(MonitorTaskCode, "sensor", nullptr, TaskPriority::Monitor);
                  

                  the sensor task is showing in diagnostics M122 B1 task list but the I2C task it's diagnostics not showing, I've checked all the Init registers with datasheet those are all same as SAMC21, How can I debug the I2C other than diagnostics, tried to send data on mainboard using CAN but no success. I've also tried to check if it's generating clock on SCL line using Oscilloscope no success.

                  dc42undefined 1 Reply Last reply Reply Quote 0
                  • dc42undefined
                    dc42 administrators @Nikhil
                    last edited by dc42

                    @nikhil There is no I2C task, and you don't need one.

                    What code does your monitor task execute?

                    You didn't need to add I2C_HANDLER4. Instead you should #define I2C_HANDLER0, 1, 2 in the config file.

                    Duet WiFi hardware designer and firmware engineer
                    Please do not ask me for Duet support via PM or email, use the forum
                    http://www.escher3d.com, https://miscsolutions.wordpress.com

                    Nikhilundefined 1 Reply Last reply Reply Quote 0
                    • Nikhilundefined
                      Nikhil @dc42
                      last edited by Nikhil

                      @dc42 okay will define these micros.
                      monitor task for now just sending a command and receiving the data

                      for (;;)
                      	{
                      		TaskBase::Take();
                      		if (running)
                      		{
                      
                      			CanMessageBuffer buf(nullptr);
                      			//	CanMessageAccelerometerData& msg = *(buf.SetupStatusMessage<CanMessageAccelerometerData>(CanInterface::GetCanAddress(), CanInterface::GetCurrentMasterAddress()));
                      			CanMonitorDataStart &monitorData = *(buf.SetupStatusMessage<
                      					CanMonitorDataStart>(CanInterface::GetCanAddress(),
                      					CanInterface::GetCurrentMasterAddress()));
                      
                      #if TEST_PACKING
                      			uint16_t pattern = 0;
                      #endif
                      			/*if (accelerometer->StartCollecting(axes))
                      			 {
                      
                      			 }*/
                      			if (monitor->readRangeSingleMillimeters() != 0)
                      			{
                      				data = monitor->readRangeSingleMillimeters();
                      				monitorData.deviceNumber = 1;
                      				if (monitor->timeoutOccurred())
                      				{
                      					debugPrintf("Timeout Error in monitor");
                      
                      				}
                      			}
                      
                      			monitor->stopContinuous();		//stop sensor data*/
                      
                      			// Wait for another command
                      			running = false;
                      		}
                      	}
                      
                      uint8_t readReg(uint8_t reg)
                      {
                        uint8_t value;
                        last_status = 0; 
                      
                        //bus->requestFrom(address, (uint8_t)1);
                       // value = bus->read();
                      
                        return Transfer((uint8_t)reg, &value, 1, 1, VL53L0XI2CTimeout);
                      }
                      
                      uint16_t readRangeSingleMillimeters()
                      {
                        startTimeout();
                        while ((readReg(RESULT_INTERRUPT_STATUS) & 0x07) == 0)
                        {
                          if (checkTimeoutExpired())
                          {
                            did_timeout = true;
                            return 65535;
                          }
                        }
                      
                        // assumptions: Linearity Corrective Gain is 1000 (default);
                        // fractional ranging is not enabled
                        uint16_t range = readReg16Bit(RESULT_RANGE_STATUS + 10);
                      
                        writeReg(SYSTEM_INTERRUPT_CLEAR, 0x01);
                      
                        return range;
                      }
                      
                      1 Reply Last reply Reply Quote 0
                      • dc42undefined
                        dc42 administrators
                        last edited by

                        @nikhil how do you set 'running' to true?

                        Duet WiFi hardware designer and firmware engineer
                        Please do not ask me for Duet support via PM or email, use the forum
                        http://www.escher3d.com, https://miscsolutions.wordpress.com

                        Nikhilundefined 1 Reply Last reply Reply Quote 0
                        • Nikhilundefined
                          Nikhil @dc42
                          last edited by Nikhil

                          @dc42

                          Init :--

                          Sensor *temp = new sensor(Platform::GetSharedI2C(), sensorxAddressLsb);  // added false for default addressss
                          	if (temp == nullptr)
                          	{
                          		//	debugPrintf("error creating sensor"); no use
                          	}
                          	if (temp->CheckPresent())   // returns hardcoded true As I was not having anything to check
                          	{
                          		if (!temp->init())			/
                          		{					// waiting time should be less while initializing
                          			debugPrintf("not initializing the sensor\n");     //no use
                          			return;
                          		}
                          
                          			// increase timing budget 
                          		temp->setMeasurementTimingBudget(200000);
                          		monitor = temp;
                          		monitorTask = new Task<MonitorTaskStackWords>;
                          		monitorTask->Create(MonitorTaskCode, "sensor", nullptr, TaskPriority::Monitor);
                          	}
                          	else
                          	{
                          		delete temp;
                          	}
                          

                          Diagnostocs

                          # if SAME5x
                          		Platform::GetSharedI2C().Diagnostics(reply);
                          # endif
                          

                          In Command processing
                          Sending temperary Gcode M54 to make 'running = true'

                          #if SUPPORT_I2C_SENSORS 
                          		case CanMessageType::monitorData:
                          			requestId = buf->msg.monitorData.requestId;
                          			rslt = MonitorHandlerProcessing::ProcessStartRequest(replyRef);
                          			break;
                          #endif
                          
                          GCodeResult MonitorHandlerProcessing::ProcessStartRequest(const StringRef &reply) noexcept
                          {
                             reply.printf("Inside monitor");
                             if (monitor == nullptr)
                             {
                             	reply.printf("monitor %u not present", CanInterface::GetCanAddress());
                             	return GCodeResult::error;
                             }
                          
                             if (running)
                             {
                             	reply.printf("Monitor is busy collecting data");
                             	return GCodeResult::error;
                             }
                          
                             running = true;
                             monitorTask->Give();
                             return GCodeResult::ok;
                          }
                          

                          first I use M54 B1 to start set 'running' = true and as soon as I do M122 B1 the response is given below and it stops the CAN communication. Means there's issue in implementing I2C client? is it?

                          M122 B1
                          Diagnostics for board 1:
                          Duet EXP3HC firmware version 3.3beta2+1PB1 (2021-04-28 17:18:32)
                          Bootloader ID: SAME5x bootloader version 2.3 (2021-01-26b1)
                          Never used RAM 158396, free system stack 0 words
                          Tasks: Move(notifyWait,160) HEAT(delaying,91) CanAsync(notifyWait,72) CanRecv(notifyWait,84) CanClock(notifyWait,74) Sensor(notifyWait,57) TMC(notifyWait,64) MAIN(running,438) AIN(delaying,260)
                          Last reset 00:03:58 ago, cause: reset button
                          Last software reset data not available
                          Driver 0: position 0, 80.0 steps/mm,  standstill, reads 41196, writes 11 timeouts 0, SG min/max 0/0, steps req 0 done 0
                          Driver 1: position 0, 80.0 steps/mm,  standstill, reads 41198, writes 11 timeouts 0, SG min/max 0/0, steps req 0 done 0
                          Driver 2: position 0, 80.0 steps/mm,  standstill, reads 41202, writes 11 timeouts 0, SG min/max 0/0, steps req 0 done 0
                          Moves scheduled 0, completed 0, in progress 0, hiccups 0, step errors 0, maxPrep 0, maxOverdue 0, maxInc 0, mcErrs 0, gcmErrs 0
                          Peak sync jitter 10, peak Rx sync delay 188, resyncs 1, no step interrupt scheduled
                          VIN: 17.2V, V12: 12.3V
                          MCU temperature: min 39.0C, current 39.2C, max 39.4C
                          Ticks since heat task active 77, ADC conversions started 238550, completed 238549, timed out 0, errs 0
                          Last sensors broadcast 0x00000000 found 0 82 ticks ago, loop time 0
                          CAN messages queued 25, send timeouts 0, received 1167, lost 0, free buffers 36, min 36, error reg 0
                          dup 0, oos 0, bm 0, wbm 0
                          Error: M122: Response timeout: CAN addr 1, req type 6024, RID=52
                          ok
                          
                          
                          dc42undefined 1 Reply Last reply Reply Quote 0
                          • dc42undefined
                            dc42 administrators @Nikhil
                            last edited by

                            @nikhil have you defined all 3 of the I2C handlers? If not then the transmit interrupt will get stuck in the dummy handler.

                            Duet WiFi hardware designer and firmware engineer
                            Please do not ask me for Duet support via PM or email, use the forum
                            http://www.escher3d.com, https://miscsolutions.wordpress.com

                            Nikhilundefined 1 Reply Last reply Reply Quote 0
                            • Nikhilundefined
                              Nikhil @dc42
                              last edited by Nikhil

                              @dc42 Yes I've defined all 3 handlers but the function calling inside handler is same. The interrupt function.

                              in config.h

                              #define I2C_HANDLER0		SERCOM4_0_Handler		// Handler for Interrupts all the handlers
                              #define I2C_HANDLER1		SERCOM4_1_Handler
                              #define I2C_HANDLER3		SERCOM4_2_Handler
                              

                              in Platform.c

                              	void I2C_HANDLER0() noexcept
                              	{
                              		Platform::sharedI2C->Interrupt();
                              	}
                              
                              	void I2C_HANDLER1() noexcept
                              		{
                              			Platform::sharedI2C->Interrupt();
                              
                              		}
                              
                              	void I2C_HANDLER3() noexcept
                              	{
                              		Platform::sharedI2C->Interrupt();
                              	}
                              
                              M122 B1
                              Diagnostics for board 1:
                              Duet EXP3HC firmware version 3.3beta2+1PB2 (2021-04-28 18:44:42)
                              Bootloader ID: SAME5x bootloader version 2.3 (2021-01-26b1)
                              Never used RAM 158396, free system stack 0 words
                              Tasks: Move(notifyWait,160) HEAT(delaying,99) CanAsync(notifyWait,72) CanRecv(notifyWait,84) CanClock(notifyWait,74) VL53L0X(notifyWait,57) TMC(notifyWait,64) MAIN(running,442) AIN(delaying,260)
                              Last reset 00:00:28 ago, cause: software
                              Last software reset data not available
                              Driver 0: position 0, 80.0 steps/mm,  standstill, reads 17991, writes 11 timeouts 0, SG min/max 0/0, steps req 0 done 0
                              Driver 1: position 0, 80.0 steps/mm,  standstill, reads 17994, writes 11 timeouts 0, SG min/max 0/0, steps req 0 done 0
                              Driver 2: position 0, 80.0 steps/mm,  standstill, reads 17998, writes 11 timeouts 0, SG min/max 0/0, steps req 0 done 0
                              Moves scheduled 0, completed 0, in progress 0, hiccups 0, step errors 0, maxPrep 0, maxOverdue 0, maxInc 0, mcErrs 0, gcmErrs 0
                              Peak sync jitter 7, peak Rx sync delay 183, resyncs 1, no step interrupt scheduled
                              VIN: 17.2V, V12: 12.3V
                              MCU temperature: min 39.2C, current 39.2C, max 39.2C
                              Ticks since heat task active 239, ADC conversions started 28984, completed 28984, timed out 0, errs 0
                              Last sensors broadcast 0x00000000 found 0 244 ticks ago, loop time 0
                              CAN messages queued 25, send timeouts 0, received 119, lost 0, free buffers 36, min 36, error reg 0
                              dup 0, oos 0, bm 0, wbm 0
                              Monitor is available
                              ok
                              

                              I2C section is not printing.

                              dc42undefined 1 Reply Last reply Reply Quote 0
                              • dc42undefined
                                dc42 administrators @Nikhil
                                last edited by

                                @nikhil, it's hard for me to comment further without seeing all the code.

                                Duet WiFi hardware designer and firmware engineer
                                Please do not ask me for Duet support via PM or email, use the forum
                                http://www.escher3d.com, https://miscsolutions.wordpress.com

                                Nikhilundefined 1 Reply Last reply Reply Quote 0
                                • Nikhilundefined
                                  Nikhil @dc42
                                  last edited by Nikhil

                                  @dc42 Thanks for the help. May be sensors function has problem will check those. Will add remote M260 for 3HC V1.0 with changes and contribute in 3HC's firmware.
                                  changes.jpg
                                  I've bypassed the resistor R22. To get PA17 is it correct one.

                                  pins.jpg

                                  Nikhilundefined 1 Reply Last reply Reply Quote 0
                                  • Nikhilundefined
                                    Nikhil @Nikhil
                                    last edited by

                                    Hi @dc42 , I went through the code and made changes. the module is working as I can see

                                    I2C bus errors 0, naks 69, other errors 0 
                                    I2C device address 0x29
                                    

                                    facing no acknowledgment. I'm using 0x29 address for the slave (sensor Adafruit VL53L0X) the same address I tried with arduino that's working fine. Can it be because of hardware. Or while sending data fast voltage is not reaching 3.3v or more?

                                    dc42undefined 1 Reply Last reply Reply Quote 0
                                    • dc42undefined
                                      dc42 administrators @Nikhil
                                      last edited by dc42

                                      @nikhil I suspect it is a firmware issue. Have you published your fork on github? Did you add external 4K7 pullup resistors to +3.3V, or does your I2C device already have those?

                                      Duet WiFi hardware designer and firmware engineer
                                      Please do not ask me for Duet support via PM or email, use the forum
                                      http://www.escher3d.com, https://miscsolutions.wordpress.com

                                      Nikhilundefined 1 Reply Last reply Reply Quote 0
                                      • Nikhilundefined
                                        Nikhil @dc42
                                        last edited by

                                        @dc42 It's working I changed the resistor as you said. I'll publish the fork. It was firmware issue.

                                        ardundefined 1 Reply Last reply Reply Quote 0
                                        • ardundefined
                                          ard @Nikhil
                                          last edited by

                                          @nikhil
                                          Hi,
                                          I'm struggle with similar problem to connect i2c sensor to expansion board Duet3HC.
                                          Could you publish your fork on github?
                                          Thanks in advance

                                          1 Reply Last reply Reply Quote 0
                                          • First post
                                            Last post
                                          Unless otherwise noted, all forum content is licensed under CC-BY-SA