Thursday 30 June 2016

Using MAX14830 with Raspberry Pi 3

MAX14830 is SPI/I2C to quad UART converter IC. This IC works with Linux, tested on Raspberry Pi 3. To get it working we need to setup device tree for our hardware. I have MAX14830EVKIT from Maxim, all four serial ports of this kit were detected and are working.

1. You need following to create a test setup

1.1. Raspberry PI 3, you can use any other SBC which you have.

1.2. MAX14830EVKIT from Maxim or similar hardware.



1.3. Connector cable to connect RPi3 to MAX14830 dev kit


1.4. Complete hardware setup


2. Flash RPi3 with latest image. My uname -a gives following

root@raspberrypi:~# uname -a
Linux raspberrypi 4.4.11-v7+ #888 SMP Mon May 23 20:10:33 BST 2016 armv7l GNU/Linux
root@raspberrypi:~# cat /etc/debian_version
8.0

You will have to compile driver for your kernel or recompile kernel with max310 driver enabled.
Driver source is located at   kernel_source/drivers/tty/serial/max310x.c.

3. Install device tree compiler using
root@raspberrypi:~# apt-get install device-tree-compiler

4. Create DTS file to turn off spidev.
 I have file named spidev-off.dts with following contents.

/dts-v1/;
/plugin/;

/ {
        compatible = "brcm,bcm2708";


        fragment@0 {
                target = <&spidev0>;
                __overlay__ {
                        status = "disabled";
                };
        };

        fragment@1 {
                target = <&spidev1>;
                __overlay__ {
                        status = "disabled";
                };
        };
};

5. Create DTS file to set clock of MAX14830. Change frequency as per your MAX14830 hardware.
Pl note this dts must be loaded ad boot time.
I have file named  max14830-clock.dts with following contents.

// Overlay for the Maxim max14830 clock
/dts-v1/;
/plugin/;

/ {
        compatible = "brcm,bcm2708";


        fragment@1 {
                target = <&clocks>;
                __overlay__ {
                        xtal36: xtal36@7 {
                                reg = <0x7>;
                                compatible = "fixed-clock";
                                #clock-cells = <0>;
                                clock-frequency = <3686400>;
                                clock-output-names = "xtal36";
                        };
                };
        };
};

6. Create DTS file for MAX14830.
I have file named max14830.dts with following content. Pl customize interrupts for your hardware.

// Overlay for the Maxim max14830
/dts-v1/;
/plugin/;

/ {
        compatible = "brcm,bcm2708";

        fragment@0 {
                target = <&spi0>;
                __overlay__ {
                        /* needed to avoid dtc warning */
                        #address-cells = <1>;
                        #size-cells = <0>;

                        status = "okay";


                        max14830_1: max14830_1@0 {
                                compatible = "maxim,max14830";
                                reg = <0>; /* CE0 */
                                clocks = <0x44>;
                                clock-names = "xtal";
                                spi-max-frequency = <12000000>;
                                status = "okay";
                                pinctrl-names = "default";
                                pinctrl-0 = <&max14830_pins>;
                                interrupt-parent = <&gpio>;
                                interrupts = <17 0x2>; /* falling edge */
                        };
                };
        };

        fragment@1 {
                target = <&gpio>;
                __overlay__ {
                        max14830_pins: max_14830_pins {
                                brcm,pins = <4>;
                                brcm,function = <0>; /* in */
                                brcm,pull = <0>; /* none */
                        };
                };
        };

        __overrides__ {
                int_pin = <&max14830_1>, "interrupts:0",
                          <&max14830_pins>, "brcm,pins:0";
                speed   = <&max14830_1>, "spi-max-frequency:0";
        };
};

Pl note line    clocks = <0x44>  above. Number 0x44 is phandle in clock settings. You can find this number by using following command.
dtc -I fs /proc/device-tree | grep -A 4 xtal36

7. Now we have 3 dts files. Compile files using dtc compiler and place .dto files in /boot/overlays/
The reason for having three different file is that you can load spidev-off.dtbo and max14830-clock,dtbo at boot time and load/unload max14830.dtbo after boot with dtoverlay command. This helps in experimenting with max14830.dts code.
To compile dts file use following command
 dtc -@ -I dts max14830.dts -o /boot/overlays/max14830.dtbo


To load dtbo at boot time, append following lines to /boot/config.txt

