From 3d1c1596bc07fe8d3d51efad44cd85fb97953258 Mon Sep 17 00:00:00 2001 From: PropGit Date: Tue, 23 Feb 2021 09:06:11 -0800 Subject: [PATCH] Updated Greg LaPolla's ILI9341 and added Bill Tuss's Stepper objects. --- .gitattributes | 2 + docs/p2.md | 2 + libraries/community/p2/All/Stepper/README.md | 23 + .../p2/All/Stepper/Step driver2 info.pdf | Bin 0 -> 131 bytes .../p2/All/Stepper/Step_driver2_cc.spin2 | 322 ++++++++ .../p2/All/Stepper/Step_driver2_sd.spin2 | 317 ++++++++ .../p2/All/Stepper/sine wave stepper.xlsx | 3 + .../p2/All/Stepper/step_driver2 demo.spin2 | 232 ++++++ .../p2/All/Stepper/stepper_sin_fc.pdf | Bin 0 -> 130 bytes .../p2/All/ili9341/Demo_ILI9341_XPT2046.spin2 | 699 ++++++++++++++++++ .../p2/All/ili9341/ILI9341-test.spin2 | 102 --- .../community/p2/All/ili9341/ILI9341.spin2 | Bin 50768 -> 0 bytes .../p2/All/ili9341/LCD_ILI9341_XPT2046.spin2 | Bin 0 -> 194926 bytes libraries/community/p2/All/ili9341/README.md | 10 +- .../community/p2/Motor Control/README.md | 2 + 15 files changed, 1607 insertions(+), 107 deletions(-) create mode 100644 libraries/community/p2/All/Stepper/README.md create mode 100644 libraries/community/p2/All/Stepper/Step driver2 info.pdf create mode 100644 libraries/community/p2/All/Stepper/Step_driver2_cc.spin2 create mode 100644 libraries/community/p2/All/Stepper/Step_driver2_sd.spin2 create mode 100644 libraries/community/p2/All/Stepper/sine wave stepper.xlsx create mode 100644 libraries/community/p2/All/Stepper/step_driver2 demo.spin2 create mode 100644 libraries/community/p2/All/Stepper/stepper_sin_fc.pdf create mode 100644 libraries/community/p2/All/ili9341/Demo_ILI9341_XPT2046.spin2 delete mode 100644 libraries/community/p2/All/ili9341/ILI9341-test.spin2 delete mode 100644 libraries/community/p2/All/ili9341/ILI9341.spin2 create mode 100644 libraries/community/p2/All/ili9341/LCD_ILI9341_XPT2046.spin2 diff --git a/.gitattributes b/.gitattributes index 83b55b8f..c3d5d7d8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,4 @@ docs/assets/P2_Silicon-1.JPG filter=lfs diff=lfs merge=lfs -text *.zip filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.xlsx filter=lfs diff=lfs merge=lfs -text diff --git a/docs/p2.md b/docs/p2.md index 8374dadf..2671533c 100644 --- a/docs/p2.md +++ b/docs/p2.md @@ -211,6 +211,8 @@ by Dave Hein ## Recent Activity ##### _Full details [here](https://github.com/parallaxinc/propeller/pulls?q=is%3Aclosed)._ +* Added Bill Tuss's [Stepper Motor Driver](https://github.com/parallaxinc/propeller/tree/master/libraries/community/p2/All/Stepper) +* Updated Greg LaPolla's P2 [ILI9341](https://github.com/parallaxinc/propeller/tree/master/libraries/community/p2/All/ili9341) object * Added Jon "JonnyMac" McPhalen's [DHTxx Temperature/Humidity](https://github.com/parallaxinc/propeller/tree/master/libraries/community/p2/All/jm_dhtxx) object * Added object from Greg LaPolla's * P1 [ADS1118 C](https://github.com/parallaxinc/propeller/tree/master/libraries/community/p1/All/ads1118/C) diff --git a/libraries/community/p2/All/Stepper/README.md b/libraries/community/p2/All/Stepper/README.md new file mode 100644 index 00000000..8db7e774 --- /dev/null +++ b/libraries/community/p2/All/Stepper/README.md @@ -0,0 +1,23 @@ +# Stepper Motor Driver Ver 2 + +## Author +Bill Tuss (forum: btuss) + +## Language +Spin2, PASM2 + +## Created: +February 9, 2021 + +## Category +Motor control + +## Description +This object implements a step motor driver. +The trajectory is sinusoidal, ramp up, a period at constant speed, ramp down. +A STOP input is monitored that will decelerate the motor to a stop in a controlled fashion. +There are two versions. One for drivers that use step and direction inputs and one for drivers with cw and ccw inputs. +A demo program in spin2 is included. + +## License +MIT (see end of source code) diff --git a/libraries/community/p2/All/Stepper/Step driver2 info.pdf b/libraries/community/p2/All/Stepper/Step driver2 info.pdf new file mode 100644 index 0000000000000000000000000000000000000000..46b975e2133dfeb108ad198a15f9c2b50d7eadb2 GIT binary patch literal 131 zcmWN?OA^8$3;@tQr|1PN;S(Bqo0100j7rB~7oJ|<=3VmE)?d>x#;L2d_cm^is`LNj zQ)cc@tEaHNoat?!^w>P6wM0*txk@B}k~nNd_Jy4+*{9@db`CMt07ytdfH(^0iU_cW Of@HLPWm*t2f%yReJtrLi literal 0 HcmV?d00001 diff --git a/libraries/community/p2/All/Stepper/Step_driver2_cc.spin2 b/libraries/community/p2/All/Stepper/Step_driver2_cc.spin2 new file mode 100644 index 00000000..42f4c702 --- /dev/null +++ b/libraries/community/p2/All/Stepper/Step_driver2_cc.spin2 @@ -0,0 +1,322 @@ +{P2 Stepper motor driver } + + +CON + + +VAR + long cog ' cog flag/id + + long CP 'current position + long SPD 'Speed in steps/sec + long STM 'steps to move +/- Routine clears this after values are read + long Asteps 'Number of steps for acceleration phase + long Offset 'degrees at ends of range to skip + + + long MODEb 'mode bits + 'b0 = 0 - stopped, 1 - moving + 'b1 = 1 - accel + 'b2 = 1 - decel + 'b3 = 1 - at slew speed + 'b4 = direction, 1=cw + 'b5 1 = decel to stop + + long sspn 'SSPIN - set to 0 to stop, 1 to start + long cwpin 'cw pin to driver + long ccwpin 'ccw pin to driver + long frequency 'clock frequency + long del + long vel + long as + long ds + long ss + long stn + + +PUB start(sp, cw, ccw): result + stop() + longmove(@sspn, @sp, 3) ' save pins + frequency := clkfreq + cog := COGINIT(COGEXEC_NEW,@_begin,@cp) +1 + return cog + +PUB stop() + +'' Stop stepper driver +'' -- frees a cog if driver was running + + if (cog) ' cog active? + cogstop(cog-1) ' yes, shut it down + cog := 0 ' and mark stopped + +PUB move(sp,st)| t + + asteps := sp/10 +2 'effectively sets max acceleration + t := abs(st/2) + offset := 40 + if asteps > t + asteps := t 'limits accel/ decel steps to 1/2 the total steps + ss := abs(st) - (asteps*2) + if ss == 0 + sp := 10*(asteps -2) 'limit acceleration for short moves + + longmove(@spd, @sp, 2) 'copy values - start the move + +PUB getpos(): result + return @cp + +PUB getsteps(): result + return @stm + +PUB getmode(): result + return @modeb + +PUB getoff(): result + return @offset + +PUB getvel(): result + return @vel + +PUB getas(): result + return @asteps + +PUB getss(): result + return @ss + + +DAT ORG 0 + +_begin mov ptrb, ptra + add ptrb, #24 '4 bytes * 6 longs + setq #4-1 + rdlong sspin,ptrb[0] 'get three pin numbers and frequency + + drvl cwpn + drvl ccwpn + +_stopped rdlong steps, ptra[2] wz 'wait for steps to be non zero + if_z jmp #_stopped + + setq #5-1 'get 5 parameters from hub + rdlong cpos, ptra[0] + + wrlong #0, ptra[2] 'set steps to zero to indicate we received them + + ' wrlong astps, ptra[12] + ' wrlong angoff, ptra[13] + + drvl cwpn + drvl ccwpn + mov stepp, cwpn 'anticipate cw + mov mode, #0 + abs steps wc 'convert neg steps to pos + muxc mode, #16 + if_nc jmp #_dirset 'set direction pin based on c D[31] + mov stepp, ccwpn 'if ccw swap the pins +_dirset wrlong mode, ptra[5] 'output the mode with dir bit set + +_setup mov halfsp, speed + shr halfsp, #1 'make half speed variable + + mov stepn, #0 + mov stom, steps + mov newmin, angoff + mov newrange, n360 + sub newrange, angoff + sub newrange, angoff 'newrange = angoff to (360-angoff) + shl newmin, #7 'partial multiply x128 11930464/128 = 93206 remaining + mov xsteps, #0 + mov t3, astps + shl t3, #1 'x2 - accel and decel + cmp t3, stom wc 'more than accel + decel steps? + if_nc jmp #_waitstart + mov xsteps, steps + sub xsteps, t3 'xsteps = excess steps above accel +decel or zero + mov stom, t3 + + +'****************************************************************************************************** + +_waitstart testp sspin wc 'wait for start pin = 1 + if_nc jmp #_waitstart + + or mode, #%011 'moving, accel + wrlong mode, ptra[5] + call #_dostep 'output a step + +_mainloop testp sspin wc 'still in run mode? + if_c jmp #_mlp1 'yes, keep running + 'if stop pressed + or mode, #%100000 'turn on decel_to_stop + sub steps, xsteps + mov xsteps, #0 + +_mlp1 cmp astps, stepn wz 'done accelerating? + if_z jmp # _mlp2 + if_nz call #_waitstep + jmp #_mainloop + +_mlp2 cmp xsteps, #1 wz 'wait till the last at_speed step + if_z jmp #_checknextmove + +_mlp3 tjz xsteps, #_mlp5 'if xsteps = 0, decelerate +_mlp4 andn mode, #%01110 'acceleration done + or mode, #%01000 'set mode -> at speed + jmp #_mlp6 + +_mlp5 andn mode, #%01110 + or mode, #%00100 'set mode -> decel + wrlong t2, ptra[11] 'output top speed + +_mlp6 wrlong mode, ptra[5] + call #_waitstep + jmp #_mainloop + +'****************************************************************************************************** + +_checknextmove + rdlong steps2, ptra[2] wz + if_z jmp #_mlp3 'no new move to consider + + mov t1, #0 'else- check if direction is same + abs steps2 wc 'convert neg steps to pos + muxc t1, #16 'set direction bit + mov t2, mode + and t2, #%10000 'clear all but direction bit + cmp t1, t2 wz ' is direction the same as current + if_nz jmp #_mlp3 'direction is different we need to stop before starting next move + + rdlong speed2, ptra[1] + cmp speed, speed2 wz 'is speed the same + if_nz jmp #_mlp3 'not the same, can't continue + +_same_speed add steps, steps2 'add new steps to current steps + add xsteps, steps2 'new steps are all at_speed steps + wrlong #0, ptra[2] 'set steps to zero to indicate we received them + jmp #_mlp4 + +'***************************************************************************************************** + +_waitstep waitct2 'wait for the delay period to end + 'then start another pulse +_dostep tjnz steps, #_dostep1 'zero steps left, we're done + pop t1 'pop the unused return address + and mode, #%0100000 'indicate stopped but leave b5 set if decelerate_to_stop + wrlong cpos, ptra[0] + wrlong mode, ptra[5] + jmp #_stopped + +_dostep1 drvh stepp 'step pin high + getct cv + addct1 cv,delayh 'start the pulse high timer + + testb mode, #4 wc 'check the direction bit + sumc cpos, #1 'add/subtract from current position + wrlong cpos, ptra[0] 'update current position + + waitct1 + drvl stepp 'step pulse end + +_ws1 testb mode, #3 wc 'at speed? + if_c sub xsteps, #1 'yes, dec xsteps + if_c jmp #_ws2 'yes, keep old delay + + call #_getdelay 'get new delay if accel or decel + +_ws2 addct2 cv, delay 'start the delay timer + sub steps, #1 'decrement the steps to go + testb mode, #3 wc 'mode = at speed? + if_nc add stepn, #1 'inc stepn if not + ret + +_getdelay qmul stepn, newrange 'scale step to range angoff - (360 - angoff) + getqx t1 + shl t1, #7 'partial multiply *32 + qdiv t1, stom + getqx newvalue + add newvalue, newmin 'new value is converted oldvalue + qmul newvalue, mult 'finish multiply * 93206 + getqx newvalue + qrotate halfsp, newvalue 'get cosine of vector + getqx t1 + mov t2, halfsp + sub t2, t1 'get velocity + + fges t2, #1 'avoid divide by zero + qdiv freq, t2 'delay = frequency/ velocity + getqx delay + fles delay, maxdelay + ret + + +'----------------------------------------------------------------------------------------------- + +delayh long 1000 'step output high time 1000/200_000_000 = 5µs +delay long 1 'delay between steps - calculated +n360 long 360 'the number 360 +mult long 93206 '372827 * 32 = 11930464 * 360 = FFFFFFFF = 4294967295 = 359.999999999degress +maxdelay long 95000000 + +cpos res 1 'current position - steps +speed res 1 'speed -steps/sec +steps res 1 'steps to move +astps res 1 'accel/ decel steps +angoff res 1 + +mode res 1 'b0 = 0 - stopped, 1 - moving + 'b1 = 1 - accel + 'b2 = 1 - decel + 'b3 = 1 - at slew speed + 'b4 = 1 direction = cw + +sspin res 1 'start =1 stop =0 pin (input) +cwpn res 1 'output to driver +ccwpn res 1 ' " +freq res 1 'system clock frequency + +stepp res 1 'depending on direction, either cwpn or ccwpn + +t1 res 1 'temp variables +t2 res 1 +t3 res 1 +cv res 1 'counter value + +stepn res 1 'step number +oldval res 1 +newmin res 1 +newvalue res 1 'converted old value +newrange res 1 +halfsp res 1 'speed/2 +stom res 1 'steps to move +xsteps res 1 'excess steps = total steps - (2*asteps) + +steps2 res 1 'second move steps and speed +speed2 res 1 + + fit 150 + +con { license } + +{{ + + Terms of Use: MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy of this + software and associated documentation files (the "Software"), to deal in the Software + without restriction, including without limitation the rights to use, copy, modify, + merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be included in all copies + or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +}} \ No newline at end of file diff --git a/libraries/community/p2/All/Stepper/Step_driver2_sd.spin2 b/libraries/community/p2/All/Stepper/Step_driver2_sd.spin2 new file mode 100644 index 00000000..f452734e --- /dev/null +++ b/libraries/community/p2/All/Stepper/Step_driver2_sd.spin2 @@ -0,0 +1,317 @@ +{P2 Stepper motor driver } + + +CON + + +VAR + long cog ' cog flag/id + + long CP 'current position + long SPD 'Speed in steps/sec + long STM 'steps to move +/- Routine clears this after values are read + long Asteps 'Number of steps for acceleration phase + long Offset 'degrees at ends of range to skip + + + long MODEb 'mode bits + 'b0 = 0 - stopped, 1 - moving + 'b1 = 1 - accel + 'b2 = 1 - decel + 'b3 = 1 - at slew speed + 'b4 = direction, 1=cw + 'b5 1 = decel to stop + + long sspn 'SSPIN - set to 0 to stop, 1 to start + long ckpn 'cw pin to driver + long drpn 'ccw pin to driver + long frequency 'clock frequency + long del + long vel + long as + long ds + long ss + long stn + + +PUB start(sp, cpn, dpn): result + stop() + longmove(@sspn, @sp, 3) ' save pins + frequency := clkfreq + cog := COGINIT(COGEXEC_NEW,@_begin,@cp) +1 + return cog + +PUB stop() + +'' Stop stepper driver +'' -- frees a cog if driver was running + + if (cog) ' cog active? + cogstop(cog-1) ' yes, shut it down + cog := 0 ' and mark stopped + +PUB move(sp,st) | t + + asteps := sp/10 +2 'effectively sets max acceleration + t := abs(st/2) + offset := 40 + if asteps > t + asteps := t 'limits accel/ decel steps to 1/2 the total steps + ss := abs(st) - (asteps*2) + if ss == 0 + sp := 10*(asteps -2) 'limit acceleration for short moves + + longmove(@spd, @sp, 2) 'copy values - start the move + +PUB getpos(): result + return @cp + +PUB getsteps(): result + return @stm + +PUB getmode(): result + return @modeb + +PUB getoff(): result + return @offset + +PUB getvel(): result + return @vel + +PUB getas(): result + return @asteps + +PUB getss(): result + return @ss + + +DAT ORG 0 + +_begin mov ptrb, ptra + add ptrb, #24 '4 bytes * 6 longs + setq #4-1 + rdlong sspin,ptrb[0] 'get three pin numbers and frequency + + drvl dirpin + drvl steppin + +_stopped rdlong steps, ptra[2] wz 'wait for steps to be non zero + if_z jmp #_stopped + + setq #5-1 'get 5 parameters from hub + rdlong cpos, ptra[0] + + wrlong #0, ptra[2] 'set steps to zero to indicate we received them + + drvl dirpin + drvl steppin + + mov mode, #0 + abs steps wc 'convert neg steps to pos + muxc mode, #16 + if_c drvh dirpin 'set direction pin based on c D[31] + if_nc drvl dirpin +_dirset wrlong mode, ptra[5] 'output the mode with dir bit set + +_setup mov halfsp, speed + shr halfsp, #1 'make half speed variable + + mov stepn, #0 + mov stom, steps + mov newmin, angoff + mov newrange, n360 + sub newrange, angoff + sub newrange, angoff 'newrange = angoff to (360-angoff) + shl newmin, #7 'partial multiply x128 11930464/128 = 93206 remaining + mov xsteps, #0 + mov t3, astps + shl t3, #1 'x2 - accel and decel + cmp t3, stom wc 'more than accel + decel steps? + if_nc jmp #_waitstart + mov xsteps, steps + sub xsteps, t3 'xsteps = excess steps above accel +decel or zero + mov stom, t3 + + +'****************************************************************************************************** + +_waitstart testp sspin wc 'wait for start pin = 1 + if_nc jmp #_waitstart + + or mode, #%011 'moving, accel + wrlong mode, ptra[5] + call #_dostep 'output a step + +_mainloop testp sspin wc 'still in run mode? + if_c jmp #_mlp1 'yes, keep running + 'if stop pressed + or mode, #%100000 'turn on decel_to_stop + sub steps, xsteps + mov xsteps, #0 + +_mlp1 cmp astps, stepn wz 'done accelerating? + if_z jmp # _mlp2 + if_nz call #_waitstep + jmp #_mainloop + +_mlp2 cmp xsteps, #1 wz 'wait till the last at_speed step + if_z jmp #_checknextmove + +_mlp3 tjz xsteps, #_mlp5 'if xsteps = 0, decelerate +_mlp4 andn mode, #%01110 'acceleration done + or mode, #%01000 'set mode -> at speed + jmp #_mlp6 + +_mlp5 andn mode, #%01110 + or mode, #%00100 'set mode -> decel + wrlong t2, ptra[11] 'output top speed + +_mlp6 wrlong mode, ptra[5] + call #_waitstep + jmp #_mainloop + +'****************************************************************************************************** + +_checknextmove + rdlong steps2, ptra[2] wz + if_z jmp #_mlp3 'no new move to consider + + mov t1, #0 'else- check if direction is same + abs steps2 wc 'convert neg steps to pos + muxc t1, #16 'set direction bit + mov t2, mode + and t2, #%10000 'clear all but direction bit + cmp t1, t2 wz ' is direction the same as current + if_nz jmp #_mlp3 'direction is different we need to stop before starting next move + + rdlong speed2, ptra[1] + cmp speed, speed2 wz 'is speed the same + if_nz jmp #_mlp3 'not the same, can't continue + +_same_speed add steps, steps2 'add new steps to current steps + add xsteps, steps2 'new steps are all at_speed steps + wrlong #0, ptra[2] 'set steps to zero to indicate we received them + jmp #_mlp4 + +'***************************************************************************************************** + +_waitstep waitct2 'wait for the delay period to end + 'then start another pulse +_dostep tjnz steps, #_dostep1 'zero steps left, we're done + pop t1 'pop the unused return address + and mode, #%0100000 'indicate stopped but leave b5 set if decelerate_to_stop + wrlong cpos, ptra[0] + wrlong mode, ptra[5] + jmp #_stopped + +_dostep1 drvh steppin 'step pin high + getct cv + addct1 cv,delayh 'start the pulse high timer + + testb mode, #4 wc 'check the direction bit + sumc cpos, #1 'add/subtract from current position + wrlong cpos, ptra[0] 'update current position + + waitct1 + drvl steppin 'step pulse end + +_ws1 testb mode, #3 wc 'at speed? + if_c sub xsteps, #1 'yes, dec xsteps + if_c jmp #_ws2 'yes, keep old delay + + call #_getdelay 'get new delay if accel or decel + +_ws2 addct2 cv, delay 'start the delay timer + sub steps, #1 'decrement the steps to go + testb mode, #3 wc 'mode = at speed? + if_nc add stepn, #1 'inc stepn if not + ret + +_getdelay qmul stepn, newrange 'scale step to range angoff - (360 - angoff) + getqx t1 + shl t1, #7 'partial multiply *32 + qdiv t1, stom + getqx newvalue + add newvalue, newmin 'new value is converted oldvalue + qmul newvalue, mult 'finish multiply * 93206 + getqx newvalue + qrotate halfsp, newvalue 'get cosine of vector + getqx t1 + mov t2, halfsp + sub t2, t1 'get velocity + + fges t2, #1 'avoid divide by zero + qdiv freq, t2 'delay = frequency/ velocity + getqx delay + fles delay, maxdelay + ret + + +'----------------------------------------------------------------------------------------------- + +delayh long 1000 'step output high time 1000/200_000_000 = 5µs +delay long 1 'delay between steps - calculated +n360 long 360 'the number 360 +mult long 93206 '93206 * 128 = 11930464 * 360 = FFFFFFFF = 4294967295 = 359.999999999degress +maxdelay long 95000000 + +cpos res 1 'current position - steps +speed res 1 'speed -steps/sec +steps res 1 'steps to move +astps res 1 'accel/ decel steps +angoff res 1 + +mode res 1 'b0 = 0 - stopped, 1 - moving + 'b1 = 1 - accel + 'b2 = 1 - decel + 'b3 = 1 - at slew speed + 'b4 = 1 direction = cw + +sspin res 1 'start =1 stop =0 pin (input) +steppin res 1 'output to driver +dirpin res 1 ' " +freq res 1 'system clock frequency + +t1 res 1 'temp variables +t2 res 1 +t3 res 1 +cv res 1 'counter value + +stepn res 1 'step number +oldval res 1 +newmin res 1 +newvalue res 1 'converted old value +newrange res 1 +halfsp res 1 'speed/2 +stom res 1 'steps to move +xsteps res 1 'excess steps = total steps - (2*asteps) + +steps2 res 1 'second move steps and speed +speed2 res 1 + + fit 150 + +con { license } + +{{ + + Terms of Use: MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy of this + software and associated documentation files (the "Software"), to deal in the Software + without restriction, including without limitation the rights to use, copy, modify, + merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be included in all copies + or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +}} \ No newline at end of file diff --git a/libraries/community/p2/All/Stepper/sine wave stepper.xlsx b/libraries/community/p2/All/Stepper/sine wave stepper.xlsx new file mode 100644 index 00000000..38a98f18 --- /dev/null +++ b/libraries/community/p2/All/Stepper/sine wave stepper.xlsx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd6e34932c977376325a7882256a626487f986e137da3a56b3ef1945f4f0e239 +size 120383 diff --git a/libraries/community/p2/All/Stepper/step_driver2 demo.spin2 b/libraries/community/p2/All/Stepper/step_driver2 demo.spin2 new file mode 100644 index 00000000..9c637d0b --- /dev/null +++ b/libraries/community/p2/All/Stepper/step_driver2 demo.spin2 @@ -0,0 +1,232 @@ +CON debug_log_size = 100_000 + +con { timing } + + CLK_FREQ = 200_000_000 ' system freq as a constant + MS_001 = CLK_FREQ / 1_000 ' ticks in 1ms + US_001 = CLK_FREQ / 1_000_000 ' ticks in 1us + + BR_TERM = 115_200 ' terminal baud rate + + _clkfreq = CLK_FREQ ' set system clock + + +con { fixed io pins } + + RX1 = 63 { I } ' programming / debug + TX1 = 62 { O } + + SF_CS = 61 { O } ' serial flash + SF_SCK = 60 { O } + SF_SDO = 59 { O } + SF_SDI = 58 { I } + + SD_SCK = 61 { O } ' sd card + SD_CS = 60 { O } + SD_SDI = 59 { O } + SD_SDO = 58 { I } + + SDA1 = 57 { IO } ' i2c (optional) + SCL1 = 56 { IO } + + +con { app io pins } + enpin = 14 ' motor enable + _spin = 15 'start stop pin (input) + _cpin = 17 'step output pin (or cw pin) + _dpin = 19 'direction output pin (or ccw pin) + + NL = 13 ''NL: New Line + + + + MAXSTR_LENGTH = 99 'Maximum length of received numerical string (not including zero terminator). + + + +obj + +' main ' * master Spin cog + stepper : "step_driver2_cc" ' pasm stepper routine + ' use step_driver2_sd for step and direction + ' use step_driver2_cc or cw, ccw motor drivers + term : "jm_serial" ' serial IO for terminal + + + +dat + + Banner byte "Stepper Demo", 0 + +var + long cpos + long mode + long stm + long spd + long ofs + long ve + long ast + long sst + long start + long endt + + byte char + byte spin + byte cpin + byte dpin + byte str_buffer[MAXSTR_LENGTH+1] 'String buffer for numerical strings + +CON '1 - Run this program with F10 + '2 - Start the PST with F12 , check echo on, Baud rate set above (BR_TERM = 115_200) + '3 - press any key to start + +pub main() | t, value,st, sp + spin := _spin + cpin := _cpin + dpin := _dpin + + setup() 'start the stepper driver, get the addresses for program values + + wait_for_terminal(true) 'press any key after the parallax serial terminal (PST) is started + + long[cpos][0] := 1000 'preset the starting position (just an arbitrary value, defaults to zero) + showvalues() + + repeat + term.fstr0(string("\r\rEnter steps: ")) ' ex: 500 -> 500 steps cw, -1000 -> 1000 steps ccw + st := decin() + + term.fstr0(string("\rEnter speed: ")) ' 1 to approx 45_000, steps per second + sp := abs(decin()) ' negative speed not allowed + if sp == 0 'zero speed not allowed + sp++ + + endt := start := getms() + + 'this is the call to the stepper driver + stepper.move(sp,st) 'speed, steps + + + term.tx(16) 'cls + repeat + showvalues() + endt := getms() + while long[mode][0] & %00001 == 1 'repeat while mode[bit0] = 1 (moving) + + + term.tx(16) 'cls + showvalues() 'one more time after all the results are in + + + + +pub setup() + + stepper.start(spin, cpin, dpin) 'start/stop pin, (step pin, dir pin to driver) + cpos := stepper.getpos() + mode := stepper.getmode() + stm := stepper.getsteps() + ofs := stepper.getoff() + ve := stepper.getvel() + ast := stepper.getas() + sst := stepper.getss() + + term.start(BR_TERM) ' start terminal io + pinlow(enpin) + +pub wait_for_terminal(clear) + + ' Download to RAM with F10 + ' F12 to open PST + ' Click [Enable] + ' Press Enter + + term.rxflush() + term.rx() + if (clear) + term.tx(term.CLS) + +PUB DecIn() : value +{{Receive carriage return terminated string of characters representing a decimal value. + Returns: the corresponding decimal value.}} + + StrInMax(@str_buffer, MAXSTR_LENGTH) + value := StrToBase(@str_buffer, 10) + +PUB StrInMax(stringptr, maxcount) |c +{{Receive a string of characters (either carriage return terminated or maxcount in length) and stores it (zero terminated) +starting at stringptr. Waits until either full string received or maxcount characters received. + Parameters: + stringptr - pointer to memory in which to store received string characters. + Memory reserved must be large enough for all string characters plus a zero terminator (maxcount + 1). + maxcount - maximum length of string to receive, or -1 for unlimited.}} + + repeat while (maxcount--) 'While maxcount not reached + c := term.rx() + if c == 8 'backspace + byte[stringptr--] := 0 + quit + elseif (byte[stringptr++] := c) == NL 'Get chars until NL + quit + byte[stringptr+(byte[stringptr-1] == NL)]~ 'Zero terminate string; overwrite NL or append 0 char + +PRI StrToBase(stringptr, base) : value | chr, index +{Converts a zero terminated string representation of a number to a value in the designated base. +Ignores all non-digit characters (except negative (-) when base is decimal (10)).} + + value := index := 0 + repeat until ((chr := byte[stringptr][index++]) == 0) + chr := -15 + --chr & %11011111 + 39*(chr > 56) 'Make "0"-"9","A"-"F","a"-"f" be 0 - 15, others out of range + if (chr > -1) and (chr < base) 'Accumulate valid values into result; ignore others + value := value * base + chr + if (base == 10) and (byte[stringptr] == "-") 'If decimal, address negative sign; ignore otherwise + value := - value + +PRI Showvalues() + term.fstr1(string("\001%s\r"), @Banner) + + term.fstr0(string("\rCurrent Position: ")) + term.jdpdec(long[cpos][0],0 ,6," ") + + term.fstr0(string("\r Mode: ")) + term.fbin(long[mode][0],6) + + term.fstr0(string("\r Offset: ")) + term.jdpdec(long[ofs][0],0,6," ") + + term.fstr0(string("\r Accel steps: ")) + term.jdpdec(long[ast][0], 0, 6, " ") + + term.fstr0(string("\r Steps at speed: ")) + term.jdpdec(long[sst][0], 0,6," ") + + term.fstr0(string("\r Max Velocity: ")) + term.jdpdec(long[ve][0],0,6," ") + + term.fstr0(string("\r\011Elapsed time (msec): ")) + term.jdpdec(endt - start,0,6," ") + +con { license } + +{{ + + Terms of Use: MIT License + + Permission is hereby granted, free of charge, to any person obtaining a copy of this + software and associated documentation files (the "Software"), to deal in the Software + without restriction, including without limitation the rights to use, copy, modify, + merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be included in all copies + or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +}} \ No newline at end of file diff --git a/libraries/community/p2/All/Stepper/stepper_sin_fc.pdf b/libraries/community/p2/All/Stepper/stepper_sin_fc.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c94802ffdc02e8a1717a523828956412aa3a09d1 GIT binary patch literal 130 zcmWN?K@!3s3;@78uiyigLP^^6Hv|%4Mx`UQ2Vbvy*-PG|^_Q*Zd5qn;dpmCr9n=5% z;VJj08;4|fdDC05qox43dlnWTSd}=hx-dc_2@*6W3bJ~nZ7wk?gJ>vB0p|pWShmQE MW;5DXEE0HcehnZf6951J literal 0 HcmV?d00001 diff --git a/libraries/community/p2/All/ili9341/Demo_ILI9341_XPT2046.spin2 b/libraries/community/p2/All/ili9341/Demo_ILI9341_XPT2046.spin2 new file mode 100644 index 00000000..fa0529ae --- /dev/null +++ b/libraries/community/p2/All/ili9341/Demo_ILI9341_XPT2046.spin2 @@ -0,0 +1,699 @@ +{{ + + ILI9341_XPT2046 Demo + +320x240 LCD driver for ILI9341 controller and XPT2046 touch screen. This version is SPI based. + +Author: Greg LaPolla +Updated: 2021-02-15 +Designed For: P2X8C4M64P +Version: 1.0 + +'' Based on Cluso's Demo ST7796 4.0in SPI 480x320 w Touch LCD Driver + +}} + +CON + _clkfreq = 200_000_000 ' clock frequency + + width = 320 ' screen width (cols) + height = 280 ' screen height (rows) + textwidth = width / 6 ' 80 chars per line 80*6=480 + + LCD_rotate_0 = $00 '\ 0 degrees + LCD_rotate_90 = $A0 '| 90 degrees + LCD_rotate_180 = $C0 '| 180 degrees + LCD_rotate_270 = $60 '/ 270 degrees + LCD_mirror_90 = $20 ' 90 degrees H-mirror +' Set the following to suit... + LCD_rotate = LCD_mirror_90 ' <--- set to suit + +' ILI9341 registers... + LCD_NOP = $00 + LCD_SW_RESET = $01 + LCD_SLEEP_ON = $10 + LCD_SLEEP_OFF = $11 + LCD_PARTIAL = $12 + LCD_NORMAL = $13 + LCD_INVERSION_OFF = $20 + LCD_INVERSION_ON = $21 + LCD_GAMMA_SET = $26 + LCD_DISPLAY_OFF = $28 + LCD_DISPLAY_ON = $29 + LCD_COL_ADR = $2A + LCD_ROW_ADR = $2B + LCD_RAM_WRITE = $2C + LCD_COLOR_SPACE = $2D '4K/65K/262K +' LCD_RAMRD = $2E + LCD_MADCTR = $36 'Mem Addr Contol (rotate screen) + LCD_PIXEL_FORMAT = $3A + LCD_FRAME_CTL1 = $B1 + LCD_INVERSION_CTL = $B4 + LCD_POWER_CTL1 = $C0 + LCD_POWER_CTL2 = $C1 + LCD_VCOM_CTL1 = $C5 + LCD_VCOM_OFFSET = $C7 + LCD_POS_GAMMA = $E0 + LCD_NEG_GAMMA = $E1 + LCD_GAMMA_RS = $F2 + +' BGR 5+6+5 16bits/pixel (RGB reversed) + black = $0000 + white = $FFFF + blue = $F800 + green = $07E0 + red = $001F + yellow= red+green + purple= red+blue + +' ' sin(x) * 1024 ' degrees +Z00 = 0 ' 0.0000 * 1024 ' 0 +Z01 = 107 ' 0.1045 * 1024 ' 6 +Z02 = 213 ' 0.2079 * 1024 ' 12 +Z03 = 316 ' 0.3090 * 1024 ' 18 +Z04 = 416 ' 0.4067 * 1024 ' 24 +Z05 = 512 ' 0.5000 * 1024 ' 30 +Z06 = 602 ' 0.5878 * 1024 ' 36 +Z07 = 685 ' 0.6691 * 1024 ' 42 +Z08 = 761 ' 0.7431 * 1024 ' 48 +Z09 = 828 ' 0.8090 * 1024 ' 54 +Z10 = 887 ' 0.8660 * 1024 ' 60 +Z11 = 935 ' 0.9135 * 1024 ' 66 +Z12 = 974 ' 0.9511 * 1024 ' 72 +Z13 = 1002 ' 0.9781 * 1024 ' 78 +Z14 = 1018 ' 0.9945 * 1024 ' 84 +Z15 = 1024 ' 1.0000 * 1024 ' 90 +'180 = ' 0.0000 * 1024 ' 180 +'270 = '-1.0000 * 1024 ' 270 + +' Clock constants +_CX = 64 '\ clock center +_CY = 64 '/ +_CD = 120 ' clock face dia +_CS = 45 ' second hand length +_CM = 40 ' minute hand length +_CH = 30 ' hour hand length +fgd = blue/2 'green ' foreground dial color (clock dial) +bgd = black ' background dial color +fgh = red ' hour hand color +fgm = yellow ' minute hand color +fgs = white ' second hand color + +baud = 2_000_000 + +OBJ + lcd: "LCD_ILI9341_XPT2046" + 'term : "jm_serial" ' LCD pasm cog driver (supports 6*8 and 8*8 pixel font) + +VAR + long cog ' pasm cog+1 + long tx,ty,tx40,ty40,tx280,ty200,spotx,spoty,int,clock_button + long cr + +DAT + colorlist word white, red+green, blue, green, red, red+blue, blue+green, blue/2 + +PUB start() | i + + cog := lcd.Start(LCD_rotate) ' sw/hw initialise LCD (rotate 0/90/180/270) + lcd.start_TS() + 'term.start(baud) +' screen defaults... + lcd.setFGcolor(blue) ' set foreground color + lcd.setBGcolor(black) ' set background color + lcd.clearScreen() ' clear screen (background color) +' Touchscreen enable interupt + lcd.get_ts($90) 'turn on ts_int + + waitms(50) + +' Select one/some of the following... + waitms(1000) ' wait + drawSomeChars() + waitms(1000) ' wait + drawSomeLines() + waitms(1000) ' wait + drawSomeBoxes() + waitms(1000) ' wait + drawSomeCircles() + 'waitms(1000) ' wait + 'waitms(5000) ' wait + +' draw some text and then do clock... + lcd.clearScreen() + lcd.setFGcolor(green) + lcd.setBGcolor(black) + lcd.SetColRow(0, height/2) ' 2nd half of screen + repeat i from $20 to $7F ' 6*8 font 96 char set + lcd.DrawChar6x8(i) + lcd.SetColRow(0, height/2+20) + repeat i from $20 to $7F ' 8*8 font 96 char set + lcd.DrawChar8x8(i) + +' do clock... + + lcd.clearScreen() + drawstring(100,160, string("CALIBRATE TOP LEFT")) + lcd.SetColRow(40, 40) + lcd.DrawChar8x8($78) 'draw top left calibration X + cr := 13 + int := 1 + + lcd.Wait_for_touch() 'wait for touch + + tx := lcd.get_ts($91) '$91 turns off interupt and collects x position + tx40 := lcd.get_ts($91) '$91 keeps off interupt after x data, calibration point tx40 + ty := lcd.get_ts($D1) '$D1 keeps off interupt and collects y position + ty40 := lcd.get_ts($D0) 'D0 turns interupt back on after calibration point ty40 + + 'term.fstr4(string("X %d Y %d int %d %s"),tx40,ty40,int,@cr) + lcd.clearscreen() + drawstring(100,160, string("CALIBRATE BOTTOM RIGHT")) + lcd.SetColRow(280,200) + lcd.DrawChar8x8($78) 'draw bottom right calibration X + + lcd.wait_for_untouch() 'wait until not touched + lcd.wait_for_touch() 'wait until touched + + tx := lcd.get_ts($91) + tx280 := lcd.get_ts($91) 'calibration point tx280 + ty := lcd.get_ts($D1) + ty200 := lcd.get_ts($D0) 'calibration point ty200 + + 'term.fstr4(string("X %d Y %d int %d %s"),tx280,ty200,spotx,@cr) + + lcd.clearscreen() + drawstring(100,160, string("TOUCH DISPLAY TO MAKE X")) + lcd.SetWindow(240,20,280,60) + lcd.FillWindow(white) + lcd.setBGcolor(white) + lcd.setFGcolor(black) + drawstring(245,36, string("CLOCK")) + lcd.setBGcolor(black) + lcd.setFGcolor(green) + + clock_button := false + + repeat until clock_button + + lcd.wait_for_untouch() 'wait until not touched + lcd.wait_for_touch() 'wait until touched + + tx := lcd.get_ts($91) + tx := lcd.get_ts($91) + ty := lcd.get_ts($D1) + ty := lcd.get_ts($D0) + + spotx := 280-(((tx-tx280)*240)/(tx40-tx280)) 'the 240 is pixels in x direction between calibration marks + spoty := 200-(((ty-ty200)*160)/(ty40-ty200)) 'the 160 is pixels in y direction between calibration marks + + if((spotx > 240) and (spotx < 300) and (spoty > 20) and (spoty < 60)) + clock_button := true + + if not clock_button + lcd.SetColRow(spotx,spoty) + lcd.DrawChar8x8($78) + + 'term.fstr4(string("X %d Y %d int %d %s"),spotx,spoty,spotx,@cr) + + main_roundclock() + +'---------------------------end main----------------------------------------------------- + +PRI drawString(col,row, str) | i + lcd.setColRow(col, row) + repeat i from 0 to 25 ' 6*8 font 96 char set + if byte[str][i] == 0 + quit + lcd.DrawChar6x8(byte[str][i]) + +PRI drawLEDs(ys, v) | x, y, z, i + + repeat i from 0 to 7 + x := 46 + (i * 6) + if i > 3 + x += 6 + lcd.setWindow(x+1, ys+1, x+4, ys+6) + if (v >> (7-i)) & 1 == 1 + lcd.fillWindow(red) + else + lcd.fillWindow(green) + lcd.setColRow(114, ys) + lcd.setFGcolor(yellow) + z := (v >> 4) | $30 + if z > $39 + z += 7 + lcd.drawChar6x8(z) + z := (v & $F) | $30 + if z > $39 + z += 7 + lcd.drawChar6x8(z) + +PRI drawStateLEDs(ys, v) | x, y, z, i + + repeat i from 0 to 5 + x := 58 + (i * 6) + if i > 3 + x += 6 + lcd.setWindow(x+1, ys+1, x+4, ys+6) + if (v >> (5-i)) & 1 == 1 + lcd.fillWindow(red) + else + lcd.fillWindow(green) + lcd.setColRow(120, ys) + lcd.setFGcolor(red) + case v + 1 : z := $30 + 2 : z := $31 + 4 : z := $32 + 8 : z := $33 + 16: z := $34 + 32: z := $35 + lcd.drawChar6x8(z) + +PRI drawSomeChars() | i +' Draw some chars ($20..$7F) + + lcd.clearScreen() + lcd.setFGcolor(green) + lcd.setBGcolor(black) + + repeat i from $20 to $7F ' 6*8 font 96 char set + lcd.DrawChar6x8(i) + + lcd.SetColRow(0, height/2) ' 2nd half of screen + + repeat i from $20 to $7F ' 8*8 font 96 char set + lcd.DrawChar8x8(i) + +PRI drawSomeLines() +' Draw some lines + + lcd.setBGcolor(black) + lcd.clearScreen() + + drawLine(0, 0, width-1, height-1, blue) + drawLine(0, height-1, width-1, 0, blue) + drawLine(0, height/2-1, width-1, height/2-1, yellow) + drawLine(width/2-1, 0, width/2-1, height-1, yellow) + drawLine(width/4-1, 0, width-width/4-1, height-1, red) + drawLine(width/4-1, height-1, width-width/4-1, 0, red) + +PRI drawSomeBoxes() | i, xs, ys, xe, ye, z +' Draw some diagonal boxes + + lcd.clearScreen() + + z := 40 + xs := 0 + ys := 0 + xe := z + ye := z + repeat i from 0 to 7 + lcd.SetWindow(xs,ys,xe,ye) + lcd.FillWindow(colorlist[i]) + xs += z + ys += z + xe += z + ye += z + + z := 40 + xs := 0 + ys := height-z + xe := z + ye := height-1 + repeat i from 0 to 7 + lcd.SetWindow(xs,ys,xe,ye) + lcd.FillWindow(colorlist[i]) + xs += z + ys -= z + xe += z + ye -= z + +PRI drawSomeCircles() | i, z, dia +' Draw some circles + + lcd.clearScreen() + + z := height/2/8 + repeat i from 0 to 7 + dia := z + (z * i) + drawCircle(width/2, height/2, dia, colorlist[i]) + +''+-----------------------------------------------------+ +''| High Level Drivers | +''+-----------------------------------------------------+ + +PRI drawLine(xs, ys, xe, ye, rgb) | i, x, y +' Draw Line - start co-ords, end co-ords, color + 'plot incrementing x axis + repeat i from 0 to xe-xs + y := (ye-ys)*i/(xe-xs) + drawPixel(xs+i, ys+y, rgb) + 'plot incrementing y axis + repeat i from 0 to ye-ys + x := (xe-xs)*i/(ye-ys) + drawPixel(xs+x, ys+i, rgb) + +PRI drawCircle(xc, yc, dia, rgb) | x, y +' Draw Circle d^2 = x^2 + y^2; y = SQRT(d^2 - x^2) (Pythagoras theorum) + repeat x from 0 to dia + y := SQRT((dia*dia) - (x*x)) + 'plot 4 quadrants for incrementing x axis + drawPixel(xc+x, yc+y, rgb) + drawPixel(xc-x, yc+y, rgb) + drawPixel(xc+x, yc-y, rgb) + drawPixel(xc-x, yc-y, rgb) + 'plot 4 quadrants for incrementing y axis (fills in more dots on circle) + drawPixel(xc+y, yc+x, rgb) + drawPixel(xc-y, yc+x, rgb) + drawPixel(xc+y, yc-x, rgb) + drawPixel(xc-y, yc-x, rgb) + +PRI drawPixel(x, y, rgb) | i +' Draw 1 pixel + lcd.setWindow(x, y, x, y) ' 1 pixel + lcd.fillWindow(rgb) + +PRI fillRectangle(xs, ys, xe, ye, rgb) + lcd.setWindow(xs, ys, xe, ye) + lcd.fillWindow(rgb) + +''+-----------------------------------------------------+ +''| Special Functions... | +''+-----------------------------------------------------+ + +PRI main_roundclock() | h, hprev, m, mprev, s, sprev, tick, hx, hz, x +' Round Clock + + lcd.setFGcolor(fgd) + lcd.setBGcolor(bgd) +' lcd.clearScreen() + +' Draw Clock Face + drawCircle(_CX, _CY, _CD/2, fgd) + lcd.setColRow( 56, 8) + lcd.DrawChar6x8("1") + lcd.DrawChar6x8("2") + lcd.setColRow( 31, 16) + lcd.DrawChar6x8("1") + lcd.DrawChar6x8("1") + lcd.setColRow( 89, 16) + lcd.DrawChar6x8("1") + lcd.setColRow( 15, 36) + lcd.DrawChar6x8("1") + lcd.DrawChar6x8("0") + lcd.setColRow(106, 36) + lcd.DrawChar6x8("2") + lcd.setColRow( 8, 60) + lcd.DrawChar6x8("9") + lcd.setColRow(112, 60) + lcd.DrawChar6x8("3") + lcd.setColRow( 15, 84) + lcd.DrawChar6x8("8") + lcd.setColRow(106, 84) + lcd.DrawChar6x8("4") + lcd.setColRow( 31, 104) + lcd.DrawChar6x8("7") + lcd.setColRow( 89, 104) + lcd.DrawChar6x8("5") + lcd.setColRow( 60, 112) + lcd.DrawChar6x8("6") + + tick := GETCT() + +' Draw the date ' date incrementing left as an exercise + lcd.SetWindow(92,0,0,0) ' only need to set x,y + lcd.DrawChar6x8("0") + lcd.DrawChar6x8("7") + lcd.DrawChar6x8(" ") + lcd.DrawChar6x8("N") + lcd.DrawChar6x8("O") + lcd.DrawChar6x8("V") + lcd.SetWindow(104,9,0,0) ' next line +1 pixel + lcd.DrawChar6x8("2") + lcd.DrawChar6x8("0") + lcd.DrawChar6x8("2") + lcd.DrawChar6x8("0") + +' Draw Clock Hands + hprev~ + mprev~ + sprev~ + repeat + repeat h from 0 to 11 + hx := h*5 ' hx= 0..59 for hour hand angle + drawLine(_CX, _CY, byte[@HH00][hprev*2], byte[@HH00][hprev*2+1], bgd) ' remove prev hour hand + drawLine(_CX, _CY, byte[@HH00][hx*2], byte[@HH00][hx*2+1], bgd) ' show hour hand + hprev := hx + repeat m from 0 to 59 + drawLine(_CX, _CY, byte[@MH00][mprev*2], byte[@MH00][mprev*2+1], bgd) ' remove prev minute hand + drawLine(_CX, _CY, byte[@MH00][m*2], byte[@MH00][m*2+1], fgm) ' show minute hand + case m + 12,24,36,48: '\ hx is +0/1/2/3/4 offset... + hx++ '| ...for hour hand to... + drawLine(_CX, _CY, byte[@HH00][hprev*2], byte[@HH00][hprev*2+1], bgd) '| ...advance every... + drawLine(_CX, _CY, byte[@HH00][hx*2], byte[@HH00][hx*2+1], fgh) '| ...12 minutes... + hprev := hx '/ ... + mprev := m + repeat s from 0 to 59 + drawLine(_CX, _CY, byte[@SH00][sprev*2], byte[@SH00][sprev*2+1], bgd) ' remove prev second hand + drawLine(_CX, _CY, byte[@SH00][s*2], byte[@SH00][s*2+1], fgs) ' show second hand + drawLine(_CX, _CY, byte[@MH00][m*2], byte[@MH00][m*2+1], fgm) ' show minute hand + drawLine(_CX, _CY, byte[@HH00][hx*2], byte[@HH00][hx*2+1], fgh) ' show hour hand + sprev := s + lcd.SetWindow(0,0,0,0) + if h<10 + lcd.DrawChar6x8("0") + lcd.DrawChar6x8(h | $30) + else + lcd.DrawChar6x8("1") + lcd.DrawChar6x8((h-10) | $30) + lcd.DrawChar6x8(":") + x := m/10 + lcd.DrawChar6x8(x | $30) + x := m//10 + lcd.DrawChar6x8(x | $30) + lcd.DrawChar6x8(":") + x := s/10 + lcd.DrawChar6x8(x | $30) + x := s//10 + lcd.DrawChar6x8(x | $30) + tick += _clkfreq ' +1S + waitct(tick) + +DAT + orgh +' Hands (seconds) x & y co-ords +SH00 byte _CX + ((_CS * Z00) >> 10), _CY - ((_CS * Z15) >> 10) '00 + byte _CX + ((_CS * Z01) >> 10), _CY - ((_CS * Z14) >> 10) '01 + byte _CX + ((_CS * Z02) >> 10), _CY - ((_CS * Z13) >> 10) '02 + byte _CX + ((_CS * Z03) >> 10), _CY - ((_CS * Z12) >> 10) '... + byte _CX + ((_CS * Z04) >> 10), _CY - ((_CS * Z11) >> 10) + byte _CX + ((_CS * Z05) >> 10), _CY - ((_CS * Z10) >> 10) + byte _CX + ((_CS * Z06) >> 10), _CY - ((_CS * Z09) >> 10) + byte _CX + ((_CS * Z07) >> 10), _CY - ((_CS * Z08) >> 10) + byte _CX + ((_CS * Z08) >> 10), _CY - ((_CS * Z07) >> 10) + byte _CX + ((_CS * Z09) >> 10), _CY - ((_CS * Z06) >> 10) + byte _CX + ((_CS * Z10) >> 10), _CY - ((_CS * Z05) >> 10) + byte _CX + ((_CS * Z11) >> 10), _CY - ((_CS * Z04) >> 10) + byte _CX + ((_CS * Z12) >> 10), _CY - ((_CS * Z03) >> 10) + byte _CX + ((_CS * Z13) >> 10), _CY - ((_CS * Z02) >> 10) + byte _CX + ((_CS * Z14) >> 10), _CY - ((_CS * Z01) >> 10) + + byte _CX + ((_CS * Z15) >> 10), _CY + ((_CS * Z00) >> 10) + byte _CX + ((_CS * Z14) >> 10), _CY + ((_CS * Z01) >> 10) + byte _CX + ((_CS * Z13) >> 10), _CY + ((_CS * Z02) >> 10) + byte _CX + ((_CS * Z12) >> 10), _CY + ((_CS * Z03) >> 10) + byte _CX + ((_CS * Z11) >> 10), _CY + ((_CS * Z04) >> 10) + byte _CX + ((_CS * Z10) >> 10), _CY + ((_CS * Z05) >> 10) + byte _CX + ((_CS * Z09) >> 10), _CY + ((_CS * Z06) >> 10) + byte _CX + ((_CS * Z08) >> 10), _CY + ((_CS * Z07) >> 10) + byte _CX + ((_CS * Z07) >> 10), _CY + ((_CS * Z08) >> 10) + byte _CX + ((_CS * Z06) >> 10), _CY + ((_CS * Z09) >> 10) + byte _CX + ((_CS * Z05) >> 10), _CY + ((_CS * Z10) >> 10) + byte _CX + ((_CS * Z04) >> 10), _CY + ((_CS * Z11) >> 10) + byte _CX + ((_CS * Z03) >> 10), _CY + ((_CS * Z12) >> 10) + byte _CX + ((_CS * Z02) >> 10), _CY + ((_CS * Z13) >> 10) + byte _CX + ((_CS * Z01) >> 10), _CY + ((_CS * Z14) >> 10) + + byte _CX - ((_CS * Z00) >> 10), _CY + ((_CS * Z15) >> 10) + byte _CX - ((_CS * Z01) >> 10), _CY + ((_CS * Z14) >> 10) + byte _CX - ((_CS * Z02) >> 10), _CY + ((_CS * Z13) >> 10) + byte _CX - ((_CS * Z03) >> 10), _CY + ((_CS * Z12) >> 10) + byte _CX - ((_CS * Z04) >> 10), _CY + ((_CS * Z11) >> 10) + byte _CX - ((_CS * Z05) >> 10), _CY + ((_CS * Z10) >> 10) + byte _CX - ((_CS * Z06) >> 10), _CY + ((_CS * Z09) >> 10) + byte _CX - ((_CS * Z07) >> 10), _CY + ((_CS * Z08) >> 10) + byte _CX - ((_CS * Z08) >> 10), _CY + ((_CS * Z07) >> 10) + byte _CX - ((_CS * Z09) >> 10), _CY + ((_CS * Z06) >> 10) + byte _CX - ((_CS * Z10) >> 10), _CY + ((_CS * Z05) >> 10) + byte _CX - ((_CS * Z11) >> 10), _CY + ((_CS * Z04) >> 10) + byte _CX - ((_CS * Z12) >> 10), _CY + ((_CS * Z03) >> 10) + byte _CX - ((_CS * Z13) >> 10), _CY + ((_CS * Z02) >> 10) + byte _CX - ((_CS * Z14) >> 10), _CY + ((_CS * Z01) >> 10) + + byte _CX - ((_CS * Z15) >> 10), _CY - ((_CS * Z00) >> 10) + byte _CX - ((_CS * Z14) >> 10), _CY - ((_CS * Z01) >> 10) + byte _CX - ((_CS * Z13) >> 10), _CY - ((_CS * Z02) >> 10) + byte _CX - ((_CS * Z12) >> 10), _CY - ((_CS * Z03) >> 10) + byte _CX - ((_CS * Z11) >> 10), _CY - ((_CS * Z04) >> 10) + byte _CX - ((_CS * Z10) >> 10), _CY - ((_CS * Z05) >> 10) + byte _CX - ((_CS * Z09) >> 10), _CY - ((_CS * Z06) >> 10) + byte _CX - ((_CS * Z08) >> 10), _CY - ((_CS * Z07) >> 10) + byte _CX - ((_CS * Z07) >> 10), _CY - ((_CS * Z08) >> 10) + byte _CX - ((_CS * Z06) >> 10), _CY - ((_CS * Z09) >> 10) + byte _CX - ((_CS * Z05) >> 10), _CY - ((_CS * Z10) >> 10) + byte _CX - ((_CS * Z04) >> 10), _CY - ((_CS * Z11) >> 10) + byte _CX - ((_CS * Z03) >> 10), _CY - ((_CS * Z12) >> 10) + byte _CX - ((_CS * Z02) >> 10), _CY - ((_CS * Z13) >> 10) + byte _CX - ((_CS * Z01) >> 10), _CY - ((_CS * Z14) >> 10) + +' Hands (minutes) x & y co-ords +MH00 byte _CX + ((_CM * Z00) >> 10), _CY - ((_CM * Z15) >> 10) '00 + byte _CX + ((_CM * Z01) >> 10), _CY - ((_CM * Z14) >> 10) '01 + byte _CX + ((_CM * Z02) >> 10), _CY - ((_CM * Z13) >> 10) '02 + byte _CX + ((_CM * Z03) >> 10), _CY - ((_CM * Z12) >> 10) '... + byte _CX + ((_CM * Z04) >> 10), _CY - ((_CM * Z11) >> 10) + byte _CX + ((_CM * Z05) >> 10), _CY - ((_CM * Z10) >> 10) + byte _CX + ((_CM * Z06) >> 10), _CY - ((_CM * Z09) >> 10) + byte _CX + ((_CM * Z07) >> 10), _CY - ((_CM * Z08) >> 10) + byte _CX + ((_CM * Z08) >> 10), _CY - ((_CM * Z07) >> 10) + byte _CX + ((_CM * Z09) >> 10), _CY - ((_CM * Z06) >> 10) + byte _CX + ((_CM * Z10) >> 10), _CY - ((_CM * Z05) >> 10) + byte _CX + ((_CM * Z11) >> 10), _CY - ((_CM * Z04) >> 10) + byte _CX + ((_CM * Z12) >> 10), _CY - ((_CM * Z03) >> 10) + byte _CX + ((_CM * Z13) >> 10), _CY - ((_CM * Z02) >> 10) + byte _CX + ((_CM * Z14) >> 10), _CY - ((_CM * Z01) >> 10) + + byte _CX + ((_CM * Z15) >> 10), _CY + ((_CM * Z00) >> 10) + byte _CX + ((_CM * Z14) >> 10), _CY + ((_CM * Z01) >> 10) + byte _CX + ((_CM * Z13) >> 10), _CY + ((_CM * Z02) >> 10) + byte _CX + ((_CM * Z12) >> 10), _CY + ((_CM * Z03) >> 10) + byte _CX + ((_CM * Z11) >> 10), _CY + ((_CM * Z04) >> 10) + byte _CX + ((_CM * Z10) >> 10), _CY + ((_CM * Z05) >> 10) + byte _CX + ((_CM * Z09) >> 10), _CY + ((_CM * Z06) >> 10) + byte _CX + ((_CM * Z08) >> 10), _CY + ((_CM * Z07) >> 10) + byte _CX + ((_CM * Z07) >> 10), _CY + ((_CM * Z08) >> 10) + byte _CX + ((_CM * Z06) >> 10), _CY + ((_CM * Z09) >> 10) + byte _CX + ((_CM * Z05) >> 10), _CY + ((_CM * Z10) >> 10) + byte _CX + ((_CM * Z04) >> 10), _CY + ((_CM * Z11) >> 10) + byte _CX + ((_CM * Z03) >> 10), _CY + ((_CM * Z12) >> 10) + byte _CX + ((_CM * Z02) >> 10), _CY + ((_CM * Z13) >> 10) + byte _CX + ((_CM * Z01) >> 10), _CY + ((_CM * Z14) >> 10) + + byte _CX - ((_CM * Z00) >> 10), _CY + ((_CM * Z15) >> 10) + byte _CX - ((_CM * Z01) >> 10), _CY + ((_CM * Z14) >> 10) + byte _CX - ((_CM * Z02) >> 10), _CY + ((_CM * Z13) >> 10) + byte _CX - ((_CM * Z03) >> 10), _CY + ((_CM * Z12) >> 10) + byte _CX - ((_CM * Z04) >> 10), _CY + ((_CM * Z11) >> 10) + byte _CX - ((_CM * Z05) >> 10), _CY + ((_CM * Z10) >> 10) + byte _CX - ((_CM * Z06) >> 10), _CY + ((_CM * Z09) >> 10) + byte _CX - ((_CM * Z07) >> 10), _CY + ((_CM * Z08) >> 10) + byte _CX - ((_CM * Z08) >> 10), _CY + ((_CM * Z07) >> 10) + byte _CX - ((_CM * Z09) >> 10), _CY + ((_CM * Z06) >> 10) + byte _CX - ((_CM * Z10) >> 10), _CY + ((_CM * Z05) >> 10) + byte _CX - ((_CM * Z11) >> 10), _CY + ((_CM * Z04) >> 10) + byte _CX - ((_CM * Z12) >> 10), _CY + ((_CM * Z03) >> 10) + byte _CX - ((_CM * Z13) >> 10), _CY + ((_CM * Z02) >> 10) + byte _CX - ((_CM * Z14) >> 10), _CY + ((_CM * Z01) >> 10) + + byte _CX - ((_CM * Z15) >> 10), _CY - ((_CM * Z00) >> 10) + byte _CX - ((_CM * Z14) >> 10), _CY - ((_CM * Z01) >> 10) + byte _CX - ((_CM * Z13) >> 10), _CY - ((_CM * Z02) >> 10) + byte _CX - ((_CM * Z12) >> 10), _CY - ((_CM * Z03) >> 10) + byte _CX - ((_CM * Z11) >> 10), _CY - ((_CM * Z04) >> 10) + byte _CX - ((_CM * Z10) >> 10), _CY - ((_CM * Z05) >> 10) + byte _CX - ((_CM * Z09) >> 10), _CY - ((_CM * Z06) >> 10) + byte _CX - ((_CM * Z08) >> 10), _CY - ((_CM * Z07) >> 10) + byte _CX - ((_CM * Z07) >> 10), _CY - ((_CM * Z08) >> 10) + byte _CX - ((_CM * Z06) >> 10), _CY - ((_CM * Z09) >> 10) + byte _CX - ((_CM * Z05) >> 10), _CY - ((_CM * Z10) >> 10) + byte _CX - ((_CM * Z04) >> 10), _CY - ((_CM * Z11) >> 10) + byte _CX - ((_CM * Z03) >> 10), _CY - ((_CM * Z12) >> 10) + byte _CX - ((_CM * Z02) >> 10), _CY - ((_CM * Z13) >> 10) + byte _CX - ((_CM * Z01) >> 10), _CY - ((_CM * Z14) >> 10) + +' Hands (hours) x & y co-ords +HH00 byte _CX + ((_CH * Z00) >> 10), _CY - ((_CH * Z15) >> 10) '00 + byte _CX + ((_CH * Z01) >> 10), _CY - ((_CH * Z14) >> 10) '01 + byte _CX + ((_CH * Z02) >> 10), _CY - ((_CH * Z13) >> 10) '02 + byte _CX + ((_CH * Z03) >> 10), _CY - ((_CH * Z12) >> 10) '... + byte _CX + ((_CH * Z04) >> 10), _CY - ((_CH * Z11) >> 10) + byte _CX + ((_CH * Z05) >> 10), _CY - ((_CH * Z10) >> 10) + byte _CX + ((_CH * Z06) >> 10), _CY - ((_CH * Z09) >> 10) + byte _CX + ((_CH * Z07) >> 10), _CY - ((_CH * Z08) >> 10) + byte _CX + ((_CH * Z08) >> 10), _CY - ((_CH * Z07) >> 10) + byte _CX + ((_CH * Z09) >> 10), _CY - ((_CH * Z06) >> 10) + byte _CX + ((_CH * Z10) >> 10), _CY - ((_CH * Z05) >> 10) + byte _CX + ((_CH * Z11) >> 10), _CY - ((_CH * Z04) >> 10) + byte _CX + ((_CH * Z12) >> 10), _CY - ((_CH * Z03) >> 10) + byte _CX + ((_CH * Z13) >> 10), _CY - ((_CH * Z02) >> 10) + byte _CX + ((_CH * Z14) >> 10), _CY - ((_CH * Z01) >> 10) + + byte _CX + ((_CH * Z15) >> 10), _CY + ((_CH * Z00) >> 10) + byte _CX + ((_CH * Z14) >> 10), _CY + ((_CH * Z01) >> 10) + byte _CX + ((_CH * Z13) >> 10), _CY + ((_CH * Z02) >> 10) + byte _CX + ((_CH * Z12) >> 10), _CY + ((_CH * Z03) >> 10) + byte _CX + ((_CH * Z11) >> 10), _CY + ((_CH * Z04) >> 10) + byte _CX + ((_CH * Z10) >> 10), _CY + ((_CH * Z05) >> 10) + byte _CX + ((_CH * Z09) >> 10), _CY + ((_CH * Z06) >> 10) + byte _CX + ((_CH * Z08) >> 10), _CY + ((_CH * Z07) >> 10) + byte _CX + ((_CH * Z07) >> 10), _CY + ((_CH * Z08) >> 10) + byte _CX + ((_CH * Z06) >> 10), _CY + ((_CH * Z09) >> 10) + byte _CX + ((_CH * Z05) >> 10), _CY + ((_CH * Z10) >> 10) + byte _CX + ((_CH * Z04) >> 10), _CY + ((_CH * Z11) >> 10) + byte _CX + ((_CH * Z03) >> 10), _CY + ((_CH * Z12) >> 10) + byte _CX + ((_CH * Z02) >> 10), _CY + ((_CH * Z13) >> 10) + byte _CX + ((_CH * Z01) >> 10), _CY + ((_CH * Z14) >> 10) + + byte _CX - ((_CH * Z00) >> 10), _CY + ((_CH * Z15) >> 10) + byte _CX - ((_CH * Z01) >> 10), _CY + ((_CH * Z14) >> 10) + byte _CX - ((_CH * Z02) >> 10), _CY + ((_CH * Z13) >> 10) + byte _CX - ((_CH * Z03) >> 10), _CY + ((_CH * Z12) >> 10) + byte _CX - ((_CH * Z04) >> 10), _CY + ((_CH * Z11) >> 10) + byte _CX - ((_CH * Z05) >> 10), _CY + ((_CH * Z10) >> 10) + byte _CX - ((_CH * Z06) >> 10), _CY + ((_CH * Z09) >> 10) + byte _CX - ((_CH * Z07) >> 10), _CY + ((_CH * Z08) >> 10) + byte _CX - ((_CH * Z08) >> 10), _CY + ((_CH * Z07) >> 10) + byte _CX - ((_CH * Z09) >> 10), _CY + ((_CH * Z06) >> 10) + byte _CX - ((_CH * Z10) >> 10), _CY + ((_CH * Z05) >> 10) + byte _CX - ((_CH * Z11) >> 10), _CY + ((_CH * Z04) >> 10) + byte _CX - ((_CH * Z12) >> 10), _CY + ((_CH * Z03) >> 10) + byte _CX - ((_CH * Z13) >> 10), _CY + ((_CH * Z02) >> 10) + byte _CX - ((_CH * Z14) >> 10), _CY + ((_CH * Z01) >> 10) + + byte _CX - ((_CH * Z15) >> 10), _CY - ((_CH * Z00) >> 10) + byte _CX - ((_CH * Z14) >> 10), _CY - ((_CH * Z01) >> 10) + byte _CX - ((_CH * Z13) >> 10), _CY - ((_CH * Z02) >> 10) + byte _CX - ((_CH * Z12) >> 10), _CY - ((_CH * Z03) >> 10) + byte _CX - ((_CH * Z11) >> 10), _CY - ((_CH * Z04) >> 10) + byte _CX - ((_CH * Z10) >> 10), _CY - ((_CH * Z05) >> 10) + byte _CX - ((_CH * Z09) >> 10), _CY - ((_CH * Z06) >> 10) + byte _CX - ((_CH * Z08) >> 10), _CY - ((_CH * Z07) >> 10) + byte _CX - ((_CH * Z07) >> 10), _CY - ((_CH * Z08) >> 10) + byte _CX - ((_CH * Z06) >> 10), _CY - ((_CH * Z09) >> 10) + byte _CX - ((_CH * Z05) >> 10), _CY - ((_CH * Z10) >> 10) + byte _CX - ((_CH * Z04) >> 10), _CY - ((_CH * Z11) >> 10) + byte _CX - ((_CH * Z03) >> 10), _CY - ((_CH * Z12) >> 10) + byte _CX - ((_CH * Z02) >> 10), _CY - ((_CH * Z13) >> 10) + byte _CX - ((_CH * Z01) >> 10), _CY - ((_CH * Z14) >> 10) + +dat +{{ ++------------------------------------------------------------------------------------------------------------------------------+ +| TERMS OF USE: MIT License | ++------------------------------------------------------------------------------------------------------------------------------+ +|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation | +|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, | +|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software| +|is furnished to do so, subject to the following conditions: | +| | +|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.| +| | +|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | +|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | +|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | +|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ++------------------------------------------------------------------------------------------------------------------------------+ +}} \ No newline at end of file diff --git a/libraries/community/p2/All/ili9341/ILI9341-test.spin2 b/libraries/community/p2/All/ili9341/ILI9341-test.spin2 deleted file mode 100644 index 15b911de..00000000 --- a/libraries/community/p2/All/ili9341/ILI9341-test.spin2 +++ /dev/null @@ -1,102 +0,0 @@ -{{ - ILI9341-test.spin2 - -Test the ILI9341-spi.spin2 driver - -Author: Greg LaPolla -Updated: 2020-12-24 -Designed For: P2X8C4M64P -Version: 1.0 - -This driver was converted to spin2 from the original spin file that was written by Mark Tillotson - -Update History: -v1.0 - Initial version 2013-11-16 - -}} - -CON - - CLK_FREQ = 200_000_000 - - RX1 = 63 'programming output - TX1 = 62 'programming input - - BR_TERM = 230_400 - - nRESET= 25 - RS = 26 - CS = 24 - MOSI = 27 - SCLK = 28 - MISO = 29 - -OBJ - disp : "ILI9341" - -VAR - BYTE buffer[100] 'buffer to assemble output strings - -PUB Main() | i, j, k - - disp.Start (nRESET, CS, RS, MOSI, SCLK) - - repeat - disp.SetColours ($0, $0F800) - disp.ClearScreen() - repeat i from 0 to 115 step 3 - disp.SetColours ($0000+i*$0842, $001F) - disp.DrawRect (40+i, i, 279-i, 239-i) - waitct (getct() + clkfreq/2) - repeat i from 0 to 63 - disp.SetColours (j+56*(i>>1), $001F) - disp.DrawRect (i*3, 17+i*2, i*3+100, 50+i*2) - waitct (getct() + clkfreq/2) - disp.SetColours ($F81F, $E) - disp.ClearScreen() - disp.DrawString (0, 0, @stringy) - disp.DrawStringSmall (0, 100, @stringy) - repeat i from 0 to 319 step 5 - disp.SetColours ($F000+$12*i, $E) - disp.DrawLine (i, 0, 319-i, 239) - waitct (getct() + clkfreq/2) - disp.SetColours ($FFFF, $0) - repeat i from 0 to 239 step 5 - disp.DrawDot (270, i) - repeat i from 0 to 239 - disp.DrawCharSmall ((i & 15)*10, (i >> 4)* 16, i) - waitct (getct() + clkfreq/2) - disp.SetColours ($0, $FFFF) - repeat i from 0 to 63 - disp.DrawChar (170+(i & 7)*18, (i >> 3)* 32, i+$20) - waitct (getct() + clkfreq/2) - disp.SetColours ($FFE0, $0010) - repeat i from 0 to 63 - disp.DrawChar (170+(i & 7)*18, (i >> 3)* 32, i+$40) - waitct (getct() + clkfreq/2) - disp.SetColours ($F800, $07F0) - repeat i from 0 to 14 - disp.DrawStringSmall (0, i<<4, @stringy2) - waitct (getct() + clkfreq) - -DAT -stringy byte "Test string",0 -stringy2 byte "The quick brown fox jumps over the lazy ",0 - -{{ - - TERMS OF USE: MIT License - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, -modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -}} \ No newline at end of file diff --git a/libraries/community/p2/All/ili9341/ILI9341.spin2 b/libraries/community/p2/All/ili9341/ILI9341.spin2 deleted file mode 100644 index 8c028fe413559509eaeeda8778aa64eac456deb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50768 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�TL#g0;=DQ)5y{lv_Mr1{84Z~ED<;oM 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 Hf8G3l0TV>| literal 0 HcmV?d00001 diff --git a/libraries/community/p2/All/ili9341/README.md b/libraries/community/p2/All/ili9341/README.md index 32e1cc6f..f1bede52 100644 --- a/libraries/community/p2/All/ili9341/README.md +++ b/libraries/community/p2/All/ili9341/README.md @@ -1,4 +1,4 @@ -# ILI9341 +# ILI9341_XPT2046 ## Language @@ -10,7 +10,7 @@ Display ## Description -ILI9341 is a spin2 object that interfaces the ILI9341 chip with the Propeller 2 P2X8C4M64P +ILI9341_XPT2046 is a spin2 object that interfaces the ILI9341 Video chip and the XPT2046 chip with the Propeller 2 P2X8C4M64P Learn more about the Propeller 2 at [www.parallax.com](http://www.parallax.com). @@ -18,9 +18,9 @@ Learn more about the Propeller 2 at [www.parallax.com](http://www.parallax.com). ## License -Copyright © 2020 Greg LaPolla ILI9341 Spin 2 Object is licensed under the MIT License. +Copyright © 2021 Greg LaPolla ILI9341_XPT2046 Spin 2 Object is licensed under the MIT License. ## Credits -ILI9341 Spin 2 Object is developed by Greg LaPolla. -This Driver was derived from The object ILI9341-spi by Mark Tillotson +ILI9341_XPT2046 Spin 2 Object is maintained by Greg LaPolla.
+This Driver was derived from Cluso's ST7796 4.0in SPI 480x320 w Touch LCD Driver diff --git a/libraries/community/p2/Motor Control/README.md b/libraries/community/p2/Motor Control/README.md index 86ef6859..755defa1 100644 --- a/libraries/community/p2/Motor Control/README.md +++ b/libraries/community/p2/Motor Control/README.md @@ -2,4 +2,6 @@ [JM Servo](../All/jm_servo) +[Stepper](../All/Stepper) + [Park Transformation](../All/ParkTransformation) \ No newline at end of file