/* P9_1.c - Test I2C byte write with DS1337 * * This program initializes the SERCOM1 as I2C and sends a * command to the DS1337 to turn on the 1 Hz output. * 1 Hz output is an open-drain output. It needs a pull-up * to observe the signal. * PA16 = SDA, PA17 = SCL * No errors or acknowledgement are checked. * * Tested with Atmel Studio 7 v7.0.1006 and Keil MDK-ARM v5.21a. */ #include "samd21.h" unsigned char* ARRAY_PORT_PINCFG0 = (unsigned char*)®_PORT_PINCFG0; unsigned char* ARRAY_PORT_PMUX0 = (unsigned char*)®_PORT_PMUX0; #define SLAVE_ADDR 0x68 /* 1101 000. DS1337 */ void I2C_init(void) ; int I2C_byte_write(unsigned char saddr, unsigned char maddr, unsigned char data); int main (void) { I2C_init(); I2C_byte_write(SLAVE_ADDR, 0x0E, 0); /* write 0 to location 0x0E */ while (1) { } } void I2C_init(void) { REG_PM_APBCMASK |= 0x00000008; /* SERCOM1 bus clock */ GCLK->CLKCTRL.reg = 0x4015; /* SERCOM1 core clock */ ARRAY_PORT_PINCFG0[16] |= 1; /* allow pmux to set PA16 pin configuration */ ARRAY_PORT_PINCFG0[17] |= 1; /* allow pmux to set PA17 pin configuration */ ARRAY_PORT_PMUX0[8] = 0x22; /* PA16 = SDA, PA17 = SCL */ REG_SERCOM1_I2CM_CTRLA = 1; /* reset SERCOM1 */ while (REG_SERCOM1_I2CM_CTRLA & 1) {} /* wait for reset to complete */ REG_SERCOM1_I2CM_CTRLA = 0x14; /* master mode */ REG_SERCOM1_I2CM_BAUD = 0; /* 1MHz main clock -> ~100KHz I2C clock */ REG_SERCOM1_I2CM_CTRLA |= 2; /* enable SERCOM1 */ REG_SERCOM1_I2CM_STATUS = 0x10; /* force idle */ } int I2C_byte_write(unsigned char saddr, unsigned char maddr, unsigned char data) { while((REG_SERCOM1_I2CM_STATUS & 0x30) != 0x10) ; /* wait until idle */ REG_SERCOM1_I2CM_ADDR = saddr << 1; /* send address */ while((REG_SERCOM1_I2CM_INTFLAG & 1) == 0); /* wait until saddr sent */ REG_SERCOM1_I2CM_DATA = maddr; /* send memory address */ while((REG_SERCOM1_I2CM_INTFLAG & 1) == 0); /* wait until maddr sent */ REG_SERCOM1_I2CM_DATA = data; /* send data */ while((REG_SERCOM1_I2CM_INTFLAG & 1) == 0); /* wait until data sent */ REG_SERCOM1_I2CM_CTRLB |= 0x30000; /* issue a stop */ return 0; }