Moved from SVN

This commit is contained in:
kirill.labutin 2025-01-09 20:12:48 +03:00
commit 6b7777fabe
36 changed files with 39138 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.idea
.svn
cmake-build-release

23
CMakeLists.txt Normal file
View File

@ -0,0 +1,23 @@
cmake_minimum_required(VERSION 3.17)
#check avr build tools installed
if (DEFINED ENV{AVR_BUILD_TOOLS})
set(BUILD_TOOLS_ROOT "$ENV{AVR_BUILD_TOOLS}")
else (DEFINED ENV{AVR_BUILD_TOOLS})
message(FATAL_ERROR "Build tools is not installed or ENV AVR_BUILD_TOOLS is not defined")
endif (DEFINED ENV{AVR_BUILD_TOOLS})
#load common project metadata
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/avr-project.cmake)
INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/avr-project.cmake)
project(${AVR_PROJECT_NAME})
INCLUDE("${BUILD_TOOLS_ROOT}/cmake-scripts/prepare-build.cmake")
else (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/avr-project.cmake)
project("Unconfigured project")
add_custom_target(
"Configure"
${BUILD_TOOLS_ROOT}/bin/avr-tools-bootstrap ${PROJECT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ProjectConfigurator
COMMENT "Start configuration utility"
)
endif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/avr-project.cmake)

835
PCB/Bottom.gbr Normal file
View File

