Trying to use Ext 1 and Ext 3 on ATSAMR21G18 board.

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

I am trying to use Ext 1 and Ext 3 on ATSAMR21G18 board. EXT 1 has an Inertial measurement unit (IMU) connected through SPI and Ext 3 has OLED1 Xplained pro (also through SPI). I need to get real time data from the IMU and display it on the OLED. I am using Atmel boards for the first time. And I am stuck because, if I try to access one device through SPI the other doesn't work and vice versa. I tried using separate select lines, still not working. Here's my code. 


#include <asf.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <stdio_ext.h>

#define SLAVE_SELECT_PIN EXT1_PIN_SPI_SS_0
#define BUF_LENGTH 2
#define ZERO 0x00
#define X_RATE_ADDR 0x04
#define OLED_SS_PIN EXT3_PIN_15
#define LCD_WIDTH_PIXELS 128
#define LCD_HEIGHT_PIXELS 32

void configure_spi_master(bool flag);
void read_command_for_imu (void);

struct spi_module spi_master_instance;
struct spi_slave_inst imu;
struct spi_slave_inst oled;
static uint16_t read_buffer = 0;
static uint16_t dummy_read;

void configure_spi_master(bool flag)
{
	struct spi_config config_spi_master;
	struct spi_slave_inst_config slave_imu_config;
	struct spi_slave_inst_config slave_oled_config;
	spi_get_config_defaults(&config_spi_master);
	spi_master_instance.receiver_enabled = true;

	/* Configure and initialize software device instance of peripheral slave IMU */
	spi_slave_inst_get_config_defaults(&slave_imu_config);
	slave_imu_config.ss_pin = SLAVE_SELECT_PIN;
	config_spi_master.transfer_mode = SPI_TRANSFER_MODE_3;
	spi_attach_slave(&imu, &slave_imu_config);

	/* Configure, initialize and enable SERCOM SPI module */
	config_spi_master.mux_setting = EXT1_SPI_SERCOM_MUX_SETTING;
	/* Configure pad 0 for data in */
	config_spi_master.pinmux_pad0 = EXT1_SPI_SERCOM_PINMUX_PAD0;
	/* Configure pad 1 as unused */
	config_spi_master.pinmux_pad1 = PINMUX_UNUSED;
	/* Configure pad 2 for data out */
	config_spi_master.pinmux_pad2 = EXT1_SPI_SERCOM_PINMUX_PAD2;
	/* Configure pad 3 for SCK */
	config_spi_master.pinmux_pad3 = EXT1_SPI_SERCOM_PINMUX_PAD3;
	spi_init(&spi_master_instance, EXT1_SPI_MODULE, &config_spi_master);

	/* Configure and initialize software device instance of peripheral slave OLED */
	spi_slave_inst_get_config_defaults(&slave_oled_config);
	slave_oled_config.ss_pin = OLED_SS_PIN;
	config_spi_master.transfer_mode = SPI_TRANSFER_MODE_3;
	spi_attach_slave(&oled, &slave_oled_config);

	/* Configure, initialize and enable SERCOM SPI module */
	config_spi_master.mux_setting = EXT3_SPI_SERCOM_MUX_SETTING;
	/* Configure pad 0 for data in */
	config_spi_master.pinmux_pad0 = EXT3_SPI_SERCOM_PINMUX_PAD0;
	/* Configure pad 1 as unused */
	config_spi_master.pinmux_pad1 = PINMUX_UNUSED;
	/* Configure pad 2 for data out */
	config_spi_master.pinmux_pad2 = EXT3_SPI_SERCOM_PINMUX_PAD2;
	/* Configure pad 3 for SCK */
	config_spi_master.pinmux_pad3 = EXT3_SPI_SERCOM_PINMUX_PAD3;
	spi_init(&spi_master_instance, EXT3_SPI_MODULE, &config_spi_master);
	spi_enable(&spi_master_instance);

}

void read_command_for_imu (void)
{
	spi_select_slave(&spi_master_instance, &imu, true);
	while (!spi_is_ready_to_write(&spi_master_instance)) {
	}
	spi_write(&spi_master_instance, X_RATE_ADDR);
   	while (!spi_is_ready_to_write(&spi_master_instance)) {
   	}
   	spi_write(&spi_master_instance, ZERO);
   	while (!spi_is_write_complete(&spi_master_instance)) {
   	}
 	while (!spi_is_ready_to_read(&spi_master_instance)) {
 	}
	spi_read(&spi_master_instance, &read_buffer);
	spi_select_slave(&spi_master_instance, &imu, false);

	spi_select_slave(&spi_master_instance, &imu, true);
	while (!spi_is_ready_to_write(&spi_master_instance)) {
	}
	spi_write(&spi_master_instance, ZERO);
	while (!spi_is_ready_to_write(&spi_master_instance)) {
	}
	spi_write(&spi_master_instance, ZERO);
	while (!spi_is_write_complete(&spi_master_instance)) {
	}
	while (!spi_is_ready_to_read(&spi_master_instance)) {
	}
	spi_read(&spi_master_instance, &read_buffer);
	spi_select_slave(&spi_master_instance, &imu, false);
	return;
}

int main(void)
{
    /* Initialize the SAM system */

	system_init();
	configure_spi_master(true);
	gfx_mono_init();
	gfx_mono_draw_filled_rect(0,0,LCD_WIDTH_PIXELS,LCD_HEIGHT_PIXELS,GFX_PIXEL_SET);

    while (true)
    {
		read_command_for_imu();
	}
}

I need help with this real soon. Quick help will be really appreciated.

Thank you.

Last Edited: Tue. Apr 19, 2016 - 09:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This has nothing to do with Studio or AVRs. Moving the thread to the "Compilers, Assembers, Linkers and General Programming (ARM-related)" forum for now.

 

And by the way pressure to respond to your thread usually has the opposite effect here, remember we are all volunteers. wink

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can't reuse the spi_master_instance like that, in this case you need two master instances (you are using two SPI buses on two different sercom instances so that makes sense I think).

/Lars