/* P9_3.c - Test I2C burst write with DS1337 * * This program initializes the SERCOM1 as I2C and write to * all the time registers of the DS1337. * 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 I2C2_init(void) ; int I2C2_burstWrite(char saddr, char maddr, int byteCount, char* data); int main (void) { /* 00 01 02 03 04 05 06 */ char timeDateToSet[15] = {0x55, 0x58, 0x10, 0x07, 0x26, 0x11, 0x16, 0}; /* 2016 November 26, Saturday, 10:58:55 */ I2C2_init(); I2C2_burstWrite(SLAVE_ADDR, 0, 7, timeDateToSet); while (1) { } } void I2C2_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 */ } /* Use burst write to write multiple bytes to consecutive locations * burst write: S-(saddr+w)-ACK-maddr-ACK-data-ACK-data-ACK-...-data-ACK-P */ int I2C2_burstWrite(char saddr, char maddr, int byteCount, 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 */ for (; byteCount > 0; byteCount--) { 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; }