@ -0,0 +1,835 @@
%TF.GenerationSoftware,Novarm,DipTrace,4.2.0.1*%
%TF.CreationDate,2022-06-14T17:56:08+02:00*%
%FSLAX26Y26*%
%MOIN*%
%TF.FileFunction,Copper,L2,Bot*%
%TF.Part,Single*%
%AMOUTLINE0*
4,1,28,
-0.019803,0.025591,
0.019803,0.025591,
0.02232,0.025259,
0.024665,0.024288,
0.026679,0.022742,
0.028225,0.020728,
0.029196,0.018383,
0.029528,0.015866,
0.029528,-0.015866,
0.029196,-0.018383,
0.028225,-0.020728,
0.026679,-0.022742,
0.024665,-0.024288,
0.02232,-0.025259,
0.019803,-0.025591,
-0.019803,-0.025591,
-0.02232,-0.025259,
-0.024665,-0.024288,
-0.026679,-0.022742,
-0.028225,-0.020728,
-0.029196,-0.018383,
-0.029528,-0.015866,
-0.029528,0.015866,
-0.029196,0.018383,
-0.028225,0.020728,
-0.026679,0.022742,
-0.024665,0.024288,
-0.02232,0.025259,
-0.019803,0.025591,
0*%
%AMOUTLINE3*
4,1,28,
0.025591,0.019803,
0.025591,-0.019803,
0.025259,-0.02232,
0.024288,-0.024665,
0.022742,-0.026679,
0.020728,-0.028225,
0.018383,-0.029196,
0.015866,-0.029528,
-0.015866,-0.029528,
-0.018383,-0.029196,
-0.020728,-0.028225,
-0.022742,-0.026679,
-0.024288,-0.024665,
-0.025259,-0.02232,
-0.025591,-0.019803,
-0.025591,0.019803,
-0.025259,0.02232,
-0.024288,0.024665,
-0.022742,0.026679,
-0.020728,0.028225,
-0.018383,0.029196,
-0.015866,0.029528,
0.015866,0.029528,
0.018383,0.029196,
0.020728,0.028225,
0.022742,0.026679,
0.024288,0.024665,
0.025259,0.02232,
0.025591,0.019803,
0*%
%AMOUTLINE6*
4,1,28,
-0.033465,0.043701,
0.033465,0.043701,
0.036012,0.043365,
0.038386,0.042382,
0.040424,0.040818,
0.041988,0.03878,
0.042972,0.036406,
0.043307,0.033858,
0.043307,-0.033858,
0.042972,-0.036406,
0.041988,-0.03878,
0.040424,-0.040818,
0.038386,-0.042382,
0.036012,-0.043365,
0.033465,-0.043701,
-0.033465,-0.043701,
-0.036012,-0.043365,
-0.038386,-0.042382,
-0.040424,-0.040818,
-0.041988,-0.03878,
-0.042972,-0.036406,
-0.043307,-0.033858,
-0.043307,0.033858,
-0.042972,0.036406,
-0.041988,0.03878,
-0.040424,0.040818,
-0.038386,0.042382,
-0.036012,0.043365,
-0.033465,0.043701,
0*%
%AMOUTLINE9*
4,1,28,
0.033465,-0.043701,
-0.033465,-0.043701,
-0.036012,-0.043365,
-0.038386,-0.042382,
-0.040424,-0.040818,
-0.041988,-0.03878,
-0.042972,-0.036406,
-0.043307,-0.033858,
-0.043307,0.033858,
-0.042972,0.036406,
-0.041988,0.03878,
-0.040424,0.040818,
-0.038386,0.042382,
-0.036012,0.043365,
-0.033465,0.043701,
0.033465,0.043701,
0.036012,0.043365,
0.038386,0.042382,
0.040424,0.040818,
0.041988,0.03878,
0.042972,0.036406,
0.043307,0.033858,
0.043307,-0.033858,
0.042972,-0.036406,
0.041988,-0.03878,
0.040424,-0.040818,
0.038386,-0.042382,
0.036012,-0.043365,
0.033465,-0.043701,
0*%
%AMOUTLINE12*
4,1,28,
0.011024,-0.033858,
-0.011024,-0.033858,
-0.013571,-0.033523,
-0.015945,-0.03254,
-0.017983,-0.030975,
-0.019547,-0.028937,
-0.020531,-0.026563,
-0.020866,-0.024016,
-0.020866,0.024016,
-0.020531,0.026563,
-0.019547,0.028937,
-0.017983,0.030975,
-0.015945,0.03254,
-0.013571,0.033523,
-0.011024,0.033858,
0.011024,0.033858,
0.013571,0.033523,
0.015945,0.03254,
0.017983,0.030975,
0.019547,0.028937,
0.020531,0.026563,
0.020866,0.024016,
0.020866,-0.024016,
0.020531,-0.026563,
0.019547,-0.028937,
0.017983,-0.030975,
0.015945,-0.03254,
0.013571,-0.033523,
0.011024,-0.033858,
0*%
%AMOUTLINE15*
4,1,28,
-0.011024,0.033858,
0.011024,0.033858,
0.013571,0.033523,
0.015945,0.03254,
0.017983,0.030975,
0.019547,0.028937,
0.020531,0.026563,
0.020866,0.024016,
0.020866,-0.024016,
0.020531,-0.026563,
0.019547,-0.028937,
0.017983,-0.030975,
0.015945,-0.03254,
0.013571,-0.033523,
0.011024,-0.033858,
-0.011024,-0.033858,
-0.013571,-0.033523,
-0.015945,-0.03254,
-0.017983,-0.030975,
-0.019547,-0.028937,
-0.020531,-0.026563,
-0.020866,-0.024016,
-0.020866,0.024016,
-0.020531,0.026563,
-0.019547,0.028937,
-0.017983,0.030975,
-0.015945,0.03254,
-0.013571,0.033523,
-0.011024,0.033858,
0*%
%AMOUTLINE18*
4,1,28,
0.027953,0.009449,
0.027953,-0.009449,
0.027617,-0.011996,
0.026634,-0.01437,
0.02507,-0.016409,
0.023031,-0.017973,
0.020658,-0.018956,
0.01811,-0.019291,
-0.01811,-0.019291,
-0.020658,-0.018956,
-0.023031,-0.017973,
-0.02507,-0.016409,
-0.026634,-0.01437,
-0.027617,-0.011996,
-0.027953,-0.009449,
-0.027953,0.009449,
-0.027617,0.011996,
-0.026634,0.01437,
-0.02507,0.016409,
-0.023031,0.017973,
-0.020658,0.018956,
-0.01811,0.019291,
0.01811,0.019291,
0.020658,0.018956,
0.023031,0.017973,
0.02507,0.016409,
0.026634,0.01437,
0.027617,0.011996,
0.027953,0.009449,
0*%
%AMOUTLINE21*
4,1,28,
-0.027953,-0.009449,
-0.027953,0.009449,
-0.027617,0.011996,
-0.026634,0.01437,
-0.02507,0.016409,
-0.023031,0.017973,
-0.020658,0.018956,
-0.01811,0.019291,
0.01811,0.019291,
0.020658,0.018956,
0.023031,0.017973,
0.02507,0.016409,
0.026634,0.01437,
0.027617,0.011996,
0.027953,0.009449,
0.027953,-0.009449,
0.027617,-0.011996,
0.026634,-0.01437,
0.02507,-0.016409,
0.023031,-0.017973,
0.020658,-0.018956,
0.01811,-0.019291,
-0.01811,-0.019291,
-0.020658,-0.018956,
-0.023031,-0.017973,
-0.02507,-0.016409,
-0.026634,-0.01437,
-0.027617,-0.011996,
-0.027953,-0.009449,
0*%
%AMOUTLINE24*
4,1,28,
0.013084,0.026447,
0.026447,0.013084,
0.028011,0.011046,
0.028994,0.008672,
0.02933,0.006125,
0.028994,0.003577,
0.028011,0.001203,
0.026447,-0.000835,
0.000835,-0.026447,
-0.001203,-0.028011,
-0.003577,-0.028994,
-0.006125,-0.02933,
-0.008672,-0.028994,
-0.011046,-0.028011,
-0.013084,-0.026447,
-0.026447,-0.013084,
-0.028011,-0.011046,
-0.028994,-0.008672,
-0.02933,-0.006125,
-0.028994,-0.003577,
-0.028011,-0.001203,
-0.026447,0.000835,
-0.000835,0.026447,
0.001203,0.028011,
0.003577,0.028994,
0.006125,0.02933,
0.008672,0.028994,
0.011046,0.028011,
0.013084,0.026447,
0*%
%AMOUTLINE27*
4,1,28,
-0.013084,-0.026447,
-0.026447,-0.013084,
-0.028011,-0.011046,
-0.028994,-0.008672,
-0.02933,-0.006125,
-0.028994,-0.003577,
-0.028011,-0.001203,
-0.026447,0.000835,
-0.000835,0.026447,
0.001203,0.028011,
0.003577,0.028994,
0.006125,0.02933,
0.008672,0.028994,
0.011046,0.028011,
0.013084,0.026447,
0.026447,0.013084,
0.028011,0.011046,
0.028994,0.008672,
0.02933,0.006125,
0.028994,0.003577,
0.028011,0.001203,
0.026447,-0.000835,
0.000835,-0.026447,
-0.001203,-0.028011,
-0.003577,-0.028994,
-0.006125,-0.02933,
-0.008672,-0.028994,
-0.011046,-0.028011,
-0.013084,-0.026447,
0*%
%AMOUTLINE30*
4,1,28,
-0.009449,0.027953,
0.009449,0.027953,
0.011996,0.027617,
0.01437,0.026634,
0.016409,0.02507,
0.017973,0.023031,
0.018956,0.020658,
0.019291,0.01811,
0.019291,-0.01811,
0.018956,-0.020658,
0.017973,-0.023031,
0.016409,-0.02507,
0.01437,-0.026634,
0.011996,-0.027617,
0.009449,-0.027953,
-0.009449,-0.027953,
-0.011996,-0.027617,
-0.01437,-0.026634,
-0.016409,-0.02507,
-0.017973,-0.023031,
-0.018956,-0.020658,
-0.019291,-0.01811,
-0.019291,0.01811,
-0.018956,0.020658,
-0.017973,0.023031,
-0.016409,0.02507,
-0.01437,0.026634,
-0.011996,0.027617,
-0.009449,0.027953,
0*%
%AMOUTLINE33*
4,1,28,
0.009449,-0.027953,
-0.009449,-0.027953,
-0.011996,-0.027617,
-0.01437,-0.026634,
-0.016409,-0.02507,
-0.017973,-0.023031,
-0.018956,-0.020658,
-0.019291,-0.01811,
-0.019291,0.01811,
-0.018956,0.020658,
-0.017973,0.023031,
-0.016409,0.02507,
-0.01437,0.026634,
-0.011996,0.027617,
-0.009449,0.027953,
0.009449,0.027953,
0.011996,0.027617,
0.01437,0.026634,
0.016409,0.02507,
0.017973,0.023031,
0.018956,0.020658,
0.019291,0.01811,
0.019291,-0.01811,
0.018956,-0.020658,
0.017973,-0.023031,
0.016409,-0.02507,
0.01437,-0.026634,
0.011996,-0.027617,
0.009449,-0.027953,
0*%
%ADD12C,0.005512*%
%TA.AperFunction,Conductor*%
%ADD15C,0.03937*%
%ADD16C,0.038583*%
%TA.AperFunction,ComponentPad*%
%ADD17C,0.05*%
%ADD18R,0.05X0.05*%
%ADD22R,0.059055X0.059055*%
%ADD23C,0.059055*%
%ADD24R,0.067323X0.067323*%
%ADD25C,0.067323*%
%ADD26R,0.094488X0.094488*%
%ADD27C,0.094488*%
%ADD28R,0.072835X0.072835*%
%ADD29C,0.072835*%
%ADD30R,0.066929X0.066929*%
%ADD31C,0.066929*%
%ADD32R,0.11811X0.11811*%
%ADD33R,0.04685X0.04685*%
%ADD34C,0.04685*%
%ADD35C,0.040551*%
%TA.AperFunction,ViaPad*%
%ADD36C,0.07874*%
%ADD81OUTLINE0*%
%ADD84OUTLINE3*%
%ADD87OUTLINE6*%
%ADD90OUTLINE9*%
%ADD93OUTLINE12*%
%ADD96OUTLINE15*%
%ADD99OUTLINE18*%
%ADD102OUTLINE21*%
%ADD105OUTLINE24*%
%ADD108OUTLINE27*%
%ADD111OUTLINE30*%
%ADD114OUTLINE33*%
G75*
G01*
%LPD*%
X2085374Y1070472D2*
D15*
X2866634D1*
X2968504Y968602D1*
X3279134D1*
X3390551Y857185D1*
X3646457D1*
X2428051D2*
X2683957D1*
X2085374Y870472D2*
X2414764D1*
X2428051Y857185D1*
X2085374Y970472D2*
X2802264D1*
X2915551Y857185D1*
X3171457D1*
X3756003Y1103839D2*
D16*
Y1151476D1*
D15*
Y1468604D1*
X3694252Y1530354D1*
X3628642D1*
X2085374Y1270472D2*
X3052085D1*
X3445374D1*
X3518504Y1343602D1*
Y1481102D1*
X3567756Y1530354D1*
X3628642D1*
X1772894Y1170472D2*
X1841634D1*
X1893602Y1118504D1*
Y1056102D1*
X2706004Y2418504D2*
X2906004D1*
X2993602D1*
X3052085Y2360021D1*
Y1270472D1*
X2118504Y2206102D2*
X2306004D1*
X2331004Y2231102D1*
Y2331102D1*
X2418406Y2418504D1*
X2706004D1*
X2274606Y1893602D2*
Y1808350D1*
X2264354Y1818602D1*
D16*
X2253740D1*
X2085374Y1270472D2*
D15*
X2066634D1*
X1981004Y1356102D1*
Y1893602D1*
X2056004Y1968602D1*
X2243504D1*
X2274606Y1937500D1*
Y1893602D1*
X1772894Y1170472D2*
X1595374D1*
X1531004Y1106102D1*
Y906102D1*
Y581102D1*
X1468504Y518602D1*
X1043504D1*
X899744Y662362D1*
X718524D1*
Y2193622D2*
Y2529547D1*
X770079Y2581102D1*
Y2695177D1*
X818504Y2743602D1*
X2231004D1*
X2256004Y2718602D1*
Y2418602D1*
X2118504Y2281102D1*
Y2206102D1*
X1531004Y906102D2*
D3*
X1406004Y1568602D2*
Y1431102D1*
X1506004Y1768602D2*
X1606004D1*
X1668504Y1706102D1*
Y1618602D1*
X1716634Y1570472D1*
X1772894D1*
Y1670472D2*
X1820374D1*
X1881004Y1731102D1*
Y1906102D1*
X1768504Y2018602D1*
X1368504D1*
X1231004Y1881102D1*
Y1718602D1*
X1281004Y1668602D1*
X1406004D1*
X2085374Y1670472D2*
X2395472D1*
X2395866Y1670866D1*
D16*
X2606004D1*
X2518504D1*
X2085374Y770472D2*
D15*
X2191634D1*
X2406004Y556102D1*
X3768504D1*
X3856004Y643602D1*
Y1493602D1*
X3719252Y1630354D1*
X3628642D1*
Y1730315D2*
X3756791D1*
X3943504Y1543602D1*
Y593602D1*
X3806004Y456102D1*
X2368504D1*
X2154134Y670472D1*
X2085374D1*
Y1470472D2*
X2595374D1*
X2709941Y1585039D1*
Y2218602D1*
Y2339764D1*
X2706004Y2343701D1*
X2085374Y1370472D2*
X2807874D1*
X2902067Y1464665D1*
Y2218602D1*
Y2339764D1*
X2906004Y2343701D1*
X1918504Y2206102D2*
Y2168602D1*
X1981004Y2106102D1*
X2406004D1*
X2468504Y2043602D1*
D16*
X2518504Y1993602D1*
Y1741339D1*
X2606004D2*
Y1780315D1*
D15*
Y2056102D1*
X2431004Y2231102D1*
X2018504Y2206102D2*
Y2431102D1*
X2041929Y2454528D1*
Y2556102D1*
X966929Y2581102D2*
Y2331102D1*
Y2295669D1*
X1068996Y2193602D1*
X1868588Y2056018D2*
D16*
X1834903Y2089703D1*
D15*
X1593504Y2331102D1*
X966929D1*
X1845079Y2556102D2*
X991929D1*
X966929Y2581102D1*
X2085374Y1770472D2*
X2142421D1*
D16*
X2162402D1*
Y1818602D1*
X2183268D1*
X2162402Y1893602D2*
D15*
Y1818602D1*
Y1770472D2*
X2166634D1*
X2193504Y1743602D1*
X2381004D1*
X2418504Y1781102D1*
Y1956102D1*
X2331004Y2043602D1*
X2018504D1*
X1981088Y2006186D1*
X1957396D1*
D16*
X1918420D1*
X1243012Y2193602D2*
D15*
X1393504D1*
X1393524Y2193622D1*
X2428051Y680020D2*
X2683957D1*
X2915551D1*
X3171457D1*
X3390551D1*
X3646457D1*
X3756005Y1033366D2*
D16*
X3756004Y994390D1*
D15*
Y731102D1*
X3704921Y680020D1*
X3646457D1*
X1968504Y833366D2*
D16*
Y794390D1*
D15*
Y618602D1*
X2016634Y570472D1*
X2029114D1*
X2085374D1*
X2029114D2*
Y504213D1*
X1993504Y468602D1*
X1739521D1*
X1643504Y564619D1*
Y1068602D1*
X1506004Y1568602D2*
Y1431102D1*
Y1668602D2*
X1568504D1*
X1593504Y1643602D1*
Y1568602D1*
X1691634Y1470472D1*
X1772894D1*
Y1370472D2*
Y1319762D1*
Y1270472D1*
X2085374Y1170472D2*
X2016634D1*
X1916634Y1270472D1*
X1772894D1*
X2085374Y1170472D2*
X3507874D1*
X3628642Y1291240D1*
Y1430315D1*
X1968406Y1056102D2*
Y1122244D1*
X2016634Y1170472D1*
X1968504Y903839D2*
D16*
Y942815D1*
D15*
Y1056004D1*
X1968406Y1056102D1*
X1393524Y662362D2*
Y1156122D1*
X1557164Y1319762D1*
X1681004D1*
X1772894D1*
X1681004Y1318602D2*
Y1319762D1*
X1406004Y1768602D2*
Y1893602D1*
X1443504Y1931102D1*
X1568504D1*
X1581004Y1918602D1*
X551181Y2913386D2*
Y2677165D1*
X433071Y2795276D2*
X669291D1*
X3858268D2*
X4094488D1*
X3976378Y2913386D2*
Y2677165D1*
X551181Y669291D2*
Y433071D1*
X433071Y551181D2*
X669291D1*
D36*
X1643504Y1068602D3*
X1506004Y1431102D3*
X1406004D3*
X1581004Y1918602D3*
X1681004Y1318602D3*
X1531004Y906102D3*
D81*
X2706004Y2418504D3*
Y2343701D3*
X2906004Y2418504D3*
Y2343701D3*
D84*
X1968406Y1056102D3*
X1893602D3*
D17*
X2431004Y2231102D3*
D18*
X2331004D3*
D87*
X1243012Y2193602D3*
D90*
X1068996D3*
D93*
X2162402Y1893602D3*
D96*
X2274606D3*
D22*
X3628642Y1730315D3*
D23*
Y1630354D3*
Y1530354D3*
Y1430315D3*
D24*
X1506002Y1768603D3*
D25*
X1406002Y1768601D3*
X1506004Y1668603D3*
X1406004Y1668601D3*
X1506006Y1568603D3*
X1406006Y1568601D3*
D26*
X2041929Y2556102D3*
D27*
X1845079D3*
D26*
X966929Y2581102D3*
D27*
X770079D3*
D28*
X1918504Y2206102D3*
D29*
X2018504D3*
X2118504D3*
D99*
X2518504Y1670866D3*
D102*
Y1741339D3*
D99*
X2606004Y1670866D3*
D102*
Y1741339D3*
X1968504Y903839D3*
D99*
Y833366D3*
D105*
X1918420Y2006187D3*
D108*
X1868588Y2056018D3*
D111*
X2253740Y1818602D3*
D114*
X2183268D3*
D99*
X3756005Y1033366D3*
D102*
X3756003Y1103839D3*
D30*
X2428051Y857185D3*
D31*
Y680020D3*
X2683957D3*
Y857185D3*
D30*
X2915551D3*
D31*
Y680020D3*
X3171457D3*
Y857185D3*
D30*
X3390551D3*
D31*
Y680020D3*
X3646457D3*
Y857185D3*
D32*
X1393524Y2193622D3*
X718524D3*
X1393524Y662362D3*
X718524D3*
D33*
X2085374Y570472D3*
D34*
Y670472D3*
Y770472D3*
Y870472D3*
Y970472D3*
Y1070472D3*
Y1170472D3*
Y1270472D3*
Y1370472D3*
Y1470472D3*
Y1570472D3*
Y1670472D3*
Y1770472D3*
Y1870472D3*
X1772894D3*
Y1770472D3*
Y1670472D3*
Y1570472D3*
Y1470472D3*
Y1370472D3*
Y1270472D3*
Y1170472D3*
Y1070472D3*
Y970472D3*
Y870472D3*
Y770472D3*
Y670472D3*
Y570472D3*
D35*
X2709941Y2218602D3*
X2902067D3*
X393701Y393701D2*
D12*
Y2952756D1*
X4133858D1*
Y393701D1*
X393701D1*
M02*