dtoverlay=spidev-off
dtoverlay=max14830-clock

8. Reboot system and load max14830.dtbo file using following command
/opt/vc/bin/dtoverlay max14830
when  max14830.dtbo is loaded, kernel driver will also get loaded. If not do depmod -a and try again.

Now check that dtbo has been loaded and there are no errors reported. If everything goes well you will find 4 device entries(ttyMAX0-3) in /dev corresponding to 4 serial ports on your card.

9. If every thing works fine, create a single dts file and load it at boot time.

Thanks

*Special thanks to Rishabh, without his help it would not have been possible.


39 comments:

  1. Hi,
    I am trying with the same method for raspberry pi3 compute module over spi0, Unable to get the ttyMAX dev interface. Geting error "max310x spi0.0: MAX14830 ID 0x0f does not match
    " Anything you can help in this regards. using the kernel 4.9.36-v7+ #1

    ReplyDelete
  2. Hi,
    If I remember correctly this error comes if there is no communication with MAX14830.
    Have you tested your hardware with normal RPi, if not I suggest first validate hardware with normal RPi and above procedure. If everything works you can move on to RPi compute.
    You may have to change interrupt pin settings when moving to rpi compute.
    Mean while if you can post your connection details and DTS files, I will try to help further.

    Best Regards

    ReplyDelete
  3. I have used same DTS file as yours. Currently the MAX14830 is getting detected, Am facing new issue related to the IRQ.

    [ 44.214640] spi0.0: ttyMAX0 at I/O 0x0 (irq = 0, base_baud = 230400) is a MAX14830
    [ 44.214904] spi0.0: ttyMAX1 at I/O 0x20 (irq = 0, base_baud = 230400) is a MAX14830
    [ 44.215098] spi0.0: ttyMAX2 at I/O 0x40 (irq = 0, base_baud = 230400) is a MAX14830
    [ 44.215330] spi0.0: ttyMAX3 at I/O 0x60 (irq = 0, base_baud = 230400) is a MAX14830
    [ 44.215544] max310x spi0.0: Unable to reguest IRQ 0
    [ 44.216388] max310x: probe of spi0.0 failed with error -22

    I have used the same IRQ line GPIO4. Since its Free Pin in my compute module. Am using the SPI0 interface only,

    Any suggestion greatly appriciate.

    ReplyDelete
  4. I have retrieved old logs from a then working setup. Also I had modified driver for additional logs. Pl refer log messages below.
    I used to get irq=170, but you are getting irq=0.
    --------------------
    Jun 2 13:07:33 raspberrypi kernel: [ 3.961595] In max310x_spi_probe
    Jun 2 13:07:33 raspberrypi kernel: [ 3.961706] probing for max14830
    Jun 2 13:07:33 raspberrypi kernel: [ 3.961760] probing for max14830
    Jun 2 13:07:33 raspberrypi kernel: [ 3.961770] using freq: 400000000
    Jun 2 13:07:33 raspberrypi kernel: [ 3.961779] Detecting max14830...
    Jun 2 13:07:33 raspberrypi kernel: [ 3.964291] spi0.0: ttyMAX0 at I/O 0x0 (irq = 170, base_baud = 25000000) is a MAX14830
    Jun 2 13:07:33 raspberrypi kernel: [ 3.964818] spi0.0: ttyMAX1 at I/O 0x20 (irq = 170, base_baud = 25000000) is a MAX14830
    Jun 2 13:07:33 raspberrypi kernel: [ 3.965211] spi0.0: ttyMAX2 at I/O 0x40 (irq = 170, base_baud = 25000000) is a MAX14830
    ------------------------

    ReplyDelete
  5. Can you post how you compiled the kernel module? I've downloaded the source (https://www.ploxiln.net/rpi_kernel_modules.html) en tried to compile the module (https://gist.github.com/fenrir-naru/95669cb8fcbf14c22e59#file-gistfile1-sh-L12) but it seems that the kmod.c file is missing to create the max310x.ko file. I managed to compile the max310x.o.

    ReplyDelete
  6. Hi,
    Sorry for late reply.

    I had setup out of tree module compilation.
    Create a directory(eg max310x) and copy max310x.c to it.
    Create a file named Makefile with following contents in this directory.
    -------------------------------------------------------
    obj-m += max310x.o

    all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

    clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
    -------------------------------------------------------

    now use make command to compile the module. If you have kernel headers/sources installed, this command should produce .ko file, which can be loaded.
    I have kernel header at /usr/src/linux-headers-4.4.11-v7+

    For details you can refer to
    https://www.kernel.org/doc/Documentation/kbuild/modules.txt

    Thanks

    ReplyDelete
  7. HI! Very good article.

    Can you please let me know the pins that you used to connect?

    ReplyDelete
  8. Hi,
    Glad that you liked article.
    RPi3 SPI0 and GPIO4 as IRQ were used.
    Below is pin mapping.

    RPi3 Pin 7 GPIO 4 <-- EVKit Pin 3 /IRQ
    RPi3 Pin 19 SPI0_MOSI --> EVKit Pin 10 MOSI
    RPi3 Pin 20 GND <-> EVKit Pin 12 GND
    RPi3 Pin 21 SPI0_MISO <-- EVKit Pin 6 MISO
    RPi3 Pin 23 SPI0_SCLK --> EVKit Pin 7 SCLK
    RPi3 Pin 24 SPI0_CE0_N --> EVKit Pin 5 CSN

    In actual setup we used two MAX14830s and derived 8 serial ports. All 8 ports were working.
    But project was abandoned in favor of mother boards with 8 serial ports.

    Thanks

    ReplyDelete
  9. Balwinder,

    Many thanks!

    To connect two board you used in parallel and chip is controlled by IRQ ? This is my doubt how to use more then one board.

    Also, I was thinking about I2C, but did not found libraries at google.

    Can you tell me the motherboard that you used? Or is it closed project?

    I might need 16 to my project.

    Best regards!

    Fernando França

    ReplyDelete
  10. Hi,
    Rpi3 has one SPI(SPI0) port on connector. This SPI0 has two slave select signals, thus it can be used to interface with two MAX14830 chips.
    The default max310 kernel driver will detect one chip and you will get 4 serial ports. These ports will be named as ttyMAX0-4
    For other chip I had duplicated original driver code and made changes so that detected ports are named as ttyMAX4-ttyMAX8. This was quick and dirty hack, but was good enough for proof of concept purpose.

    Regarding your second question about motherboards: There are various MBs available with 8-10 serial ports on board. These MBs are either Celeron or Intel Atom based, Mostly made in Taiwan. You can look at website of Asrock, ECS, Adlink etc.

    Thanks

    ReplyDelete
  11. Sorry I was trying to figure out by my self what is causing the below error, but I had no success:
    [ 167.278757] max310x: loading out-of-tree module taints kernel.
    [ 167.280399] OF: /soc/spi@7e204000/max14830_1@0: could not get #clock-cells for /soc/fb
    [ 167.280413] ERROR: could not get clock /soc/spi@7e204000/max14830_1@0:xtal(0)
    [ 167.280427] max310x spi0.0: Cannot get clock
    [ 167.280546] max310x: probe of spi0.0 failed with error -22
    [ 182.915277] OF: Duplicate name in spi@7e204000, renamed to "max14830_1@0#1"
    [ 182.915416] spi-bcm2835 3f204000.spi: chipselect 0 already in use
    [ 182.915421] spi_master spi0: spi_device register error /soc/spi@7e204000/max14830_1@0
    [ 182.915426] of_spi_notify: failed to create for '/soc/spi@7e204000/max14830_1@0'
    [ 182.915429] OF: changeset notifier error @/soc/spi@7e204000/max14830_1@0
    root@raspberrypi:/home/pi#

    Can you try to help me?

    Many thanks

    ReplyDelete
  12. I Thing it is related to the phindle clock at the overlays>

    dtc -I fs /proc/device-tree | grep -A 4 xtal36
    : Warning (reg_format): "reg" property in /soc/cprman@7e101000/xtal36@7 has invalid length (4 bytes) (#address-cells == 2, #size-cells == 1)
    : Warning (unit_address_vs_reg): Node /soc has a reg or ranges property, but no unit name
    : Warning (unit_address_vs_reg): Node /soc/vchiq has a reg or ranges property, but no unit name
    : Warning (unit_address_vs_reg): Node /soc/gpiomem has a reg or ranges property, but no unit name
    : Warning (unit_address_vs_reg): Node /soc/local_intc has a reg or ranges property, but no unit name
    : Warning (unit_address_vs_reg): Node /memory has a reg or ranges property, but no unit name
    : Warning (unit_address_vs_reg): Node /axi/vc_mem has a reg or ranges property, but no unit name
    : Warning (avoid_default_addr_size): Relying on default #address-cells value for /soc/cprman@7e101000/xtal36@7
    : Warning (avoid_default_addr_size): Relying on default #size-cells value for /soc/cprman@7e101000/xtal36@7
    : Warning (avoid_default_addr_size): Relying on default #address-cells value for /axi/vc_mem
    : Warning (avoid_default_addr_size): Relying on default #size-cells value for /axi/vc_mem
    xtal36@7 {
    compatible = "fixed-clock";
    #clock-cells = <0x0>;
    phandle = <0x4c>;
    reg = <0x7>;
    clock-output-names = "xtal36";
    clock-frequency = <0x384000>;
    linux,phandle = <0x4c>;
    };
    };

    ReplyDelete
  13. As per DTS posted above, you are using "clock-frequency = <0x384000>;". I had used <3686400>.
    Also you will need to load all three DTS files as described above.

    Pl note I will not be able to reply for few days as I am going on leave from today evening (22/12/17 4PM IST).

    Thanks

    ReplyDelete
  14. Hmm, I´m loading them at /boot/config.txt

    I will double check this, and read a little bit more about DTS.

    Really thank for your help! Happy Christmas and new year for you!

    Best regards

    ReplyDelete
    Replies
    1. Thank you for your best wishes.
      Sorry, I was unable to reply as I was away.
      Belated, best wishes for new year.

      I hope you have progressed on your project, if not I will be happy to help you for your project in whatever way I can.

      Best Regards

      Delete
  15. Hi!

    Sorry for my late reply, I was also in vocations.

    I think that the clock problem is related to the DTS file created, note the below warnings:
    root@raspberrypi:/home/pi/Developer/max14830/DTS# dtc -@ -I dts max14830-clock.dts -o /boot/overlays/max14830-clock.dtbo
    /boot/overlays/max14830-clock.dtbo: Warning (reg_format): "reg" property in /fragment@1/__overlay__/xtal36@7 has invalid length (4 bytes) (#address-cells == 2, #size-cells == 1)
    /boot/overlays/max14830-clock.dtbo: Warning (unit_address_vs_reg): Node /fragment@1 has a unit name, but no reg property
    /boot/overlays/max14830-clock.dtbo: Warning (avoid_default_addr_size): Relying on default #address-cells value for /fragment@1/__overlay__/xtal36@7
    /boot/overlays/max14830-clock.dtbo: Warning (avoid_default_addr_size): Relying on default #size-cells value for /fragment@1/__overlay__/xtal36@7

    I´m copying and pasting your code.

    When I run "dtc -I fs /proc/device-tree | grep -A 4 xtal36" I receive:
    : Warning (unit_address_vs_reg): Node /axi/vc_mem has a reg or ranges property, but no unit name
    : Warning (avoid_default_addr_size): Relying on default #address-cells value for /soc/cprman@7e101000/xtal36@7
    : Warning (avoid_default_addr_size): Relying on default #size-cells value for /soc/cprman@7e101000/xtal36@7
    : Warning (avoid_default_addr_size): Relying on default #address-cells value for /axi/vc_mem
    : Warning (avoid_default_addr_size): Relying on default #size-cells value for /axi/vc_mem
    xtal36@7 {
    compatible = "fixed-clock";
    #clock-cells = <0x0>;
    phandle = <0x4d>;
    reg = <0x7>;
    clock-output-names = "xtal36";
    clock-frequency = <0x384000>;
    linux,phandle = <0x4d>;
    };
    };



    ReplyDelete
    Replies
    1. You can ignore warnings.
      The output of "dtc -I fs /proc/device-tree | grep -A 4 xtal36" command shows that clock has been setup.
      Now pl note phandle = <0x4d> in the output above.
      You will need to change clock settings in max-14830.dts as following
      clocks = <0x4d>

      If you have already changed and still it is not working, pl check on oscilloscope for clock signals.

      I have retrieved my old setup, I will make it work, and post more information with screen shots.

      Delete
    2. Hi!

      Sorry for that yes, after adjusting phandle it did work, but I´m now having same problem as Mr. harsha, I´m getting IRQ = 0 ...

      [ 668.119613] max310x: loading out-of-tree module taints kernel.
      [ 668.123817] spi0.0: ttyMAX0 at I/O 0x0 (irq = 0, base_baud = 230400) is a MAX14830
      [ 668.125819] spi0.0: ttyMAX1 at I/O 0x20 (irq = 0, base_baud = 230400) is a MAX14830
      [ 668.127201] spi0.0: ttyMAX2 at I/O 0x40 (irq = 0, base_baud = 230400) is a MAX14830
      [ 668.129256] spi0.0: ttyMAX3 at I/O 0x60 (irq = 0, base_baud = 230400) is a MAX14830
      [ 668.130534] max310x spi0.0: Unable to reguest IRQ 0
      [ 668.134707] max310x: probe of spi0.0 failed with error -22

      Do you have any ideas?

      Delete
    3. Pl try with following dts file. It works on my old setup. It has configuration for two max14830 ICs, but works for one IC also. There is additional configuration for interrupts in this files, which might be the reason.


      // Overlay for the Maxim max14830
      /dts-v1/;
      /plugin/;

      / {
      compatible = "brcm,bcm2708";

      fragment@0 {
      target = <&spi0>;
      __overlay__ {
      /* needed to avoid dtc warning */
      #address-cells = <1>;
      #size-cells = <0>;

      status = "okay";


      max14830_1: max14830_1@0 {
      compatible = "maxim,max148301";
      reg = <0>; /* CE0 */
      clocks = <0x44>;
      clock-names = "xtal";
      pinctrl-names = "default";
      pinctrl-0 = <&irq0_pin>;
      interrupt-parent = <&gpio>;
      interrupts = <17 0x2>; /* falling edge */
      spi-max-frequency = <12000000>;
      status = "okay";
      };
      };
      };

      fragment@1 {
      target = <&spi0>;
      __overlay__ {
      /* needed to avoid dtc warning */
      #address-cells = <1>;
      #size-cells = <0>;

      status = "okay";


      max14830_2: max14830_2@0 {
      compatible = "maxim,max148302";
      reg = <1>; /* CE0 */
      clocks = <0x44>;
      clock-names = "xtal";
      pinctrl-names = "default";
      pinctrl-0 = <&irq1_pin>;
      interrupt-parent = <&gpio>;
      interrupts = <16 0x2>; /* falling edge */
      spi-max-frequency = <12000000>;
      status = "okay";
      };
      };
      };


      fragment@4 {
      target = <&gpio>;
      __overlay__ {
      irq0_pin: irq0_pin {
      brcm,pins = <17>;
      brcm,function = <0>; /* in */
      brcm,pull = <0>; /* none */
      };
      irq1_pin: irq1_pin {
      brcm,pins = <16>;
      brcm,function = <0>; /* in */
      brcm,pull = <0>; /* none */
      };
      };
      };


      __overrides__ {
      int_pin0 = <&max14830_1>, "interrupts:0",
      <&irq0_pin>, "brcm,pins:0";
      int_pin1 = <&max14830_2>, "interrupts:0",
      <&irq1_pin>, "brcm,pins:0";
      };
      };


      Delete
    4. I have modified max14830.dts file above. It includes settings for interrupt.
      I apologize for the mistake, don't remember how I missed that information in original post.

      Delete
  16. Dear all,

    @Balwinder, many thanks for this post.

    I've just bought a MAX14830 evaluation board and will try to setup everything like you in order to conduct a few tests before maybe routing a custom board after that.

    It would be really handy for me to get access to the GPIOs and Multidrop mode. Do you think this is possible with the linux kernel driver ? If so are there any special syscalls ? On the contrary do you have any ideas how I could achieve this ? (Sorry if In ask too much questions, I'm fairly new to the device tree manipulation and kernel modules handling).

    All the best,

    Clément

    ReplyDelete
  17. Glad that post was useful to you.

    Once ports are detected you can use them as any other serial ports, no spacial syscalls are required.
    By multi drop if you mean that you want to connect two ICs on one SPI port, pl read on.
    I had used two MAX14830s connected to one SPI port, they had different chip enable. All 8 ports from two MAX14830 were working.
    For two ICs, you can find dts above in one of the answers.
    The default max310 kernel driver will detect one chip and you will get 4 serial ports. These ports will be named as ttyMAX0-4
    For other chip I had duplicated original driver code and made changes so that detected ports are named as ttyMAX4-ttyMAX8.
    This was quick and dirty hack, but was good enough for proof of concept purpose

    Regards

    ReplyDelete
    Replies
    1. Hello Balwinder,

      Your post was very useful indeed. Many thanks for that. By Multidrop I was refering to the ability of the MAX14830 to send and receive 9-bit data frames on the UART.

      I succeeded in making the same configuration as yours. How have you managed to merge the 3 device tree overlays into one ? I'm stuck with the phandle reference to xtal36@7. Is there a way to reference it without hard-coding the value ?

      Thanks.

      Clément

      Delete
    2. Happy to see that post was useful.

      I think linux doesn't support 9bit mode, but I am not sure, termios/termios2 settings doesn't have it. We use lot of multi drop communication over RS485, but we compare address of slave in firmware, maybe that is the way you would want to go.

      There is alternate syntax to reference clock using <&xtal36>, but I did not test it. If you test it pl let us know if it works.

      Delete
    3. I am using <&{/clocks/xtal36@7}> to refer xtal in the device tree successfully.

      Delete
  18. Hi. Thanks for the very useful post. I have a custom board with MAX 14830. It is very similar - almost same as the official eval board. The chip is detected and ttys are created without any problem. I also decoded the SPI communication during probe, read and send so there does not seem to be any problem. However, after using it for a few minutes -and I cannot give a better explanation yet because I could not find anything concrete until now- it basically stops working. No receive, no send, no communication in the SPI, like the chip is not there. Do you have any idea or comment what could be the reason ? or how can I debug this ? Best regards.

    ReplyDelete
    Replies
    1. I would first check hardware thoroughly.
      1. Check power supply for any noise or misbehave.
      2. Check for any dry solder or loose connection.

      There are tools which can send/receive data to/from SPI. Unload driver and use such tools to send commands to chip manually.
      Hope it helps.

      Regards

      Delete
  19. Dear Balwinder,

    Good day!

    First of all many thanks for you help! Sorry for my delay, I needed to run another project with 4~20mA readings.

    Now I´m back on this and I read much more about DTC.

    Still have one doubt regarding interrupts = <17 0x2>; /* falling edge */

    How 17 is related to GPIO 4, as 17(Hex) = 23(DEC)

    Also, my system works now, but only to send data, it is not receiving. I´m still troubleshooting it. If you have any information that might help it will be much appreciated.

    Regards,

    Fernando França

    ReplyDelete
    Replies
    1. Hi Fernando,

      Receiving will not work if your interrupt setup is not correct, since the driver is interrupt based (it does not poll). You can check this by looking into (cat) /proc/interrupts, the count of your interrupt should increase as it receives data, if not, that means it is not working.

      I think 17 is not hex (otherwise it should be written as 0x17). You should set this correctly based on your setup.

      Mete

      Delete
    2. Hi Mete,

      Thanks for you reply.

      It seems that my interrupt is ok:

      183: 0 0 0 0 pinctrl-bcm2835 17 Edge spi0.0

      Delete
    3. Sorry also forgot to say that when detecting MAX14830 it keeps the same IRQ id

      [ 3.889036] spi0.0: ttyMAX0 at I/O 0x0 (irq = 183, base_baud = 230400) is a MAX14830
      [ 3.889705] spi0.0: ttyMAX1 at I/O 0x20 (irq = 183, base_baud = 230400) is a MAX14830
      [ 3.890335] spi0.0: ttyMAX2 at I/O 0x40 (irq = 183, base_baud = 230400) is a MAX14830
      [ 3.890978] spi0.0: ttyMAX3 at I/O 0x60 (irq = 183, base_baud = 230400) is a MAX14830

      Delete
    4. So the line "183: 0 0 0 0 pinctrl-bcm2835 17 Edge spi0.0" means no IRQ 183 happened (counts are all zero, there are 4 counts because the cpu has 4 cores). Are you using the eval board ? If not, you can double check if you have a pull-up resistor on the IRQ line and also double check the device tree if the GPIO for IRQ you specified is the same as the one you are using. You can check if there is any problem with the device tree using vcdbg and dtc, see here, section 4.1: https://www.raspberrypi.org/documentation/configuration/device-tree.md

      Mete

      Delete
    5. It looks like hardware problem. Pl verify wiring of IRQ line. For reference connection details are given below.

      RPi3 Pin 7 GPIO 4 <-- EVKit Pin 3 /IRQ
      RPi3 Pin 19 SPI0_MOSI --> EVKit Pin 10 MOSI
      RPi3 Pin 20 GND <-> EVKit Pin 12 GND
      RPi3 Pin 21 SPI0_MISO <-- EVKit Pin 6 MISO
      RPi3 Pin 23 SPI0_SCLK --> EVKit Pin 7 SCLK
      RPi3 Pin 24 SPI0_CE0_N --> EVKit Pin 5 CSN

      Also pl verify wiring of your serial ports, you can check for any activity on Rx0/1/2/3 pins of serial port.

      Regards

      Delete
    6. Hi Baldiwin,

      Good day!

      Sorry forgot to mention that it worked well!

      Thanks for all your support!

      Later on I will try with two MAX14830.

      Regards,

      Fernando França

      Delete
    7. hello everyone

      [ 5.154467] max310: loading out-of-tree module taints kernel.
      [ 6.454168] spi0.0: ttyMAX0 at I/O 0x0 (irq = 167, base_baud = 921600) is a MAX14830
      [ 6.461224] spi0.0: ttyMAX1 at I/O 0x20 (irq = 167, base_baud = 921600) is a MAX14830
      [ 6.462130] spi0.0: ttyMAX2 at I/O 0x40 (irq = 167, base_baud = 921600) is a MAX14830
      [ 6.471268] spi0.0: ttyMAX3 at I/O 0x60 (irq = 167, base_baud = 921600) is a MAX14830

      it seems max14830 ic working fine.my next issue how can i check serial work fine or not.

      Delete
  20. I'm trying to add the MAX14830 board to a PiZero.
    So far I've created the dts files and compiled them. However, when I try to load max14830.dtbo, I get the following from dmesg
    [ 427.966603] max310x: loading out-of-tree module taints kernel.
    [ 427.977896] OF: /soc/spi@7e204000/max14830_1@0: could not get #clock-cells for /soc/gpio@7e200000/spi0_gpio35
    [ 427.988238] ERROR: could not get clock /soc/spi@7e204000/max14830_1@0:xtal(0)
    [ 427.996578] max310x spi0.0: Cannot get clock
    [ 428.001482] max310x: probe of spi0.0 failed with error -22

    I suspect this is to do with differences between the PiZero and the Pi3.
    The ouput from dtc -I fs /proc/device-tree | grep -A 4 xtal36 doesn't yeild anything of interest, which probably means the clock definitions differ.
    Any suggestions on how to proceed.
    Thanks

    ReplyDelete
  21. Hi,
    I am trying with the Beaglebone black SPI1 ,
    in dmesg i am getting ttyMAX0-3 but in /dev it is not showing
    [ 20.564431] spi2.0: ttyMAX0 at I/O 0x0 (irq = 102, base_baud = 230400) is a MAX14830
    [ 20.591983] serial serial0: tty port ttyMAX0 registered
    [ 20.627598] spi2.0: ttyMAX1 at I/O 0x20 (irq = 102, base_baud = 230400) is a MAX14830
    [ 20.647886] serial serial1: tty port ttyMAX1 registered
    [ 20.713357] spi2.0: ttyMAX2 at I/O 0x40 (irq = 102, base_baud = 230400) is a MAX14830
    [ 20.812649] serial serial2: tty port ttyMAX2 registered
    [ 20.867482] spi2.0: ttyMAX3 at I/O 0x60 (irq = 102, base_baud = 230400) is a MAX14830
    [ 20.883749] serial serial3: tty port ttyMAX3 registered

    Any suggestion plz
    Thanks

    ReplyDelete
  22. file

    max14830-clock.dts
    /dts-v1/;
    /plugin/;

    / {
    compatible = "brcm,bcm2708";


    fragment@1 {
    target = <&clocks>;
    __overlay__ {
    xtal36: xtal36@7 {
    reg = <0x7>;
    compatible = "fixed-clock";
    #clock-cells = <0>;
    phandle = <0x4d>;
    linux,phandle = <0x4d>;
    clock-frequency = <0x384000>;
    clock-output-names = "xtal36";
    };
    };
    };
    };

    root@raspberrypi:/boot/overlays# dtc -@ -I dts max14830-clock.dts -o /boot/overlays/max14830-clock.dtbo
    /boot/overlays/max14830-clock.dtbo: Warning (reg_format): /fragment@1/__overlay__/xtal36@7:reg: property has invalid length (4 bytes) (#address-cells == 2, #size-cells == 1)
    /boot/overlays/max14830-clock.dtbo: Warning (pci_device_reg): Failed prerequisite 'reg_format'
    /boot/overlays/max14830-clock.dtbo: Warning (pci_device_bus_num): Failed prerequisite 'reg_format'
    /boot/overlays/max14830-clock.dtbo: Warning (simple_bus_reg): Failed prerequisite 'reg_format'
    /boot/overlays/max14830-clock.dtbo: Warning (avoid_default_addr_size): /fragment@1/__overlay__/xtal36@7: Relying on default #address-cells value
    /boot/overlays/max14830-clock.dtbo: Warning (avoid_default_addr_size): /fragment@1/__overlay__/xtal36@7: Relying on default #size-cells value
    /boot/overlays/max14830-clock.dtbo: Warning (avoid_unnecessary_addr_size): Failed prerequisite 'avoid_default_addr_size'
    /boot/overlays/max14830-clock.dtbo: Warning (unique_unit_address): Failed prerequisite 'avoid_default_addr_size'

    please help i am new in dts.how can i find correct parameter to this file

    ReplyDelete
  23. Dear all,

    @sahil, many thanks for this post.

    hello i am useing rpi4 and i perform interfacing between max14830 and rpi4.i have done above step with following files.

    spidev-off.dts

    /dts-v1/;
    /plugin/;

    / {
    compatible = "brcm,bcm2708";


    fragment@0 {
    target = <&spidev0>;
    __overlay__ {
    status = "disabled";
    };
    };

    fragment@1 {
    target = <&spidev1>;
    __overlay__ {
    status = "disabled";
    };
    };
    };


    max14830-clock.dts

    // Overlay for the Maxim max14830 clock
    /dts-v1/;
    /plugin/;

    / {
    compatible = "brcm,bcm2711";


    fragment@1 {
    target = <&clocks>;
    __overlay__ {
    xtal36: xtal36@7 {
    reg = <0x07>;
    compatible = "fixed-clock";
    #clock-cells = <0>;
    clock-frequency = < 0x384000 >;
    clock-output-names = "xtal36";
    };
    };
    };
    };

    max14830.dts

    // Overlay for the Maxim max14830
    /dts-v1/;
    /plugin/;

    / {
    compatible = "brcm,bcm2711";

    fragment@0 {
    target = <&spi0>;
    __overlay__ {
    /* needed to avoid dtc warning */
    #address-cells = <1>;
    #size-cells = <0>;

    status = "okay";


    max14830_1: max14830_1@0 {
    compatible = "maxim,max148301";
    reg = <0>; /* CE0 */
    clocks = <0xdb>;
    clock-names = "xtal";
    pinctrl-names = "default";
    pinctrl-0 = <&irq0_pin>;
    interrupt-parent = <&gpio>;
    interrupts = <17 0x2>; /* falling edge */
    spi-max-frequency = <12000000>;
    status = "okay";
    };
    };
    };

    fragment@1 {
    target = <&spi0>;
    __overlay__ {
    /* needed to avoid dtc warning */
    #address-cells = <1>;
    #size-cells = <0>;

    status = "okay";


    max14830_2: max14830_2@0 {
    compatible = "maxim,max148302";
    reg = <1>; /* CE0 */
    clocks = <0xdb>;
    clock-names = "xtal";
    pinctrl-names = "default";
    pinctrl-0 = <&irq1_pin>;
    interrupt-parent = <&gpio>;
    interrupts = <16 0x2>; /* falling edge */
    spi-max-frequency = <12000000>;
    status = "okay";
    };
    };
    };


    fragment@4 {
    target = <&gpio>;
    __overlay__ {
    irq0_pin: irq0_pin {
    brcm,pins = <17>;
    brcm,function = <0>; /* in */
    brcm,pull = <0>; /* none */
    };
    irq1_pin: irq1_pin {
    brcm,pins = <16>;
    brcm,function = <0>; /* in */
    brcm,pull = <0>; /* none */
    };
    };
    };

    after this i am going to load module using following command.

    /opt/vc/bin/dtoverlay max14830

    output:
    /opt/vc/bin/dtoverlay max14830
    * Failed to apply overlay '1_max14830' (kernel)
    i have no clue regarding this issue .please help

    thank u

    ReplyDelete