diff --git a/README.md b/README.md index 4fc545e8e2cbe3bdc6dd850ab488d7fd6fd97d6c..c9077bfd7582d6f2eb4227c1c0fbca46847c7e07 100644 --- a/README.md +++ b/README.md @@ -21,14 +21,15 @@ See [circuit chatter](/circuit) and [programming chatter](/embedded). # Circuit Notes 17 - - crystal - - qfn64 footprint update! - - power conn. size wrong, check update - - pullup (pulldown?) on EN, not step + - after power pad update, gnd route is unhappy + - capacitor 10uf underneath phy pad # Circuit Notes 23 - mounting hole beside ports RIP, move across to not GND motor to port shield with screw + - heat-sinkableness would be *very* rad considering 101c temp. at 1A + - 2oz if JLCPCB makes this easy + - 497-15314-1-ND or DMC4029SK4-13DICT-ND for new fets / better heat ## MKStepper17 diff --git a/circuit/atkstepper17/atkstepper17.brd b/circuit/atkstepper17/atkstepper17.brd index 39cd619d6b243d41053e9e7d97c2ce4cd821ab10..4a7f7a8850d72fa154546831c41ea02362c97fb7 100644 --- a/circuit/atkstepper17/atkstepper17.brd +++ b/circuit/atkstepper17/atkstepper17.brd @@ -3,7 +3,7 @@ <eagle version="9.0.0"> <drawing> <settings> -<setting alwaysvectorfont="yes"/> +<setting alwaysvectorfont="no"/> <setting verticaltext="up"/> </settings> <grid distance="0.1" unitdist="mm" unit="mm" style="lines" multiple="1" display="yes" altdistance="1" altunitdist="mm" altunit="mm"/> @@ -203,56 +203,56 @@ sprint and then pass on</text> <library name="power"> <packages> <package name="PWRPAD_M3-PEM-MOUNT"> -<pad name="P$1" x="0" y="0" drill="4.1" diameter="6.2" thermals="no"/> +<pad name="P$1" x="0" y="0" drill="4.4" diameter="7" thermals="no"/> <polygon width="0.127" layer="31"> -<vertex x="-0.6" y="3"/> -<vertex x="0.6" y="3"/> +<vertex x="-0.6" y="3.6"/> +<vertex x="0.6" y="3.6"/> <vertex x="0.4" y="2.1"/> <vertex x="-0.4" y="2.1"/> </polygon> <polygon width="0.127" layer="31"> -<vertex x="0.6" y="-3"/> -<vertex x="-0.6" y="-3"/> +<vertex x="0.6" y="-3.6"/> +<vertex x="-0.6" y="-3.6"/> <vertex x="-0.4" y="-2.1"/> <vertex x="0.4" y="-2.1"/> </polygon> <polygon width="0.127" layer="31"> -<vertex x="-3" y="-0.6"/> -<vertex x="-3" y="0.6"/> +<vertex x="-3.6" y="-0.6"/> +<vertex x="-3.6" y="0.6"/> <vertex x="-2.1" y="0.4"/> <vertex x="-2.1" y="-0.4"/> </polygon> <polygon width="0.127" layer="31"> -<vertex x="3" y="0.6"/> -<vertex x="3" y="-0.6"/> +<vertex x="3.6" y="0.6"/> +<vertex x="3.6" y="-0.6"/> <vertex x="2.1" y="-0.4"/> <vertex x="2.1" y="0.4"/> </polygon> <polygon width="0.127" layer="31"> -<vertex x="-2.55269375" y="1.73136875"/> -<vertex x="-1.704165625" y="2.579896875"/> +<vertex x="-2.95269375" y="2.13136875"/> +<vertex x="-2.104165625" y="2.979896875"/> <vertex x="-1.19203125" y="1.784921875"/> <vertex x="-1.75771875" y="1.2192375"/> </polygon> <polygon width="0.127" layer="31"> -<vertex x="2.59705625" y="-1.72131875"/> -<vertex x="1.748528125" y="-2.569846875"/> +<vertex x="2.99705625" y="-2.12131875"/> +<vertex x="2.148528125" y="-2.969846875"/> <vertex x="1.23639375" y="-1.774871875"/> <vertex x="1.80208125" y="-1.2091875"/> </polygon> <polygon width="0.127" layer="31"> -<vertex x="-1.704165625" y="-2.569846875"/> -<vertex x="-2.55269375" y="-1.72131875"/> +<vertex x="-2.104165625" y="-2.969846875"/> +<vertex x="-2.95269375" y="-2.12131875"/> <vertex x="-1.75771875" y="-1.2091875"/> <vertex x="-1.19203125" y="-1.774871875"/> </polygon> <polygon width="0.127" layer="31"> -<vertex x="1.748528125" y="2.579896875"/> -<vertex x="2.59705625" y="1.73136875"/> +<vertex x="2.148528125" y="2.979896875"/> +<vertex x="2.99705625" y="2.13136875"/> <vertex x="1.80208125" y="1.2192375"/> <vertex x="1.23639375" y="1.784921875"/> </polygon> -<circle x="0" y="0" radius="3" width="0.125" layer="51"/> +<circle x="0" y="0" radius="3.5" width="0.125" layer="51"/> </package> <package name="PWRPAD_3-25MM"> <pad name="P$1" x="0" y="0" drill="3.25" diameter="5.75" thermals="no"/> @@ -1859,10 +1859,9 @@ design rules under a new name.</description> <wire x1="10.3714" y1="23.79635625" x2="9.665" y2="24.50275625" width="0.1524" layer="1"/> <contactref element="R8" pad="2"/> <contactref element="U1" pad="1"/> -<wire x1="12.7528" y1="34.6382" x2="12.1640125" y2="34.0494125" width="0.1524" layer="1"/> -<wire x1="15.2472" y1="34.6382" x2="15.7382" y2="34.1472" width="0.1524" layer="1"/> +<wire x1="15.2472" y1="34.6382" x2="15.2927" y2="34.5927" width="0.1524" layer="1"/> +<wire x1="15.2927" y1="34.5927" x2="15.7382" y2="34.1472" width="0.1524" layer="1"/> <wire x1="15.7382" y1="34.1472" x2="15.7382" y2="33.5525125" width="0.1524" layer="1"/> -<wire x1="12.7528" y1="34.6382" x2="15.2472" y2="34.6382" width="0.1524" layer="1"/> <wire x1="17.8825625" y1="31.40815" x2="18.20245625" y2="31.40815" width="0.1524" layer="1"/> <via x="18.20245625" y="31.40815" extent="1-16" drill="0.3"/> <wire x1="18.20245625" y1="31.40815" x2="18.42240625" y2="31.1882" width="0.1524" layer="16"/> @@ -1899,14 +1898,13 @@ design rules under a new name.</description> <wire x1="10.2858" y1="31.78005" x2="10.2858" y2="32.23245" width="0.1524" layer="1"/> <wire x1="10.2858" y1="32.23245" x2="9.76105" y2="32.7572" width="0.1524" layer="1"/> <wire x1="9.76105" y1="32.7572" x2="10.08094375" y2="32.7572" width="0.1524" layer="16"/> -<wire x1="10.08094375" y1="32.7572" x2="11.111871875" y2="33.788128125" width="0.1524" layer="16"/> +<wire x1="10.08094375" y1="32.7572" x2="11.14695625" y2="33.8232125" width="0.1524" layer="16"/> <wire x1="9.665" y1="24.50275625" x2="9.665" y2="30.21065625" width="0.1524" layer="1"/> -<wire x1="12.1640125" y1="34.0494125" x2="12.0356" y2="34.0494125" width="0.1524" layer="1"/> -<via x="12.0356" y="34.0494125" extent="1-16" drill="0.3"/> -<wire x1="12.0356" y1="34.0494125" x2="12.0356" y2="34.0356" width="0.1524" layer="16"/> -<wire x1="12.0356" y1="34.0356" x2="11.8232125" y2="33.8232125" width="0.1524" layer="16"/> -<wire x1="11.14695625" y1="33.8232125" x2="11.111871875" y2="33.788128125" width="0.1524" layer="16"/> -<wire x1="11.8232125" y1="33.8232125" x2="11.14695625" y2="33.8232125" width="0.1524" layer="16"/> +<wire x1="14.4322125" y1="33.8232125" x2="15.407146875" y2="34.798146875" width="0.1524" layer="16"/> +<via x="15.407146875" y="34.798146875" extent="1-16" drill="0.3"/> +<wire x1="15.407146875" y1="34.798146875" x2="15.2927" y2="34.6837" width="0.1524" layer="1"/> +<wire x1="15.2927" y1="34.6837" x2="15.2927" y2="34.5927" width="0.1524" layer="1"/> +<wire x1="11.14695625" y1="33.8232125" x2="14.4322125" y2="33.8232125" width="0.1524" layer="16"/> </signal> <signal name="TMC_CSN"> <contactref element="U2" pad="2"/> @@ -2142,7 +2140,8 @@ design rules under a new name.</description> <wire x1="10.0666" y1="23.6701" x2="8.7867" y2="24.95" width="0.1524" layer="1"/> <wire x1="8.7867" y1="24.95" x2="8.4" y2="24.95" width="0.1524" layer="1"/> <wire x1="8.4" y1="24.95" x2="8.25" y2="25.1" width="0.1524" layer="1"/> -<wire x1="7" y1="25.1" x2="8.25" y2="25.1" width="0" layer="19" extent="1-1"/> +<wire x1="7" y1="25.1" x2="7.15" y2="24.95" width="0.1524" layer="1"/> +<wire x1="7.15" y1="24.95" x2="8.4" y2="24.95" width="0.1524" layer="1"/> </signal> <signal name="STLERR"> <contactref element="R2" pad="1"/> diff --git a/circuit/atkstepper17/atkstepper17.sch b/circuit/atkstepper17/atkstepper17.sch index 1ae89557ba3392ec5b6643490d8118d5171aab39..734ededc9e4d4a0061a67627eca6d9ef0f10fedb 100644 --- a/circuit/atkstepper17/atkstepper17.sch +++ b/circuit/atkstepper17/atkstepper17.sch @@ -3,7 +3,7 @@ <eagle version="9.0.0"> <drawing> <settings> -<setting alwaysvectorfont="yes"/> +<setting alwaysvectorfont="no"/> <setting verticaltext="up"/> </settings> <grid distance="0.1" unitdist="inch" unit="inch" style="lines" multiple="1" display="yes" altdistance="0.01" altunitdist="inch" altunit="inch"/> @@ -181,56 +181,56 @@ <pad name="P$1" x="0" y="0" drill="2.05" diameter="3.8" thermals="no"/> </package> <package name="PWRPAD_M3-PEM-MOUNT"> -<pad name="P$1" x="0" y="0" drill="4.1" diameter="6.2" thermals="no"/> +<pad name="P$1" x="0" y="0" drill="4.4" diameter="7" thermals="no"/> <polygon width="0.127" layer="31"> -<vertex x="-0.6" y="3"/> -<vertex x="0.6" y="3"/> +<vertex x="-0.6" y="3.6"/> +<vertex x="0.6" y="3.6"/> <vertex x="0.4" y="2.1"/> <vertex x="-0.4" y="2.1"/> </polygon> <polygon width="0.127" layer="31"> -<vertex x="0.6" y="-3"/> -<vertex x="-0.6" y="-3"/> +<vertex x="0.6" y="-3.6"/> +<vertex x="-0.6" y="-3.6"/> <vertex x="-0.4" y="-2.1"/> <vertex x="0.4" y="-2.1"/> </polygon> <polygon width="0.127" layer="31"> -<vertex x="-3" y="-0.6"/> -<vertex x="-3" y="0.6"/> +<vertex x="-3.6" y="-0.6"/> +<vertex x="-3.6" y="0.6"/> <vertex x="-2.1" y="0.4"/> <vertex x="-2.1" y="-0.4"/> </polygon> <polygon width="0.127" layer="31"> -<vertex x="3" y="0.6"/> -<vertex x="3" y="-0.6"/> +<vertex x="3.6" y="0.6"/> +<vertex x="3.6" y="-0.6"/> <vertex x="2.1" y="-0.4"/> <vertex x="2.1" y="0.4"/> </polygon> <polygon width="0.127" layer="31"> -<vertex x="-2.55269375" y="1.73136875"/> -<vertex x="-1.704165625" y="2.579896875"/> +<vertex x="-2.95269375" y="2.13136875"/> +<vertex x="-2.104165625" y="2.979896875"/> <vertex x="-1.19203125" y="1.784921875"/> <vertex x="-1.75771875" y="1.2192375"/> </polygon> <polygon width="0.127" layer="31"> -<vertex x="2.59705625" y="-1.72131875"/> -<vertex x="1.748528125" y="-2.569846875"/> +<vertex x="2.99705625" y="-2.12131875"/> +<vertex x="2.148528125" y="-2.969846875"/> <vertex x="1.23639375" y="-1.774871875"/> <vertex x="1.80208125" y="-1.2091875"/> </polygon> <polygon width="0.127" layer="31"> -<vertex x="-1.704165625" y="-2.569846875"/> -<vertex x="-2.55269375" y="-1.72131875"/> +<vertex x="-2.104165625" y="-2.969846875"/> +<vertex x="-2.95269375" y="-2.12131875"/> <vertex x="-1.75771875" y="-1.2091875"/> <vertex x="-1.19203125" y="-1.774871875"/> </polygon> <polygon width="0.127" layer="31"> -<vertex x="1.748528125" y="2.579896875"/> -<vertex x="2.59705625" y="1.73136875"/> +<vertex x="2.148528125" y="2.979896875"/> +<vertex x="2.99705625" y="2.13136875"/> <vertex x="1.80208125" y="1.2192375"/> <vertex x="1.23639375" y="1.784921875"/> </polygon> -<circle x="0" y="0" radius="3" width="0.125" layer="51"/> +<circle x="0" y="0" radius="3.5" width="0.125" layer="51"/> </package> <package name="QFN36-5X6"> <description><b>QFN 32</b> 5 x 5 mm<p> @@ -777,6 +777,9 @@ Source: http://datasheets.maxim-ic.com/en/ds/MAX7042.pdf</description> <rectangle x1="0.7" y1="-2.4" x2="1.3" y2="-2.1" layer="31"/> <rectangle x1="-0.3" y1="-2.4" x2="0.3" y2="-2.1" layer="31"/> </package> +<package name="PWRPAD_3-25MM-SKINNY"> +<pad name="P$1" x="0" y="0" drill="3.25" diameter="5.35" thermals="no"/> +</package> </packages> <symbols> <symbol name="PWRPAD"> @@ -877,6 +880,14 @@ Source: http://datasheets.maxim-ic.com/en/ds/MAX7042.pdf</description> <technology name=""/> </technologies> </device> +<device name="M3-SKINNY" package="PWRPAD_3-25MM-SKINNY"> +<connects> +<connect gate="G$1" pin="PWRPAD" pad="P$1"/> +</connects> +<technologies> +<technology name=""/> +</technologies> +</device> </devices> </deviceset> <deviceset name="TMC2130" prefix="U"> diff --git a/circuit/atkstepper17/eagle.epf b/circuit/atkstepper17/eagle.epf index 3449f46b6d370e6ba81d509ecaac46cf31e1174d..e20b1d67aa7efced57531fa9fdadf747773b74c6 100644 --- a/circuit/atkstepper17/eagle.epf +++ b/circuit/atkstepper17/eagle.epf @@ -17,7 +17,6 @@ UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries/eagle/motors.lbr" UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries/eagle/power.lbr" UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries/eagle/sensor.lbr" UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/sparkfun/SparkFun-Connectors.lbr" -UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/marekr/borkedlabs-passives.lbr" UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/jake/tag-connect-2050.lbr" UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/Comparators.lbr" UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/Digital.lbr" @@ -35,12 +34,13 @@ UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/lt-spice-simulation.lbr" UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/lt-supply.lbr" UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/rload.lbr" UsedLibrary="C:/EAGLE 8.3.2/lbr/ltspice/sym.lbr" +UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/marekr/borkedlabs-passives.lbr" [Win_1] Type="Schematic Editor" Number=1 File="atkstepper17.sch" -View="13.4383 104.876 242.064 267.489" +View="80.8728 52.8383 355.224 247.974" 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" @@ -79,14 +79,14 @@ ArcDirection=0 AddLevel=2 PadsSameType=0 Layer=91 -Views=" 1: 13.4383 104.876 242.064 267.489" +Views=" 1: 80.8728 52.8383 355.224 247.974" Sheet="1" [Win_2] Type="Board Editor" Number=2 File="atkstepper17.brd" -View="-6.59981 -11.5805 57.317 53.9612" +View="11.3999 -6.36849 64.664 48.2496" WireWidths=" 0.0762 0.1016 0.127 0.15 0.2 0.254 0.3048 0.4064 0.508 0.6096 1.016 2.54 0.8128 1.27 0.2032 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" @@ -124,14 +124,14 @@ SwapLevel=0 ArcDirection=0 AddLevel=2 PadsSameType=0 -Layer=16 +Layer=1 [Win_3] Type="Control Panel" Number=0 [Desktop] -Screen="6000 2160" +Screen="3840 1080" Window="Win_1" Window="Win_2" Window="Win_3" diff --git a/circuit/atkstepper23/eagle.epf b/circuit/atkstepper23/eagle.epf index 2f1918cdfc3500aede00826dfbe1989f67506692..242a224234857a4ae6d8dc73cb2a2d0b9897b94b 100644 --- a/circuit/atkstepper23/eagle.epf +++ b/circuit/atkstepper23/eagle.epf @@ -41,7 +41,7 @@ UsedLibrary="D:/Dropbox (Personal)/CBA/doc/libraries_jake/eagle/marekr/borkedlab Type="Schematic Editor" Number=1 File="atkstepper23.sch" -View="21.5059 117.164 186.993 223.802" +View="-14.9679 131.343 223.333 284.902" 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" @@ -80,14 +80,14 @@ ArcDirection=0 AddLevel=2 PadsSameType=0 Layer=97 -Views=" 1: 21.5059 117.164 186.993 223.802" +Views=" 1: -14.9679 131.343 223.333 284.902" Sheet="1" [Win_2] Type="Board Editor" Number=2 File="atkstepper23.brd" -View="30.3953 18.0172 51.4583 40.4406" +View="9.59723 -14.0936 85.0697 66.2535" WireWidths=" 0.0762 0.1016 0.127 0.15 0.2 0.2032 0.254 0.3048 0.508 1.016 1.27 2.54 0.8128 0.6096 0.4064 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" diff --git a/embedded/atkstepper17/atkstepper17/atkhandler.c b/embedded/atkstepper17/atkstepper17/atkhandler.c new file mode 100644 index 0000000000000000000000000000000000000000..b0decb920d6defc5f52df04eba9136cca660028b --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/atkhandler.c @@ -0,0 +1,164 @@ +/* +* atkhandler.c +* +* Created: 3/12/2018 11:55:30 AM +* Author: Jake +*/ + +#include "hardware.h" +#include "atkhandler.h" + +int32_t steps; + +void atk_handle_packet(uint8_t *packet, uint8_t length){ + // dirty debug reply + //atk_return_packet(packet, length); + // through packet + int i = 0; + int atk_handler_state = ATK_HANDLER_OUTSIDE; + uint8_t testReply[4] = {127, 12, 24, 48}; + + while(i < length){ // prep for the messy double switch :| + switch (atk_handler_state){ + case ATK_HANDLER_OUTSIDE: + if (packet[i] == ATK_END_ROUTE_DELIMITER){ + atk_handler_state = ATK_HANDLER_INSIDE; + } + i ++; + break; + + case ATK_HANDLER_INSIDE: + switch (packet[i]){ + case DELIM_KEY_TEST: + pin_toggle(&stlerr); + // see the packet, make sure you're not doing something else with this light + atk_reply_packet(packet, testReply, 4); + i ++; + break; + + case DELIM_KEY_RESET: + // TODO + break; + + case DELIM_KEY_TRAPEZOID: + //pin_toggle(&stlerr); + if(i + 12 > length){ + i ++; + } else { + // in steps (discrete) + steps = ((int32_t)packet[i+1] << 24) | ((int32_t)packet[i+2] << 16) | ((int32_t)packet[i+3] << 8) | (int32_t)packet[i+4]; + // in steps/s + uint32_t entryspeed = ((int32_t)packet[i+5] << 24) | ((int32_t)packet[i+6] << 16) | ((int32_t)packet[i+7] << 8) | (int32_t)packet[i+8]; + // in steps/min/s + uint32_t accel = ((int32_t)packet[i+9] << 24) | ((int32_t)packet[i+10] << 16) | ((int32_t)packet[i+11] << 8) | (int32_t)packet[i+12]; + // in steps/min + uint32_t accellength = ((int32_t)packet[i+13] << 24) | ((int32_t)packet[i+14] << 16) | ((int32_t)packet[i+15] << 8) | (int32_t)packet[i+16]; + // in steps/min + uint32_t deccellength = ((int32_t)packet[i+17] << 24) | ((int32_t)packet[i+18] << 16) | (int32_t)(packet[i+19] << 8) | (int32_t)packet[i+20]; + // do the business + i += 21; + stepper_new_block(packet, &stepper, steps, entryspeed, accel, accellength, deccellength); + } + break; + + case DELIM_KEY_WAIT: + if(i + 8 > length){ + i ++; + } else { + steps = ((int32_t)packet[i+1] << 24) | ((int32_t)packet[i+2] << 16) | ((int32_t)packet[i+3] << 8) | (int32_t)packet[i+4]; + // in steps/s + uint32_t speed = ((int32_t)packet[i+5] << 24) | ((int32_t)packet[i+6] << 16) | ((int32_t)packet[i+7] << 8) | (int32_t)packet[i+8]; + i += 8; + stepper_new_wait(packet, &stepper, steps, speed); + } + + default: + // probably an error + i ++; + break; + } // end interior switch + break; + + default : + // throw err + break; + } // end y/n switch + } +} + +// HERE return with address header, or from old packet with new data + +uint8_t ackPack[256]; + +void atk_reply_packet(uint8_t *opPacket, uint8_t *replyData, uint8_t replyLength){ + // find address chunk in opPacket + int i = 2; + int stop = 0; + while(i < opPacket[0]){ + if(opPacket[i] == ATK_END_ROUTE_DELIMITER){ + stop = i; + break; + } + i ++; + } + + uint8_t ackLength = stop + replyLength + 1; + ackPack[0] = ackLength; + + if(stop){ + // reverse the address header + for(int a = stop - 1, b = 1; a >= 1; a--, b++){ + ackPack[b] = opPacket[a]; + } + // and append the end block + ackPack[stop] = ATK_END_ROUTE_DELIMITER; + // now fill with provided reply data + for(int u = 0; u <= replyLength; u ++){ + ackPack[u + stop + 1] = replyData[u]; + } + // checking the port exists, send it out + if(ackPack[1] >= SYSTEM_NUM_UPS){ + ackPack[1] = SYSTEM_NUM_UPS - 1; + } + uart_sendchars_buffered(ups[ackPack[1]], ackPack, ackPack[0]);//ups[ackPack[1]], ackPack, ackLength); + } +} + +void atk_return_packet(uint8_t *packet, uint8_t length){ + //uart_sendchar_buffered(ups[1], 120); + //uart_sendchars_buffered(ups[1], packet, length); + // using this placeholder + ackPack[0] = length; + // find route header + int i = 2; + int stop = 0; + while(i < length){ + if(packet[i] == ATK_END_ROUTE_DELIMITER){ + stop = i; + break; + } + i ++; + } + // do the business + if(stop){ + // reverse the address header + for(int a = stop - 1, b = 1; a >= 1; a--, b++){ + ackPack[b] = packet[a]; + } + // fill the rest with same packet data + ackPack[stop] = ATK_END_ROUTE_DELIMITER; + for(int u = stop; u < length; u ++){ + ackPack[u] = packet[u]; + } + // checking the packet exists, send it out + if(ackPack[1] >= SYSTEM_NUM_UPS){ + ackPack[1] = SYSTEM_NUM_UPS - 1; + } + uart_sendchars_buffered(ups[ackPack[1]], ackPack, ackPack[0]); + // NOW: + // looking for justice: why no return packet on double length hop? + // debug with 2nd ftdi + //uart_sendchar_buffered(ups[1], 121); + //uart_sendchars_buffered(ups[1], ackpack, length); + } +} \ No newline at end of file diff --git a/embedded/atkstepper17/atkstepper17/atkhandler.h b/embedded/atkstepper17/atkstepper17/atkhandler.h new file mode 100644 index 0000000000000000000000000000000000000000..1b6879aa507d2433667ff90eda849c58a8c25f65 --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/atkhandler.h @@ -0,0 +1,28 @@ +/* + * atkhandler.h + * + * Created: 3/12/2018 11:55:40 AM + * Author: Jake + */ + + +#ifndef ATKHANDLER_H_ +#define ATKHANDLER_H_ + +#include <avr/io.h> + +#define ATK_HANDLER_OUTSIDE 0 +#define ATK_HANDLER_INSIDE 1 + +#define DELIM_KEY_TEST 127 // toggles a light, to test network +#define DELIM_KEY_RESET 128 + +#define DELIM_KEY_TRAPEZOID 131 +#define DELIM_KEY_WAIT 132 + +void atk_handle_packet(uint8_t *packet, uint8_t length); + +void atk_reply_packet(uint8_t *opPacket, uint8_t *replyData, uint8_t replyLength); +void atk_return_packet(uint8_t *packet, uint8_t length); + +#endif /* atkHANDLER_H_ */ \ No newline at end of file diff --git a/embedded/atkstepper17/atkstepper17/atkport.c b/embedded/atkstepper17/atkstepper17/atkport.c new file mode 100644 index 0000000000000000000000000000000000000000..65b80e0eddbf8a8a2e0a8a941c5d8a86e2d25a02 --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/atkport.c @@ -0,0 +1,123 @@ +/* + * atkport.c + * + * Created: 2/23/2018 9:17:48 AM + * Author: Jake + */ + +#include "atkport.h" +#include "hardware.h" +#include "fastmath.h" + +void atkport_init(atkport_t *atkp, uint8_t portnum, uartport_t *uart){ + atkp->uart = uart; + atkp->portnum = portnum; + + atkport_reset(atkp); +} + +void atkport_reset(atkport_t *atkp){ + atkp->packet_num = 0; + atkp->packets_ready = 0; + atkp->packet_state = ATKPORT_OUTSIDE_PACKET; + atkp->packet_position = 0; + + pin_set(atkp->uart->stlrx); + pin_set(atkp->uart->stltx); +} + +void atkport_scan(atkport_t *atkp, uint32_t maxpackets){ + // scan through for completely received packets + while(atkp->packets_ready <= maxpackets){ + // check that we have bytes to read out of the buffer + if(atkp->uart->rbrx->head == atkp->uart->rbrx->tail){ // direct access, rather than through rbempty() shaves 2us + pin_set(atkp->uart->stlrx); + break; + } else { + // pull bytes out of buffer into the packet structure + atkp->packets[atkp->packet_num][atkp->packet_position] = rb_get(atkp->uart->rbrx); + atkp->packet_position ++; + // now segment, point to them + if(atkp->packet_position >= atkp->packets[atkp->packet_num][0]){ + // length is 1st byte, like array[n] not array[n-1] + // now volley for next pass + // packet_num is index of head of packet buffer (just an array) + atkp->packet_num = fastModulo((atkp->packet_num + 1), ATKPORT_NUM_STATIC_PACKETS); // inc. and loop + // packets_ready is the number of ready-state packets in that buffer (array) + atkp->packets_ready ++; + // the position, in bytes, where we are currently operating. + // at this point, we have come to the end, so we're resetting counter for the next + atkp->packet_position = 0; + } + } + } + // end 1st scan for packets, now we know we have atkport->packet_num packets completely received + // now we handle those packets + while(atkp->packets_ready > 0){ + // the particular packet index + uint32_t p = fastModulo((atkp->packet_num + ATKPORT_NUM_STATIC_PACKETS - atkp->packets_ready), ATKPORT_NUM_STATIC_PACKETS); //(atkp->packet_num + ATKPORT_NUM_STATIC_PACKETS - atkp->packets_ready) % ATKPORT_NUM_STATIC_PACKETS; + // first we shift the old pointer out (p[1] is, at the moment, the port the last node tx'd on) + atkpacket_shift_pointer(atkp->packets[p], atkp->portnum); + // now p[1] is next port + // now to handle + // [p][0] is length of packet + if(atkp->packets[p][1] == ATK_ROUTE_POINTER){ + atk_handle_packet(atkp->packets[p], atkp->packets[p][0]); + } else if(atkp->packets[p][1] == ATK_ROUTE_FLOOD){ + // loop through bytes to find pointer and increment + // now ship it out on all ports + for(int i = 0; i < ATKPORT_NUM_PORTS; i ++){ + if(i == atkp->portnum){ + // don't flood back + } else { + uart_sendchars_buffered(ups[i], atkp->packets[p], atkp->packets[p][0]); + } + } + } else { + // packet is for a particular port, + if(atkp->packets[p][1] > ATKPORT_NUM_PORTS){ + // port does not exist, throw error + // pin_clear(&stlerr); + } else { + // debug option + //uart_sendchars_buffered(&upU, atkp->packets[p], atkp->packets[p][0]); + uart_sendchars_buffered(ups[atkp->packets[p][1]], atkp->packets[p], atkp->packets[p][0]); + } + } + // debug reply (at the moment, reply is handled in atk_handle_packet + // uart_sendchars_buffered(atkp->uart, atkp->packets[p], atkp->packets[p][0]); + atkp->packets_ready --; + } +} + +void atkpacket_shift_pointer(uint8_t *packet, uint8_t portnum){ + int i = 2; + while(i < packet[0]){ // while less than length + if(packet[i] == ATK_END_ROUTE_DELIMITER){ + // put our port in tail + packet[i-1] = portnum; + break; + } else { + // shift 'em down + packet[i-1] = packet[i]; + } + i ++; + } +} + +void atkport_send_packet(uint8_t *address, uint8_t address_length, uint8_t *payload, uint8_t payloadlength){ + // 1st byte is port out + // not yet implemented, using atk_return_packet ... all of these could be cleaner +} + +// UNIT TESTS: +/* + flood packets + multiple receptions? handle in app? + packets no end addr bar delimiter, packets no pointer, general white noise + packets varying length + packets wrong length ? very hard to catch w/o hella state ... timeout? + packets no end addr delimiter? + packets to ports not existing + // next: write javascript terminal packet builder for unit tests! +*/ \ No newline at end of file diff --git a/embedded/atkstepper17/atkstepper17/atkport.h b/embedded/atkstepper17/atkstepper17/atkport.h new file mode 100644 index 0000000000000000000000000000000000000000..c99365fd2000dc1bec261aa932808e9e23bdf5d3 --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/atkport.h @@ -0,0 +1,47 @@ +/* + * atkport.h + * + * Created: 2/23/2018 9:17:34 AM + * Author: Jake + */ + + +#ifndef ATKPORT_H_ +#define ATKPORT_H_ + +#include "uartport.h" +#include "pin.h" + +#define ATKPORT_NUM_STATIC_PACKETS 8 +#define ATKPORT_NUM_PORTS 6 + +#define ATKPORT_OUTSIDE_PACKET 0 +#define ATKPORT_INSIDE_PACKET 1 + +#define ATK_END_ROUTE_DELIMITER 255 +#define ATK_ROUTE_POINTER 254 +#define ATK_ROUTE_FLOOD 253 + +typedef struct{ + uartport_t *uart; + + uint8_t portnum; // which port are we + + uint32_t packet_num; + uint32_t packet_position; + uint32_t packets_ready; + uint32_t packet_state; + uint8_t packets[ATKPORT_NUM_STATIC_PACKETS][256]; // packets for handling by app +}atkport_t; + +void atkport_init(atkport_t *atkp, uint8_t portnum, uartport_t *uart); + +void atkport_reset(atkport_t *atkp); + +void atkport_scan(atkport_t *atkp, uint32_t maxpackets); + +void atkpacket_shift_pointer(uint8_t *packet, uint8_t portnum); + +void atkport_send_packet(uint8_t *address, uint8_t address_length, uint8_t *payload, uint8_t payloadlength); + +#endif /* atkPORT_H_ */ \ No newline at end of file diff --git a/embedded/atkstepper17/atkstepper17/fastmath.c b/embedded/atkstepper17/atkstepper17/fastmath.c new file mode 100644 index 0000000000000000000000000000000000000000..91d749c7d4d98df07849944e54772b75852596fc --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/fastmath.c @@ -0,0 +1,11 @@ +/* + * fastmath.c + * + * Created: 6/20/2018 12:38:38 PM + * Author: Jake + */ + +int fastModulo(int dividend, int divisor){ + // divisor must be a power of 2! + return dividend & (divisor - 1); +} \ No newline at end of file diff --git a/embedded/atkstepper17/atkstepper17/fastmath.h b/embedded/atkstepper17/atkstepper17/fastmath.h new file mode 100644 index 0000000000000000000000000000000000000000..d1c2cb1b34048c184621f5446f18901c8a8a1272 --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/fastmath.h @@ -0,0 +1,14 @@ +/* + * fastmath.h + * + * Created: 6/20/2018 12:35:50 PM + * Author: Jake + */ + + +#ifndef FASTMATH_H_ +#define FASTMATH_H_ + +int fastModulo(int dividend, int divisor); + +#endif /* FASTMATH_H_ */ \ No newline at end of file diff --git a/embedded/atkstepper17/atkstepper17/hardware.h b/embedded/atkstepper17/atkstepper17/hardware.h new file mode 100644 index 0000000000000000000000000000000000000000..4370e1a422debbcc75cc0ef87023b094b559badc --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/hardware.h @@ -0,0 +1,74 @@ +/* + * hardware.h + * + * Created: 6/18/2018 12:18:05 PM + * Author: Jake + */ + + +#ifndef HARDWARE_H_ +#define HARDWARE_H_ + +#include "pin.h" +#include "ringbuffer.h" +#include "uartport.h" +#include "spiport.h" +#include "atkport.h" +#include "atkhandler.h" +#include "tmc26x.h" +#include "stepper.h" + +// results in 1MBaud +#define SYSTEM_BAUDA 3 +#define SYSTEM_BAUDB 0 +#define SYSTEM_NUM_UPS 2 + +pin_t stlclk; +pin_t stlerr; + +// UP0 + +ringbuffer_t up0rbrx; +ringbuffer_t up0rbtx; + +uartport_t up0; + +pin_t up0rxled; +pin_t up0txled; + +atkport_t atkp0; + +// UP1 + +ringbuffer_t up1rbrx; +ringbuffer_t up1rbtx; + +uartport_t up1; + +pin_t up1rxled; +pin_t up1txled; + +atkport_t atkp1; + +// UPS + +uartport_t *ups[SYSTEM_NUM_UPS]; + +// Stepper +// SPI + +spiport_t spitmc; +pin_t spicspin; + +pin_t tmcen; +pin_t tmcsg; +pin_t step; +pin_t dir; + +tmc26_t tmc; + +stepper_t stepper; + +unsigned long timebase; + +#endif /* HARDWARE_H_ */ \ No newline at end of file diff --git a/embedded/atkstepper17/atkstepper17/main.c b/embedded/atkstepper17/atkstepper17/main.c new file mode 100644 index 0000000000000000000000000000000000000000..f81f96d8ae1a65c64bdbc68a019f69cada303a07 --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/main.c @@ -0,0 +1,147 @@ +/* +* atkrouter.c +* +* Created: 6/17/2018 2:48:08 PM +* Author : Jake +*/ + +#include <avr/io.h> +#include <avr/interrupt.h> +#include "hardware.h" +#include "fastmath.h" + +// stlclk PA0 +// stlerr PA1 + +void clock_init(void){ + OSC.XOSCCTRL = OSC_XOSCSEL_XTAL_256CLK_gc | OSC_FRQRANGE_12TO16_gc; // select external source + OSC.CTRL = OSC_XOSCEN_bm; // enable external source + while(!(OSC.STATUS & OSC_XOSCRDY_bm)); // wait for external + OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | OSC_PLLFAC0_bm | OSC_PLLFAC1_bm; // select external osc for pll, do pll = source * 3 + //OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | OSC_PLLFAC1_bm; // pll = source * 2 for 32MHz std clock + OSC.CTRL |= OSC_PLLEN_bm; // enable PLL + while (!(OSC.STATUS & OSC_PLLRDY_bm)); // wait for PLL to be ready + CCP = CCP_IOREG_gc; // enable protected register change + CLK.CTRL = CLK_SCLKSEL_PLL_gc; // switch to PLL for main clock +} + +void uarts_init(void){ + // UP0 + rb_init(&up0rbrx); + rb_init(&up0rbtx); + pin_init(&up0rxled, &PORTE, PIN4_bm, 4, 1); + pin_init(&up0txled, &PORTE, PIN5_bm, 5, 1); + uart_init(&up0, &USARTE1, &PORTE, PIN6_bm, PIN7_bm, &up0rbrx, &up0rbtx, &up0rxled, &up0txled); + //PORTE.PIN7CTRL = PORT_SRLEN_bm; + uart_start(&up0, SYSTEM_BAUDA, SYSTEM_BAUDB); + + ups[0] = &up0; +} + +void atkps_init(void){ + atkport_init(&atkp0, 0, &up0); + atkport_init(&atkp1, 1, &up1); +} + +void stephardware_init(void){ + pin_init(&spicspin, &PORTC, PIN4_bm, 4, 1); + spi_init(&spitmc, &USARTC1, &PORTC, PIN6_bm, PIN7_bm, PIN5_bm, &spicspin); + spi_start(&spitmc, 0); + + pin_init(&tmcen, &PORTC, PIN3_bm, 3, 1); + pin_init(&tmcsg, &PORTA, PIN2_bm, 2, 0); + pin_init(&step, &PORTA, PIN0_bm, 0, 1); + pin_init(&dir, &PORTA, PIN1_bm, 1, 1); + + tmc26_init(&tmc, &spitmc, &tmcen, &tmcsg); + + stepper_init(&stepper, &step, &dir); +} + +void tickers_init(void){ + // one 'ticker' to execute steps + // turn on TCC0, do perclk / 8 + TCC0.CTRLA = TC_CLKSEL_DIV256_gc; + + // compare and capture at value + uint16_t pera = 40; // ~ 200us timer to start... + // write low first, bc bussing / xmega 8-bit oddities cc datasheet @ 3.11 + uint8_t peral = (uint8_t) pera; + uint8_t perah = (uint8_t) (pera >> 8); + TCC0.PERBUFL = peral; + TCC0.PERBUFH = perah; + + // set cca interrupt on + TCC0.INTCTRLA = TC_OVFINTLVL_HI_gc; + + // another ticker to execute accel + TCC1.CTRLA = TC_CLKSEL_DIV256_gc; + TCC1.PERBUFL = peral; + TCC1.PERBUFH = perah; + + TCC1.INTCTRLA = TC_OVFINTLVL_HI_gc; +} + +int main(void) +{ + clock_init(); + uarts_init(); + atkps_init(); + + // enable interrupts + sei(); + PMIC.CTRL |= PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; + + pin_init(&stlclk, &PORTF, PIN7_bm, 7, 1); + pin_init(&stlerr, &PORTF, PIN6_bm, 6, 1); + pin_set(&stlerr); + pin_set(&stlclk); + + // stepper business + stephardware_init(); + + tmc26_start(&tmc); + tmc26_enable(&tmc); + + tickers_init(); + + // runtime globals + uint32_t tck = 0; + + while (1) + { + atkport_scan(&atkp0, 2); + atkport_scan(&atkp1, 2); + // just... as fast as we can + tck++; + // this modulo op is slow AF + // that means streamlining atkport_scan without modulos is probably a rad thing + if(!(fastModulo(tck, 4096))){ + pin_toggle(&stlclk); + } + } +} + +ISR(TCC0_OVF_vect){ + stepper_updatesteps(&stepper); +} + +ISR(TCC1_OVF_vect){ + stepper_updateaccel(&stepper); +} + +ISR(USARTE1_RXC_vect){ + uart_rxhandler(&up0); +} + +ISR(USARTE1_DRE_vect){ + uart_txhandler(&up0); +} + +ISR(USARTE0_RXC_vect){ + uart_rxhandler(&up1); +} + +ISR(USARTE0_DRE_vect){ + uart_txhandler(&up1); +} \ No newline at end of file diff --git a/embedded/atkstepper17/atkstepper17/pin.c b/embedded/atkstepper17/atkstepper17/pin.c new file mode 100644 index 0000000000000000000000000000000000000000..071e771a5468cccc6c73bdf445068095b3dd07af --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/pin.c @@ -0,0 +1,49 @@ +/* + * pin.c + * + * Created: 6/18/2018 12:22:50 PM + * Author: Jake + */ + +#include "pin.h" + +void pin_init(pin_t *pin, PORT_t *port, uint8_t pin_bm, uint8_t pin_pos, uint8_t inout){ + pin->port = port; + pin->pin_bm = pin_bm; + pin->pin_pos = pin_pos; + if(inout){ + pin_output(pin); + } else { + pin_input(pin); + } +} + +void pin_output(pin_t *pin){ + pin->port->DIRSET = pin->pin_bm; +} + +void pin_set(pin_t *pin){ + pin->port->OUTSET = pin->pin_bm; +} +void pin_clear(pin_t *pin){ + pin->port->OUTCLR = pin->pin_bm; +} + +void pin_toggle(pin_t *pin){ + pin->port->OUTTGL = pin->pin_bm; +} + +void pin_input(pin_t *pin){ + pin->port->DIRCLR = pin->pin_bm; +} + +void pin_pullup(pin_t *pin){ + // ? how to access PIN0CTRL, etc? +} +void pin_pulldown(pin_t *pin){ + // +} + +uint8_t pin_read(pin_t *pin){ + return (pin->port->IN & pin->pin_bm); +} \ No newline at end of file diff --git a/embedded/atkstepper17/atkstepper17/pin.h b/embedded/atkstepper17/atkstepper17/pin.h new file mode 100644 index 0000000000000000000000000000000000000000..d7ddab6e023abc0744743c66bfc7686fad2b3bac --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/pin.h @@ -0,0 +1,34 @@ +/* + * pin.h + * + * Created: 6/18/2018 12:22:58 PM + * Author: Jake + */ + + +#ifndef PIN_H_ +#define PIN_H_ + +#include "avr/io.h" + +typedef struct { + PORT_t *port; + uint8_t pin_bm; + uint8_t pin_pos; +}pin_t; + +void pin_init(pin_t *pin, PORT_t *port, uint8_t pin_bm, uint8_t pin_pos, uint8_t inout); + +void pin_output(pin_t *pin); +void pin_set(pin_t *pin); +void pin_clear(pin_t *pin); +void pin_toggle(pin_t *pin); + +void pin_input(pin_t *pin); +void pin_pullup(pin_t *pin); +void pin_pulldown(pin_t *pin); + +uint8_t pin_read(pin_t *pin); + + +#endif /* PIN_H_ */ \ No newline at end of file diff --git a/embedded/atkstepper17/atkstepper17/ringbuffer.c b/embedded/atkstepper17/atkstepper17/ringbuffer.c new file mode 100644 index 0000000000000000000000000000000000000000..a77dc50785ca9153ce3d05a656dd190bb0a59d05 --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/ringbuffer.c @@ -0,0 +1,72 @@ +/* + * ringbuffer.c + * + * Created: 2/7/2018 11:39:44 AM + * Author: Jake + */ + +#include "ringbuffer.h" +#include "fastmath.h" + +uint8_t rb_init(ringbuffer_t *rb){ + rb->size = RINGBUFFER_SIZE; // stuck with this, due to not having malloc, wall of skill + //rb->buffer = malloc(size); + rb_reset(rb); + return 1; +} + +uint8_t rb_reset(ringbuffer_t *rb){ + if(rb){ + rb->head = 0; + rb->tail = 0; + return 1; + } else { + return 0; + } +} + +uint8_t rb_empty(ringbuffer_t *rb){ + return (rb->head == rb->tail); +} + +uint8_t rb_full(ringbuffer_t *rb){ + // read from tail, update at head + // if head is 'just behind' tail (in ring) we have no extra space: the + return fastModulo((rb->head + 1), RINGBUFFER_SIZE) == rb->tail; +} + +uint8_t rb_freespace(ringbuffer_t *rb){ + if(rb->head >= rb->tail){ + return rb->size - (rb->head - rb->tail); + } else { + return rb->tail - rb->head - 1; + } +} + +uint8_t rb_putchar(ringbuffer_t *rb, uint8_t data){ + rb->buffer[rb->head] = data; + rb->head = fastModulo((rb->head + 1), RINGBUFFER_SIZE); // increment and loop about + return 1; +} + +uint8_t rb_putdata(ringbuffer_t *rb, uint8_t *data, uint8_t size){ + /* + if(rb_freespace(rb) >= size){ + // rb_freespace, not working? + return 0; + } else { + */ + for(int i = 0; i < size; i ++){ + rb_putchar(rb, data[i]); + } + + return 1; + //} +} + +uint8_t rb_get(ringbuffer_t *rb){ + uint8_t data = rb->buffer[rb->tail]; + rb->tail = fastModulo((rb->tail + 1), RINGBUFFER_SIZE); + return data; +} + diff --git a/embedded/atkstepper17/atkstepper17/ringbuffer.h b/embedded/atkstepper17/atkstepper17/ringbuffer.h new file mode 100644 index 0000000000000000000000000000000000000000..921c8ba7717b5eedc76175a83f87db0308e6ca5e --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/ringbuffer.h @@ -0,0 +1,43 @@ +/* + * ringbuffer.h + * + * Created: 2/7/2018 11:39:54 AM + * Author: Jake + */ + +#ifndef RINGBUFFER_H_ +#define RINGBUFFER_H_ + +/* +a ringbuffer, +s/o https://github.com/dhess/c-ringbuf +s/o https://embeddedartistry.com/blog/2017/4/6/circular-buffers-in-cc +s/o https://www.downtowndougbrown.com/2013/01/microcontrollers-interrupt-safe-ring-buffers/ +*/ + +#include "avr/io.h" +#include <stdlib.h> // for size_t + +#define RINGBUFFER_SIZE 256 + +typedef struct{ + uint8_t buffer[256]; // static! big enough + size_t head; + size_t tail; + size_t size; +} ringbuffer_t; + +uint8_t rb_init(ringbuffer_t *rb); + +uint8_t rb_reset(ringbuffer_t *rb); + +uint8_t rb_empty(ringbuffer_t *rb); +uint8_t rb_full(ringbuffer_t *rb); +uint8_t rb_freespace(ringbuffer_t *rb); + +uint8_t rb_putchar(ringbuffer_t *rb, uint8_t data); +uint8_t rb_putdata(ringbuffer_t *rb, uint8_t *data, uint8_t size); + +uint8_t rb_get(ringbuffer_t *rb); + +#endif /* RINGBUFFER_H_ */ \ No newline at end of file diff --git a/embedded/atkstepper17/atkstepper17/spiport.c b/embedded/atkstepper17/atkstepper17/spiport.c new file mode 100644 index 0000000000000000000000000000000000000000..a7698bc628f04f00f6730ef8df697754c951b9ed --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/spiport.c @@ -0,0 +1,54 @@ +/* + * spiport.c + * + * Created: 2/7/2018 10:51:42 AM + * Author: Jake + */ + +#include "spiport.h" + +void spi_init(spiport_t *spi, USART_t *com, PORT_t *port, uint8_t miso_bm, uint8_t mosi_bm, uint8_t sck_bm, pin_t *csn){ + spi->com = com; + spi->port = port; + + spi->miso_bm = miso_bm; + spi->mosi_bm = mosi_bm; + spi->sck_bm = sck_bm; + spi->csn = csn; +} + +void spi_start(spiport_t *spi, uint8_t cpha){ + spi->port->DIRSET = spi->mosi_bm; + spi->port->DIRSET = spi->sck_bm; + spi->port->DIRCLR = spi->miso_bm; + + // want BSEL 7 and BSCALE -4 + spi->com->BAUDCTRLA = 0; //130; + spi->com->BAUDCTRLB = 1; //USART_BSCALE3_bm | USART_BSCALE2_bm | USART_BSCALE1_bm | USART_BSCALE0_bm; + + spi->com->CTRLB = USART_TXEN_bm | USART_RXEN_bm; + + spi->com->CTRLC = USART_CMODE_MSPI_gc; // set to master spi mode + if(cpha != 0){ + spi->com->CTRLC |= (1 << 1); // in master spi mode, this bit is clock polarity + } +} + +void spi_txchar_polled(spiport_t *spi, uint8_t data){ + while(!(spi->com->STATUS & USART_DREIF_bm)); + spi->com->DATA = data; +} + +void spi_txchars_polled(spiport_t *spi, uint8_t *data, uint8_t length){ + pin_clear(spi->csn); + for(int i = 0; i < length; i ++){ + spi_txchar_polled(spi, data[i]); + spi->com->STATUS |= USART_TXCIF_bm; // clear transmit complete flag + } + while(!(spi->com->STATUS & USART_TXCIF_bm)); // wait for complete before + pin_set(spi->csn); +} + +void spi_txrxchar_polled(spiport_t *spi, uint8_t data, uint8_t *rxdata){ + // how to read? +} \ No newline at end of file diff --git a/embedded/atkstepper17/atkstepper17/spiport.h b/embedded/atkstepper17/atkstepper17/spiport.h new file mode 100644 index 0000000000000000000000000000000000000000..cd5e5aa10ae4d4a5f85c73acd785d2b727d67650 --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/spiport.h @@ -0,0 +1,35 @@ +/* + * spiport.h + * + * Created: 2/7/2018 10:51:52 AM + * Author: Jake + */ + + +#ifndef SPIPORT_H_ +#define SPIPORT_H_ + +#include <avr/io.h> +#include "pin.h" + +typedef struct{ + USART_t *com; + PORT_t *port; + + uint8_t miso_bm; + uint8_t mosi_bm; + uint8_t sck_bm; + + pin_t *csn; +}spiport_t; + +void spi_init(spiport_t *spi, USART_t *com, PORT_t *port, uint8_t miso_bm, uint8_t mosi_bm, uint8_t sck_bm, pin_t *csn); + +void spi_start(spiport_t *spi, uint8_t cpha); // bits: 0: 8, 1: 32 + +void spi_txchar_polled(spiport_t *spi, uint8_t data); +void spi_txchars_polled(spiport_t *spi, uint8_t *data, uint8_t length); +void spi_txrxchar_polled(spiport_t *spi, uint8_t data, uint8_t *rxdata); + + +#endif /* SPIPORT_H_ */ \ No newline at end of file diff --git a/embedded/atkstepper17/atkstepper17/stepper.c b/embedded/atkstepper17/atkstepper17/stepper.c new file mode 100644 index 0000000000000000000000000000000000000000..8fb78ee0e1bb7ecd35673bbbb1f610a61311a80b --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/stepper.c @@ -0,0 +1,237 @@ +/* +* stepper.c +* +* Created: 2/17/2018 5:39:34 PM +* Author: Jake +*/ + +#include "stepper.h" +#include "hardware.h" +#include "atkport.h" +#include "atkhandler.h" +#include "fastmath.h" + +void stepper_init(stepper_t *stepper, pin_t *step_pin, pin_t *dir_pin){ + stepper->step_pin = step_pin; + stepper->dir_pin = dir_pin; + + stepper_reset(stepper); +} + +void stepper_reset(stepper_t *stepper){ + stepper->blockhead = 0; + stepper->blocktail = 0; + stepper->blocksize = BLOCKS_QUEUE_SIZE; + + stepper->speed_period = 0; + stepper->accel_period = 0; + + stepper->speed = 0; + + stepper->position_ticks = 0; + stepper->position_accel_to = 0; + stepper->position_deccel_from = 0; +} + +void stepper_steps(stepper_t *stepper, int32_t steps, uint32_t speed){ + // not implemented atm +} + +void stepper_new_block(uint8_t *packet, stepper_t *stepper, int32_t steps, uint32_t entryspeed, uint32_t accel, uint32_t accellength, uint32_t deccellength){ + // does assignments and adds to queue + // track this address so that we can ack to it when the move is complete + // a sloppy copy, I'm sure + for(int i = 0; i < packet[0]; i ++){ + stepper->block[stepper->blockhead].packet[i] = packet[i]; + } + + // a real move + stepper->block[stepper->blockhead].is_nomove = 0; + + // TODO: should block the execution of this block while we do this, so that we + // have an interrupt safe ringbuffer + + // enforce no div/0 + (entryspeed < 3) ? entryspeed = 3 : (0); //(0) is NOP: 3 is min steps/s due to timer resolution + (entryspeed > 187500) ? entryspeed = 187500 : (0); // no faster than this pls, else underneat timer resolution + // going to have to catch blocks which cause deceleration to 0 during deceleration phases ! + stepper->block[stepper->blockhead].entry_speed = entryspeed; + + // do starting speed period + (accel < 3) ? accel = 3 : (0); + (accel > 187500) ? accel = 187500 : (0); + stepper->block[stepper->blockhead].accel_period = STEPTICKER_ONE_SECOND / accel; + + // set dir + if(steps < 0){ + stepper->block[stepper->blockhead].dir = 0; + } else { + stepper->block[stepper->blockhead].dir = 1; + } + + // do lengths + stepper->block[stepper->blockhead].position_end = abs(steps); + stepper->block[stepper->blockhead].position_accel_to = accellength; + stepper->block[stepper->blockhead].position_deccel_from = deccellength; + + // ready set + stepper->block[stepper->blockhead].is_new = 1; + + // if there are currently no steps to make, we're not sure about the current step frequency, we'll set the period + // otherwise we're taking for granted that we've set this properly following the last move + if(stepper->blockhead == stepper->blocktail){ + uint16_t newper = STEPTICKER_ONE_SECOND / entryspeed; + stepticker_newperiod(newper); + stepticker_reset(); + uint16_t accper = STEPTICKER_ONE_SECOND / accel; + accelticker_newperiod(accper); + accelticker_reset(); + pin_clear(&stlerr); + } + // increment block head ptr: should catch full queue HERE but not bothering + stepper->blockhead = fastModulo((stepper->blockhead + 1), BLOCKS_QUEUE_SIZE); +} + +void stepper_new_wait(uint8_t *packet, stepper_t *stepper, int32_t steps, uint32_t speed){ + for(int i = 0; i < packet[0]; i ++){ + stepper->block[stepper->blockhead].packet[i] = packet[i]; + } + + // we have a waiting block, we'll say accel is now = speed for supposed steps + stepper->block[stepper->blockhead].is_nomove = 1; + // still need to check this + (speed < 3) ? speed = 3 : (0); + (speed > 187500) ? speed = 187500 : (0); + // but we're going to wrap everything else in update() to avoid accel etc checks, we're just going to be counting + stepper->block[stepper->blockhead].entry_speed = speed; + stepper->block[stepper->blockhead].position_end = abs(steps); + stepper->block[stepper->blockhead].accel_period = STEPTICKER_ONE_SECOND - 1; + stepper->block[stepper->blockhead].position_accel_to = 0; + stepper->block[stepper->blockhead].position_deccel_from = abs(steps); + + // ready set + stepper->block[stepper->blockhead].is_new = 1; + + // if there are currently no steps to make, we're not sure about the current step frequency, we'll set the period + // otherwise we're taking for granted that we've set this properly following the last move + if(stepper->blockhead == stepper->blocktail){ + pin_clear(&stlerr); + // could we just call stepper_update now? + uint16_t newper = STEPTICKER_ONE_SECOND / speed; + stepticker_newperiod(newper); + stepticker_reset(); + uint16_t accper = STEPTICKER_ONE_SECOND - 1; // gets 16-bit truncated + accelticker_newperiod(accper); + accelticker_reset(); + pin_clear(&stlerr); + } + + stepper->blockhead = fastModulo((stepper->blockhead + 1), BLOCKS_QUEUE_SIZE); +} + +void stepper_updatesteps(stepper_t *stepper){ + if(stepper->blockhead == stepper->blocktail){ + // no steps to make, ringbuffer is empty + pin_set(&stlerr); + } else if(stepper->block[stepper->blocktail].position_end > stepper->position_ticks){ + // we have somewhere to go + if(stepper->block[stepper->blocktail].is_new){ + // if we're just starting this block, set the speed + stepper->speed = stepper->block[stepper->blocktail].entry_speed; + stepper->speed_period = STEPTICKER_ONE_SECOND / stepper->speed; + stepticker_newperiod(stepper->speed_period); + stepticker_reset(); + + // and set the accel ticker + accelticker_newperiod(stepper->block[stepper->blocktail].accel_period); + accelticker_reset(); + + // and set the dir + if(stepper->block[stepper->blocktail].dir > 0){ + pin_set(stepper->dir_pin); + } else { + pin_clear(stepper->dir_pin); + } + // and distance was 0'd after last move + // and then clear this flag + stepper->block[stepper->blocktail].is_new = 0; + } + + // if there's steps to make, and this timer is firing, it's time to step! + if(!stepper->block[stepper->blocktail].is_nomove){ + pin_toggle(stepper->step_pin); + } + + stepper->position_ticks ++; + + if(stepper->position_ticks < stepper->block[stepper->blocktail].position_accel_to){ + stepper->accelstate = STEP_ACCELSTATE_ACCEL; + } else if (stepper->position_ticks > stepper->block[stepper->blocktail].position_deccel_from){ + stepper->accelstate = STEP_ACCELSTATE_DECEL; + } else { + stepper->accelstate = STEP_ACCELSTATE_CRUISE; + } + + } else { + // looks a lot like we're done here + // send a reply for windowed transmission + // this is dirty because we're passing the packet (referenced here in the ringbuffer) by reference, + // properly return_packet should take a copy of the packet so that we can be done with it now, but *it* goes faster than *this* (almost for sure...) + // so, we shrugman for now + // apa_return_packet(stepper->block[stepper->blocktail].packet, 25); + uint8_t reply[2]; + if(stepper->block[stepper->blocktail].is_nomove){ + reply[0] = DELIM_KEY_WAIT; + reply[1] = 12; + } else { + reply[0] = DELIM_KEY_TRAPEZOID; + reply[1] = 24; + } + atk_reply_packet(stepper->block[stepper->blocktail].packet, reply, 2); + // increment ringbuffer along + stepper->blocktail = fastModulo((stepper->blocktail + 1), BLOCKS_QUEUE_SIZE); + stepper->position_ticks = 0; // clear so that we evaluate new block as having steps to make + } +} + +void stepper_updateaccel(stepper_t *stepper){ + // check for acceleration or deceleration + switch (stepper->accelstate){ + case STEP_ACCELSTATE_ACCEL: + stepper->speed ++; + (stepper->speed > 187500) ? stepper->speed = 187500 : (0); // max speed due to timer res + stepper->speed_period = STEPTICKER_ONE_SECOND / stepper->speed; + stepticker_newperiod(stepper->speed_period); + break; + case STEP_ACCELSTATE_DECEL: + stepper->speed --; + (stepper->speed < 3) ? stepper->speed = 3 : (0); // min speed due to timer res + stepper->speed_period = STEPTICKER_ONE_SECOND / stepper->speed; + stepticker_newperiod(stepper->speed_period); + break; + case STEP_ACCELSTATE_CRUISE: + (0); + break; + default: + (0); + break; + } +} + +void stepticker_newperiod(uint16_t per){ + TCC0.PERBUFL = (uint8_t) per; + TCC0.PERBUFH = (uint8_t) (per >> 8); +} + +void stepticker_reset(void){ + TCC0.CTRLFSET = TC_CMD_RESTART_gc; +} + +void accelticker_newperiod(uint16_t per){ + TCC1.PERBUFL = (uint8_t) per; + TCC1.PERBUFH = (uint8_t) (per >> 8); +} + +void accelticker_reset(void){ + TCC1.CTRLFSET = TC_CMD_RESTART_gc; +} \ No newline at end of file diff --git a/embedded/atkstepper17/atkstepper17/stepper.h b/embedded/atkstepper17/atkstepper17/stepper.h new file mode 100644 index 0000000000000000000000000000000000000000..e58e77cb6114d131f10cb6536b210d20e440b617 --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/stepper.h @@ -0,0 +1,95 @@ +/* + * stepper.h + * + * Created: 2/17/2018 5:39:45 PM + * Author: Jake + */ + + +#ifndef STEPPER_H_ +#define STEPPER_H_ + +#include "pin.h" + +#define BLOCKS_QUEUE_SIZE 16 +#define STEPTICKER_ONE_SECOND 187500 // one tick of timer is 5.3-- us +#define STEP_ACCELSTATE_CRUISE 0 +#define STEP_ACCELSTATE_ACCEL 1 +#define STEP_ACCELSTATE_DECEL 2 + +// one movement +typedef struct { + // from whence you came + uint8_t packet[256]; // C quesion: how to do this properly with malloc() ? malloc() on embedded sys? + + // tracking + uint8_t is_new; + uint8_t is_nomove; + + // for what you do + uint8_t dir; // 0 or 1 + uint32_t position_end; // in steps + uint32_t entry_speed; + uint32_t accel_period; + uint32_t position_accel_to; + uint32_t position_deccel_from; +}block_t; + +// the stepper +typedef struct { + pin_t *step_pin; + pin_t *dir_pin; + + // block ringbuffer + block_t block[BLOCKS_QUEUE_SIZE]; + uint8_t blockhead; + uint8_t blocktail; + uint8_t blocksize; + + // tracking time periods + uint16_t speed_period; // meaning we have a min. step speed of STEPTICKER_ONE_SECOND / 2^16 ( ~ 2.86 s/s) + uint16_t accel_period; + + // tracking time for updates + uint8_t accelstate; + + // have to track speed to update accel + uint32_t speed; + + // targets + uint32_t position_ticks; + uint32_t position_accel_to; + uint32_t position_deccel_from; +}stepper_t; + +void stepper_init(stepper_t *stepper, pin_t *step_pin, pin_t *dir_pin); + +void stepper_reset(stepper_t *stepper); + +// steps discrete, mm/min +void stepper_steps(stepper_t *stepper, int32_t steps, uint32_t speed); + +// steps discrete, mm/min, mm/min/s (mm/s better but we want more discrete resolution) +void stepper_new_block(uint8_t *packet, stepper_t *stepper, int32_t steps, uint32_t entryspeed, uint32_t accel, uint32_t accellength, uint32_t deccellength); + +void stepper_new_wait(uint8_t *packet, stepper_t *stepper, int32_t steps, uint32_t speed); + +void stepper_updatesteps(stepper_t *stepper); + +void stepper_updateaccel(stepper_t *stepper); + +void stepticker_newperiod(uint16_t per); + +void stepticker_reset(void); + +void accelticker_newperiod(uint16_t per); + +void accelticker_reset(void); + +/* +step to-do +// block ringbuffer, pull and reply blocks - architecture for network functions, generally? +// doc this https://embeddedgurus.com/stack-overflow/2011/02/efficient-c-tip-13-use-the-modulus-operator-with-caution/ +*/ + +#endif /* STEPPER_H_ */ \ No newline at end of file diff --git a/embedded/atkstepper17/atkstepper17/tmc26x.c b/embedded/atkstepper17/atkstepper17/tmc26x.c new file mode 100644 index 0000000000000000000000000000000000000000..da44efd69cc754cf05861e8badc58aaef49662e6 --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/tmc26x.c @@ -0,0 +1,74 @@ +/* + * tmc26x.c + * + * Created: 2/7/2018 10:17:39 PM + * Author: Jake + */ + +#include "tmc26x.h" + +void tmc26_init(tmc26_t *tmc, spiport_t *spi, pin_t *en, pin_t *sg){ + tmc->spi = spi; + tmc->en_pin = en; + tmc->sg_pin = sg; +} + +void tmc26_write(tmc26_t *tmc, uint32_t word){ + // takes a 20-bit TMC ready word and writes it on the SPI port, using three 8-bit words + //word = word << 4; // go left for 4 empty bits at the end of byte 3 (20 not 24 bit word) + uint8_t bytes[3]; + bytes[0] = word >> 16;// | 0b11110000; // top 4 & mask for visibility + bytes[1] = word >> 8; // middle 8 + bytes[2] = word; // last 4 and 0's + spi_txchars_polled(tmc->spi, bytes, 3); +} + +void tmc26_start(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, + // enable step/dir, sense resistor full scale current voltage is 0.16mv, readback stallguard2 data, reserved + uint32_t drvconf = 0b11100000000000110000; + tmc26_write(tmc, drvconf); + + // address, sgfilt off, threshold value, current scaling (5-bit value appended) + uint32_t sgthresh_mask = 0b00000111111100000000; + int32_t sgthres_val = 60; + uint32_t cscale_mask = 0b00000000000000011111; + uint32_t cscale_val = 6; + uint32_t sgcsconf = 0b11010000000000000000 | ((sgthres_val << 8) & sgthresh_mask) | (cscale_val & cscale_mask); + tmc26_write(tmc, sgcsconf); + + // turning coolstep off + uint32_t smarten = 0b10100000000000000000; + tmc26_write(tmc, smarten); + + // times, delays, cycle mode + uint32_t chopconf = 0b10011000001000010011; + tmc26_write(tmc, chopconf); + + // 9th bit is intpol, 8th is dedge, last 4 are microstepping + // 0101 8 + // 0100 16 + // 0011 32 + // 0010 64 + // 0001 128 + // 0000 256 + uint32_t drvctrl = 0b00000000001100000100; + tmc26_write(tmc, drvctrl); +} + +void tmc26_update(tmc26_t *tmc){ + uint32_t smarten = 0b10100000000000000000; + tmc26_write(tmc, smarten); +} + +void tmc26_enable(tmc26_t *tmc){ + pin_clear(tmc->en_pin); +} + +void tmc26_disable(tmc26_t *tmc){ + pin_set(tmc->en_pin); +} \ No newline at end of file diff --git a/embedded/atkstepper17/atkstepper17/tmc26x.h b/embedded/atkstepper17/atkstepper17/tmc26x.h new file mode 100644 index 0000000000000000000000000000000000000000..a9f1e61edde58a1715c1639bb79bde584ca564a3 --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/tmc26x.h @@ -0,0 +1,38 @@ +/* + * tmc26x.h + * + * Created: 2/7/2018 10:17:49 PM + * Author: Jake + */ + + +#ifndef TMC26X_H_ +#define TMC26X_H_ + +#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 *en_pin; + pin_t *sg_pin; +}tmc26_t; + +void tmc26_init(tmc26_t *tmc, spiport_t *spi, pin_t *en, pin_t *sg); + +void tmc26_write(tmc26_t *tmc, uint32_t word); + +void tmc26_start(tmc26_t *tmc); + +void tmc26_update(tmc26_t *tmc); + +void tmc26_enable(tmc26_t *tmc); + +void tmc26_disable(tmc26_t *tmc); + +#endif /* TMC2660_H_ */ \ No newline at end of file diff --git a/embedded/atkstepper17/atkstepper17/uartport.c b/embedded/atkstepper17/atkstepper17/uartport.c new file mode 100644 index 0000000000000000000000000000000000000000..8b51d63cb10a34774577d7b82e0f7937fcecd41e --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/uartport.c @@ -0,0 +1,70 @@ +/* + * uartport.c + * + * Created: 6/18/2018 12:12:32 PM + * Author: Jake + */ + +#include "uartport.h" +#include "hardware.h" + +void uart_init(uartport_t *up, USART_t *uart, PORT_t *port, uint8_t pinRX_bm, uint8_t pinTX_bm, ringbuffer_t *rbrx, ringbuffer_t *rbtx, pin_t *stlrx, pin_t *stltx){ + up->uart = uart; + up->port = port; + up->pinRX_bm = pinRX_bm; + up->pinTX_bm = pinTX_bm; + up->rbrx = rbrx; + up->rbtx = rbtx; + up->stlrx = stlrx; + up->stltx = stltx; +} + +void uart_start(uartport_t *up, uint8_t BAUDA, uint8_t BAUDB){ + up->uart->BAUDCTRLA = BAUDA; + up->uart->BAUDCTRLB = BAUDB; + + up->uart->CTRLA |= USART_RXCINTLVL_MED_gc | USART_TXCINTLVL_OFF_gc | USART_DREINTLVL_OFF_gc; + + up->uart->CTRLB = USART_TXEN_bm | USART_RXEN_bm; + + // should try that parity + up->uart->CTRLC = USART_CMODE_ASYNCHRONOUS_gc | USART_PMODE_DISABLED_gc | USART_CHSIZE_8BIT_gc; + + up->port->DIRCLR = up->pinRX_bm; + up->port->DIRSET = up->pinTX_bm; + + pin_set(up->stlrx); + pin_set(up->stltx); +} + +void uart_sendchar_polled(uartport_t *up, uint8_t data){ + while(!(up->uart->STATUS & USART_DREIF_bm)); + up->uart->DATA = data; +} + +void uart_sendchar_buffered(uartport_t *up, uint8_t data){ + rb_putchar(up->rbtx, data); + pin_clear(up->stltx); + up->uart->CTRLA |= USART_DREINTLVL_MED_gc; +} + +void uart_sendchars_buffered(uartport_t *up, uint8_t *data, uint8_t length){ + rb_putdata(up->rbtx, data, length); + pin_clear(up->stltx); + up->uart->CTRLA |= USART_DREINTLVL_MED_gc; +} + +void uart_rxhandler(uartport_t *up){ + uint8_t data = up->uart->DATA; + rb_putchar(up->rbrx, data); + pin_clear(up->stlrx); +} + +void uart_txhandler(uartport_t *up){ + if(!rb_empty(up->rbtx)){ + up->uart->DATA = rb_get(up->rbtx); + } else { + up->uart->CTRLA = USART_DREINTLVL_OFF_gc | USART_RXCINTLVL_MED_gc; + pin_set(up->stltx); + } +} \ No newline at end of file diff --git a/embedded/atkstepper17/atkstepper17/uartport.h b/embedded/atkstepper17/atkstepper17/uartport.h new file mode 100644 index 0000000000000000000000000000000000000000..72fa539b121a11546dddae9a76892d4ad2ef0315 --- /dev/null +++ b/embedded/atkstepper17/atkstepper17/uartport.h @@ -0,0 +1,42 @@ +/* + * uartport.h + * + * Created: 6/18/2018 12:12:43 PM + * Author: Jake + */ + + +#ifndef UARTPORT_H_ +#define UARTPORT_H_ + +#include "avr/io.h" +#include "ringbuffer.h" +#include "pin.h" + +typedef struct{ + USART_t *uart; + PORT_t *port; + + uint8_t pinRX_bm; + uint8_t pinTX_bm; + + ringbuffer_t *rbrx; + ringbuffer_t *rbtx; + + pin_t *stlrx; + pin_t *stltx; + +}uartport_t; + +void uart_init(uartport_t *up, USART_t *uart, PORT_t *port, uint8_t pinRX_bm, uint8_t pinTX_bm, ringbuffer_t *rbrx, ringbuffer_t *rbtx, pin_t *stlrx, pin_t *stltx); + +void uart_start(uartport_t *up, uint8_t BAUDA, uint8_t BAUDB); + +void uart_sendchar_polled(uartport_t *up, uint8_t data); +void uart_sendchar_buffered(uartport_t *up, uint8_t data); +void uart_sendchars_buffered(uartport_t *up, uint8_t *data, uint8_t length); + +void uart_rxhandler(uartport_t *up); +void uart_txhandler(uartport_t *up); + +#endif /* UARTPORT_H_ */ \ No newline at end of file diff --git a/embedded/atkstepper23/atkstepper23/atkhandler.c b/embedded/atkstepper23/atkstepper23/atkhandler.c index 85c6ce94cb50ff4269c876a03a4de57071a2d6c1..b0decb920d6defc5f52df04eba9136cca660028b 100644 --- a/embedded/atkstepper23/atkstepper23/atkhandler.c +++ b/embedded/atkstepper23/atkstepper23/atkhandler.c @@ -30,6 +30,7 @@ void atk_handle_packet(uint8_t *packet, uint8_t length){ case ATK_HANDLER_INSIDE: switch (packet[i]){ case DELIM_KEY_TEST: + pin_toggle(&stlerr); // see the packet, make sure you're not doing something else with this light atk_reply_packet(packet, testReply, 4); i ++; @@ -59,6 +60,17 @@ void atk_handle_packet(uint8_t *packet, uint8_t length){ stepper_new_block(packet, &stepper, steps, entryspeed, accel, accellength, deccellength); } break; + + case DELIM_KEY_WAIT: + if(i + 8 > length){ + i ++; + } else { + steps = ((int32_t)packet[i+1] << 24) | ((int32_t)packet[i+2] << 16) | ((int32_t)packet[i+3] << 8) | (int32_t)packet[i+4]; + // in steps/s + uint32_t speed = ((int32_t)packet[i+5] << 24) | ((int32_t)packet[i+6] << 16) | ((int32_t)packet[i+7] << 8) | (int32_t)packet[i+8]; + i += 8; + stepper_new_wait(packet, &stepper, steps, speed); + } default: // probably an error diff --git a/embedded/atkstepper23/atkstepper23/atkhandler.h b/embedded/atkstepper23/atkstepper23/atkhandler.h index d676f9a5740f698671fd9ce71379ad2f7f834d68..1b6879aa507d2433667ff90eda849c58a8c25f65 100644 --- a/embedded/atkstepper23/atkstepper23/atkhandler.h +++ b/embedded/atkstepper23/atkstepper23/atkhandler.h @@ -18,6 +18,7 @@ #define DELIM_KEY_RESET 128 #define DELIM_KEY_TRAPEZOID 131 +#define DELIM_KEY_WAIT 132 void atk_handle_packet(uint8_t *packet, uint8_t length); diff --git a/embedded/atkstepper23/atkstepper23/main.c b/embedded/atkstepper23/atkstepper23/main.c index 52521e26e4f6ec45c329568dac92a9b9f29e57f8..cf19332b78d02d7c9cfe076ba5ea374db194079c 100644 --- a/embedded/atkstepper23/atkstepper23/main.c +++ b/embedded/atkstepper23/atkstepper23/main.c @@ -129,8 +129,8 @@ int main(void) tck++; // this modulo op is slow AF // that means streamlining atkport_scan without modulos is probably a rad thing - if(!(fastModulo(tck, 16384))){ - //pin_toggle(&stlclk); + if(!(fastModulo(tck, 4096))){ + pin_toggle(&stlclk); } } } diff --git a/embedded/atkstepper23/atkstepper23/stepper.c b/embedded/atkstepper23/atkstepper23/stepper.c index 656ab0b1f1f353e53e198506133c620b9b493e74..8fb78ee0e1bb7ecd35673bbbb1f610a61311a80b 100644 --- a/embedded/atkstepper23/atkstepper23/stepper.c +++ b/embedded/atkstepper23/atkstepper23/stepper.c @@ -45,84 +45,94 @@ void stepper_new_block(uint8_t *packet, stepper_t *stepper, int32_t steps, uint3 stepper->block[stepper->blockhead].packet[i] = packet[i]; } - if(entryspeed == 0){ - // we have a waiting block, we'll say accel is now = speed for supposed steps - stepper->block[stepper->blockhead].is_nomove = 1; - // still need to check this - (accel < 3) ? accel = 3 : (0); - (accel > 187500) ? accel = 187500 : (0); - // but we're going to wrap everything else in update() to avoid accel etc checks, we're just going to be counting - stepper->block[stepper->blockhead].entry_speed = accel; - stepper->block[stepper->blockhead].position_end = abs(steps); - stepper->block[stepper->blockhead].accel_period = STEPTICKER_ONE_SECOND; - stepper->block[stepper->blockhead].position_accel_to = 0; - stepper->block[stepper->blockhead].position_deccel_from = abs(steps); - - // ready set - stepper->block[stepper->blockhead].is_new = 1; - - // if there are currently no steps to make, we're not sure about the current step frequency, we'll set the period - // otherwise we're taking for granted that we've set this properly following the last move - if(stepper->blockhead == stepper->blocktail){ - // could we just call stepper_update now? - uint16_t newper = STEPTICKER_ONE_SECOND / accel; - stepticker_newperiod(newper); - stepticker_reset(); - uint16_t accper = 65536; // gets 16-bit truncated - accelticker_newperiod(accper); - accelticker_reset(); - } + // a real move + stepper->block[stepper->blockhead].is_nomove = 0; + + // TODO: should block the execution of this block while we do this, so that we + // have an interrupt safe ringbuffer + + // enforce no div/0 + (entryspeed < 3) ? entryspeed = 3 : (0); //(0) is NOP: 3 is min steps/s due to timer resolution + (entryspeed > 187500) ? entryspeed = 187500 : (0); // no faster than this pls, else underneat timer resolution + // going to have to catch blocks which cause deceleration to 0 during deceleration phases ! + stepper->block[stepper->blockhead].entry_speed = entryspeed; + + // do starting speed period + (accel < 3) ? accel = 3 : (0); + (accel > 187500) ? accel = 187500 : (0); + stepper->block[stepper->blockhead].accel_period = STEPTICKER_ONE_SECOND / accel; + + // set dir + if(steps < 0){ + stepper->block[stepper->blockhead].dir = 0; } else { - // a real move - stepper->block[stepper->blockhead].is_nomove = 0; - - // TODO: should block the execution of this block while we do this, so that we - // have an interrupt safe ringbuffer - - // enforce no div/0 - (entryspeed < 3) ? entryspeed = 3 : (0); //(0) is NOP: 3 is min steps/s due to timer resolution - (entryspeed > 187500) ? entryspeed = 187500 : (0); // no faster than this pls, else underneat timer resolution - // going to have to catch blocks which cause deceleration to 0 during deceleration phases ! - stepper->block[stepper->blockhead].entry_speed = entryspeed; - - // do starting speed period - (accel < 3) ? accel = 3 : (0); - (accel > 187500) ? accel = 187500 : (0); - stepper->block[stepper->blockhead].accel_period = STEPTICKER_ONE_SECOND / accel; - - // set dir - if(steps < 0){ - stepper->block[stepper->blockhead].dir = 0; - } else { - stepper->block[stepper->blockhead].dir = 1; - } - - // do lengths - stepper->block[stepper->blockhead].position_end = abs(steps); - stepper->block[stepper->blockhead].position_accel_to = accellength; - stepper->block[stepper->blockhead].position_deccel_from = deccellength; - - // ready set - stepper->block[stepper->blockhead].is_new = 1; - - // if there are currently no steps to make, we're not sure about the current step frequency, we'll set the period - // otherwise we're taking for granted that we've set this properly following the last move - if(stepper->blockhead == stepper->blocktail){ - uint16_t newper = STEPTICKER_ONE_SECOND / entryspeed; - stepticker_newperiod(newper); - stepticker_reset(); - uint16_t accper = STEPTICKER_ONE_SECOND / accel; - accelticker_newperiod(accper); - accelticker_reset(); - } + stepper->block[stepper->blockhead].dir = 1; + } + + // do lengths + stepper->block[stepper->blockhead].position_end = abs(steps); + stepper->block[stepper->blockhead].position_accel_to = accellength; + stepper->block[stepper->blockhead].position_deccel_from = deccellength; + + // ready set + stepper->block[stepper->blockhead].is_new = 1; + + // if there are currently no steps to make, we're not sure about the current step frequency, we'll set the period + // otherwise we're taking for granted that we've set this properly following the last move + if(stepper->blockhead == stepper->blocktail){ + uint16_t newper = STEPTICKER_ONE_SECOND / entryspeed; + stepticker_newperiod(newper); + stepticker_reset(); + uint16_t accper = STEPTICKER_ONE_SECOND / accel; + accelticker_newperiod(accper); + accelticker_reset(); + pin_clear(&stlerr); } // increment block head ptr: should catch full queue HERE but not bothering stepper->blockhead = fastModulo((stepper->blockhead + 1), BLOCKS_QUEUE_SIZE); } +void stepper_new_wait(uint8_t *packet, stepper_t *stepper, int32_t steps, uint32_t speed){ + for(int i = 0; i < packet[0]; i ++){ + stepper->block[stepper->blockhead].packet[i] = packet[i]; + } + + // we have a waiting block, we'll say accel is now = speed for supposed steps + stepper->block[stepper->blockhead].is_nomove = 1; + // still need to check this + (speed < 3) ? speed = 3 : (0); + (speed > 187500) ? speed = 187500 : (0); + // but we're going to wrap everything else in update() to avoid accel etc checks, we're just going to be counting + stepper->block[stepper->blockhead].entry_speed = speed; + stepper->block[stepper->blockhead].position_end = abs(steps); + stepper->block[stepper->blockhead].accel_period = STEPTICKER_ONE_SECOND - 1; + stepper->block[stepper->blockhead].position_accel_to = 0; + stepper->block[stepper->blockhead].position_deccel_from = abs(steps); + + // ready set + stepper->block[stepper->blockhead].is_new = 1; + + // if there are currently no steps to make, we're not sure about the current step frequency, we'll set the period + // otherwise we're taking for granted that we've set this properly following the last move + if(stepper->blockhead == stepper->blocktail){ + pin_clear(&stlerr); + // could we just call stepper_update now? + uint16_t newper = STEPTICKER_ONE_SECOND / speed; + stepticker_newperiod(newper); + stepticker_reset(); + uint16_t accper = STEPTICKER_ONE_SECOND - 1; // gets 16-bit truncated + accelticker_newperiod(accper); + accelticker_reset(); + pin_clear(&stlerr); + } + + stepper->blockhead = fastModulo((stepper->blockhead + 1), BLOCKS_QUEUE_SIZE); +} + void stepper_updatesteps(stepper_t *stepper){ if(stepper->blockhead == stepper->blocktail){ // no steps to make, ringbuffer is empty + pin_set(&stlerr); } else if(stepper->block[stepper->blocktail].position_end > stepper->position_ticks){ // we have somewhere to go if(stepper->block[stepper->blocktail].is_new){ @@ -171,14 +181,13 @@ void stepper_updatesteps(stepper_t *stepper){ // apa_return_packet(stepper->block[stepper->blocktail].packet, 25); uint8_t reply[2]; if(stepper->block[stepper->blocktail].is_nomove){ - reply[0] = 131; + reply[0] = DELIM_KEY_WAIT; reply[1] = 12; } else { - reply[0] = 131; + reply[0] = DELIM_KEY_TRAPEZOID; reply[1] = 24; } atk_reply_packet(stepper->block[stepper->blocktail].packet, reply, 2); - // increment ringbuffer along stepper->blocktail = fastModulo((stepper->blocktail + 1), BLOCKS_QUEUE_SIZE); stepper->position_ticks = 0; // clear so that we evaluate new block as having steps to make @@ -189,23 +198,23 @@ void stepper_updateaccel(stepper_t *stepper){ // check for acceleration or deceleration switch (stepper->accelstate){ case STEP_ACCELSTATE_ACCEL: - stepper->speed ++; - (stepper->speed > 187500) ? stepper->speed = 187500 : (0); // max speed due to timer res - stepper->speed_period = STEPTICKER_ONE_SECOND / stepper->speed; - stepticker_newperiod(stepper->speed_period); - break; + stepper->speed ++; + (stepper->speed > 187500) ? stepper->speed = 187500 : (0); // max speed due to timer res + stepper->speed_period = STEPTICKER_ONE_SECOND / stepper->speed; + stepticker_newperiod(stepper->speed_period); + break; case STEP_ACCELSTATE_DECEL: - stepper->speed --; - (stepper->speed < 3) ? stepper->speed = 3 : (0); // min speed due to timer res - stepper->speed_period = STEPTICKER_ONE_SECOND / stepper->speed; - stepticker_newperiod(stepper->speed_period); - break; + stepper->speed --; + (stepper->speed < 3) ? stepper->speed = 3 : (0); // min speed due to timer res + stepper->speed_period = STEPTICKER_ONE_SECOND / stepper->speed; + stepticker_newperiod(stepper->speed_period); + break; case STEP_ACCELSTATE_CRUISE: - (0); - break; + (0); + break; default: - (0); - break; + (0); + break; } } diff --git a/embedded/atkstepper23/atkstepper23/stepper.h b/embedded/atkstepper23/atkstepper23/stepper.h index 562f8c39d17d34f75db74975763e02a53c334adf..e58e77cb6114d131f10cb6536b210d20e440b617 100644 --- a/embedded/atkstepper23/atkstepper23/stepper.h +++ b/embedded/atkstepper23/atkstepper23/stepper.h @@ -72,6 +72,8 @@ void stepper_steps(stepper_t *stepper, int32_t steps, uint32_t speed); // steps discrete, mm/min, mm/min/s (mm/s better but we want more discrete resolution) void stepper_new_block(uint8_t *packet, stepper_t *stepper, int32_t steps, uint32_t entryspeed, uint32_t accel, uint32_t accellength, uint32_t deccellength); +void stepper_new_wait(uint8_t *packet, stepper_t *stepper, int32_t steps, uint32_t speed); + void stepper_updatesteps(stepper_t *stepper); void stepper_updateaccel(stepper_t *stepper);