BIN
PCB/PCB.g2g Normal file

Binary file not shown.

18684
PCB/bottom.gcode Normal file

File diff suppressed because it is too large Load Diff

17654
PCB/bottom.tap Normal file

File diff suppressed because it is too large Load Diff

BIN
PCB/pcb.dip Normal file

Binary file not shown.

BIN
PCB/schematic.dch Normal file

Binary file not shown.

3
avr-dependencies.cmake Normal file
View File

@ -0,0 +1,3 @@
#add libraries here
#NOT WORKING FOR TINY!
load_external_library(utils svn https://svn.kirillius.ru/mcu-avr/avr-iohelp/trunk/lib/utils)

25
avr-project.cmake Normal file
View File

@ -0,0 +1,25 @@
set(AVR_EX_FUSE 0xff)
set(AVR_H_FUSE 0xD1)
set(AVR_L_FUSE 0xDC)
set(AVR_MCU atmega328p)
set(AVR_PROGRAMMER usbasp)
set(AVR_PROJECT_NAME feeder)
set(AVR_UPLOADTOOL_PORT usb)
set(MCU_SPEED 6908300)
#additional compiler parameters
#set(EXTRA_FLAGS "-Wl,-u,vfprintf -lprintf_min")
#add_definitions("-Wno-shift-overflow")
#Add defines
#add_definitions("-DNAME=VALUE")
add_definitions("-DTM1637_PORT=PORTD")
add_definitions("-DTM1637_PIN=PIND")
add_definitions("-DTM1637_REGISTER=DDRD")
add_definitions("-DTM1637_CLK=PD0")
add_definitions("-DTM1637_DIO=PD1")

176
lib/tm1637/tm1637.cpp Normal file
View File

@ -0,0 +1,176 @@
//
// Created by kerya on 12.06.2022.
//
#include <util/delay.h>
#include "tm1637.h"
void TM1637::redraw() {
// Write COMM1
start();
send(TM1637_I2C_COMM1);
stop();
// Write COMM2 + first digit address
start();
send(TM1637_I2C_COMM2);
// Write the data bytes
for (uint8_t b: data) send(b);
//for (uint8_t i = 0; i < sizeof(data); i++) send(data[i]);
stop();
// Write COMM3 + brightness
start();
send(TM1637_I2C_COMM3 + (brightness & 0x0f));
stop();
}
TM1637::TM1637() {
clear();
brightness = 0;
TM1637_REGISTER &= ~(1 << TM1637_DIO); //set to IN
TM1637_REGISTER &= ~(1 << TM1637_CLK);
TM1637_PORT &= ~(1 << TM1637_CLK); //set states to LOW
TM1637_PORT &= ~(1 << TM1637_DIO);
}
void TM1637::start() {
TM1637_REGISTER |= (1 << TM1637_DIO);
delay();
}
void TM1637::stop() {
TM1637_REGISTER |= (1 << TM1637_DIO);
delay();
TM1637_REGISTER &= ~(1 << TM1637_CLK);
delay();
TM1637_REGISTER &= ~(1 << TM1637_DIO);
delay();
}
void TM1637::delay() {
_delay_us(100);
}
//Button = 0 = &
//OUTPUT = 1 = |
uint8_t TM1637::send(uint8_t d) {
for (uint8_t i = 0; i < 8; i++) {
TM1637_REGISTER |= (1 << TM1637_CLK);
delay();
if (d >> i & 0x1) {
TM1637_REGISTER &= ~(1 << TM1637_DIO);
} else {
TM1637_REGISTER |= (1 << TM1637_DIO);
}
delay();
TM1637_REGISTER &= ~(1 << TM1637_CLK);
delay();
}
TM1637_REGISTER |= (1 << TM1637_CLK);
TM1637_REGISTER &= ~(1 << TM1637_DIO);
delay();
TM1637_REGISTER &= ~(1 << TM1637_CLK);
delay();
uint8_t ack = TM1637_PIN & (1 << TM1637_DIO);
if (ack == 0) TM1637_REGISTER |= (1 << TM1637_DIO);
delay();
TM1637_REGISTER |= (1 << TM1637_CLK);
delay();
return ack;
}
void TM1637::enable() {
brightness = 0x0f;
redraw();
}
void TM1637::disable() {
clear();
brightness = 0;
redraw();
}
void TM1637::setSegment(uint8_t index, uint8_t d) {
if (index < sizeof(data)) {
data[index] = d;
}
}
//
// A
// ---
// F | | B
// -G-
// E | | C
// ---
// D
// XGFEDCBA
//0b01111111
//
uint8_t TM1637::encodeChar(char c) {
switch (c) {
case 'A':
return 0b01110111;
case 'C':
return 0b00111001;
case 'E':
return 0b01111001;
case 'L':
return 0b00111000;
case 'P':
return 0b01110011;
case 'T':
return 0b01111000;
case 'U':
return 0b00111110;
case 'H':
case 'K':
case 'X':
return 0b01110110;
case 'O':
case '0':
return 0b00111111;
case '1':
return 0b00000110;
case '2':
return 0b01011011;
case '3':
return 0b01001111;
case '4':
case 'Y':
return 0b01100110;
case '5':
return 0b01101101;
case '6':
return 0b01111101;
case '7':
return 0b00000111;
case '8':
return 0b01111111;
case '9':
return 0b01101111;
default:
return 0;
}
}
void TM1637::clear() {
for (uint8_t &i: data) i = 0;
}
uint8_t TM1637::encodeNumber(uint8_t n) {
if (n >= 10) return 0;
return encodeChar((char) 48 + n);
}

64
lib/tm1637/tm1637.h Normal file
View File

@ -0,0 +1,64 @@
//
// Created by kerya on 12.06.2022.
//
#include <avr/io.h>
#ifndef TM1637_H
#define TM1637_H
#ifndef TM1637_PORT
#error "TM1637_PORT is not defined"
#endif
#ifndef TM1637_PIN
#error "TM1637_PIN is not defined"
#endif
#ifndef TM1637_REGISTER
#error "TM1637_REGISTER is not defined"
#endif
#ifndef TM1637_CLK
#error "TM1637_CLK is not defined"
#endif
#ifndef TM1637_DIO
#error "TM1637_DIO is not defined"
#endif
#define TM1637_I2C_COMM1 0x40
#define TM1637_I2C_COMM2 0xC0
#define TM1637_I2C_COMM3 0x80
#define SEG_DOT 0b10000000
class TM1637 {
private:
uint8_t data[4];
uint8_t brightness;
void start();
void stop();
uint8_t send(uint8_t d);
void delay();
public:
void clear();
void redraw();
TM1637();
void setSegment(uint8_t index, uint8_t data);
uint8_t encodeChar(char c);
uint8_t encodeNumber(uint8_t n);
void enable();
void disable();
};
#endif //TM1637_H

24
lib/utils/ADC.cpp Normal file
View File

@ -0,0 +1,24 @@
//
// Created by User on 018 18.05.20.
//
#include "ADC.h"
#define ADC_PORT_SELECTION_MASK ((1<<REFS0) | (1<<REFS1) | (1<<ADLAR))
void ADCIO::setup() {
ADCSRA |= (1<<ADEN); //включаем ADC
ADCSRA |= (1<<ADPS0)|(1<<ADPS1)|(1<<ADPS2);//выставляем делитель частоты 128
ADMUX |= (1<<REFS0); //используем внешнее опорное напряжение
}
uint16_t ADCIO::read(ADCPort port) {
ADMUX &= ADC_PORT_SELECTION_MASK;
ADMUX |= port;
uint16_t result = 0;
for(uint8_t i=0;i<ADC_READ_COUNT;i++){
ADCSRA |= (1<<ADSC);//включаем АЦП
while((ADCSRA & (1<<ADSC))); //ждём готовность
result+=(uint16_t)ADCW;
}
return result/ADC_READ_COUNT;
}

27
lib/utils/ADC.h Normal file
View File

@ -0,0 +1,27 @@
//
// Created by User on 018 18.05.20.
//
#ifndef AVR_IOHELP_ADC_H
#define AVR_IOHELP_ADC_H
#include <avr/io.h>
#define ADC_READ_COUNT 5
enum ADCPort{
ADC0 = 0x00,
ADC1 = 0x01,
ADC2 = 0x02,
ADC3 = 0x03,
ADC4 = 0x04,
ADC5 = 0x05,
ADC6 = 0x06,
ADC7 = 0x07
//ADC8_INTERNAL = 0b1000
};
namespace ADCIO{
void setup();
uint16_t read(ADCPort port);
}
#endif //AVR_IOHELP_ADC_H

43
lib/utils/EEPROM.cpp Normal file
View File

@ -0,0 +1,43 @@
#include "EEPROM.h"
namespace EEPROM {
void set(uint16_t address, uint8_t data) {
if (get(address) != data) {
/* Wait for completion of previous write */
while (EECR & (1 << EEPE));
/* Set up address and Data Registers */
EEAR = address;
EEDR = data;
/* Write logical one to EEMPE */
EECR |= (1 << EEMPE);
/* Start eeprom write by setting EEPE */
EECR |= (1 << EEPE);
}
}
void set(uint16_t address, void *dataSource, size_t dataSize) {
uint8_t *data = (uint8_t *) dataSource;
for (size_t i = 0; i < dataSize; i++) {
set(address + i, data[i]);
}
}
uint8_t get(uint16_t address) {
/* Wait for completion of previous write */
while (EECR & (1 << EEPE));
/* Set up address register */
EEAR = address;
/* Start eeprom read by writing EERE */
EECR |= (1 << EERE);
/* Return data from Data Register */
return EEDR;
}
void get(uint16_t address, void *dataDest, size_t dataSize) {
uint8_t *data = (uint8_t *) dataDest;
for (size_t i = 0; i < dataSize; i++) {
data[i] = get(address + i);
}
}
}

15
lib/utils/EEPROM.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef AVR_IOHELP_EEPROM_H
#define AVR_IOHELP_EEPROM_H
#include <avr/io.h>
#include <stddef.h>
namespace EEPROM{
void set(uint16_t address, uint8_t data);
void set(uint16_t address, void * dataSource, size_t dataSize);
uint8_t get(uint16_t address);
void get(uint16_t address, void * dataDest, size_t dataSize);
}
#endif //AVR_IOHELP_EEPROM_H

77
lib/utils/TWI.cpp Normal file
View File

@ -0,0 +1,77 @@
#include "TWI.h"
namespace TWI {
BusState startMessage(Address addr) {
TWCR = (1 << TWSTA) | (1 << TWEN) | (1 << TWINT);
wait();
uint8_t status = sendByte(addr);
if (status == 0x18 || status == 0x40) return TWI_OK;
else return status;
}
void close() {
TWCR = (1 << TWSTO) | (1 << TWEN) | (1 << TWINT);
}
BusState sendByte(uint8_t byte) {
TWDR = byte;
TWCR = (1 << TWEN) | (1 << TWINT);
wait();
uint8_t status = (TWSR & 0xF8);
if (status != 0x28 && status != 0x30) return status;
else return TWI_OK;
}
void wait() {
while (!(TWCR & (1 << TWINT)));
}
BusState nack() {
TWCR = (1 << TWEN) | (1 << TWINT);
wait();
uint8_t status = (TWSR & 0xF8);
if (status != 0x50 && status != 0x58) return status;
else return TWI_OK;
}
BusState ack() {
TWCR = (1 << TWEN) | (1 << TWINT) | (1 << TWEA);
wait();
uint8_t status = (TWSR & 0xF8);
if (status != 0x50 && status != 0x58) return status;
else return TWI_OK;
}
uint8_t readByte() {
return TWDR;
}
void init(uint32_t busSpeed) {
// TWSR = ~(1 << TWPS0);
// TWSR = ~(1 << TWPS1);
TWBR = ((F_CPU / busSpeed - 16) / (2 * 4));
/*
// initialize twi prescaler and bit rate
cbi(TWSR, TWPS0);
cbi(TWSR, TWPS1);
TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;*/
/* twi bit rate formula from atmega128 manual pg 204
SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))
note: TWBR should be 10 or higher for master mode
It is 72 for a 16mhz Wiring board with 100kHz TWI */
// enable twi module, acks, and twi interrupt
TWCR = _BV(TWEN) | _BV(TWEA); //| _BV(TWIE);
//
}
}

23
lib/utils/TWI.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef TWI_H
#define TWI_H
#include <avr/io.h>
#define TWI_OK 0x00
namespace TWI {
typedef uint8_t BusState;
typedef uint8_t Address;
void init(uint32_t busSpeed);
void close();
BusState startMessage(Address addr);
BusState sendByte(uint8_t byte);
BusState ack();
uint8_t readByte();
BusState nack();
void wait();
}
#endif

32
lib/utils/Timer.cpp Normal file
View File

@ -0,0 +1,32 @@
//
// Created by User on 018 18.05.20.
//
#include "Timer.h"
void Timer1::setup(TimerPrescaler prescaler, uint16_t OCR) {
TCCR1B |= (1 << WGM12); //режим сброса по свпадению
switch (prescaler) {
case PRESCALER_NO:
TCCR1B |= (1 << CS10);
break;
case PRESCALER_8:
TCCR1B |= (1 << CS11);
break;
case PRESCALER_64:
TCCR1B |= (1 << CS10) | (1 << CS10);
break;
case PRESCALER_256:
TCCR1B |= (1 << CS12);
break;
case PRESCALER_1024:
TCCR1B |= (1 << CS12) | (1 << CS10);
break;
}
TIMSK1 |= (1 << OCIE1A); //устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR1A(H и L)
OCR1AH = (OCR & 0xFF00) >> 8;
OCR1AL = (OCR & 0x00FF);
}

23
lib/utils/Timer.h Normal file
View File

@ -0,0 +1,23 @@
//
// Created by User on 018 18.05.20.
//
#ifndef AVR_IOHELP_TIMER_H
#define AVR_IOHELP_TIMER_H
#include <avr/io.h>
#define onTimer1Triggered() ISR(TIMER1_COMPA_vect)
enum TimerPrescaler{
PRESCALER_NO,
PRESCALER_8,
PRESCALER_64,
PRESCALER_256,
PRESCALER_1024
};
namespace Timer1{
void setup(TimerPrescaler prescaler, uint16_t OCR);
}
#endif //AVR_IOHELP_TIMER_H

22
lib/utils/iohelp.h Normal file
View File

@ -0,0 +1,22 @@
//
// Created by kirillius on 20.04.2020.
//
#ifndef AVR_IOHELP_H
#define AVR_IOHELP_H
//Пример: pinmode_input(DDRB, PORTB1);
#define pinmode_input(DDREGISTER, PINNAME) (DDREGISTER &= ~(1<<PINNAME))
#define pinmode_output(DDREGISTER, PINNAME) (DDREGISTER |= (1<<PINNAME))
//Пример: pinstateset(PORTB, PORTB1, true);
#define pinstateset(PORTREGISTER, PINNAME, STATE) do{ if(STATE){ PORTREGISTER |= (1<<PINNAME); }else{ PORTREGISTER &= ~(1<<PINNAME); } }while(0)
//Пример: int state = pinstateget(PINB, PORTB1);
#define pinstateget(PINREGISTER, PINNAME) (PINREGISTER & (1<<PINNAME))
#endif //AVR_IOHELP_H

22
lib/utils/spi.cpp Normal file
View File

@ -0,0 +1,22 @@
//
// Created by kirillius on 25.09.2021.
//
#include "spi.h"
uint8_t SPI::transfer(uint8_t byte){
SPDR = byte;
while(!(SPSR & (1<<SPIF))); //ожидание готовности SPI
return SPDR; //возврат того, что пришло
}
void SPI::send(uint8_t byte){
SPI::transfer(byte);
}
uint8_t SPI::receive(){
return SPI::transfer(0xFF);
}
uint8_t SPI::data() {
return SPDR;
}

19
lib/utils/spi.h Normal file
View File

@ -0,0 +1,19 @@
//
// Created by kirillius on 25.09.2021.
//
#ifndef AVR_IOHELP_SPI_H
#define AVR_IOHELP_SPI_H
#include <avr/io.h>
#define SPI(MOSI, MISO, SCK) do{DDRB = ((DDRB&~(1<<MISO))|(1<<MOSI)|(1<<SCK)); (SPCR |= (1<<SPE)|(1<<MSTR)); SPSR |= (1<<SPI2X);}while(0)
namespace SPI{
uint8_t transfer(uint8_t byte);
void send(uint8_t byte);
uint8_t receive();
uint8_t data();
}
#endif //AVR_IOHELP_SPI_H

258
obsolete/TM1637Display.cpp Normal file
View File

@ -0,0 +1,258 @@
// Author: avishorp@gmail.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
extern "C" {
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <util/delay.h>
}
#include "TM1637Display.h"
#define TM1637_I2C_COMM1 0x40
#define TM1637_I2C_COMM2 0xC0
#define TM1637_I2C_COMM3 0x80
//
// A
// ---
// F | | B
// -G-
// E | | C
// ---
// D
const uint8_t digitToSegment[] = {
// XGFEDCBA
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111, // 9
0b01110111, // A
0b01111100, // b
0b00111001, // C
0b01011110, // d
0b01111001, // E
0b01110001 // F
};
static const uint8_t minusSegments = 0b01000000;
TM1637Display::TM1637Display(unsigned int bitDelay) {
// Copy the pin numbers
m_bitDelay = bitDelay;
// Set the pin direction and default value.
// Both pins are set as inputs, allowing the pull-up resistors to pull them up
TM_PINMODE_IN(TM1637_DIO);
TM_PINMODE_IN(TM1637_CLK);
TM1637_PORT &= ~(1 << TM1637_CLK); //set states to LOW
TM1637_PORT &= ~(1 << TM1637_DIO);
}
void TM1637Display::setBrightness(uint8_t brightness, bool on) {
m_brightness = (brightness & 0x7) | (on ? 0x08 : 0x00);
}
void TM1637Display::setSegments(const uint8_t segments[], uint8_t length, uint8_t pos) {
// Write COMM1
start();
writeByte(TM1637_I2C_COMM1);
stop();
// Write COMM2 + first digit address
start();
writeByte(TM1637_I2C_COMM2 + (pos & 0x03));
// Write the data bytes
for (uint8_t k = 0; k < length; k++)
writeByte(segments[k]);
stop();
// Write COMM3 + brightness
start();
writeByte(TM1637_I2C_COMM3 + (m_brightness & 0x0f));
stop();
}
void TM1637Display::clear() {
uint8_t data[] = {0, 0, 0, 0};
setSegments(data);
}
void TM1637Display::showNumberDec(int num, bool leading_zero, uint8_t length, uint8_t pos) {
showNumberDecEx(num, 0, leading_zero, length, pos);
}
void TM1637Display::showNumberDecEx(int num, uint8_t dots, bool leading_zero,
uint8_t length, uint8_t pos) {
showNumberBaseEx(num < 0 ? -10 : 10, num < 0 ? -num : num, dots, leading_zero, length, pos);
}
void TM1637Display::showNumberHexEx(uint16_t num, uint8_t dots, bool leading_zero,
uint8_t length, uint8_t pos) {
showNumberBaseEx(16, num, dots, leading_zero, length, pos);
}
void TM1637Display::showNumberBaseEx(int8_t base, uint16_t num, uint8_t dots, bool leading_zero,
uint8_t length, uint8_t pos) {
bool negative = false;
if (base < 0) {
base = -base;
negative = true;
}
uint8_t digits[4];
if (num == 0 && !leading_zero) {
// Singular case - take care separately
for (uint8_t i = 0; i < (length - 1); i++)
digits[i] = 0;
digits[length - 1] = encodeDigit(0);
} else {
//uint8_t i = length-1;
//if (negative) {
// // Negative number, show the minus sign
// digits[i] = minusSegments;
// i--;
//}
for (int i = length - 1; i >= 0; --i) {
uint8_t digit = num % base;
if (digit == 0 && num == 0 && leading_zero == false)
// Leading zero is blank
digits[i] = 0;
else
digits[i] = encodeDigit(digit);
if (digit == 0 && num == 0 && negative) {
digits[i] = minusSegments;
negative = false;
}
num /= base;
}
}
if (dots != 0) {
showDots(dots, digits);
}
setSegments(digits, length, pos);
}
void TM1637Display::bitDelay() {
//delayMicroseconds(m_bitDelay);
_delay_us(DEFAULT_BIT_DELAY);
}
void TM1637Display::start() {
//pinMode(m_pinDIO, OUTPUT);
TM_PINMODE_OUT(TM1637_DIO);
bitDelay();
}
void TM1637Display::stop() {
TM_PINMODE_OUT(TM1637_DIO);
//pinMode(m_pinDIO, OUTPUT);
bitDelay();
TM_PINMODE_IN(TM1637_CLK);
//pinMode(m_pinClk, INPUT);
bitDelay();
TM_PINMODE_IN(TM1637_DIO);
//pinMode(m_pinDIO, INPUT);
bitDelay();
}
bool TM1637Display::writeByte(uint8_t b) {
uint8_t data = b;
// 8 Data Bits
for (uint8_t i = 0; i < 8; i++) {
// CLK low
//pinMode(m_pinClk, OUTPUT);
TM_PINMODE_OUT(TM1637_CLK);
bitDelay();
// Set data bit
if (data & 0x01)
//pinMode(m_pinDIO, INPUT);
TM_PINMODE_IN(TM1637_DIO);
else
//pinMode(m_pinDIO, OUTPUT);
TM_PINMODE_OUT(TM1637_DIO);
bitDelay();
// CLK high
TM_PINMODE_IN(TM1637_CLK);
//pinMode(m_pinClk, INPUT);
bitDelay();
data = data >> 1;
}
// Wait for acknowledge
// CLK to zero
TM_PINMODE_OUT(TM1637_CLK);
TM_PINMODE_IN(TM1637_DIO);
// pinMode(m_pinClk, OUTPUT);
// pinMode(m_pinDIO, INPUT);
bitDelay();
// CLK to high
//pinMode(m_pinClk, INPUT);
TM_PINMODE_IN(TM1637_CLK);
bitDelay();
uint8_t ack = TM1637_PIN & (1 << TM1637_DIO);// digitalRead(m_pinDIO);
if (ack == 0)
TM_PINMODE_OUT(TM1637_DIO);
//pinMode(m_pinDIO, OUTPUT);
bitDelay();
TM_PINMODE_OUT(TM1637_CLK);
//pinMode(m_pinClk, OUTPUT);
bitDelay();
return ack;
}
void TM1637Display::showDots(uint8_t dots, uint8_t *digits) {
for (int i = 0; i < 4; ++i) {
digits[i] |= (dots & 0x80);
dots <<= 1;
}
}
uint8_t TM1637Display::encodeDigit(uint8_t digit) {
return digitToSegment[digit & 0x0f];
}

171
obsolete/TM1637Display.h Normal file
View File

@ -0,0 +1,171 @@
// Author: avishorp@gmail.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#ifndef __TM1637DISPLAY__
#define __TM1637DISPLAY__
#include <avr/io.h>
#define TM1637_REG DDRD
#define TM1637_PORT PORTD
#define TM1637_PIN PIND
#define TM1637_DIO PORTD1
#define TM1637_CLK PORTD0
#define TM_PINMODE_IN(pin) do{ TM1637_REG &= ~(1<<pin); }while(0x0)
#define TM_PINMODE_OUT(pin) do{ TM1637_REG |= (1<<pin); }while(0x0)
#include <inttypes.h>
#define DEFAULT_BIT_DELAY 100
class TM1637Display {
public:
//! Initialize a TM1637Display object, setting the clock and
//! data pins.
//!
//! @param bitDelay - The delay, in microseconds, between bit transition on the serial
//! bus connected to the display
TM1637Display(unsigned int bitDelay = DEFAULT_BIT_DELAY);
//! Sets the brightness of the display.
//!
//! The setting takes effect when a command is given to change the data being
//! displayed.
//!
//! @param brightness A number from 0 (lowes brightness) to 7 (highest brightness)
//! @param on Turn display on or off
void setBrightness(uint8_t brightness, bool on = true);
//! Display arbitrary data on the module
//!
//! This function receives raw segment values as input and displays them. The segment data
//! is given as a byte array, each byte corresponding to a single digit. Within each byte,
//! bit 0 is segment A, bit 1 is segment B etc.
//! The function may either set the entire display or any desirable part on its own. The first
//! digit is given by the @ref pos argument with 0 being the leftmost digit. The @ref length
//! argument is the number of digits to be set. Other digits are not affected.
//!
//! @param segments An array of size @ref length containing the raw segment values
//! @param length The number of digits to be modified
//! @param pos The position from which to start the modification (0 - leftmost, 3 - rightmost)
void setSegments(const uint8_t segments[], uint8_t length = 4, uint8_t pos = 0);
//! Clear the display
void clear();
//! Display a decimal number
//!
//! Display the given argument as a decimal number.
//!
//! @param num The number to be shown
//! @param leading_zero When true, leading zeros are displayed. Otherwise unnecessary digits are
//! blank. NOTE: leading zero is not supported with negative numbers.
//! @param length The number of digits to set. The user must ensure that the number to be shown
//! fits to the number of digits requested (for example, if two digits are to be displayed,
//! the number must be between 0 to 99)
//! @param pos The position of the most significant digit (0 - leftmost, 3 - rightmost)
void showNumberDec(int num, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0);
//! Display a decimal number, with dot control
//!
//! Display the given argument as a decimal number. The dots between the digits (or colon)
//! can be individually controlled.
//!
//! @param num The number to be shown
//! @param dots Dot/Colon enable. The argument is a bitmask, with each bit corresponding to a dot
//! between the digits (or colon mark, as implemented by each module). i.e.
//! For displays with dots between each digit:
//! * 0.000 (0b10000000)
//! * 00.00 (0b01000000)
//! * 000.0 (0b00100000)
//! * 0.0.0.0 (0b11100000)
//! For displays with just a colon:
//! * 00:00 (0b01000000)
//! For displays with dots and colons colon:
//! * 0.0:0.0 (0b11100000)
//! @param leading_zero When true, leading zeros are displayed. Otherwise unnecessary digits are
//! blank. NOTE: leading zero is not supported with negative numbers.
//! @param length The number of digits to set. The user must ensure that the number to be shown
//! fits to the number of digits requested (for example, if two digits are to be displayed,
//! the number must be between 0 to 99)
//! @param pos The position of the most significant digit (0 - leftmost, 3 - rightmost)
void showNumberDecEx(int num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0);
//! Display a hexadecimal number, with dot control
//!
//! Display the given argument as a hexadecimal number. The dots between the digits (or colon)
//! can be individually controlled.
//!
//! @param num The number to be shown
//! @param dots Dot/Colon enable. The argument is a bitmask, with each bit corresponding to a dot
//! between the digits (or colon mark, as implemented by each module). i.e.
//! For displays with dots between each digit:
//! * 0.000 (0b10000000)
//! * 00.00 (0b01000000)
//! * 000.0 (0b00100000)
//! * 0.0.0.0 (0b11100000)
//! For displays with just a colon:
//! * 00:00 (0b01000000)
//! For displays with dots and colons colon:
//! * 0.0:0.0 (0b11100000)
//! @param leading_zero When true, leading zeros are displayed. Otherwise unnecessary digits are
//! blank
//! @param length The number of digits to set. The user must ensure that the number to be shown
//! fits to the number of digits requested (for example, if two digits are to be displayed,
//! the number must be between 0 to 99)
//! @param pos The position of the most significant digit (0 - leftmost, 3 - rightmost)
void
showNumberHexEx(uint16_t num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0);
//! Translate a single digit into 7 segment code
//!
//! The method accepts a number between 0 - 15 and converts it to the
//! code required to display the number on a 7 segment display.
//! Numbers between 10-15 are converted to hexadecimal digits (A-F)
//!
//! @param digit A number between 0 to 15
//! @return A code representing the 7 segment image of the digit (LSB - segment A;
//! bit 6 - segment G; bit 7 - always zero)
static uint8_t encodeDigit(uint8_t digit);
protected:
void bitDelay();
void start();
void stop();
bool writeByte(uint8_t b);
void showDots(uint8_t dots, uint8_t *digits);
void showNumberBaseEx(int8_t base, uint16_t num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 4,
uint8_t pos = 0);
private:
// uint8_t m_pinClk;
// uint8_t m_pinDIO;
uint8_t m_brightness;
unsigned int m_bitDelay;
};
#endif // __TM1637DISPLAY__

609
src/Application.cpp Normal file
View File

@ -0,0 +1,609 @@
//
// Created by kirillius on 13.06.2022.
//
#include <util/delay.h>
#include <string.h>
#include <avr/interrupt.h>
#include <utils/ADC.h>
#include "Application.h"
#include "ExMath.h"
#define DIVIDER_COEFF (100000.0f/15000.0f)
Application::Application() {
systime.minutes = 0;
systime.seconds = 0;
systime.hours = 12;
display.clear();
display.enable();
setText("OKAY");
display.redraw();
_delay_ms(1000);
display.disable();
config.load();
feedTimer.set(0);
//PD0 - DISP CLK
//PD1 - DISP DATA
//PD2 - B_MODE
//PD3 - UP
//PD4 - down
//PD6 - motor
//Button - 0
//OUT - 1
DDRD |= (1 << PORTD6);
PORTD &= ~(1 << PORTD6);
DDRD &= ~(1 << PORTD2);
DDRD &= ~(1 << PORTD3);
DDRD &= ~(1 << PORTD4);
PORTD |= (1 << PORTD2);
PORTD |= (1 << PORTD3);
PORTD |= (1 << PORTD4);
//SETUP timer
TCCR1A = 0;
TCCR1B = 0;
TCCR1B |= (1 << WGM12);// Режим CTC (сброс по совпадению)
TCCR1B |= (1 << CS12);// Тактирование от CLK CLK/256
OCR1A = (uint16_t) ((long) (F_CPU) / 256 / CLOCK_FREQ);
//OCR1AH = 0b01111010;//(uint16_t) ((long) (F_CPU) / 2 / 1024 / CLOCK_FREQ) - 1;
//OCR1AL = 0b00010010;
TIMSK1 |= (1 << OCIE1A);// Прерывание по совпадению
ADCIO::setup();
sei();
}
Button Application::getButton() {
if ((PIND & (1 << PORTD2)) == 0) return B_MODE;
if ((PIND & (1 << PORTD3)) == 0) return B_DOWN;
if ((PIND & (1 << PORTD4)) == 0) return B_UP;
return B_NONE;
}
void Application::tick() {
if (feedTimer.isTimeOut() || getCharge() == 0) {
PORTD &= ~(1 << PORTD6);
} else {
PORTD |= (1 << PORTD6);
}
systime.addSecond();
timer.tick();
feedTimer.tick();
if (systime.seconds == 0 && config.startTime.hours == systime.hours &&
config.startTime.minutes == systime.minutes) {
feedTimer.set(config.feedTimer);
}
}
void Application::sleep() {
standby = true;
display.disable();
}
void Application::wakeup() {
standby = false;
display.enable();
}
void Application::update() {
if (!standby) {
if (page == P_NONE) sleep();
else {
timer.set(DEFAULT_TIMER);
switch (page) {
case P_TIME:
page = timePage();
break;
case P_CHARGE:
page = chargePage();
break;
case P_SETUP:
page = setupPage();
break;
case P_TEST:
page = testPage();
break;
case S_MENU:
page = setupMenuPage();
break;
case S_T1:
page = setupT1Page();
break;
case S_T2:
page = setupT2Page();
break;
case S_T3:
page = setupT3Page();
break;
case S_VBAT:
page = setupVBatPage();
break;
default:
break;
}
}
} else if (getButton() != B_NONE) {
wakeup();
page = P_TIME;
}
}
Page Application::nextPage() {
if (page == S_VBAT) return S_T1;
if (page == P_SETUP) return P_TIME;
else return static_cast<Page>(page + 1);
}
Page Application::prevPage() {
if (page == S_T1) return S_VBAT;
if (page == P_TIME) return P_SETUP;
else return static_cast<Page>(page - 1);
}
void Application::setText(const char *str) {
display.clear();
uint8_t encoded[4] = {0, 0, 0, 0};
size_t offset = 0;
for (size_t i = 0; i < strlen(str); i++) {
char c = str[i];
if (c == '.') {
if (offset > 0 && offset <= sizeof(encoded)) {
encoded[offset - 1] |= SEG_DOT;
}
} else if (offset < sizeof(encoded)) {
encoded[offset++] = display.encodeChar(c);
} else break;
}
for (uint8_t i = 0; i < sizeof(encoded); i++) display.setSegment(i, encoded[i]);
display.redraw();
}
void Application::blinkText(const char *str, uint8_t count) {
for (uint8_t i = 0; i < count; i++) {
setText(str);
_delay_ms(250);
display.clear();
display.redraw();
_delay_ms(250);
}
}
float Application::getVoltage() {
float value = ((float) ADCIO::read(ADC0)) / 1024; //[0;1] 0=0V 1=3.3V
return 3.3f * value * DIVIDER_COEFF / config.calibration;
}
float Application::getCharge() {
float nominal = config.vbat;
float min = 0.793650794f * nominal;
/*
12 nominal
---- = ----------
10 x
x = nominal * 10 / 12;
*/
float value = lerp(0, 100, clamp01(ilerp(min, nominal, getVoltage())));
return value;
}
//-----===== PAGES =====-----
Page Application::timePage() {
timer.set(DEFAULT_TIMER);
renderTime(&systime, true);
_delay_ms(INPUT_DELAY);
switch (getButton()) {
case B_MODE:
return P_NONE;
case B_UP:
return nextPage();
case B_DOWN:
return prevPage();
case B_NONE:
break;
}
bool dot = false;
while (!timer.isTimeOut()) {
renderTime(&systime, dot = !dot);
_delay_ms(1000);
switch (getButton()) {
case B_MODE:
return P_NONE;
case B_UP:
return nextPage();
case B_DOWN:
return prevPage();
case B_NONE:
break;
}
}
return P_NONE;
}
Page Application::chargePage() {
timer.set(DEFAULT_TIMER);
const char text[] = "3AP.";
setText(text);
_delay_ms(INPUT_DELAY);
switch (getButton()) {
case B_MODE:
return P_NONE;
case B_UP:
return nextPage();
case B_DOWN:
return prevPage();
case B_NONE:
break;
}
_delay_ms(1500);
uint8_t a, b, c, n = 0;
while (!timer.isTimeOut()) {
if (n % 3 == 0) {
display.clear();
//show charge
auto value = getCharge();
a = (uint8_t) (value / 100);
b = (uint8_t) ((value - a * 100) / 10);
c = (uint8_t) ((value - a * 100 - b * 10));
display.setSegment(1, display.encodeNumber(a));
display.setSegment(2, display.encodeNumber(b));
display.setSegment(3, display.encodeNumber(c));
display.redraw();
} else if (n % 3 == 1) {
display.clear();
//show voltage
auto voltage = getVoltage();
a = (uint8_t) (voltage / 10);
b = (uint8_t) ((voltage - a * 10));
c = (uint8_t) ((voltage - a * 10 - b) * 10);
display.setSegment(0, display.encodeNumber(a));
display.setSegment(1, display.encodeNumber(b) | SEG_DOT);
display.setSegment(2, display.encodeNumber(c));
display.setSegment(3, display.encodeChar('U'));
display.redraw();
} else if (n % 3 == 2) {
//show text
setText(text);
}
_delay_ms(1500);
n++;
switch (getButton()) {
case B_MODE:
return P_NONE;
case B_UP:
return nextPage();
case B_DOWN:
return prevPage();
case B_NONE:
break;
}
}
return P_NONE;
}
Page Application::setupPage() {
const char text[] = "HACT.";
setText(text);
while (!timer.isTimeOut()) {
_delay_ms(INPUT_DELAY);
if (isCalibration()) {
blinkText("CAL", 10);
timer.set(DEFAULT_TIMER);
while (!timer.isTimeOut()) {
uint8_t a, b, c, d;
a = (uint8_t) config.calibration;
b = (uint8_t) ((config.calibration - a) * 10);
c = (uint8_t) ((config.calibration - a - 0.1f * b) * 100);
d = (uint8_t) ((config.calibration - a - 0.1f * b - 0.01f * c) * 1000);
display.setSegment(0, display.encodeNumber(a) | SEG_DOT);
display.setSegment(1, display.encodeNumber(b));
display.setSegment(2, display.encodeNumber(c));
display.setSegment(3, display.encodeNumber(d));
display.redraw();
_delay_ms(50);
Button button = getButton();
if (button != B_NONE) {
timer.reset();
switch (button) {
case B_MODE:
config.save();
return P_NONE;
case B_UP:
config.calibration += 0.001;
if (config.calibration >= 9.999) config.calibration = 9.999;
break;
case B_DOWN:
config.calibration -= 0.001;
if (config.calibration <= 0.001) config.calibration = 0.001;
break;
case B_NONE:
break;
}
}
}
timer.set(DEFAULT_TIMER);
} else
switch (getButton()) {
case B_MODE:
blinkText(text, 5);
return S_MENU;
case B_UP:
return nextPage();
case B_DOWN:
return prevPage();
case B_NONE:
break;
}
}
return P_NONE;
}
Page Application::setupT1Page() {
return commonTimeSetup(&systime);
}
Page Application::setupT2Page() {
return commonTimeSetup(&config.startTime);
}
Page Application::setupT3Page() {
timer.set(SETUP_TIMER);
uint8_t a, b, c = 0;
while (!timer.isTimeOut()) {
a = config.feedTimer / 100;
b = (config.feedTimer - a * 100) / 10;
c = (config.feedTimer - a * 100 - b * 10);
display.setSegment(0, display.encodeNumber(a));
display.setSegment(1, display.encodeNumber(b));
display.setSegment(2, display.encodeNumber(c));
display.setSegment(3, display.encodeChar('C'));
display.redraw();
_delay_ms(INPUT_DELAY);
switch (getButton()) {
case B_MODE:
return S_MENU;
case B_UP:
timer.reset();
config.feedTimer += 5;
if (config.feedTimer >= 600) config.feedTimer = 600;
break;
case B_DOWN:
timer.reset();
if (config.feedTimer > 5) config.feedTimer -= 5;
break;
case B_NONE:
break;
}
}
return S_MENU;
}
Page Application::setupVBatPage() {
timer.set(SETUP_TIMER);
uint8_t a, b, c = 0;
while (!timer.isTimeOut()) {
a = (uint8_t) (config.vbat / 10);
b = (uint8_t) (config.vbat - a * 10);
c = (uint8_t) ((config.vbat - a * 10 - b) * 10);
display.setSegment(0, display.encodeNumber(a));
display.setSegment(1, display.encodeNumber(b) | SEG_DOT);
display.setSegment(2, display.encodeNumber(c));
display.setSegment(3, display.encodeChar('U'));
display.redraw();
_delay_ms(INPUT_DELAY);
switch (getButton()) {
case B_MODE:
return S_MENU;
case B_UP:
timer.reset();
config.vbat += 0.1f;
if (config.vbat > 24) config.vbat = 24;
break;
case B_DOWN:
timer.reset();
config.vbat -= 0.1f;
if (config.vbat < 4.f) config.vbat = 4;
break;
case B_NONE:
break;
}
}
return S_MENU;
}
Page Application::commonTimeSetup(Time *time) {
Time local;
time->copy(&local);
timer.set(SETUP_TIMER);
while (!timer.isTimeOut()) {
renderTime(&local, true);
_delay_ms(INPUT_DELAY);
switch (getButton()) {
case B_MODE:
timer.set(0);
break;
case B_UP:
timer.reset();
local.hours++;
if (local.hours == 24) local.hours = 0;
break;
case B_DOWN:
timer.reset();
local.minutes++;
if (local.minutes == 60) local.minutes = 0;
break;
case B_NONE:
break;
}
}
local.copy(time);
return S_MENU;
}
void Application::renderTime(Time *time, bool dot) {
uint8_t a = time->hours / 10;
uint8_t b = time->hours - a * 10;
display.setSegment(0, display.encodeNumber(a));
display.setSegment(1, display.encodeNumber(b) | (dot ? SEG_DOT : 0x0));
a = time->minutes / 10;
b = time->minutes - a * 10;
display.setSegment(2, display.encodeNumber(a));
display.setSegment(3, display.encodeNumber(b));
display.redraw();
}
Page Application::testPage() {
uint8_t a, b, c = 0;
while (!timer.isTimeOut()) {
setText("TECT");
_delay_ms(INPUT_DELAY);
switch (getButton()) {
case B_MODE:
blinkText("TECT", 5);
if (getCharge() > 0) {
feedTimer.set(config.feedTimer);
display.clear();
while (!feedTimer.isTimeOut()) {
a = feedTimer.getTime() / 100;
b = (feedTimer.getTime() - a * 100) / 10;
c = (feedTimer.getTime() - a * 100 - b * 10);
display.setSegment(0, display.encodeNumber(a));
display.setSegment(1, display.encodeNumber(b));
display.setSegment(2, display.encodeNumber(c));
display.redraw();
_delay_ms(INPUT_DELAY);
if (getButton() == B_MODE) {
feedTimer.set(0);
return P_TEST;
}
}
timer.set(DEFAULT_TIMER);
} else {
blinkText("HU3.", 3);
blinkText("3AP.", 3);
blinkText("6AT.", 3);
return P_TEST;
}
break;
case B_UP:
return nextPage();
case B_DOWN:
return prevPage();
case B_NONE:
break;
}
}
return P_NONE;
}
Page Application::setupMenuPage() {
uint8_t item = 0;
timer.set(SETUP_TIMER);
while (!timer.isTimeOut()) {
switch (item) {
case 0:
setText("T1");
break;
case 1:
setText("T2");
break;
case 2:
setText("T3");
break;
case 3:
setText("H.6AT");
break;
}
_delay_ms(INPUT_DELAY*2);
switch (getButton()) {
case B_MODE:
switch (item) {
case 0:
return S_T1;
case 1:
return S_T2;
case 2:
return S_T3;
case 3:
return S_VBAT;
}
break;
case B_UP:
timer.reset();
item++;
if (item > 3) item = 0;
break;
case B_DOWN:
if (item == 0) item = 3;
else item--;
timer.reset();
break;
case B_NONE:
break;
}
}
config.save();
setText("COXP.");
_delay_ms(1000);
return P_SETUP;
}
bool Application::isCalibration() {
return ((PIND & (1 << PORTD2)) == 0) && ((PIND & (1 << PORTD3)) == 0) && ((PIND & (1 << PORTD4)) == 0);
}

99
src/Application.h Normal file
View File

@ -0,0 +1,99 @@
//
// Created by kirillius on 13.06.2022.
//
#ifndef FEEDER_APPLICATION_H
#define FEEDER_APPLICATION_H
#define INPUT_DELAY 350
#define DEFAULT_TIMER 30
#define SETUP_TIMER 15
#define CLOCK_FREQ 1
#include "tm1637/tm1637.h"
#include "utils/EEPROM.h"
#include "Time.h"
#include "Config.h"
#include "Timer.h"
enum Button {
B_MODE,
B_UP,
B_DOWN,
B_NONE
};
enum Page {
P_NONE,
P_TIME,
P_TEST,
P_CHARGE,
P_SETUP,
S_MENU,
S_T1,
S_T2,
S_T3,
S_VBAT
};
class Application {
private:
TM1637 display;
Config config;
Time systime;
Timer timer;
bool standby = true;
Page page = P_NONE;
Timer feedTimer;
Button getButton();
bool isCalibration();
void sleep();
void wakeup();
Page nextPage();
Page prevPage();
Page timePage();
Page chargePage();
Page setupPage();
Page setupMenuPage();
Page setupT1Page();
Page setupT2Page();
Page setupT3Page();
Page setupVBatPage();
Page testPage();
Page commonTimeSetup(Time *time);
void renderTime(Time *time, bool dot);
void setText(const char *str);
void blinkText(const char *str, uint8_t count);
float getCharge();
float getVoltage();
public:
Application();
void tick();
void update();
};
#endif //FEEDER_APPLICATION_H

25
src/Config.cpp Normal file
View File

@ -0,0 +1,25 @@
//
// Created by kirillius on 13.06.2022.
//
#include "Config.h"
#include "utils/EEPROM.h"
void Config::load() {
if (EEPROM::get(CONFIG_EEPROM_ADDR) == CONFIG_EEPROM_FLAG) {
//is valid EEPROM
EEPROM::get(CONFIG_EEPROM_ADDR + 1, (void *) this, sizeof(Config));
} else {
//load defaults
vbat = 4;
startTime.hours = 12;
startTime.minutes = 00;
feedTimer = 10;
calibration=1;
}
}
void Config::save() {
EEPROM::set(CONFIG_EEPROM_ADDR, CONFIG_EEPROM_FLAG);
EEPROM::set(CONFIG_EEPROM_ADDR + 1, (void *) this, sizeof(Config));
}

26
src/Config.h Normal file
View File

@ -0,0 +1,26 @@
//
// Created by kirillius on 13.06.2022.
//
#ifndef FEEDER_CONFIG_H
#define FEEDER_CONFIG_H
#include "Time.h"
#define CONFIG_EEPROM_ADDR 0x13
#define CONFIG_EEPROM_FLAG 0x24
struct Config {
public:
float vbat;
uint16_t feedTimer;
Time startTime;
float calibration;
void load();
void save();
};
#endif //FEEDER_CONFIG_H

22
src/ExMath.cpp Normal file
View File

@ -0,0 +1,22 @@
//
// Created by kerya on 18.06.2022.
//
#include "ExMath.h"
float lerp(float a, float b, float t) {
return (1.f - t) * a + b * t;
}
float ilerp(float a, float b, float v) {
return (a != b) ? (v - a) / (b - a) : 1;
}
float clamp(float v, float min, float max) {
return (v < min) ? min : (v > max) ? max : v;
}
float clamp01(float v) {
return clamp(v, 0, 1);
}

11
src/ExMath.h Normal file
View File

@ -0,0 +1,11 @@
//
// Created by kerya on 18.06.2022.
//
#ifndef FEEDER_EXMATH_H
#define FEEDER_EXMATH_H
float lerp(float a,float b,float t);
float ilerp(float a,float b,float v);
float clamp(float v,float min,float max);
float clamp01(float v);
#endif //FEEDER_EXMATH_H

27
src/Time.cpp Normal file
View File

@ -0,0 +1,27 @@
//
// Created by kirillius on 13.06.2022.
//
#include "Time.h"
void Time::addSecond() {
seconds++;
if (seconds >= 60) {
seconds = 0;
minutes++;
}
if (minutes >= 60) {
hours++;
minutes = 0;
}
if (hours >= 24) {
hours = 0;
}
}
void Time::copy(Time *to) {
to->hours = hours;
to->minutes = minutes;
to->seconds = seconds;
}

21
src/Time.h Normal file
View File

@ -0,0 +1,21 @@
//
// Created by kirillius on 13.06.2022.
//
#ifndef FEEDER_TIME_H
#define FEEDER_TIME_H
#include <stdint.h>
struct Time {
uint8_t hours;
uint8_t minutes;
uint8_t seconds;
void copy(Time *to);
void addSecond();
};
#endif //FEEDER_TIME_H

27
src/Timer.cpp Normal file
View File

@ -0,0 +1,27 @@
//
// Created by kirillius on 13.06.2022.
//
#include "Timer.h"
Timer::Timer() : time(0) {}
void Timer::set(uint16_t seconds) {
lastTime = time = seconds;
}
void Timer::tick() {
if (time > 0) time--;
}
bool Timer::isTimeOut() {
return time == 0;
}
void Timer::reset() {
time = lastTime;
}
uint16_t Timer::getTime() {
return time;
}

30
src/Timer.h Normal file
View File

@ -0,0 +1,30 @@
//
// Created by kirillius on 13.06.2022.
//
#ifndef FEEDER_TIMER_H
#define FEEDER_TIMER_H
#include <stdint.h>
struct Timer {
private:
uint16_t time;
uint16_t lastTime;
public:
Timer();
void reset();
void set(uint16_t seconds);
void tick();
bool isTimeOut();
uint16_t getTime();
};
#endif //FEEDER_TIMER_H

18
src/main.cpp Normal file
View File

@ -0,0 +1,18 @@
#include <util/delay.h>
#include <avr/interrupt.h>
#include "Application.h"
Application *application = nullptr;
ISR(TIMER1_COMPA_vect) {
if (application != nullptr) application->tick();
}
int main() {
Application instance;
application = &instance;
while (true) {
instance.update();
_delay_ms(1000);
}
}