diff options
Diffstat (limited to 'src/atsamd/i2c.c')
-rw-r--r-- | src/atsamd/i2c.c | 34 |
1 files changed, 17 insertions, 17 deletions
diff --git a/src/atsamd/i2c.c b/src/atsamd/i2c.c index 03a75f11..89b190fa 100644 --- a/src/atsamd/i2c.c +++ b/src/atsamd/i2c.c @@ -1,5 +1,6 @@ // i2c support on samd // +// Copyright (C) 2019 Florian Heilmann <Florian.Heilmann@gmx.net> // Copyright (C) 2018-2019 Kevin O'Connor <kevin@koconnor.net> // // This file may be distributed under the terms of the GNU GPLv3 license. @@ -13,22 +14,14 @@ #define I2C_FREQ 100000 static void -i2c_init(void) +i2c_init(uint32_t bus, SercomI2cm *si) { - static int have_run_init; - if (have_run_init) + static int have_run_init[8]; + if (have_run_init[bus]) return; - have_run_init = 1; - - // Setup clock - enable_pclock(SERCOM3_GCLK_ID_CORE, ID_SERCOM3); - - // Configure SDA, SCL pins - gpio_peripheral(GPIO('A', 22), 'C', 0); - gpio_peripheral(GPIO('A', 23), 'C', 0); + have_run_init[bus] = 1; // Configure i2c - SercomI2cm *si = &SERCOM3->I2CM; si->CTRLA.reg = 0; uint32_t areg = (SERCOM_I2CM_CTRLA_LOWTOUTEN | SERCOM_I2CM_CTRLA_INACTOUT(3) @@ -36,7 +29,7 @@ i2c_init(void) | SERCOM_I2CM_STATUS_MEXTTOUT | SERCOM_I2CM_CTRLA_MODE(5)); si->CTRLA.reg = areg; - uint32_t freq = get_pclock_frequency(SERCOM3_GCLK_ID_CORE); + uint32_t freq = sercom_get_pclock_frequency(bus); uint32_t baud = (freq/I2C_FREQ - 10 - freq*TIME_RISE/1000000000) / 2; si->BAUD.reg = baud; si->CTRLA.reg = areg | SERCOM_I2CM_CTRLA_ENABLE; @@ -52,10 +45,17 @@ i2c_init(void) struct i2c_config i2c_setup(uint32_t bus, uint32_t rate, uint8_t addr) { - if (bus) +#ifdef SERCOM7 + if (bus > 7) +#else + if (bus > 5) +#endif shutdown("Unsupported i2c bus"); - i2c_init(); - return (struct i2c_config){ .addr=addr<<1 }; + Sercom *sercom = sercom_enable_pclock(bus); + sercom_i2c_pins(bus); + SercomI2cm *si = &sercom->I2CM; + i2c_init(bus, si); + return (struct i2c_config){ .si=si, .addr=addr<<1 }; } static void @@ -97,7 +97,7 @@ i2c_stop(SercomI2cm *si) void i2c_write(struct i2c_config config, uint8_t write_len, uint8_t *write) { - SercomI2cm *si = &SERCOM3->I2CM; + SercomI2cm *si = (SercomI2cm *)config.si; i2c_start(si, config.addr); while (write_len--) i2c_send_byte(si, *write++); |