7 Replies Latest reply on Dec 8, 2016 12:07 PM by Intel Corporation

    MAX3107 Implementation help

    shih91

      Hi guys,

       

      May I know anyone has interfaced MAX3107 chip with Intel Edison? All I can find on this forum is this thread regarding MAX3107 and it wasn't helpful.. Configuring a MAX3107-family SPI UART

       

      My project is currently using a mini breakout board that is connected to a custom made PCB that has a MAX3107. I chose SPI interface over I2C interface because my project needs to achieve a very high data transfer rate of 3Mbps at the UART side. Specifically, the RX line of MAX3107 will be taking in 3Mbps of data, then Intel Edison will access the RX buffer of MAX3107 when the RX Trigger Interrupt has been triggered.

       

      I looked into the kernel file found here:

      Linux/drivers/serial/max3107.h - Linux Cross Reference - Free Electrons

      Linux/drivers/serial/max3107.c - Linux Cross Reference - Free Electrons

       

      I tried compiling the Yocto kernel (linux-yocto-3.10-master) from:

      GitHub - instantinfrastructure/linux-yocto-3.10: Fork of http://git.yoctoproject.org/cgit/cgit.cgi/linux-yocto-3.10/

      But it failed several times before I gave up.

      I copied the whole source code to the Intel Edison over WinSCP and configured the kernel using "make menuconfig" then "make V=0 all".

       

      I tried to understand what the driver of MAX3107 in the Yocto kernel is doing, but so far I could only figure out how it initialized the registers. I modified the code a little and used it in the application layer (C program). Below is the code that I modified into:

      
      
      

       

       

        buf[0] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVMSB_REG)
        | ((0x00) & MAX3107_SPI_TX_DATA_MASK);
        buf[1] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVLSB_REG)
        | ((0x01) & MAX3107_SPI_TX_DATA_MASK);
        buf[2] = (MAX3107_WRITE_BIT | MAX3107_BRGCFG_REG)
        | ((0x0A) & 0xff);
      
        /* 2. Configure LCR register, 8N1 mode by default */
        buf[3] = (MAX3107_WRITE_BIT | MAX3107_LCR_REG)
        | MAX3107_LCR_WORD_LEN_8;
      
        /* 3. Configure MODE 1 register */
        buf[4] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG)
        | MAX3107_MODE1_IRQSEL_BIT;
      
        /* 4. Configure MODE 2 register */
        buf[5] = (MAX3107_WRITE_BIT | MAX3107_MODE2_REG)
        | MAX3107_MODE2_LOOPBACK_BIT;
        /* Reset FIFOs */
        buf[5] |= MAX3107_MODE2_FIFORST_BIT;
      
        /* 5. Configure FIFO trigger level register */
        buf[6] = (MAX3107_WRITE_BIT | MAX3107_FIFOTRIGLVL_REG);
        /* RX FIFO trigger for 16 words, TX FIFO trigger not used */
        buf[6] |= (MAX3107_FIFOTRIGLVL_RX(1) | MAX3107_FIFOTRIGLVL_TX(0));
      
        /* 6. Configure flow control levels */
        buf[7] = (MAX3107_WRITE_BIT | MAX3107_FLOWLVL_REG);
      
        /* 7. Configure flow control */
        buf[8] = (MAX3107_WRITE_BIT | MAX3107_FLOWCTRL_REG);
      
        /* 8. Configure RX timeout register */
        buf[9] = (MAX3107_WRITE_BIT | MAX3107_RXTO_REG);
      
        /* 9. Configure LSR interrupt enable register */
        buf[10] = (MAX3107_WRITE_BIT | MAX3107_LSR_IRQEN_REG);
        /* Enable RX timeout interrupt */
        buf[10] |= MAX3107_LSR_RXTO_BIT;
      
        /* Perform SPI transfer */
        if(mraa_spi_write_buf_word(dev, buf, 11) == NULL){
        printf("Initialisation stage 1 failed \n");
        }
        else{
        printf("Initialisation stage 1 success! \n");
        }
      
        /* 10. Clear IRQ status register by reading it */
        buf[0] = MAX3107_IRQSTS_REG;
      
        /* 11. Configure interrupt enable register */
        /* Enable LSR interrupt */
        /* Enable RX FIFO interrupt */
        buf[1] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG)
        | (MAX3107_IRQ_LSR_BIT | MAX3107_IRQ_RXFIFO_BIT);
      
        /* 12. Clear FIFO reset that was set in step 6 */
        buf[2] = (MAX3107_WRITE_BIT | MAX3107_MODE2_REG)
        | MAX3107_MODE2_LOOPBACK_BIT;
      
        /* Perform SPI transfer */
        if(mraa_spi_write_buf_word(dev, buf, 2) == NULL){
        printf("Initialisation stage 2 failed \n");
        }
        else{
        printf("Initialisation stage 2 success! \n");
        }
      

       

      As you can see above, I enabled a loopback test and would like to see if I can read back the data that I sent through SPI via UART. Below is the piece of code that I used to test:

       

      char text[] = "Hello world 123";
      uint8_t *readbuffer;
      uint8_t *writebuffer;
      writebuffer = text;
      printf("%s\n", writebuffer);
      // sleep(1);
      mraa_spi_write_buf(spi, writebuffer, strlen(writebuffer));
      if(mraa_gpio_read(IRQ) == 1){
        memset(writebuffer, 0, strlen(writebuffer));
        readbuffer = mraa_spi_write_buf(spi, writebuffer, 15);
      }
      if(strlen(readbuffer) == 0){
        printf("SPI transfer failed, size of write buffer : %d \n", strlen(writebuffer));
      }
      printf("Here is what i should get back : %s\n", writebuffer);
      printf("Here is what i got back : %s \n", readbuffer);
      

       

      This is the result that I always get:

      root@edison:~# ./test
      Initialised pin 55
      Initialised pin 54
      Writing to registers...
      Resetting
      Resetted
      Done writing to registers!!!
      Hello world 123
      SPI transfer failed, size of write buffer : 15
      Here is what i should get back : Hello world 123
      Here is what i got back :
      

       

      I hope I did not miss out any information, and I really need help regarding this project. =/

       

      I attached the max3107test.c file to this thread as well.

        • 1. Re: MAX3107 Implementation help
          Intel Corporation
          This message was posted on behalf of Intel Corporation

          Hello shih91,

          Thanks for reaching out!

          I'm a little lost, I believe you are trying to get the MAX3107 to work with Edison and you are supposed to use SPI for it, right? If that's the case, why were you trying to modify Edison's image? 

          Now, regarding the max3107.h and max3107.c files you mentioned, they are called drivers but because of its simplicity I would say that they are simply a library. I mean, this is the entire driver, right? There is no services or any other files related to them, right?

          If that was the case then, using this "driver" should only involve including it on your code. I might be overlooking a lot of things, so, please correct me if I'm wrong.

          If the above was the case, and you indeed just included the "driver" to your code, then the SPI crash makes sense. The "driver" uses a generic SPI library to work and I can see that you are using mraa to control SPI. So, that means that in your code there are two "entities" that want to use the SPI bus at the same time, does that make sense?

          As I mentioned above, I might be overlooking a lot of details, so, please correct me if I did any incorrect assumptions.

          Let me know.
          -Peter.

          • 2. Re: MAX3107 Implementation help
            shih91

            Hello Peter,

             

            Yes, I am trying to get MAX3107 to work with Edison via SPI. I am relatively new with IoT development and linux kernel stuffs.

             

            I believe I was supposed to load MAX3107 driver into Edison's kernel for the drivers to work in Edison? Am I able to use the drivers as libraries in my codes?

             

            I'm sorry, I don't really know what to do as of now. But I think I will try to include max3107.h in my code and try to use the functions. Hopefully they will achieve what I am trying to do.

             

            Thanks for helping btw!

            • 3. Re: MAX3107 Implementation help
              Intel Corporation
              This message was posted on behalf of Intel Corporation

              Hi shih91,

              I'm glad to help!

              For a regular driver, you would be right, drivers have to be included into Linux's kernel so that it can detect the device and manage it appropriately. I took a quick look at the links you provided to the MAX3107's driver. This files, to me, look more like a library than a driver. I might be missing some information and actually be wrong, however, I wouldn't rule out the possibility that you can simply use this driver as a library. As I mentioned above, other drivers that I have seen in the past create services and other files required to detect when the device is plugged. 

              So, you could try to use this as a library. Nevertheless, as I pointed out in my previous reply, if you use mraa, you'll probably end up having issues because the .c file uses Linux's generic SPI library. So, you'll either have to use that library in your application or modify the .c to make it compatible with mraa. Otherwise, you'll end up crashing the SPI bus because it will be required by two different "entities" at the same time.

              I hope this helps.
              -Peter.

              • 4. Re: MAX3107 Implementation help
                shih91

                Hi,

                 

                Sorry for the late reply.

                 

                I have tried to include and use the driver as library in my application code. But it has given me an error stating the functions that I used was not declared. Do I have to modify the max3107.c file to remove all the kernel portions and make it a library file manually? I.e.,

                 

                1191module_init(max3107_init);
                1192 module_exit(max3107_exit);
                1193
                1194 MODULE_DESCRIPTION("MAX3107 driver");
                1195 MODULE_AUTHOR("Aavamobile");
                1196 MODULE_ALIAS("max3107-spi");
                1197MODULE_LICENSE("GPL v2");
                

                 

                Again, many thanks for your help.

                • 5. Re: MAX3107 Implementation help
                  Intel Corporation
                  This message was posted on behalf of Intel Corporation

                  I believe this is one of the details I mentioned that I could have missed, I'm not an expert on this, so, my suggestions would be: yes, try doing this modifications and check if you are able to use it. If this creates more issues that it solves, then I might be wrong and this driver indeed has to be added to Yocto's kernel.

                  If that was the case, (as I mentioned I'm not an expert on this subject) I suggest you to read the following document which I believe can help you compiling this driver:

                  http://www.tldp.org/LDP/lkmpg/2.6/html/lkmpg.html

                  Please go ahead with your tests, and let us know how they go.
                  -Peter.

                  • 6. Re: MAX3107 Implementation help
                    shih91

                    Hi Peter,

                     

                    I have tried lots of stuffs ranging from including the driver files as libraries in my code to compiling the whole yocto image to include the MAX310X module. All have failed.... I am literally at dead end right now.

                     

                    Detailed explanation of the stuffs I have tried:

                    1) removing the lines that were meant for kernel codes and compile it together with my code

                    2) compiling max310x.c and max310x.h using Makefile as stated in the guide in the previous post

                    3) downloading the whole yocto image and configure the kernel setting using menuconfig and compile the whole image

                     

                    None has worked thus far. Anyone has any suggestion how should I proceed?

                    • 7. Re: MAX3107 Implementation help
                      Intel Corporation
                      This message was posted on behalf of Intel Corporation

                      Hi shih91,

                      I'm sorry to hear that, in that case my best suggestion is that you use the MAX3107 datasheet (https://datasheets.maximintegrated.com/en/ds/MAX3107.pdf) to program it directly through SPI (eliminating the need of a driver) or to contact the MAX3107 manufacturer (https://www.maximintegrated.com/en/support/overview.html) for help.

                      I hope this helps.
                      -Peter.