This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Use low power accelerator ADX362 on Thingy:91 board to wake up nRF9160

Hello there!

We would like to use INT1 pin of ADX362 low power accelerometer on Thingy:91 board to interrupt nRF9160 (e.g. wake it up) when some motion is detected.

To the best of my understanding, in asset tracker application you are polling the accelerometer in order to find out the orientation of the board (UPSIDE_DOWN, UP, SIDE...).

Can you give me some hints on how should I configure P0.09 pin of nRF9160 SiP in order to be able to catch the interrupts as well as how should I configure ADX362 module to give me motion interrupts?

Thanks in advance for your time and efforts!

Sincerely,

Bojan.

  • Hi, !

    What I am experiencing here is inconsistent behaviour of the system and I am getting crazy...

    Sometimes I successfully read ADXL362 ID, sometimes every SECOND read ID is successful, sometimes I can't read it at all!?

    Here is the piece of code I am using to read/write ADXL362 over SPI:

    int read_adxl362(struct device *spi, struct spi_config *spi_cfg,
                     u8_t addr, u8_t *data, u32_t num_bytes){
        
        int err = 0;
    
        /* read cmd */
        err = adxl362_access(spi, spi_cfg,
                               ADXL362_READ_CMD, addr, data, num_bytes);
        if (err) {
                printk("Error during SPI read\n");
                return -EIO;
        }
    
        return 0;       
    }
    
    int write_adxl362(struct device *spi, struct spi_config *spi_cfg,
                      u8_t addr, u8_t *data, u32_t num_bytes){
    
        int err = 0;
        /* write cmd */
        err = adxl362_access(spi, spi_cfg,
                               ADXL362_WRITE_CMD, addr, data, num_bytes);
        if (err) {
                printk("Error during SPI write\n");
                return -ENXIO;
        }
    
        return 0;
    }
    
    int adxl362_access(struct device *spi, struct spi_config *spi_cfg,
    			    u8_t cmd, u8_t addr, void *data, size_t len)
    {
    	u8_t access[2];
    	struct spi_buf bufs[] = {
    		{
    			.buf = access,
    		},
    		{
    			.buf = data,
    			.len = len
    		}
    	};
    	struct spi_buf_set tx = {
    		.buffers = bufs
    	};
    
    	access[0] = cmd;
          
            if (cmd == ADXL362_WRITE_CMD || cmd == ADXL362_READ_CMD) {
    		access[1] = addr;
    
    		bufs[0].len = 2;
    		tx.count = 2;
    
    		if (cmd == ADXL362_READ_CMD) {
    			struct spi_buf_set rx = {
    				.buffers = bufs,
    				.count = 2
    			};
    
    			return spi_transceive(spi, spi_cfg, &tx, &rx);
    		}
    	} else {
    		tx.count = 1;
                    return -EFAULT;
    	}
    }

    Gentlemen from Nordic, is this good way to read/write over SPI or I am missing something? Can you reference me to the point where I can read about proper SPI communication over nRF9160?

    , did you experience in the past some strange and inconsistent reading/writing ADXL362 registers? Can you share with me your code for accessing (reading/writing) ADXL362 registers?

    Thanks in advance!

    Sincerely,

    Bojan

  • I see you are trying to use the ADXL362 driver. I'm not surprised that you are having issues as I remember having issues with those as well.

    I decided to make my own seperate read and write functions for the SPI peripheral using only spi_tranceive() when reading and using spi_write when writing. See spi.h.

    The code is similar to what is in that function, just remove RX code from your write function and replace spi_tranceive() with spi_write().

    tx.count should be 1 when reading and 2 when writing.

  • Hey, .

    I don't try to use ADXL362 driver. Those are my functions for accessing ADXL362 based on SPIM example. Here is how I finally managed to access (read/write) ADXL362 internal registers:

    int read_adxl362(struct device *spi, const struct spi_config *spi_cfg,
                     u8_t addr, u8_t *data, u32_t num_bytes){
        
        int err = 0;
    
        /* read cmd */
        err = adxl362_access(spi, spi_cfg,
                               ADXL362_READ_CMD, addr, data, num_bytes);
        if (err) {
                printk("Error during SPI read\n");
                return -EIO;
        }
    
        return 0;       
    }
    
    int write_adxl362(struct device *spi, const struct spi_config *spi_cfg,
                      u8_t addr, u8_t *data, u32_t num_bytes){
    
        int err = 0;
        /* write cmd */
        err = adxl362_access(spi, spi_cfg,
                               ADXL362_WRITE_CMD, addr, data, num_bytes);
        if (err) {
                printk("Error during SPI write\n");
                return -ENXIO;
        }
    
        return 0;
    }
    
    int adxl362_access(struct device *spi, const struct spi_config *spi_cfg,
    			    u8_t cmd, u8_t addr, void *data, size_t len)
    {
    
    	int err;
    	static u8_t tx_buffer[2];
    	//static u8_t rx_buffer[1];
            tx_buffer[0] = cmd;
            tx_buffer[1] = addr;
    
    	const struct spi_buf tx_buf = {
    		.buf = tx_buffer,
    		.len = sizeof(tx_buffer)
    	};
    	const struct spi_buf_set tx = {
    		.buffers = &tx_buf,
    		.count = 1
    	};
    
    	struct spi_buf rx_buf = {
    		.buf = data,
    		.len = len + 2,
    	};
    	const struct spi_buf_set rx = {
    		.buffers = &rx_buf,
    		.count = 1
    	};
    
    	err = spi_transceive(spi_dev, spi_cfg, &tx, &rx);
    	if (err) {
    		printk("SPI error: %d\n", err);
    	}
    
            return err;
    }

    As you can see, I have a single rx and single tx buffer which seems to be logical. spi_write() function is actually spi_transcieve() with NULL argument on &rx place.

    Cheers,

    Bojan.

Related