SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By emoney
#179004
Hello,
I am trying to get this HMC5883l magnetometer to work, but I think I'm having trouble with my TWI read command. I seem to get some data back, however, when moving the magnetometer around it does not change at all. Below is my code. I would appreciate any help. Thank you in advanced.
Code: Select all
/**
 * Magnetometer HMC5883L I2C example program
 */

#include <asf.h>
#include <stdio.h>
#include <conf_usart_serial.h>
#include <conf_twim.h>
#include <twi_master.h>
#include "interrupt.h"
#include "conf_board.h"
#include "user_board.h"
#include "sysclk.h"
#include "conf_clock.h"
#include "ioport.h"

#define TWI_MASTER			TWIC
#define TWI_MASTER_PORT		PORTC
#define TWI_SPEED			100000
#define TWI_MASTER_ADDR		0x50
#define	TWI_SLAVE_ADDR		0x1E	
#define SLAVE_LENGTH		6	

#define DATA_LENGTH			8
#define MSG_LENGTH			3
#define RCV_LENGTH			6

TWI_Slave_t slave;
//uint8_t data_received[6];
const uint8_t slave_mem_addr[SLAVE_LENGTH] = {
	0x03,
};

uint8_t CRA_Reg[MSG_LENGTH] = {0x3C, 0x00, 0x70};		// 8-average, 15Hz default, normal mode
uint8_t CRB_Reg[MSG_LENGTH] = {0x3C, 0x01, 0xA0};		// Gain = 5
uint8_t Mode[MSG_LENGTH] = {0x3C, 0x02, 0x00};			// Continuous measurement mode
uint8_t StartPoint[2] = {0x3C, 0x03};
uint8_t ReadNow[1] = {0x3D};						// Read all 6 bytes
		
uint8_t data_received[RCV_LENGTH] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
	
	
	twi_package_t Write_CRA = {
		.chip			= TWI_SLAVE_ADDR,				// slave bus address
	//	.addr			= 0x00,
	//	.addr_length	= sizeof (uint8_t),
		.buffer			= (void *)CRA_Reg,				// transfer data source buffer
		.length			= sizeof(CRA_Reg),				// transfer data size bytes
		.no_wait		= false
	};
	
	twi_package_t Write_CRB = {

		.chip			= TWI_SLAVE_ADDR,				// slave bus address
	//	.addr			= 0x01,
	//	.addr_length	= sizeof (uint8_t),
		.buffer			= (void *)CRB_Reg,				// transfer data source buffer
		.length			= sizeof(CRB_Reg),				// transfer data size bytes
		.no_wait		= false
	};
	
	twi_package_t Write_Mode = {
		.chip			= TWI_SLAVE_ADDR,				// slave bus address
	//	.addr			= 0x02,
	//	.addr_length	= sizeof (uint8_t),
		.buffer			= (void *)Mode,					// transfer data source buffer
		.length			= sizeof(Mode),					// transfer data size bytes
		.no_wait		= false
	};
	
	
	twi_package_t Read_Now = {
		.chip			= TWI_SLAVE_ADDR,				// slave bus address
		//	.addr			= 0x02,
		//	.addr_length	= sizeof (uint8_t),
		.buffer			= (void *)ReadNow,				// transfer data source buffer
		.length			= sizeof(ReadNow),				// transfer data size bytes
		.no_wait		= false
	};

	twi_package_t Read_All = {
		.chip			= TWI_SLAVE_ADDR,				// slave bus address
		.addr[0]		= 0x03,
		.addr_length	= sizeof (uint8_t),
		.buffer			= data_received,				// transfer data destination
		.length			= 6,							// transfer data size bytes
		.no_wait		= false
	};
	
	twi_package_t Start_Point = {
		.chip			= TWI_SLAVE_ADDR,				// slave bus address
		//.addr			= 0x03,
		//.addr_length	= sizeof (uint8_t),
		.buffer			= (void *)StartPoint,				// transfer data source buffer
		.length			= sizeof(StartPoint),							// transfer data size bytes
		.no_wait		= false
	};
		
	
twi_options_t m_options = {
	.speed		= TWI_SPEED,
	.chip		= TWI_MASTER_ADDR,
	
};


// *******************************************************
// 	----------------- INITIALIZE UART ----------------------
// 	*******************************************************
		static void uartrx_init(void)
		{
			usart_rx_enable(UART_Data);
			usart_tx_enable(UART_Data);
			usart_set_rx_interrupt_level(UART_Data, USART_RXCINTLVL_MED_gc);
		}


void twi_setup()
{
	
	TWI_MASTER_PORT.PIN0CTRL = PORT_OPC_WIREDANDPULL_gc;		// set SDA/SCL pins for master TWI to be wired and enable pull-up
	TWI_MASTER_PORT.PIN1CTRL = PORT_OPC_WIREDANDPULL_gc;
	irq_initialize_vectors();
		
	sysclk_enable_peripheral_clock(&TWI_MASTER);
	twi_master_init(&TWI_MASTER, &m_options);
	twi_master_enable(&TWI_MASTER);
 	
	cpu_irq_enable();
	
 }	
 

int main (void)
{
	sysclk_init();	
	board_init();
	twi_setup();
	uartrx_init();
	
	delay_ms(100);
	
	static usart_rs232_options_t UART1_OPTIONS = {
		.baudrate = UART1_BAUDRATE,
		.charlength = UART1_CHAR_LENGTH,
		.paritytype = UART1_PARITY,
		.stopbits = UART1_STOP_BIT
	};
	
	usart_init_rs232(UART_Data, &UART1_OPTIONS);

	UART_Data_.CTRLB |= USART_CLK2X_bm;												// 2x clock mode.  Apparently can't set until init
	usart_set_baudrate(UART_Data, UART1_OPTIONS.baudrate, sysclk_get_per_hz());
	//***************************

		twi_master_write(&TWI_MASTER, &Write_CRA);
		twi_master_write(&TWI_MASTER, &Write_CRB);
		twi_master_write(&TWI_MASTER, &Write_Mode);
// 
		while(1)
		{
 			delay_ms(400);

		 twi_master_write(&TWI_MASTER, &Read_Now);	
		 
		 twi_master_read(&TWI_MASTER, &Read_All);		
		 				
  		 usart_serial_write_packet(UART_Data, data_received, 6);	// transmit recv_data over UART

 			
   		}

}