From 98836489a23de7083f673fd8c2e73facae775625 Mon Sep 17 00:00:00 2001 From: Joseph Coffland Date: Sat, 2 Jan 2016 18:24:58 -0800 Subject: [PATCH] Complete TMC2660 driver --- src/tmc2660.c | 105 ++++++++++++++++++++++++++++++++++++++------------ src/tmc2660.h | 3 ++ 2 files changed, 84 insertions(+), 24 deletions(-) diff --git a/src/tmc2660.c b/src/tmc2660.c index c6a8164..502d5e9 100644 --- a/src/tmc2660.c +++ b/src/tmc2660.c @@ -49,6 +49,10 @@ typedef enum { } spi_state_t; typedef struct { + tmc2660_state_t state; + uint8_t reset; + uint8_t reg; + uint16_t mstep; uint8_t status; uint32_t regs[5]; @@ -64,9 +68,7 @@ static const uint32_t reg_addrs[] = { }; -static volatile tmc2660_state_t state; static volatile uint8_t driver; -static volatile uint8_t reg; static tmc2660_driver_t drivers[TMC2660_NUM_DRIVERS]; static volatile spi_state_t spi_state; @@ -97,8 +99,7 @@ static void spi_cs(int driver, int enable) { static void spi_send() { - // Flush any status errors - // TODO check errors + // Flush any status errors (TODO check for errors) uint8_t x = SPIC.STATUS; x = x; @@ -107,29 +108,45 @@ static void spi_send() { else spi_in = spi_in << 8 | SPIC.DATA; // Write - if (spi_byte < 3) - SPIC.DATA = 0xff & (spi_out >> ((2 - spi_byte++) * 8)); + if (spi_byte < 3) SPIC.DATA = 0xff & (spi_out >> ((2 - spi_byte++) * 8)); else spi_byte = 0; } void spi_next() { + tmc2660_driver_t *drv = &drivers[driver]; + uint16_t spi_delay = 1; + switch (spi_state) { case SPI_STATE_SELECT: // Select driver spi_cs(driver, 1); // Next state - TMC2660_TIMER.PER = 4; + spi_delay = 2; spi_state = SPI_STATE_WRITE; break; case SPI_STATE_WRITE: - spi_out = reg_addrs[reg] | drivers[driver].regs[reg]; + switch (drv->state) { + case TMC2660_STATE_CONFIG: + spi_out = reg_addrs[drv->reg] | drv->regs[drv->reg]; + break; + + case TMC2660_STATE_MONITOR: + spi_out = reg_addrs[TMC2660_DRVCONF] | drv->regs[TMC2660_DRVCONF]; + break; + + case TMC2660_STATE_RESET: + spi_out = + reg_addrs[TMC2660_CHOPCONF] | (drv->regs[TMC2660_CHOPCONF] & 0xffff0); + break; + } + spi_send(); // Next state - TMC2660_TIMER.PER = 16; + spi_delay = 3; spi_state = SPI_STATE_READ; break; @@ -137,22 +154,41 @@ void spi_next() { // Deselect driver spi_cs(driver, 0); - // Read response - drivers[driver].mstep = (spi_in >> 14) & 0x3ff; - drivers[driver].status = spi_in >> 4; + switch (drv->state) { + case TMC2660_STATE_CONFIG: + if (++drv->reg == 5) { + drv->state = TMC2660_STATE_MONITOR; + drv->reg = 0; + } + break; + + case TMC2660_STATE_MONITOR: + // Read response + drv->mstep = (spi_in >> 14) & 0x3ff; + drv->status = spi_in >> 4; + + if (drv->reset) { + drv->state = TMC2660_STATE_RESET; + drv->reset = 0; + + } else if (++driver == TMC2660_NUM_DRIVERS) { + driver = 0; + spi_delay = 500; + break; + } + break; + + case TMC2660_STATE_RESET: + drv->state = TMC2660_STATE_CONFIG; + break; + } - // Next state + // Next state (delay set above) spi_state = SPI_STATE_SELECT; - - if (++reg == 5) { - reg = 0; - if (++driver == TMC2660_NUM_DRIVERS) driver = 0; - - TMC2660_TIMER.PER = 10; - - } else TMC2660_TIMER.PER = 2; break; } + + TMC2660_TIMER.PER = spi_delay; } @@ -168,13 +204,15 @@ ISR(TCC1_OVF_vect) { void tmc2660_init() { // Reset state - state = TMC2660_STATE_CONFIG; spi_state = SPI_STATE_SELECT; - driver = reg = spi_byte = 0; + driver = spi_byte = 0; memset(drivers, 0, sizeof(drivers)); // Configure motors for (int i = 0; i < TMC2660_NUM_DRIVERS; i++) { + drivers[i].state = TMC2660_STATE_CONFIG; + drivers[i].reg = 0; + drivers[i].regs[TMC2660_DRVCTRL] = 0; drivers[i].regs[TMC2660_CHOPCONF] = 0x14557; drivers[i].regs[TMC2660_SMARTEN] = 0x8202; @@ -214,7 +252,7 @@ void tmc2660_init() { // Configure SPI PR.PRPC &= ~PR_SPI_bm; // Disable power reduction - SPIC.CTRL = SPI_ENABLE_bm | SPI_DORD_bm | SPI_MASTER_bm | SPI_MODE_3_gc | + SPIC.CTRL = SPI_ENABLE_bm | SPI_MASTER_bm | SPI_MODE_3_gc | SPI_PRESCALER_DIV128_gc; // enable, big endian, master, mode 3, clock/128 PORTC.REMAP = PORT_SPI_bm; // Swap SCK and MOSI SPIC.INTCTRL = SPI_INTLVL_MED_gc; // interupt level @@ -235,3 +273,22 @@ uint8_t tmc2660_status(int driver) { uint16_t tmc2660_step(int driver) { return drivers[driver].mstep; } + + +void tmc2660_reset(int driver) { + drivers[driver].reset = 1; +} + + +int tmc2660_ready(int driver) { + return + drivers[driver].state == TMC2660_STATE_MONITOR && !drivers[driver].reset; +} + + +int tmc2660_all_ready() { + for (int i = 0; i < TMC2660_NUM_DRIVERS; i++) + if (!tmc2660_ready(i)) return 0; + + return 1; +} diff --git a/src/tmc2660.h b/src/tmc2660.h index 8a0ff88..ad6f2d2 100644 --- a/src/tmc2660.h +++ b/src/tmc2660.h @@ -57,6 +57,9 @@ void tmc2660_init(); uint8_t tmc2660_status(int driver); uint16_t tmc2660_step(int driver); +void tmc2660_reset(int driver); +int tmc2660_ready(int driver); +int tmc2660_all_ready(); #define TMC2660_DRVCTRL 0 #define TMC2660_DRVCTRL_ADDR (0UL << 18) -- 2.27.0