From 4f871e6291317b68d7a7bc5796d0bc5b96036f8f Mon Sep 17 00:00:00 2001 From: Jake <jake.read@cba.mit.edu> Date: Sat, 17 Feb 2018 15:57:34 -0500 Subject: [PATCH] time-ticker and step-ticker running --- circuit/mkstepper/eagle.epf | 53 +------- embedded/README.md | 67 +++++++++- .../.vs/mkstepper-v011/v14/.atsuo | Bin 73728 -> 78336 bytes .../mkstepper-v011/Debug/Makefile | 10 +- .../mkstepper-v011/Debug/makedep.mk | 2 +- .../mkstepper-v011/mkstepper-v011/hardware.h | 4 +- embedded/mkstepper-v011/mkstepper-v011/main.c | 124 ++++++++++++++++-- .../mkstepper-v011/mkstepper-v011.cproj | 4 +- .../mkstepper-v011/mkstepper-v011/spiport.h | 2 + .../mkstepper-v011/mkstepper-v011/tmc26.c | 8 +- .../mkstepper-v011/mkstepper-v011/tmc26.h | 7 +- 11 files changed, 203 insertions(+), 78 deletions(-) diff --git a/circuit/mkstepper/eagle.epf b/circuit/mkstepper/eagle.epf index 1a2929f..286d8c5 100644 --- a/circuit/mkstepper/eagle.epf +++ b/circuit/mkstepper/eagle.epf @@ -34,10 +34,10 @@ UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/sym.lbr" [Win_1] Type="Board Editor" Loc="0 0 1919 1016" -State=3 +State=1 Number=2 File="mkstepper.brd" -View="19.1941 22.2824 34.6011 26.8063" +View="-9.82612 13.6225 69.6706 36.9648" WireWidths=" 0.0762 0.1016 0.127 0.4064 0.15 0.2032 0.508 1.016 0.254 0.2 2.54 0.1524 1.27 0.8128 0.6096 0.3048" PadDiameters=" 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0 0.55 0.45 0.425" PadDrills=" 0.2 0.25 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6 0.35 0.3" @@ -78,54 +78,6 @@ PadsSameType=0 Layer=16 [Win_2] -Type="Schematic Editor" -Loc="-1928 -8 -9 1008" -State=1 -Number=1 -File="mkstepper.sch" -View="37.2579 86.1909 222.169 205.063" -WireWidths=" 0.0762 0.1016 0.127 0.15 0.2 0.2032 0.254 0.3048 0.4064 0.508 0.6096 0.8128 1.016 1.27 2.54 0.1524" -PadDiameters=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0" -PadDrills=" 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.65 0.7 0.75 0.8 0.85 0.9 1 0.6" -ViaDiameters=" 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1 1.05 1.1 1.15 1.2 1.3 0" -ViaDrills=" 0.2 0.25 0.3 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 1 0.35" -HoleDrills=" 0.2 0.25 0.3 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 1 0.35" -TextSizes=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.9304 2.1844 2.54 3.81 5.08 6.4516 1.778" -PolygonSpacings=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 5.08 6.4516 1.27" -PolygonIsolates=" 0.254 0.3048 0.4064 0.6096 0.8128 1.016 1.27 1.4224 1.6764 1.778 1.9304 2.1844 2.54 3.81 6.4516 0" -MiterRadiuss=" 0.254 0.3175 0.635 1.27 2.54 1 2 2.5 5 7.5 10 0" -DimensionWidths=" 0 0.127 0.254 0.1 0.26 0.13" -DimensionExtWidths=" 0.127 0.254 0.1 0.13 0.26 0" -DimensionExtLengths=" 1.27 2.54 1 2 3 0" -DimensionExtOffsets=" 1.27 2.54 1 2 3 0" -SmdSizes=" 0.3048 0.1524 0.4064 0.2032 0.6096 0.3048 0.8128 0.4064 1.016 0.508 1.27 0.6604 1.4224 0.7112 1.6764 0.8128 1.778 0.9144 1.9304 0.9652 2.1844 1.0668 2.54 1.27 3.81 1.9304 5.08 2.54 6.4516 3.2512 1.27 0.635" -WireBend=0 -WireBendSet=31 -WireCap=1 -MiterStyle=0 -PadShape=0 -ViaShape=1 -PolygonPour=0 -PolygonRank=0 -PolygonThermals=1 -PolygonOrphans=0 -TextRatio=8 -DimensionUnit=1 -DimensionPrecision=2 -DimensionShowUnit=0 -PinDirection=3 -PinFunction=0 -PinLength=2 -PinVisible=3 -SwapLevel=0 -ArcDirection=0 -AddLevel=2 -PadsSameType=0 -Layer=91 -Views=" 1: 37.2579 86.1909 222.169 205.063" -Sheet="1" - -[Win_3] Type="Control Panel" Loc="0 0 1919 1016" State=1 @@ -135,4 +87,3 @@ Number=0 Screen="3840 1080" Window="Win_1" Window="Win_2" -Window="Win_3" diff --git a/embedded/README.md b/embedded/README.md index f6becb0..5ed8e37 100644 --- a/embedded/README.md +++ b/embedded/README.md @@ -459,4 +459,69 @@ So, here's the plan: OK, ENOUGH CHAT amirite? Let's get down to bones and write a timer. -Er, first I'm going to wrap these C bits up nicely and commit. \ No newline at end of file +## Timers and Interrupts + +My first sad discovery is that with a 32.768kHz clock source for the Real Time Counter, the best I can do is 30us clock intervals. I should have known! haha. I would like to run the time-incrementing on this clock. I can either run a faster timer and then try to calibrate / sync them ... sounds tricky. Or I can just use a faster clock and commit to putting a reliable crystal on the next board, for ~12MHz source (which I'm still struggling to figure out how to make this chip actually chooch at 150MHz?). + +I can alternately just run the step ticker at 30us. + +In either case, I'm not making any progress just sitting here. + +OK: for speed I'm going to use the SysTick timer to do time counting (i.e updating a micros() type function) and then drive another timer at 10us or so to check for steps. + +Here's some code that's working. I originally tried this with a 16 bit timer, to no luck, and I have no idea why. + +```C + +// from MAIN: + // Timers: in 32 bit mode we pair two - obscure datasheet reading later, they pair in a predefined way: 0 with 1... + // a word of warning: with the same code, a 16-bit timer was not working. I am mystified. + TC0->COUNT32.CTRLA.bit.ENABLE = 0; + TC1->COUNT32.CTRLA.bit.ENABLE = 0; + // unmask clocks + MCLK->APBAMASK.reg |= MCLK_APBAMASK_TC0 | MCLK_APBAMASK_TC1; // at 15.8.9 + // generate a gclk + GCLK->GENCTRL[10].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL) | GCLK_GENCTRL_GENEN; + while(GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL(10)); + // ship gclk to their channels + GCLK->PCHCTRL[TC0_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(10); + GCLK->PCHCTRL[TC1_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(10); + // turn on in mode, presync + TC0->COUNT32.CTRLA.reg = TC_CTRLA_MODE_COUNT32 | TC_CTRLA_PRESCSYNC_PRESC; + TC1->COUNT32.CTRLA.reg = TC_CTRLA_MODE_COUNT32 | TC_CTRLA_PRESCSYNC_PRESC; + // allow interrupt to trigger on this event (overflow) + TC0->COUNT32.INTENSET.bit.OVF = 1; + // enable, sync for enable write + TC0->COUNT32.CTRLA.bit.ENABLE = 1; + while(TC0->COUNT32.SYNCBUSY.bit.ENABLE); + TC1->COUNT32.CTRLA.bit.ENABLE = 1; + while(TC0->COUNT32.SYNCBUSY.bit.ENABLE); + // counter is there, can read COUNT, it's not updating, so a clock is probably off. + +// and later, to read COUNT and send to UART + +void SysTick_Handler(void){ + lpcnt ++; + pin_toggle(&stlb); + /* + while(!rb_empty(up1.rbrx)){ + uart_sendchar_buffered(&up1, rb_get(up1.rbrx)); + } + */ + TC0->COUNT32.CTRLBSET.reg = TCC_CTRLBSET_CMD_READSYNC; + uint32_t thecount = TC0->COUNT32.COUNT.reg; + uint8_t onemicro = thecount; + uint8_t twomicro = thecount >> 8; + uint8_t threemicro = thecount >> 16; + uint8_t fourmicro = thecount >> 24; + uart_sendchar_buffered(&up1, onemicro); + uart_sendchar_buffered(&up1, twomicro); + uart_sendchar_buffered(&up1, threemicro); + uart_sendchar_buffered(&up1, fourmicro); + + uart_sendchar_buffered(&up1, lpcnt); + uint8_t stop = TC1->COUNT8.STATUS.bit.STOP; + uart_sendchar_buffered(&up1, stop); +} +``` + diff --git a/embedded/mkstepper-v011/.vs/mkstepper-v011/v14/.atsuo b/embedded/mkstepper-v011/.vs/mkstepper-v011/v14/.atsuo index c07e4635da7580fbeaa3150c81ae549f11bceb7d..942319214ae661d3644c079192eaa8ffdf913868 100644 GIT binary patch delta 2447 zcmZoTz|!!9WkLX>?8ZQ8CcXn2GgT)nzszXDz`)R;HMxqZigD%SuS~%#;tUK7ljUNR zCL1uZu~{-OFi7!Cu449_e3;2_@)u@>SV0B`hW|)_g@J)V2r4GQz`(!*Wy6$+F)%Rv z`~UyH6axbT$n2R63=F~y3=CWh3=E=BIYR~phQI&+{}-7UsLrT8F;LiY8q^duC=D}B z28nOVz`$U}z`$V6z`$U^z`y`<Y{cZJBHod{3=9l@3=9nZ3=9kb3=9l`3=9lG3=9mx z3=9k*3=9mR3=9lm3=9n6Q2Qep7#OB7Ffc?jFfhb0Ffhb2Ffhb1Ffb%QZA)ZeU`S$M zV5pfGn9kA#3ZO5H6?_*|pYe*VAT<ctH6lSl2nrH51_lNWXi&g{j+=pjfscWKVG;ua z11RV~9tQ;-h!%hb9f%DIIuH#CIuH%Qe<x4mQpO*C{7@f(ln+e!34p>6WIYT|;+nv_ zl!1X^83O~uas~#56`Omxk{KuQc(5>oLK>PB8KWkb@&vQUA_-0Y!sE}$2ugoU$f6~@ z0UV&v0fjCsAy59oJBJRI2nKL~d<6<*xXmRJ0h5oom~8$b#KAmC&6$%yoq>Tt6Uo7> z%?u0-cP3Y=`Lk#t3%7%Xf2w&;KEh<c+RebgaBFg<sW*oP0|SE&vci4_28IWdf9m_Q zfD#kJVuSOXj3DQLawJ03u!Zr_<e$o|g0Hl9$MjEKR=~3E8eeDh%oPk11BE9q5|d-x zHu<2~W>GzcWQNW|SI!q?PkhVv|G}Yq5o_`oCI(7QUL+1tVn2CewBF>nFplX$5{$x= zdk*DKuGm*JIY%m#v3PQWw8P{B;t87-v>q@{GIHi*lxARHkVA6y<PxLv;4;O4iDi-- z%j6p4mQ5B17$+M_OHN+DSbdU$Gb^JANWD~y8mK6mT%r)b0?Hhdp#rQ{3=9lalYc6B zbHMTi%#)KuSSD8}`fzAN^A=2e@)u2=$qGU$cq55%lAQBoXBpec4RS{&yD%F}E|Krq zq;-UqLl>GOVWxp>`Jo>`WT3M?VgUK(uV}fb9zzC0=jPA+FGK87Gv`%tb~I`+LqgU< zVe%od6_c|pcm&tzPJddF^gZsSn(eZjIU8?+6)aFqm|S>BYI3`<+GGdo1CtZ17fepD zPM9R)!okVFzyK;7kzH3I<HNzqz`y`1L}B8SzsOwR0F~FE0tY6@2`Z65iHBigpf+Rw z#6V%q2@DJj6QRYUB(%_&%D}(?3Wezm3=F(bu}K>PXERQ+6PPSuWK2{nPYlrj+n|VS z11M#Hk}8S~8v_?JV)d?#!)6DE1I$!OBcLn?s)}Gi!KTc>z;K0W^DkF6xk+{|;G_cb zKTLjeiJd<qDB-e#ba71n>0Cd#Lc#}@#Th5LC{0#UQ)5BS;gd_$E?{Ka$t9*ClRcPq zc)-~glsFg|7&fKc<J^2NP>G4LYBFQUy~+JyHyN)?UU+u(<bw%XP?lZzp~(e5B{oY$ zy<nUy@btju191+lo7c8IU=(YF8Uvzwp^4uGqTeoDi<7-1H`&NcFC%*L!*h|$P<r#k zlfRh7K!qhp7YKu@9Z(Sl)p;-ht}_{`6GCrZ`@o7t6jYpnbb+uNv_f;4>=1QhGT$xE z%{f<&O7kKcF1Xq5LjcR<Mqjhd8#V+mPHu`R*j%vS3L~TR^obIT5tIF_#3#Q$>_7S3 zVXn!KEyX6UU+h2KSDsOEx|S?s?xH1Jiw-a?TE{k7F=5W+xG=-bXHOU#F51Gh=#SK* zZA{A~7�V4J*PztMDGDMs<haYrI2>sbp;zbntEJehZY&g8fw*^}iD<)CMv={ypQ z9iWnHvVk<m<o2IJliwfCpC-u|I{CtDuE~-=1t-t^nLc^_A{9n(08DR`V9cEULXJ_4 zEy~3z#-(Vp!_fxD$%Rt_CeK_fKDp;m>}2($LQu7W5{$yr<>eTQrx!>v-kr`N$0$BI HM`{`X?pgNi delta 2385 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 diff --git a/embedded/mkstepper-v011/mkstepper-v011/Debug/Makefile b/embedded/mkstepper-v011/mkstepper-v011/Debug/Makefile index dcfb0ff..bf46e90 100644 --- a/embedded/mkstepper-v011/mkstepper-v011/Debug/Makefile +++ b/embedded/mkstepper-v011/mkstepper-v011/Debug/Makefile @@ -44,7 +44,7 @@ C_SRCS += \ ../pin.c \ ../ringbuffer.c \ ../spiport.c \ -../tmc2660.c \ +../tmc26.c \ ../uartport.c @@ -61,7 +61,7 @@ main.o \ pin.o \ ringbuffer.o \ spiport.o \ -tmc2660.o \ +tmc26.o \ uartport.o OBJS_AS_ARGS += \ @@ -71,7 +71,7 @@ main.o \ pin.o \ ringbuffer.o \ spiport.o \ -tmc2660.o \ +tmc26.o \ uartport.o C_DEPS += \ @@ -81,7 +81,7 @@ main.d \ pin.d \ ringbuffer.d \ spiport.d \ -tmc2660.d \ +tmc26.d \ uartport.d C_DEPS_AS_ARGS += \ @@ -91,7 +91,7 @@ main.d \ pin.d \ ringbuffer.d \ spiport.d \ -tmc2660.d \ +tmc26.d \ uartport.d OUTPUT_FILE_PATH +=mkstepper-v011.elf diff --git a/embedded/mkstepper-v011/mkstepper-v011/Debug/makedep.mk b/embedded/mkstepper-v011/mkstepper-v011/Debug/makedep.mk index 72ec45f..4599793 100644 --- a/embedded/mkstepper-v011/mkstepper-v011/Debug/makedep.mk +++ b/embedded/mkstepper-v011/mkstepper-v011/Debug/makedep.mk @@ -14,7 +14,7 @@ ringbuffer.c spiport.c -tmc2660.c +tmc26.c uartport.c diff --git a/embedded/mkstepper-v011/mkstepper-v011/hardware.h b/embedded/mkstepper-v011/mkstepper-v011/hardware.h index 60974c4..6db8c08 100644 --- a/embedded/mkstepper-v011/mkstepper-v011/hardware.h +++ b/embedded/mkstepper-v011/mkstepper-v011/hardware.h @@ -13,7 +13,7 @@ #include "uartport.h" #include "spiport.h" #include "ringbuffer.h" -#include "tmc2660.h" +#include "tmc26.h" pin_t stlr; pin_t stlb; @@ -35,4 +35,6 @@ pin_t sg_pin; tmc26_t tmc; +uint32_t overflows; + #endif /* HARDWARE_H_ */ \ No newline at end of file diff --git a/embedded/mkstepper-v011/mkstepper-v011/main.c b/embedded/mkstepper-v011/mkstepper-v011/main.c index 194b8c4..3f20bb1 100644 --- a/embedded/mkstepper-v011/mkstepper-v011/main.c +++ b/embedded/mkstepper-v011/mkstepper-v011/main.c @@ -49,6 +49,9 @@ void clock_init(void){ // (20 then to prescale the DFLL48M such that it runs at 120MHz // generic clock channel 0 is the reference for the DFLL - we'll try to set that up first + + // for 120mhz do https://github.com/adafruit/ArduinoCore-samd/blob/samd51/cores/arduino/startup.c + OSCCTRL->DFLLMUL.reg = OSCCTRL_DFLLMUL_MUL(20) | OSCCTRL_DFLLMUL_CSTEP(12) | OSCCTRL_DFLLMUL_FSTEP(5); while(OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_DFLLMUL){ @@ -75,16 +78,79 @@ void clock_init(void){ MCLK->CPUDIV.reg = MCLK_CPUDIV_DIV_DIV1; } +void ticker_init(void){ + // Timers: in 32 bit mode we pair two - obscure datasheet reading later, they pair in a predefined way: 0 with 1... + // a word of warning: with the same code, a 16-bit timer was not working. I am mystified. + TC0->COUNT32.CTRLA.bit.ENABLE = 0; + TC1->COUNT32.CTRLA.bit.ENABLE = 0; + // unmask clocks + MCLK->APBAMASK.reg |= MCLK_APBAMASK_TC0 | MCLK_APBAMASK_TC1; // at 15.8.9 + // generate a gclk + GCLK->GENCTRL[10].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL) | GCLK_GENCTRL_GENEN; + while(GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL(10)); + // ship gclk to their channels + GCLK->PCHCTRL[TC0_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(10); + GCLK->PCHCTRL[TC1_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(10); + // turn on in mode, presync + TC0->COUNT32.CTRLA.reg = TC_CTRLA_MODE_COUNT32 | TC_CTRLA_PRESCSYNC_PRESC | TC_CTRLA_PRESCALER_DIV16; + TC1->COUNT32.CTRLA.reg = TC_CTRLA_MODE_COUNT32 | TC_CTRLA_PRESCSYNC_PRESC | TC_CTRLA_PRESCALER_DIV16; + // allow interrupt to trigger on this event (overflow) + TC0->COUNT32.INTENSET.bit.OVF = 1; + // enable, sync for enable write + TC0->COUNT32.CTRLA.bit.ENABLE = 1; + while(TC0->COUNT32.SYNCBUSY.bit.ENABLE); + TC1->COUNT32.CTRLA.bit.ENABLE = 1; + while(TC0->COUNT32.SYNCBUSY.bit.ENABLE); + // counter is there, can read COUNT, it's not updating, so a clock is probably off. + // this for counting + overflows = 0; +} + +#define TICKER_SYNC (TC0->COUNT32.CTRLBSET.reg = TCC_CTRLBSET_CMD_READSYNC) +#define TICKER (TC0->COUNT32.COUNT.reg) + +void stepticker_init(void){ + // Timers: in 32 bit mode we pair two - obscure datasheet reading later, they pair in a predefined way: 0 with 1... + // a word of warning: with the same code, a 16-bit timer was not working. I am mystified. + TC2->COUNT32.CTRLA.bit.ENABLE = 0; + TC3->COUNT32.CTRLA.bit.ENABLE = 0; + // unmask clocks + MCLK->APBBMASK.reg |= MCLK_APBBMASK_TC2 | MCLK_APBBMASK_TC3; // at 15.8.9 + // generate a gclk + GCLK->GENCTRL[11].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL) | GCLK_GENCTRL_GENEN; + while(GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL(11)); + // ship gclk to their channels + GCLK->PCHCTRL[TC2_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(11); + GCLK->PCHCTRL[TC3_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(11); + // turn on in mode, presync + TC2->COUNT32.CTRLA.reg = TC_CTRLA_MODE_COUNT32 | TC_CTRLA_PRESCSYNC_PRESC | TC_CTRLA_PRESCALER_DIV64 | TC_CTRLA_CAPTEN0;// | TC_CTRLA_CAPTEN1; + TC3->COUNT32.CTRLA.reg = TC_CTRLA_MODE_COUNT32 | TC_CTRLA_PRESCSYNC_PRESC | TC_CTRLA_PRESCALER_DIV64 | TC_CTRLA_CAPTEN0;// | TC_CTRLA_CAPTEN1; + // do frequency match + TC2->COUNT32.WAVE.reg = TC_WAVE_WAVEGEN_MFRQ; + TC3->COUNT32.WAVE.reg = TC_WAVE_WAVEGEN_MFRQ; + // allow interrupt to trigger on this event (compare channel 0) + TC2->COUNT32.INTENSET.bit.MC0 = 1; + TC2->COUNT32.INTENSET.bit.MC1 = 1; // don't know why, but had to turn this on to get the interrupts + // set period + while(TC2->COUNT32.SYNCBUSY.bit.CC0); + TC2->COUNT32.CC[0].reg = 11; + // enable, sync for enable write + TC2->COUNT32.CTRLA.bit.ENABLE = 1; + while(TC2->COUNT32.SYNCBUSY.bit.ENABLE); + TC3->COUNT32.CTRLA.bit.ENABLE = 1; + while(TC3->COUNT32.SYNCBUSY.bit.ENABLE); +} + +#define STEPTICKER_SYNC (TC2->COUNT32.CTRLBSET.reg = TCC_CTRLBSET_CMD_READSYNC) +#define STEPTICKER (TC2->COUNT32.COUNT.reg) + int main(void) { /* Initialize the SAM system */ SystemInit(); - SysTick_Config(5000000); - - //clock_init(); + SysTick_Config(2500000); // making ticks about 2us // lights - stlb = pin_new(&PORT->Group[1], 14); pin_output(&stlb); pin_set(&stlb); @@ -98,6 +164,8 @@ int main(void) NVIC_EnableIRQ(SERCOM4_2_IRQn); //up1rx NVIC_EnableIRQ(SERCOM5_0_IRQn); NVIC_EnableIRQ(SERCOM5_2_IRQn); + NVIC_EnableIRQ(TC0_IRQn); + NVIC_EnableIRQ(TC2_IRQn); // ringbuffers (for uart ports) rb_init(&up1_rbrx); @@ -124,7 +192,7 @@ int main(void) // spi spi_tmc = spi_new(SERCOM0, &PORT->Group[0], 4, 7, 5, 6, HARDWARE_IS_APBA, HARDWARE_ON_PERIPHERAL_D); MCLK->APBAMASK.reg |= MCLK_APBAMASK_SERCOM0; - spi_init(&spi_tmc, 8, SERCOM0_GCLK_ID_CORE, 3, 0, 2, 0, 1, 1, 0); + spi_init(&spi_tmc, 8, SERCOM0_GCLK_ID_CORE, 8, 0, 2, 0, 1, 1, 0); // TMC // STEP PB08 @@ -141,6 +209,14 @@ int main(void) // enable tmc26_enable(&tmc); + ticker_init(); // for counting + // 32 bit timer, each tick is 1/3 of one us. + // to read, do TICKER_SYNC, and then var = TICKER as defined + // overflows in 17.9 minutes + + stepticker_init(); // fires interrupt to check if we need to take a step + // 32 bit timer at 48mhz / 64 and fires on top of 12 for a 16us period: 48 small ticks of 1/3us within each period + step_pin = pin_new(&PORT->Group[1], 8); dir_pin = pin_new(&PORT->Group[1], 9); pin_output(&step_pin); @@ -148,25 +224,39 @@ int main(void) while (1) { - //pin_clear(&en_pin); - tmc26_update(&tmc); - //pin_set(&en_pin); - //pin_toggle(&step_pin); + // still doin it + //tmc26_update(&tmc); // delay - for(int i=0; i < 12; i++){ + for(int i=0; i < 126; i++){ pin_toggle(&stlr); + //pin_toggle(&en_pin); } // step pin_toggle(&step_pin); - } } +uint8_t lpcnt = 0; + void SysTick_Handler(void){ + lpcnt ++; pin_toggle(&stlb); + /* while(!rb_empty(up1.rbrx)){ uart_sendchar_buffered(&up1, rb_get(up1.rbrx)); } + */ + STEPTICKER_SYNC; + uint32_t thecount = STEPTICKER; + uint8_t onemicro = thecount; + uint8_t twomicro = thecount >> 8; + uint8_t threemicro = thecount >> 16; + uint8_t fourmicro = thecount >> 24; + uart_sendchar_buffered(&up1, onemicro); + uart_sendchar_buffered(&up1, twomicro); + uart_sendchar_buffered(&up1, threemicro); + uart_sendchar_buffered(&up1, fourmicro); + uart_sendchar_buffered(&up1, overflows); } void SERCOM4_0_Handler(void){ @@ -183,4 +273,16 @@ void SERCOM5_0_Handler(void){ void SERCOM5_2_Handler(void){ uart_rxhandler(&up2); +} + +void TC0_Handler(void){ // fires rarely, for counting overflows of time-ticker + TC0->COUNT32.INTFLAG.bit.OVF = 1; // to clear it + overflows ++; +} + +void TC2_Handler(void){ // fires every 16us, for step checking + TC2->COUNT32.INTFLAG.bit.MC0 = 1; + TC2->COUNT32.INTFLAG.bit.MC1 = 1; + overflows ++; + pin_toggle(&en_pin); } \ No newline at end of file diff --git a/embedded/mkstepper-v011/mkstepper-v011/mkstepper-v011.cproj b/embedded/mkstepper-v011/mkstepper-v011/mkstepper-v011.cproj index 1c7366f..f691b7f 100644 --- a/embedded/mkstepper-v011/mkstepper-v011/mkstepper-v011.cproj +++ b/embedded/mkstepper-v011/mkstepper-v011/mkstepper-v011.cproj @@ -190,10 +190,10 @@ <Compile Include="spiport.h"> <SubType>compile</SubType> </Compile> - <Compile Include="tmc2660.c"> + <Compile Include="tmc26.c"> <SubType>compile</SubType> </Compile> - <Compile Include="tmc2660.h"> + <Compile Include="tmc26.h"> <SubType>compile</SubType> </Compile> <Compile Include="uartport.c"> diff --git a/embedded/mkstepper-v011/mkstepper-v011/spiport.h b/embedded/mkstepper-v011/mkstepper-v011/spiport.h index d4ac775..5b6000d 100644 --- a/embedded/mkstepper-v011/mkstepper-v011/spiport.h +++ b/embedded/mkstepper-v011/mkstepper-v011/spiport.h @@ -11,6 +11,8 @@ #include "sam.h" +// TODO: cleaning settings / init values for prettiness, ease of use on variable devices + typedef struct{ Sercom *com; PortGroup *port; diff --git a/embedded/mkstepper-v011/mkstepper-v011/tmc26.c b/embedded/mkstepper-v011/mkstepper-v011/tmc26.c index ff770d2..13687c7 100644 --- a/embedded/mkstepper-v011/mkstepper-v011/tmc26.c +++ b/embedded/mkstepper-v011/mkstepper-v011/tmc26.c @@ -5,7 +5,7 @@ * Author: Jake */ -#include "tmc2660.h" +#include "tmc26.h" tmc26_t tmc26_new(spiport_t *spi, pin_t *en, pin_t *sg){ tmc26_t tmc; @@ -28,6 +28,8 @@ void tmc26_write(tmc26_t *tmc, uint32_t word){ } void tmc26_init(tmc26_t *tmc){ + pin_output(tmc->en_pin); + //pin_input(tmc->sg_pin); tmc26_disable(tmc); // turnt off // address, slope control hi and lo to minimum, short to ground protection on, short to gnd timer 3.2us, @@ -62,9 +64,9 @@ void tmc26_update(tmc26_t *tmc){ } void tmc26_enable(tmc26_t *tmc){ - pin_set(tmc->en_pin); + pin_clear(tmc->en_pin); } tmc26_disable(tmc26_t *tmc){ - pin_clear(tmc->en_pin); + pin_set(tmc->en_pin); } \ No newline at end of file diff --git a/embedded/mkstepper-v011/mkstepper-v011/tmc26.h b/embedded/mkstepper-v011/mkstepper-v011/tmc26.h index 8ff49cb..1329c01 100644 --- a/embedded/mkstepper-v011/mkstepper-v011/tmc26.h +++ b/embedded/mkstepper-v011/mkstepper-v011/tmc26.h @@ -13,13 +13,14 @@ #include "spiport.h" #include "pin.h" +// TODO: adding updates (microstep, current) +// in that, calculating current +// TODO: reading stallguard, understanding if is already doing closed loop? + typedef struct{ spiport_t *spi; - pin_t *step_pin; - pin_t *dir_pin; pin_t *en_pin; - pin_t *sg_pin; }tmc26_t; -- GitLab