Intel® Makers
Intel® Edison, Intel® Joule™, Intel® Curie™, Intel® Galileo
Welcome - This is a Peer-to-Peer Forum only. Intel has discontinued these products but you may find support from other customers on this Forum
9873 Discussions

MAX3107 Implementation help


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..

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: L364 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

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)


/* 3. Configure MODE 1 register */

buf[4] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG)


/* 4. Configure MODE 2 register */

buf[5] = (MAX3107_WRITE_BIT | MAX3107_MODE2_REG)


/* Reset FIFOs */

buf[5] |= MAX3107_MODE2_FIFORST_BIT;

/* 5. Configure FIFO trigger level register */


/* 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");



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)


/* 12. Clear FIFO reset that was set in step 6 */

buf[2] = (MAX3107_WRITE_BIT | MAX3107_MODE2_REG)


/* Perform SPI transfer */

if(mraa_spi_write_buf_word(dev, buf, 2) == NULL){

printf("Initialisation stage 2 failed \n");



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...



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.

7 Replies
Community Manager

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.



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!

Community Manager

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.




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., L1191 1191;i=module_init module_init(;i=max3107_init max3107_init); L1192 1192;i=module_exit module_exit(;i=max3107_exit max3107_exit); L1193 1193 L1194 1194;i=MODULE_DESCRIPTION MODULE_DESCRIPTION("MAX3107 driver"); L1195 1195;i=MODULE_AUTHOR MODULE_AUTHOR("Aavamobile"); L1196 1196;i=MODULE_ALIAS MODULE_ALIAS("max3107-spi"); L1197 1197;i=MODULE_LICENSE MODULE_LICENSE("GPL v2");

Again, many thanks for your help.

Community Manager

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:



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



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?

Community Manager

Hi shih91,



I'm sorry to hear that, in that case my best suggestion is that you use the MAX3107 datasheet ( to program it directly through SPI (eliminating the need of a driver) or to contact the MAX3107 manufacturer ( for help.



I hope this helps.