I am new in the world of microcontrollers, so maybe I am just missing some basic detail.

I am using an Atmel SAML21J board (as master) and for that I am trying to connect a Kionix sensor (as slave) via SPI connection, but unfortunately I cannot receive any data from the sensor. The connection is established on the EXT1 of the board (I also tried it on EXT2 without any success either) and it is configured as a new Atmel Start project (IDE: Atmel Studio 7):

- SPI_SS_A - PA05
- SPI_SCK - PA07

(Of course VCC and Ground is also connected and the LED on the sensor is lit up. So, with this configuration I am using SERCOM0 for communication) Clocks:

- Core: 4MHz
- Slow: 400kHz

The Datasheet of the sensor says that MSB first, also CPOL and CPHA should be set to 0-0, and I set the SS as a digital output with initial high level, so before every data write or read I should set the level of SS to low and then back to high. Receiver buffer is enabled, and the baud rate is 50000.

So the source code:

#include <stdio.h>
#include <atmel_start.h>
#include <atmel_start_pins.h>
#include <kx_registers.h>

struct io_descriptor *accelerometer_spi_io;

void SPI_init(void)
    spi_m_sync_get_io_descriptor(&SPI_0, &accelerometer_spi_io);

int main(void)
    uint8_t read_buffer = 0x00;
    uint8_t write_buffer[2] = {0x00, 0x00};


    // Just trying to read the value of WHO_AM_I register of the sensor
    gpio_set_pin_level(SS_EXT1, false); // Set SS to low
    read_buffer = WHO_I_AM + 128; // In case of reading the first bit of the first byte(register address) should be set to 1
    io_read(accelerometer_spi_io, &read_buffer, 1); // And it initialized read_buffer to 0x00
    gpio_set_pin_level(SS_EXT1, true); // Set SS back to high

    // Trying to write some data in ODCNTL register
    gpio_set_pin_level(SS_EXT1, false);
    write_buffer[0] = ODCNTL; // If I understood correctly in case of writing the first byte should be the address of the register, the second should be the data to be transferred toward that register
    write_buffer[1] = 0x01;
    io_write(accelerometer_spi_io, (uint8_t *)write_buffer, 2);
    gpio_set_pin_level(SS_EXT1, true);

    // Read ODCNTL data
    read_buffer = ODCNTL + 128;
    gpio_set_pin_level(SS_EXT1, false);
    io_read(accelerometer_spi_io, &read_buffer, 1); // And it initialized read_buffer to 0x00 again
    gpio_set_pin_level(SS_EXT1, true);

    while (1) {
        // Do data streaming after the configuration

The question is that: What do I miss? Or am I using the built in io_write and io_read functions properly? Any tips or suggestions are appreciated. Thank you in advance for all your help.

  • \$\begingroup\$ Where do you set the data direction registers? \$\endgroup\$ – Lundin Jul 5 '19 at 11:42
  • \$\begingroup\$ Where do you set the baudrate to 50000? \$\endgroup\$ – Lundin Jul 5 '19 at 11:45
  • \$\begingroup\$ When creating a new Atmel start project you can specify for certain PINs which is an output and what is its initial level (I only specified the SS for digital output with initial level high, the other SPI related PINs are set by default when importing the SPI driver). So I think I do not need to set it here too \$\endgroup\$ – BLaszlo Jul 5 '19 at 11:46
  • \$\begingroup\$ And don't forget the Atmel BS registers PINCFG and PMUX... \$\endgroup\$ – Lundin Jul 5 '19 at 11:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.