Browse Source

added files

Ondřej Hruška 5 years ago
commit
22c3498042
44 changed files with 6893 additions and 0 deletions
  1. 5 0
      .gitignore
  2. 58 0
      7seg_mux_drv.pro
  3. 378 0
      7seg_mux_drv.pro.user
  4. 150 0
      Makefile
  5. 47 0
      lib/adc.c
  6. 20 0
      lib/adc.h
  7. 66 0
      lib/blockdev.h
  8. 89 0
      lib/calc.h
  9. 103 0
      lib/color.c
  10. 57 0
      lib/color.h
  11. 52 0
      lib/debounce.c
  12. 66 0
      lib/debounce.h
  13. 88 0
      lib/dht11.c
  14. 17 0
      lib/dht11.h
  15. 1253 0
      lib/fat16.c
  16. 276 0
      lib/fat16.h
  17. 64 0
      lib/fat16_internal.h
  18. 276 0
      lib/iopins.c
  19. 213 0
      lib/iopins.h
  20. 365 0
      lib/lcd.c
  21. 146 0
      lib/lcd.h
  22. 21 0
      lib/nsdelay.h
  23. 248 0
      lib/onewire.c
  24. 58 0
      lib/onewire.h
  25. 202 0
      lib/sd.c
  26. 53 0
      lib/sd.h
  27. 184 0
      lib/sd_blockdev.c
  28. 7 0
      lib/sd_blockdev.h
  29. 67 0
      lib/sd_fat.c
  30. 32 0
      lib/sd_fat.h
  31. 83 0
      lib/sipo_pwm.c
  32. 49 0
      lib/sipo_pwm.h
  33. 168 0
      lib/sonar.c
  34. 67 0
      lib/sonar.h
  35. 35 0
      lib/spi.c
  36. 30 0
      lib/spi.h
  37. 246 0
      lib/stream.c
  38. 106 0
      lib/stream.h
  39. 714 0
      lib/uart.c
  40. 253 0
      lib/uart.h
  41. 139 0
      lib/wsrgb.c
  42. 53 0
      lib/wsrgb.h
  43. 275 0
      main.c
  44. 14 0
      style.astylerc

+ 5 - 0
.gitignore View File

@@ -0,0 +1,5 @@
1
+*.lst
2
+*.elf
3
+*.hex
4
+*~
5
+*.bak

+ 58 - 0
7seg_mux_drv.pro View File

@@ -0,0 +1,58 @@
1
+TEMPLATE = app
2
+CONFIG += console
3
+CONFIG -= app_bundle
4
+CONFIG -= qt
5
+
6
+INCLUDEPATH += \
7
+	lib \
8
+	/usr/avr/include
9
+
10
+DEFINES += __AVR_ATmega328P__ F_CPU=16000000UL
11
+
12
+DISTFILES += \
13
+    style.astylerc \
14
+    Makefile
15
+
16
+HEADERS += \
17
+    lib/adc.h \
18
+    lib/blockdev.h \
19
+    lib/calc.h \
20
+    lib/color.h \
21
+    lib/debounce.h \
22
+    lib/dht11.h \
23
+    lib/fat16.h \
24
+    lib/fat16_internal.h \
25
+    lib/iopins.h \
26
+    lib/lcd.h \
27
+    lib/nsdelay.h \
28
+    lib/onewire.h \
29
+    lib/sd.h \
30
+    lib/sd_blockdev.h \
31
+    lib/sd_fat.h \
32
+    lib/sipo_pwm.h \
33
+    lib/sonar.h \
34
+    lib/spi.h \
35
+    lib/stream.h \
36
+    lib/uart.h \
37
+    lib/wsrgb.h
38
+
39
+SOURCES += \
40
+    lib/adc.c \
41
+    lib/color.c \
42
+    lib/debounce.c \
43
+    lib/dht11.c \
44
+    lib/fat16.c \
45
+    lib/iopins.c \
46
+    lib/lcd.c \
47
+    lib/onewire.c \
48
+    lib/sd.c \
49
+    lib/sd_blockdev.c \
50
+    lib/sd_fat.c \
51
+    lib/sipo_pwm.c \
52
+    lib/sonar.c \
53
+    lib/spi.c \
54
+    lib/stream.c \
55
+    lib/uart.c \
56
+    lib/wsrgb.c \
57
+    lib/main.c \
58
+    main.c

+ 378 - 0
7seg_mux_drv.pro.user View File

@@ -0,0 +1,378 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE QtCreatorProject>
3
+<!-- Written by QtCreator 3.6.0, 2016-02-04T02:02:53. -->
4
+<qtcreator>
5
+ <data>
6
+  <variable>EnvironmentId</variable>
7
+  <value type="QByteArray">{dfe3cb4a-0f3e-4da9-9c52-5d2c464adafb}</value>
8
+ </data>
9
+ <data>
10
+  <variable>ProjectExplorer.Project.ActiveTarget</variable>
11
+  <value type="int">0</value>
12
+ </data>
13
+ <data>
14
+  <variable>ProjectExplorer.Project.EditorSettings</variable>
15
+  <valuemap type="QVariantMap">
16
+   <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
17
+   <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
18
+   <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
19
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
20
+    <value type="QString" key="language">Cpp</value>
21
+    <valuemap type="QVariantMap" key="value">
22
+     <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
23
+    </valuemap>
24
+   </valuemap>
25
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
26
+    <value type="QString" key="language">QmlJS</value>
27
+    <valuemap type="QVariantMap" key="value">
28
+     <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
29
+    </valuemap>
30
+   </valuemap>
31
+   <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
32
+   <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
33
+   <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
34
+   <value type="int" key="EditorConfiguration.IndentSize">4</value>
35
+   <value type="bool" key="EditorConfiguration.KeyboardTooltips">true</value>
36
+   <value type="int" key="EditorConfiguration.MarginColumn">80</value>
37
+   <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
38
+   <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
39
+   <value type="int" key="EditorConfiguration.PaddingMode">1</value>
40
+   <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
41
+   <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
42
+   <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
43
+   <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
44
+   <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
45
+   <value type="int" key="EditorConfiguration.TabSize">8</value>
46
+   <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
47
+   <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
48
+   <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
49
+   <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
50
+   <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
51
+   <value type="bool" key="EditorConfiguration.inEntireDocument">true</value>
52
+  </valuemap>
53
+ </data>
54
+ <data>
55
+  <variable>ProjectExplorer.Project.PluginSettings</variable>
56
+  <valuemap type="QVariantMap"/>
57
+ </data>
58
+ <data>
59
+  <variable>ProjectExplorer.Project.Target.0</variable>
60
+  <valuemap type="QVariantMap">
61
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
62
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
63
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{ee748544-c6c0-4f44-9cef-fbb65dc2525a}</value>
64
+   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
65
+   <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
66
+   <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">1</value>
67
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
68
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory"></value>
69
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
70
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
71
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
72
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
73
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
74
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
75
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
76
+       <value type="QString">-w</value>
77
+       <value type="QString">-r</value>
78
+      </valuelist>
79
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
80
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
81
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
82
+     </valuemap>
83
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
84
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
85
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
86
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
87
+    </valuemap>
88
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
89
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
90
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
91
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
92
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
93
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
94
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
95
+       <value type="QString">-w</value>
96
+       <value type="QString">-r</value>
97
+      </valuelist>
98
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
99
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
100
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
101
+     </valuemap>
102
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
103
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
104
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
105
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
106
+    </valuemap>
107
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
108
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
109
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
110
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
111
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
112
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
113
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
114
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
115
+   </valuemap>
116
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
117
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/ondra/elektro/avr-projects/devel/build-7seg_mux_drv-Desktop-Release</value>
118
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
119
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
120
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
121
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
122
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
123
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
124
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
125
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
126
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
127
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
128
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
129
+     </valuemap>
130
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
131
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
132
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
133
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
134
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
135
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
136
+       <value type="QString">-w</value>
137
+       <value type="QString">-r</value>
138
+      </valuelist>
139
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
140
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
141
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
142
+     </valuemap>
143
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
144
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
145
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
146
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
147
+    </valuemap>
148
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
149
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
150
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
151
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
152
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
153
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
154
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
155
+       <value type="QString">-w</value>
156
+       <value type="QString">-r</value>
157
+      </valuelist>
158
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
159
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
160
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
161
+     </valuemap>
162
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
163
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
164
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
165
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
166
+    </valuemap>
167
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
168
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
169
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
170
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
171
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
172
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
173
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
174
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
175
+   </valuemap>
176
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
177
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/ondra/elektro/avr-projects/devel/build-7seg_mux_drv-Desktop-Profile</value>
178
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
179
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
180
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
181
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
182
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
183
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
184
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
185
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
186
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
187
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">true</value>
188
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
189
+     </valuemap>
190
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
191
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
192
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
193
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
194
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
195
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
196
+       <value type="QString">-w</value>
197
+       <value type="QString">-r</value>
198
+      </valuelist>
199
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
200
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
201
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
202
+     </valuemap>
203
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
204
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
205
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
206
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
207
+    </valuemap>
208
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
209
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
210
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
211
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
212
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
213
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
214
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
215
+       <value type="QString">-w</value>
216
+       <value type="QString">-r</value>
217
+      </valuelist>
218
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
219
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
220
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
221
+     </valuemap>
222
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
223
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
224
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
225
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
226
+    </valuemap>
227
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
228
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
229
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
230
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Profile</value>
231
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
232
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
233
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
234
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
235
+   </valuemap>
236
+   <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
237
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
238
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
239
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
240
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
241
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
242
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
243
+    </valuemap>
244
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
245
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy locally</value>
246
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
247
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
248
+   </valuemap>
249
+   <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
250
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
251
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
252
+    <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
253
+    <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
254
+    <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
255
+    <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
256
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
257
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
258
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
259
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
260
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
261
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
262
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
263
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
264
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
265
+    <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
266
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
267
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
268
+    <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
269
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
270
+    <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
271
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
272
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
273
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
274
+     <value type="int">0</value>
275
+     <value type="int">1</value>
276
+     <value type="int">2</value>
277
+     <value type="int">3</value>
278
+     <value type="int">4</value>
279
+     <value type="int">5</value>
280
+     <value type="int">6</value>
281
+     <value type="int">7</value>
282
+     <value type="int">8</value>
283
+     <value type="int">9</value>
284
+     <value type="int">10</value>
285
+     <value type="int">11</value>
286
+     <value type="int">12</value>
287
+     <value type="int">13</value>
288
+     <value type="int">14</value>
289
+    </valuelist>
290
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
291
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
292
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">7seg_mux_drv</value>
293
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">7seg_mux_drv2</value>
294
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/ondra/elektro/avr/7seg_mux_drv/7seg_mux_drv.pro</value>
295
+    <value type="bool" key="QmakeProjectManager.QmakeRunConfiguration.UseLibrarySearchPath">true</value>
296
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
297
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">7seg_mux_drv.pro</value>
298
+    <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
299
+    <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">true</value>
300
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
301
+    <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
302
+    <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
303
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
304
+    <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
305
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
306
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
307
+   </valuemap>
308
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
309
+    <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
310
+    <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
311
+    <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
312
+    <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
313
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
314
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
315
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
316
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
317
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
318
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
319
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
320
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
321
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
322
+    <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
323
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
324
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
325
+    <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
326
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
327
+    <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
328
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
329
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
330
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
331
+     <value type="int">0</value>
332
+     <value type="int">1</value>
333
+     <value type="int">2</value>
334
+     <value type="int">3</value>
335
+     <value type="int">4</value>
336
+     <value type="int">5</value>
337
+     <value type="int">6</value>
338
+     <value type="int">7</value>
339
+     <value type="int">8</value>
340
+     <value type="int">9</value>
341
+     <value type="int">10</value>
342
+     <value type="int">11</value>
343
+     <value type="int">12</value>
344
+     <value type="int">13</value>
345
+     <value type="int">14</value>
346
+    </valuelist>
347
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
348
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
349
+    <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Arguments">flash</value>
350
+    <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable">make</value>
351
+    <value type="bool" key="ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal">false</value>
352
+    <value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory">%{buildDir}</value>
353
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Run make</value>
354
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
355
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
356
+    <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
357
+    <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
358
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
359
+    <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
360
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
361
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
362
+   </valuemap>
363
+   <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">2</value>
364
+  </valuemap>
365
+ </data>
366
+ <data>
367
+  <variable>ProjectExplorer.Project.TargetCount</variable>
368
+  <value type="int">1</value>
369
+ </data>
370
+ <data>
371
+  <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
372
+  <value type="int">18</value>
373
+ </data>
374
+ <data>
375
+  <variable>Version</variable>
376
+  <value type="int">18</value>
377
+ </data>
378
+</qtcreator>

+ 150 - 0
Makefile View File

@@ -0,0 +1,150 @@
1
+## === CPU settings ===
2
+# CPU type
3
+MCU	= atmega328p
4
+# CPU frequency
5
+F_CPU = 16000000
6
+# Fuses
7
+LFUSE = 0xFF
8
+HFUSE = 0xDE
9
+EFUSE = 0x05
10
+
11
+
12
+## === Source files ===
13
+# Main C file
14
+MAIN = main.c
15
+# Extra C files in this folder
16
+LOCAL_SOURCE =
17
+
18
+# Library directory (with C files)
19
+EXTRA_SOURCE_DIR = lib/
20
+
21
+
22
+# C files in the library directory
23
+EXTRA_SOURCE_FILES = uart.c iopins.c stream.c adc.c dht11.c sonar.c onewire.c
24
+
25
+# Files that need config file - uncomment when needed, but also add the configs!
26
+
27
+# EXTRA_SOURCE_FILES += sipo_pwm.c
28
+# EXTRA_SOURCE_FILES += lcd.c
29
+# EXTRA_SOURCE_FILES += color.c wsrgb.c
30
+# EXTRA_SOURCE_FILES += debouce.c
31
+
32
+
33
+## === Programmer ===
34
+PROGRAMMER_TYPE = arduino
35
+PROGRAMMER_ARGS = -b 57600 -P /dev/ttyUSB0
36
+
37
+
38
+## === C flags ===
39
+
40
+CFLAGS = -std=gnu99 -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL -I. -I$(EXTRA_SOURCE_DIR)
41
+CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
42
+CFLAGS += -Wall -Wno-main -Wno-strict-prototypes -Wno-comment
43
+CFLAGS += -g2 -Wextra -Wfatal-errors -Wno-unused-but-set-variable
44
+CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax
45
+# CFLAGS += -lm  ## Math
46
+# CFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm  ## for floating-point printf
47
+# CFLAGS += -Wl,-u,vfprintf -lprintf_min      ## for smaller printf
48
+CFLAGS_BUILD = $(CFLAGS) -Os
49
+
50
+
51
+# ---------------------------------------------------------------------------
52
+
53
+## Defined programs / locations
54
+CC = avr-gcc
55
+OBJCOPY = avr-objcopy
56
+OBJDUMP = avr-objdump
57
+AVRSIZE = avr-size
58
+AVRDUDE = avrdude
59
+
60
+## === File lists ===
61
+TARGET = $(strip $(basename $(MAIN)))
62
+SRC1 = $(TARGET).c
63
+SRC = $(SRC1)
64
+EXTRA_SOURCE = $(addprefix $(EXTRA_SOURCE_DIR), $(EXTRA_SOURCE_FILES))
65
+SRC += $(EXTRA_SOURCE)
66
+SRC += $(LOCAL_SOURCE)
67
+
68
+HEADERS = $(SRC:.c=.h)
69
+OBJ = $(SRC:.c=.o)
70
+
71
+
72
+## === File generation ===
73
+all: $(TARGET).hex size
74
+pre: $(TARGET).pre
75
+
76
+%.hex: %.elf
77
+	$(OBJCOPY) -R .eeprom -O ihex $< $@
78
+
79
+%.elf: $(SRC)
80
+	$(CC) $(CFLAGS_BUILD) $(SRC) --output $@
81
+
82
+%.pre: $(SRC1)
83
+	$(CC) $(CFLAGS) -E $(SRC1) --output $@
84
+
85
+%.eeprom: %.elf
86
+	$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
87
+
88
+%.lst: %.elf
89
+	$(OBJDUMP) -S $< > $@
90
+
91
+# Show debug info
92
+debug:
93
+	@echo
94
+	@echo "Source files:"   $(SRC)
95
+	@echo "MCU, F_CPU, BAUD:"  $(MCU), $(F_CPU), $(BAUD)
96
+	@echo
97
+
98
+
99
+# Disassemble the ELF
100
+disassemble: $(TARGET).lst
101
+dis: disassemble
102
+lst: disassemble
103
+
104
+# Make eeprom file
105
+eeprom: $(TARGET).eeprom
106
+
107
+# Show how big the resulting program is
108
+size:  $(TARGET).elf
109
+	$(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf
110
+
111
+# Clean all produced trash
112
+clean:
113
+	rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \
114
+	$(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \
115
+	$(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \
116
+	$(TARGET).eeprom
117
+
118
+# Clean all trash
119
+purge:
120
+	rm -f *.elf *.hex *.obj *.o *.d *.eep *.lst *.lss *.sym *.map *~
121
+
122
+
123
+## === avrdude ===
124
+
125
+flash: $(TARGET).hex
126
+	$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<
127
+
128
+flashe: $(TARGET).eeprom
129
+	$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$<
130
+
131
+shell:
132
+	$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt
133
+
134
+fser: all flash ser
135
+
136
+ser:
137
+	gtkterm -p /dev/ttyUSB0
138
+
139
+# === fuses ===
140
+
141
+FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
142
+
143
+fuses:
144
+	$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) \
145
+			   $(PROGRAMMER_ARGS) $(FUSE_STRING)
146
+show_fuses:
147
+	$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nv
148
+
149
+set_default_fuses:  FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
150
+set_default_fuses:  fuses

+ 47 - 0
lib/adc.c View File

@@ -0,0 +1,47 @@
1
+#include <avr/io.h>
2
+#include <stdbool.h>
3
+#include <stdint.h>
4
+
5
+#include "calc.h"
6
+#include "adc.h"
7
+
8
+/** Initialize the ADC */
9
+void adc_init()
10
+{
11
+	ADCSRA |= _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0);  // 128 prescaler -> 125 kHz
12
+	ADMUX  |= _BV(REFS0);  // Voltage reference
13
+	sbi(ADCSRA, ADEN);  // Enable ADC
14
+}
15
+
16
+
17
+/** Disable AD */
18
+void adc_disable()
19
+{
20
+	cbi(ADCSRA, ADEN);
21
+}
22
+
23
+
24
+/** Sample analog pin with 8-bit precision */
25
+uint8_t adc_read_byte(uint8_t channel)
26
+{
27
+	set_low_nibble(ADMUX, channel);  // Select channel to sample
28
+	sbi(ADMUX, ADLAR);  // Align result to left
29
+	sbi(ADCSRA, ADSC);  // Start conversion
30
+
31
+	while (bit_is_high(ADCSRA, ADSC)); // Wait for it...
32
+
33
+	return ADCH;  // The upper 8 bits of ADC result
34
+}
35
+
36
+
37
+/** Sample analog pin with 10-bit precision */
38
+uint16_t adc_read_word(uint8_t channel)
39
+{
40
+	set_low_nibble(ADMUX, channel);  // Select channel to sample
41
+	cbi(ADMUX, ADLAR);  // Align result to right
42
+	sbi(ADCSRA, ADSC);  // Start conversion
43
+
44
+	while (get_bit(ADCSRA, ADSC)); // Wait for it...
45
+
46
+	return ADCW;  // The whole ADC word (10 bits)
47
+}

+ 20 - 0
lib/adc.h View File

@@ -0,0 +1,20 @@
1
+#pragma once
2
+
3
+//
4
+// Utilities for build-in A/D converter
5
+//
6
+
7
+#include <avr/io.h>
8
+#include <stdint.h>
9
+
10
+/** Initialize the ADC */
11
+void adc_init();
12
+
13
+/** Disable AD (for power saving?) */
14
+void adc_disable();
15
+
16
+/** Sample analog pin with 8-bit precision */
17
+uint8_t adc_read_byte(uint8_t channel);
18
+
19
+/** Sample analog pin with 10-bit precision */
20
+uint16_t adc_read_word(uint8_t channel);

+ 66 - 0
lib/blockdev.h View File

@@ -0,0 +1,66 @@
1
+#pragma once
2
+
3
+//
4
+// Block device interface, somewhat akin to stream.h
5
+// Used for filesystem implementations.
6
+//
7
+
8
+#include <stdint.h>
9
+
10
+/** Abstract block device interface
11
+ *
12
+ * Populate an instance of this with pointers to your I/O functions.
13
+ */
14
+typedef struct
15
+{
16
+	/** Sequential read at cursor
17
+	 * @param dest destination memory structure
18
+	 * @param len  number of bytes to load and store in {dest}
19
+	 */
20
+	void (*load)(void* dest, const uint16_t len);
21
+
22
+
23
+	/** Sequential write at cursor
24
+	 * @param src source memory structure
25
+	 * @param len number of bytes to write
26
+	 */
27
+	void (*store)(const void* src, const uint16_t len);
28
+
29
+
30
+	/** Write one byte at cursor
31
+	 * @param b byte to write
32
+	 */
33
+	void (*write)(const uint8_t b);
34
+
35
+
36
+	/** Read one byte at cursor
37
+	 * @return the read byte
38
+	 */
39
+	uint8_t (*read)(void);
40
+
41
+
42
+	/** Absolute seek - set cursor
43
+	 * @param addr new cursor address
44
+	 */
45
+	void (*seek)(const uint32_t addr);
46
+
47
+
48
+	/** Relative seek - move cursor
49
+	 * @param offset cursor address change
50
+	 */
51
+	void (*rseek)(const int16_t offset);
52
+
53
+
54
+
55
+	/** Flush the data buffer if it's dirty.
56
+	 *
57
+	 * Should be called after each sequence of writes,
58
+	 * to avoid data loss.
59
+	 *
60
+	 * Tmplementations that do not need this should provide
61
+	 * a no-op function.
62
+	 */
63
+	void (*flush)(void);
64
+
65
+} BLOCKDEV;
66
+

+ 89 - 0
lib/calc.h View File

@@ -0,0 +1,89 @@
1
+#pragma once
2
+
3
+//
4
+// Bit and byte manipulation utilities
5
+//
6
+
7
+#include <stdint.h>
8
+
9
+
10
+// --- Increment in range ---
11
+// when overflown, wraps within range. Lower bound < upper bound.
12
+// ..., upper bound excluded
13
+#define inc_wrap(var, min, max)  { if ((var) >= (max - 1)) { (var) = (min); } else { (var)++; } }
14
+// ..., upper bound included
15
+#define inc_wrapi(var, min, max) inc_wrap((var), (min), (max) + 1)
16
+
17
+
18
+// --- Decrement in range ---
19
+// when underflown, wraps within range. Lower bound < upper bound.
20
+// ..., upper bound excluded
21
+#define dec_wrap(var, min, max)  { if ((var) <= (min)) { (var) = (max) - 1; } else { (var)--; } }
22
+// ..., upper bound included
23
+#define dec_wrapi(var, min, max) dec_wrap((var), (min), (max) + 1)
24
+
25
+
26
+// --- Bit manipulation --
27
+
28
+// Set bit
29
+#define sbi(reg, bit) { (reg) |=  (1 << (uint8_t)(bit)); }
30
+
31
+// Clear bit
32
+#define cbi(reg, bit) { (reg) &= ~(1 << (uint8_t)(bit)); }
33
+
34
+// Get n-th bit
35
+#define get_bit(reg, bit) (((reg) >> (uint8_t)(bit)) & 0x1)
36
+
37
+// Test n-th bit (Can't use bit_is_set, as it's redefined in sfr_def.h)
38
+#define bit_is_high(reg, bit) get_bit(reg, bit)
39
+#define bit_is_low(reg, bit)  (!get_bit(reg, bit))
40
+
41
+// Write value to n-th bit
42
+#define set_bit(reg, bit, value) { (reg) = ((reg) & ~(1 << (uint8_t)(bit))) | (((uint8_t)(value) & 0x1) << (uint8_t)(bit)); }
43
+
44
+// Invert n-th bit
45
+#define toggle_bit(reg, bit) { (reg) ^= (1 << (uint8_t)(bit)); }
46
+
47
+
48
+// --- Bit manipulation with pointer to variable ---
49
+
50
+// Set n-th bit in pointee
51
+#define sbi_p(reg_p, bit) { (*(reg_p)) |=  (1 << (uint8_t)(bit)); }
52
+// Clear n-th bit in pointee
53
+#define cbi_p(reg_p, bit) { (*(reg_p)) &= ~(1 << (uint8_t)(bit)); }
54
+
55
+// Get n-th bit in pointee
56
+#define get_bit_p(reg_p, bit) ((*(reg_p) >> (uint8_t)(bit)) & 0x1)
57
+
58
+// Test n-th bit in pointee (Can't use bit_is_set, as it's redefined in sfr_def.h)
59
+#define bit_is_high_p(reg_p, bit) get_bit_p(reg_p, bit)
60
+#define bit_is_low_p(reg_p, bit)  (!get_bit_p(reg_p, bit))
61
+
62
+// Write value to a bit in pointee
63
+#define set_bit_p(reg_p, bit, value) { *(reg_p) = (*(reg_p) & ~(1 << ((uint8_t)(bit) & 0x1))) | (((uint8_t)(value) & 0x1) << (uint8_t)(bit)); }
64
+#define toggle_bit_p(reg_p, bit)     { *(reg_p) ^= (1 << (uint8_t)(bit)); }
65
+
66
+
67
+// --- Nibble manipulation ---
68
+
69
+// Replace nibble in a byte
70
+#define set_low_nibble(reg, value)  { (reg) = ((reg) & 0xF0) | ((uint8_t)(value) & 0xF); }
71
+#define set_high_nibble(reg, value) { (reg) = ((reg) & 0x0F) | (((uint8_t)(value) & 0xF) << 4); }
72
+
73
+#define set_low_nibble_p(reg_p, value)  { *(reg_p) = (*(reg_p) & 0xF0) | ((uint8_t)(value) & 0xF); }
74
+#define set_high_nibble_p(reg_p, value) { *(reg_p) = (*(reg_p) & 0x0F) | (((uint8_t)(value) & 0xF) << 4); }
75
+
76
+#define low_nibble(x) ((uint8_t)(x) & 0xF)
77
+#define high_nibble(x) (((uint8_t)(x) & 0xF0) >> 4)
78
+
79
+// --- Range tests ---
80
+
81
+// Test if X is within low..high, regardless of bounds order
82
+#define in_range(x, low, high)  ((((low)  < (high)) && ((x) >= (low) && (x)  < (high))) || (((low) > (high)) && ((x) >= (high) && (x)  < (low))))
83
+// ..., include greater bound
84
+#define in_rangei(x, low, high) ((((low) <= (high)) && ((x) >= (low) && (x) <= (high))) || (((low) > (high)) && ((x) >= (high) && (x) <= (low))))
85
+
86
+// Test if X in low..high, wrap around ends if needed.
87
+#define in_range_wrap(x, low, high)  ((((low)  < (high)) && ((x) >= (low) && (x) < (high)))  || (((low) > (high)) && ((x) >= (low) || (x)  < (high))))
88
+// ..., include upper bound
89
+#define in_range_wrapi(x, low, high) ((((low) <= (high)) && ((x) >= (low) && (x) <= (high))) || (((low) > (high)) && ((x) >= (low) || (x) <= (high))))

+ 103 - 0
lib/color.c View File

@@ -0,0 +1,103 @@
1
+#include <avr/io.h>
2
+#include <util/delay.h>
3
+#include <stdint.h>
4
+
5
+#include "iopins.h"
6
+#include "nsdelay.h"
7
+#include "color.h"
8
+
9
+
10
+// --- HSL ---
11
+
12
+#ifdef HSL_LINEAR
13
+const uint8_t FADE_128[] =
14
+{
15
+	0,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  3,  3,  3,  4,  4,  4,  4,
16
+	5,  5,  6,  6,  6,  7,  7,  8,  8,  8,  9,  10, 10, 10, 11, 12, 13, 14,
17
+	14, 15, 16, 17, 18, 20, 21, 22, 24, 26, 27, 28, 30, 31, 32, 34, 35, 36,
18
+	38, 39, 40, 41, 42, 44, 45, 46, 48, 49, 50, 52, 54, 56, 58, 59, 61, 63,
19
+	65, 67, 68, 69, 71, 72, 74, 76, 78, 80, 82, 85, 88, 90, 92, 95, 98, 100,
20
+	103, 106, 109, 112, 116, 119, 122, 125, 129, 134, 138, 142, 147, 151,
21
+	153, 156, 160, 163, 165, 170, 175, 180, 185, 190, 195, 200, 207, 214, 218,
22
+	221, 225, 228, 232, 234, 241, 248, 254, 255
23
+};
24
+#endif
25
+
26
+// based on: https://github.com/lewisd32/avr-hsl2rgb
27
+xrgb_t hsl_xrgb(const hsl_t cc)
28
+{
29
+	// 0 .. 256*3
30
+	const uint16_t hh = (uint16_t) cc.h * 3;
31
+	const uint8_t hue_mod = hh % 256;
32
+
33
+	uint8_t r_temp, g_temp, b_temp;
34
+	if (hh < 256)
35
+	{
36
+		r_temp = hue_mod ^ 255;
37
+		g_temp = hue_mod;
38
+		b_temp = 0;
39
+	}
40
+	else if (hh < 512)
41
+	{
42
+		r_temp = 0;
43
+		g_temp = hue_mod ^ 255;
44
+		b_temp = hue_mod;
45
+	}
46
+	else if (hh < 768)
47
+	{
48
+		r_temp = hue_mod;
49
+		g_temp = 0;
50
+		b_temp = hue_mod ^ 255;
51
+	}
52
+	else
53
+	{
54
+		r_temp = 0;
55
+		g_temp = 0;
56
+		b_temp = 0;
57
+	}
58
+
59
+	const uint8_t inverse_sat = (cc.s ^ 255);
60
+
61
+	xrgb_t rgb;
62
+
63
+	uint8_t t8;
64
+	uint16_t t16;
65
+
66
+#ifdef HSL_LINEAR
67
+	const uint8_t bri = FADE_128[cc.l >> 1];
68
+#else
69
+	const uint8_t bri = cc.l;
70
+#endif
71
+
72
+	t8 = r_temp;
73
+	t16 = t8 * cc.s + t8;
74
+	t16 = t16 + t8;
75
+	t8 = t16 >> 8;
76
+	t8 = t8 + inverse_sat;
77
+	t16 = t8 * bri;
78
+	t16 = t16 + t8;
79
+	t8 = t16 >> 8;
80
+	rgb.r = t8;
81
+
82
+	t8 = g_temp;
83
+	t16 = t8 * cc.s;
84
+	t16 = t16 + t8;
85
+	t8 = t16 >> 8;
86
+	t8 = t8 + inverse_sat;
87
+	t16 = t8 * bri;
88
+	t16 = t16 + t8;
89
+	t8 = t16 >> 8;
90
+	rgb.g = t8;
91
+
92
+	t8 = b_temp;
93
+	t16 = t8 * cc.s;
94
+	t16 = t16 + t8;
95
+	t8 = t16 >> 8;
96
+	t8 = t8 + inverse_sat;
97
+	t16 = t8 * bri;
98
+	t16 = t16 + t8;
99
+	t8 = t16 >> 8;
100
+	rgb.b = t8;
101
+
102
+	return rgb;
103
+}

+ 57 - 0
lib/color.h View File

@@ -0,0 +1,57 @@
1
+#pragma once
2
+
3
+// --- color types ---
4
+//
5
+// The XXXc macros don't use cast, so they can be used in array initializers.
6
+//
7
+//  xrgb ... 3-byte true-color RGB (8 bits per component)
8
+//  rgb24 ... 24-bit color value, with equal nr of bits per component
9
+//
10
+//  XX_r (_g, _b) ... extract component from the color, and convert it to 0..255
11
+
12
+// Define HSL_LINEAR to get more linear brightness in hsl->rgb conversion
13
+
14
+
15
+typedef struct
16
+{
17
+	uint8_t r;
18
+	uint8_t g;
19
+	uint8_t b;
20
+} xrgb_t;
21
+
22
+
23
+typedef uint32_t rgb24_t;
24
+
25
+#define xrgb(rr, gg, bb) ((xrgb_t)xrgbc(rr, gg, bb))
26
+// xrgb for constant array declarations
27
+#define xrgbc(rr, gg, bb) { .r = ((uint8_t)(rr)), .g = ((uint8_t)(gg)), .b = ((uint8_t)(bb)) }
28
+#define xrgb_r(c) ((uint8_t)(c.r))
29
+#define xrgb_g(c) ((uint8_t)(c.g))
30
+#define xrgb_b(c) ((uint8_t)(c.b))
31
+#define xrgb_rgb24(c) ((((rgb24_t)c.r) << 16) | (((rgb24_t)c.g) << 8) | (((rgb24_t)c.b)))
32
+#define xrgb_rgb15(c) (((((rgb15_t)c.r) & 0xF8) << 7) | ((((rgb15_t)c.g) & 0xF8) << 2) | ((((rgb15_t)c.b) & 0xF8) >> 3))
33
+#define xrgb_rgb12(c) (((((rgb12_t)c.r) & 0xF0) << 4) | ((((rgb12_t)c.g) & 0xF0)) | ((((rgb12_t)c.b) & 0xF0) >> 4))
34
+#define xrgb_rgb6(c)  (((((rgb6_t)c.r) & 0xC0) >> 2)  | ((((rgb6_t)c.g) & 0xC0) >> 4) | ((((rgb6_t)c.b) & 0xC0) >> 6))
35
+
36
+#define rgb24c(r,g,b) (((((rgb24_t)r) & 0xFF) << 16) | ((((rgb24_t)g) & 0xFF) << 8) | (((rgb24_t)b) & 0xFF))
37
+#define rgb24(r,g,b) ((rgb24_t) rgb24(r,g,b))
38
+
39
+#define rgb24_r(c) ((((rgb24_t) (c)) >> 16) & 0xFF)
40
+#define rgb24_g(c) ((((rgb24_t) (c)) >> 8) & 0xFF)
41
+#define rgb24_b(c) ((((rgb24_t) (c)) >> 0) & 0xFF)
42
+#define rgb24_xrgb(c) xrgb(rgb24_r(c), rgb24_g(c), rgb24_b(c))
43
+#define rgb24_xrgbc(c) xrgbc(rgb24_r(c), rgb24_g(c), rgb24_b(c))
44
+
45
+#define add_xrgb(x, y) ((xrgb_t) { (((y).r > (255 - (x).r)) ? 255 : ((x).r + (y).r)), (((y).g > (255 - (x).g)) ? 255 : ((x).g + (y).g)), (((y).b > 255 - (x).b) ? 255 : ((x).b + (y).b)) })
46
+
47
+
48
+// HSL data structure
49
+typedef struct
50
+{
51
+	uint8_t h;
52
+	uint8_t s;
53
+	uint8_t l;
54
+} hsl_t;
55
+
56
+/* Convert HSL to XRGB */
57
+xrgb_t hsl_xrgb(const hsl_t color);

+ 52 - 0
lib/debounce.c View File

@@ -0,0 +1,52 @@
1
+#include <avr/io.h>
2
+#include <stdbool.h>
3
+
4
+#include "debounce.h"
5
+#include "calc.h"
6
+#include "iopins.h"
7
+#include "debo_config.h"
8
+
9
+/** Debounce data array */
10
+uint8_t debo_next_slot = 0;
11
+
12
+uint8_t debo_register(PORT_P reg, uint8_t bit, bool invert)
13
+{
14
+	debo_slots[debo_next_slot] = (debo_slot_t)({
15
+		.reg = reg,
16
+		.bit = bit | ((invert & 1) << 7) | (get_bit_p(reg, bit) << 6), // bit 7 = invert, bit 6 = state
17
+		.count = 0,
18
+	});
19
+
20
+	return debo_next_slot++;
21
+}
22
+
23
+
24
+/** Check debounced pins, should be called periodically. */
25
+void debo_tick()
26
+{
27
+	for (uint8_t i = 0; i < debo_next_slot; i++)
28
+	{
29
+		// current pin value (right 3 bits, xored with inverse bit)
30
+		bool value = get_bit_p(debo_slots[i].reg, debo_slots[i].bit & 0x7);
31
+
32
+		if (value != get_bit(debo_slots[i].bit, 6))
33
+		{
34
+
35
+			// different pin state than last recorded state
36
+			if (debo_slots[i].count < DEBO_TICKS)
37
+			{
38
+				debo_slots[i].count++;
39
+			}
40
+			else
41
+			{
42
+				// overflown -> latch value
43
+				set_bit(debo_slots[i].bit, 6, value); // set state bit
44
+				debo_slots[i].count = 0;
45
+			}
46
+		}
47
+		else
48
+		{
49
+			debo_slots[i].count = 0; // reset the counter
50
+		}
51
+	}
52
+}

+ 66 - 0
lib/debounce.h View File

@@ -0,0 +1,66 @@
1
+#pragma once
2
+
3
+//
4
+//  An implementation of button debouncer.
5
+//
6
+//  ----
7
+//
8
+//  You must provide a config file debo_config.h (next to your main.c)
9
+//
10
+//  A pin is registered like this:
11
+//
12
+//    #define BTN1 12 // pin D12
13
+//    #define BTN2 13
14
+//
15
+//    debo_add(BTN0);  // The function returns number assigned to the pin (0, 1, ...)
16
+//    debo_add_rev(BTN1);  // active low
17
+//    debo_register(&PINB, PB2, 0);  // direct access - register, pin & invert
18
+//
19
+//  Then periodically call the tick function (perhaps in a timer interrupt):
20
+//
21
+//    debo_tick();
22
+//
23
+//  To check if input is active, use
24
+//
25
+//    debo_get_pin(0); // state of input #0 (registered first)
26
+//    debo_get_pin(1); // state of input #1 (registered second)
27
+//
28
+
29
+
30
+#include <avr/io.h>
31
+#include <stdbool.h>
32
+#include <stdint.h>
33
+
34
+#include "calc.h"
35
+#include "iopins.h"
36
+
37
+// Your config file
38
+#include "debo_config.h"
39
+/*
40
+	#define DEBO_CHANNELS 2
41
+	#define DDEBO_TICKS 5
42
+*/
43
+
44
+
45
+/* Internal deboucer entry */
46
+typedef struct
47
+{
48
+	PORT_P reg;    // pointer to IO register
49
+	uint8_t bit;   // bits 6 and 7 of this hold "state" & "invert" flag
50
+	uint8_t count; // number of ticks this was in the new state
51
+} debo_slot_t;
52
+
53
+debo_slot_t debo_slots[DEBO_CHANNELS];
54
+
55
+/** Add a pin for debouncing (must be used with constant args) */
56
+#define debo_add_rev(pin) debo_register(&_pin(pin), _pn(pin), 1)
57
+#define debo_add(pin)  debo_register(&_pin(pin), _pn(pin), 0)
58
+
59
+/** Add a pin for debouncing (low level function) */
60
+uint8_t debo_register(PORT_P pin_reg_pointer, uint8_t bit, bool invert);
61
+
62
+/** Check debounced pins, should be called periodically. */
63
+void debo_tick();
64
+
65
+/** Get a value of debounced pin */
66
+#define debo_get_pin(i) (get_bit(debo_slots[i].bit, 6) ^ get_bit(debo_slots[i].bit, 7))

+ 88 - 0
lib/dht11.c View File

@@ -0,0 +1,88 @@
1
+#include <avr/io.h>
2
+#include <util/delay.h>
3
+#include <stdint.h>
4
+#include <stdbool.h>
5
+
6
+#include "iopins.h"
7
+#include "dht11.h"
8
+
9
+/** Read one bit */
10
+bool _dht11_rxbit(const uint8_t pin)
11
+{
12
+	// Wait until start of pulse
13
+	while (is_low_n(pin));
14
+
15
+	uint8_t cnt = 0;
16
+	while (is_high_n(pin))
17
+	{
18
+		cnt++;
19
+		_delay_us(5);
20
+	}
21
+
22
+	return (cnt > 8);
23
+}
24
+
25
+
26
+/** Read one byte */
27
+uint8_t _dht11_rxbyte(const uint8_t pin)
28
+{
29
+	uint8_t byte = 0;
30
+
31
+	for (uint8_t i = 0; i < 8; i++)
32
+	{
33
+		if (_dht11_rxbit(pin))
34
+			byte |= (1 << (7 - i));
35
+	}
36
+
37
+	return byte;
38
+}
39
+
40
+
41
+/** Read tehmperature and humidity from the DHT11, returns false on failure */
42
+bool dht11_read(const uint8_t pin, dht11_result_t* result)
43
+{
44
+	// bus down for > 18 ms
45
+	as_output_n(pin);
46
+	pin_low_n(pin);
47
+	_delay_ms(20);
48
+
49
+	// bus up for 20-40us
50
+	pin_high_n(pin);
51
+	_delay_us(20);
52
+
53
+	// release
54
+	as_input_pu_n(pin);
55
+
56
+	// DHT should send 80us LOW & 80us HIGH
57
+
58
+	_delay_us(40);
59
+	if (!is_low_n(pin))
60
+		return false; // init error
61
+
62
+	_delay_us(80);
63
+	if (!is_high_n(pin))
64
+		return false; // init error
65
+
66
+	// skip to start of first bit
67
+	_delay_us(50);
68
+
69
+	// Receive 5 data bytes (Rh int, Rh dec, Temp int, Temp dec, Checksum)
70
+	// Decimal bytes are zero for DHT11 -> we can ignore them.
71
+	uint8_t bytes[5];
72
+	uint8_t sum = 0;
73
+
74
+	for (uint8_t i = 0; i < 5; i++)
75
+	{
76
+		uint8_t b = _dht11_rxbyte(pin);
77
+		bytes[i] = b;
78
+		if (i < 4) sum += b;
79
+	}
80
+
81
+	// Verify checksum
82
+	if (sum != bytes[4]) return false;
83
+
84
+	result->rh = bytes[0];
85
+	result->temp = bytes[2];
86
+
87
+	return true;
88
+}

+ 17 - 0
lib/dht11.h View File

@@ -0,0 +1,17 @@
1
+#pragma once
2
+
3
+//
4
+// Reading temperature and relative humidity from DHT11
5
+//
6
+
7
+#include <stdint.h>
8
+#include <stdbool.h>
9
+
10
+typedef struct
11
+{
12
+	int8_t temp;
13
+	int8_t rh;
14
+} dht11_result_t;
15
+
16
+/** Read tehmperature and humidity from the DHT11, returns false on failure */
17
+bool dht11_read(const uint8_t pin, dht11_result_t* result);

File diff suppressed because it is too large
+ 1253 - 0
lib/fat16.c


+ 276 - 0
lib/fat16.h View File

@@ -0,0 +1,276 @@
1
+#pragma once
2
+
3
+//
4
+// Simple FAT16 library.
5
+//
6
+// To use it, implement BLOCKDEV functions
7
+// and attach them to it's instance.
8
+//
9
+
10
+#include <stdint.h>
11
+#include <stdbool.h>
12
+
13
+#include "blockdev.h"
14
+
15
+
16
+// -------------------------------
17
+
18
+/**
19
+ * File types (values can be used for debug printing).
20
+ * Accessible using file->type
21
+ */
22
+typedef enum
23
+{
24
+	FT_NONE = '-',
25
+	FT_DELETED = 'x',
26
+	FT_SUBDIR = 'D',
27
+	FT_PARENT = 'P',
28
+	FT_LABEL = 'L',
29
+	FT_LFN = '~',
30
+	FT_INVALID = '?', // not recognized weird file
31
+	FT_SELF = '.',
32
+	FT_FILE = 'F'
33
+} FAT16_FT;
34
+
35
+
36
+/** "File address" for saving and restoring file */
37
+typedef struct
38
+{
39
+	uint16_t clu;
40
+	uint16_t num;
41
+	uint32_t cur_rel;
42
+} FSAVEPOS;
43
+
44
+
45
+// Include definitions of fully internal structs
46
+#include "fat16_internal.h"
47
+
48
+
49
+/**
50
+ * File handle struct.
51
+ *
52
+ * File handle contains cursor, file name, type, size etc.
53
+ * Everything (files, dirs) is accessed using this.
54
+ */
55
+typedef struct __attribute__((packed))
56
+{
57
+	/**
58
+	 * Raw file name. Starting 0x05 was converted to 0xE5.
59
+	 * To get PRINTABLE file name, use fat16_dispname()
60
+	 */
61
+	uint8_t name[11];
62
+
63
+	/**
64
+	 * File attributes - bit field composed of FA_* flags
65
+	 * (internal)
66
+	 */
67
+	uint8_t attribs;
68
+
69
+	// 14 bytes skipped (10 reserved, date, time)
70
+
71
+	/** First cluster of the file. (internal) */
72
+	uint16_t clu_start;
73
+
74
+	/**
75
+	 * File size in bytes.
76
+	 * This is the current allocated and readable file size.
77
+	 */
78
+	uint32_t size;
79
+
80
+
81
+	// --- the following fields are added when reading ---
82
+
83
+	/** File type. */
84
+	FAT16_FT type;
85
+
86
+
87
+	// --- INTERNAL FIELDS ---
88
+
89
+	// Cursor variables. (internal)
90
+	uint32_t cur_abs; // absolute position in device
91
+	uint32_t cur_rel; // relative position in file
92
+	uint16_t cur_clu; // cluster where the cursor is
93
+	uint16_t cur_ofs; // offset within the active cluster
94
+
95
+	// File position in the directory. (internal)
96
+	uint16_t clu; // first cluster of directory
97
+	uint16_t num; // file entry number
98
+
99
+	// Pointer to the FAT16 handle. (internal)
100
+	const FAT16* fat;
101
+}
102
+FFILE;
103
+
104
+
105
+/**
106
+ * Store modified file metadata and flush it to disk.
107
+ */
108
+void ff_flush_file(FFILE* file);
109
+
110
+
111
+/**
112
+ * Save a file "position" into a struct, for later restoration.
113
+ * Cursor is also saved.
114
+ */
115
+FSAVEPOS ff_savepos(const FFILE* file);
116
+
117
+/**
118
+ * Restore a file from a saved position.
119
+ */
120
+void ff_reopen(FFILE* file, const FSAVEPOS* pos);
121
+
122
+
123
+/**
124
+ * Initialize the file system - store into "fat"
125
+ */
126
+bool ff_init(const BLOCKDEV* dev, FAT16* fat);
127
+
128
+
129
+/**
130
+ * Open the first file of the root directory.
131
+ * The file may be invalid (eg. a volume label, deleted etc),
132
+ * or blank (type FT_NONE) if the filesystem is empty.
133
+ */
134
+void ff_root(const FAT16* fat, FFILE* file);
135
+
136
+
137
+/**
138
+ * Resolve the disk label.
139
+ * That can be in the Boot Sector, or in the first root directory entry.
140
+ *
141
+ * @param fat       the FAT handle
142
+ * @param label_out string to store the label in. Should have at least 12 bytes.
143
+ */
144
+char* ff_disk_label(const FAT16* fat, char* label_out);
145
+
146
+
147
+// ----------- FILE I/O -------------
148
+
149
+
150
+/**
151
+ * Move file cursor to a position relative to file start
152
+ * Returns false on I/O error (bad file, out of range...)
153
+ */
154
+bool ff_seek(FFILE* file, uint32_t addr);
155
+
156
+
157
+/**
158
+ * Read bytes from file into memory
159
+ * Returns number of bytes read, 0 on error.
160
+ */
161
+uint16_t ff_read(FFILE* file, void* target, uint16_t len);
162
+
163
+
164
+/**
165
+ * Write into file at a "seek" position.
166
+ */
167
+bool ff_write(FFILE* file, const void* source, uint32_t len);
168
+
169
+
170
+/**
171
+ * Store a 0-terminated string at cursor.
172
+ */
173
+bool ff_write_str(FFILE* file, const char* source);
174
+
175
+
176
+/**
177
+ * Create a new file in given folder
178
+ *
179
+ * file ... open directory; new file is opened into this handle.
180
+ * name ... name of the new file, including extension
181
+ */
182
+bool ff_newfile(FFILE* file, const char* name);
183
+
184
+
185
+/**
186
+ * Create a sub-directory of given name.
187
+ * Directory is allocated and populated with entries "." and ".."
188
+ */
189
+bool ff_mkdir(FFILE* file, const char* name);
190
+
191
+
192
+/**
193
+ * Set new file size.
194
+ * Allocates / frees needed clusters, does NOT erase them.
195
+ *
196
+ * Useful mainly for shrinking.
197
+ */
198
+void set_file_size(FFILE* file, uint32_t size);
199
+
200
+
201
+/**
202
+ * Delete a *FILE* and free it's clusters.
203
+ */
204
+bool ff_rmfile(FFILE* file);
205
+
206
+
207
+/**
208
+ * Delete an empty *DIRECTORY* and free it's clusters.
209
+ */
210
+bool ff_rmdir(FFILE* file);
211
+
212
+
213
+/**
214
+ * Delete a file or directory, even FT_LFN and FT_INVALID.
215
+ * Directories are deleted recursively (!)
216
+ */
217
+bool ff_delete(FFILE* file);
218
+
219
+
220
+
221
+// --------- NAVIGATION ------------
222
+
223
+
224
+/** Go to previous file in the directory (false = no prev file) */
225
+bool ff_prev(FFILE* file);
226
+
227
+
228
+/** Go to next file in directory (false = no next file) */
229
+bool ff_next(FFILE* file);
230
+
231
+
232
+/**
233
+ * Open a subdirectory denoted by the file.
234
+ * Provided handle changes to the first entry of the directory.
235
+ */
236
+bool ff_opendir(FFILE* dir);
237
+
238
+
239
+/**
240
+ * Open a parent directory. Fails in root.
241
+ * Provided handle changes to the first entry of the parent directory.
242
+ */
243
+bool ff_parent(FFILE* file);
244
+
245
+
246
+/** Jump to first file in this directory */
247
+void ff_first(FFILE* file);
248
+
249
+
250
+/**
251
+ * Find a file with given "display name" in this directory, and open it.
252
+ * If file is found, "file" will contain it's handle.
253
+ * Otherwise, the handle is unchanged.
254
+ */
255
+bool ff_find(FFILE* file, const char* name);
256
+
257
+
258
+// -------- FILE INSPECTION -----------
259
+
260
+/** Check if file is a valid entry, or long-name/label/deleted */
261
+bool ff_is_regular(const FFILE* file);
262
+
263
+
264
+/**
265
+ * Resolve a file name, trim spaces and add null terminator.
266
+ * Returns the passed char*, or NULL on error.
267
+ */
268
+char* ff_dispname(const FFILE* file, char* disp_out);
269
+
270
+
271
+/**
272
+ * Convert filename to zero-padded fixed length one
273
+ * Returns the passed char*.
274
+ */
275
+char* ff_rawname(const char* disp_in, char* raw_out);
276
+

+ 64 - 0
lib/fat16_internal.h View File

@@ -0,0 +1,64 @@
1
+#pragma once
2
+
3
+#include <stdint.h>
4
+#include <stdbool.h>
5
+
6
+// Internal types and stuff that is needed in the header for declarations,
7
+// but is not a part of the public API.
8
+
9
+/** Boot Sector structure */
10
+typedef struct __attribute__((packed))
11
+{
12
+	// Fields loaded directly from disk:
13
+
14
+	// 13 bytes skipped
15
+	uint8_t sectors_per_cluster;
16
+	uint16_t reserved_sectors;
17
+	uint8_t num_fats;
18
+	uint16_t root_entries;
19
+	// 3 bytes skipped
20
+	uint16_t fat_size_sectors;
21
+	// 8 bytes skipped
22
+	uint32_t total_sectors; // if "short size sectors" is used, it's copied here too
23
+	// 7 bytes skipped
24
+	char volume_label[11]; // space padded, no terminator
25
+
26
+	// Added fields:
27
+
28
+	uint32_t bytes_per_cluster;
29
+
30
+}
31
+Fat16BootSector;
32
+
33
+
34
+/** FAT filesystem handle */
35
+typedef struct __attribute__((packed))
36
+{
37
+	// Backing block device
38
+	const BLOCKDEV* dev;
39
+
40
+	// Root directory sector start
41
+	uint32_t rd_addr;
42
+
43
+	// Start of first cluster (number "2")
44
+	uint32_t data_addr;
45
+
46
+	// Start of fat table
47
+	uint32_t fat_addr;
48
+
49
+	// Boot sector data struct
50
+	Fat16BootSector bs;
51
+}
52
+FAT16;
53
+
54
+
55
+/**
56
+ * File Attributes (bit flags)
57
+ * Accessible using file->attribs
58
+ */
59
+#define FA_READONLY 0x01 // read only file
60
+#define FA_HIDDEN   0x02 // hidden file
61
+#define FA_SYSTEM   0x04 // system file
62
+#define FA_LABEL    0x08 // volume label entry, found only in root directory.
63
+#define FA_DIR      0x10 // subdirectory
64
+#define FA_ARCHIVE  0x20 // archive flag

+ 276 - 0
lib/iopins.c View File

@@ -0,0 +1,276 @@
1
+#include <avr/io.h>
2
+#include <stdbool.h>
3
+#include <stdint.h>
4
+
5
+#include "calc.h"
6
+#include "iopins.h"
7
+
8
+
9
+void set_dir_n(const uint8_t pin, const uint8_t d)
10
+{
11
+	switch(pin) {
12
+		case 0: set_dir(0, d); return;
13
+		case 1: set_dir(1, d); return;
14
+		case 2: set_dir(2, d); return;
15
+		case 3: set_dir(3, d); return;
16
+		case 4: set_dir(4, d); return;
17
+		case 5: set_dir(5, d); return;
18
+		case 6: set_dir(6, d); return;
19
+		case 7: set_dir(7, d); return;
20
+		case 8: set_dir(8, d); return;
21
+		case 9: set_dir(9, d); return;
22
+		case 10: set_dir(10, d); return;
23
+		case 11: set_dir(11, d); return;
24
+		case 12: set_dir(12, d); return;
25
+		case 13: set_dir(13, d); return;
26
+		case 14: set_dir(14, d); return;
27
+		case 15: set_dir(15, d); return;
28
+		case 16: set_dir(16, d); return;
29
+		case 17: set_dir(17, d); return;
30
+		case 18: set_dir(18, d); return;
31
+		case 19: set_dir(19, d); return;
32
+		case 20: set_dir(20, d); return;
33
+		case 21: set_dir(21, d); return;
34
+	}
35
+}
36
+
37
+void as_input_n(const uint8_t pin)
38
+{
39
+	switch(pin) {
40
+		case 0: as_input(0); return;
41
+		case 1: as_input(1); return;
42
+		case 2: as_input(2); return;
43
+		case 3: as_input(3); return;
44
+		case 4: as_input(4); return;
45
+		case 5: as_input(5); return;
46
+		case 6: as_input(6); return;
47
+		case 7: as_input(7); return;
48
+		case 8: as_input(8); return;
49
+		case 9: as_input(9); return;
50
+		case 10: as_input(10); return;
51
+		case 11: as_input(11); return;
52
+		case 12: as_input(12); return;
53
+		case 13: as_input(13); return;
54
+		case 14: as_input(14); return;
55
+		case 15: as_input(15); return;
56
+		case 16: as_input(16); return;
57
+		case 17: as_input(17); return;
58
+		case 18: as_input(18); return;
59
+		case 19: as_input(19); return;
60
+		case 20: as_input(20); return;
61
+		case 21: as_input(21); return;
62
+	}
63
+}
64
+
65
+
66
+void as_input_pu_n(const uint8_t pin)
67
+{
68
+	switch(pin) {
69
+		case 0: as_input_pu(0); return;
70
+		case 1: as_input_pu(1); return;
71
+		case 2: as_input_pu(2); return;
72
+		case 3: as_input_pu(3); return;
73
+		case 4: as_input_pu(4); return;
74
+		case 5: as_input_pu(5); return;
75
+		case 6: as_input_pu(6); return;
76
+		case 7: as_input_pu(7); return;
77
+		case 8: as_input_pu(8); return;
78
+		case 9: as_input_pu(9); return;
79
+		case 10: as_input_pu(10); return;
80
+		case 11: as_input_pu(11); return;
81
+		case 12: as_input_pu(12); return;
82
+		case 13: as_input_pu(13); return;
83
+		case 14: as_input_pu(14); return;
84
+		case 15: as_input_pu(15); return;
85
+		case 16: as_input_pu(16); return;
86
+		case 17: as_input_pu(17); return;
87
+		case 18: as_input_pu(18); return;
88
+		case 19: as_input_pu(19); return;
89
+		case 20: as_input_pu(20); return;
90
+		case 21: as_input_pu(21); return;
91
+	}
92
+}
93
+
94
+
95
+void as_output_n(const uint8_t pin)
96
+{
97
+	switch(pin) {
98
+		case 0: as_output(0); return;
99
+		case 1: as_output(1); return;
100
+		case 2: as_output(2); return;
101
+		case 3: as_output(3); return;
102
+		case 4: as_output(4); return;
103
+		case 5: as_output(5); return;
104
+		case 6: as_output(6); return;
105
+		case 7: as_output(7); return;
106
+		case 8: as_output(8); return;
107
+		case 9: as_output(9); return;
108
+		case 10: as_output(10); return;
109
+		case 11: as_output(11); return;
110
+		case 12: as_output(12); return;
111
+		case 13: as_output(13); return;
112
+		case 14: as_output(14); return;
113
+		case 15: as_output(15); return;
114
+		case 16: as_output(16); return;
115
+		case 17: as_output(17); return;
116
+		case 18: as_output(18); return;
117
+		case 19: as_output(19); return;
118
+		case 20: as_output(20); return;
119
+		case 21: as_output(21); return;
120
+	}
121
+}
122
+
123
+void set_pin_n(const uint8_t pin, const uint8_t v)
124
+{
125
+	switch(pin) {
126
+		case 0: set_pin(0, v); return;
127
+		case 1: set_pin(1, v); return;
128
+		case 2: set_pin(2, v); return;
129
+		case 3: set_pin(3, v); return;
130
+		case 4: set_pin(4, v); return;
131
+		case 5: set_pin(5, v); return;
132
+		case 6: set_pin(6, v); return;
133
+		case 7: set_pin(7, v); return;
134
+		case 8: set_pin(8, v); return;
135
+		case 9: set_pin(9, v); return;
136
+		case 10: set_pin(10, v); return;
137
+		case 11: set_pin(11, v); return;
138
+		case 12: set_pin(12, v); return;
139
+		case 13: set_pin(13, v); return;
140
+		case 14: set_pin(14, v); return;
141
+		case 15: set_pin(15, v); return;
142
+		case 16: set_pin(16, v); return;
143
+		case 17: set_pin(17, v); return;
144
+		case 18: set_pin(18, v); return;
145
+		case 19: set_pin(19, v); return;
146
+		case 20: set_pin(20, v); return;
147
+		case 21: set_pin(21, v); return;
148
+	}
149
+}
150
+
151
+void pin_low_n(const uint8_t pin)
152
+{
153
+	switch(pin) {
154
+		case 0: pin_low(0); return;
155
+		case 1: pin_low(1); return;
156
+		case 2: pin_low(2); return;
157
+		case 3: pin_low(3); return;
158
+		case 4: pin_low(4); return;
159
+		case 5: pin_low(5); return;
160
+		case 6: pin_low(6); return;
161
+		case 7: pin_low(7); return;
162
+		case 8: pin_low(8); return;
163
+		case 9: pin_low(9); return;
164
+		case 10: pin_low(10); return;
165
+		case 11: pin_low(11); return;
166
+		case 12: pin_low(12); return;
167
+		case 13: pin_low(13); return;
168
+		case 14: pin_low(14); return;
169
+		case 15: pin_low(15); return;
170
+		case 16: pin_low(16); return;
171
+		case 17: pin_low(17); return;
172
+		case 18: pin_low(18); return;
173
+		case 19: pin_low(19); return;
174
+		case 20: pin_low(20); return;
175
+		case 21: pin_low(21); return;
176
+	}
177
+}
178
+
179
+void pin_high_n(const uint8_t pin)
180
+{
181
+	switch(pin) {
182
+		case 0: pin_high(0); return;
183
+		case 1: pin_high(1); return;
184
+		case 2: pin_high(2); return;
185
+		case 3: pin_high(3); return;
186
+		case 4: pin_high(4); return;
187
+		case 5: pin_high(5); return;
188
+		case 6: pin_high(6); return;
189
+		case 7: pin_high(7); return;
190
+		case 8: pin_high(8); return;
191
+		case 9: pin_high(9); return;
192
+		case 10: pin_high(10); return;
193
+		case 11: pin_high(11); return;
194
+		case 12: pin_high(12); return;
195
+		case 13: pin_high(13); return;
196
+		case 14: pin_high(14); return;
197
+		case 15: pin_high(15); return;
198
+		case 16: pin_high(16); return;
199
+		case 17: pin_high(17); return;
200
+		case 18: pin_high(18); return;
201
+		case 19: pin_high(19); return;
202
+		case 20: pin_high(20); return;
203
+		case 21: pin_high(21); return;
204
+	}
205
+}
206
+
207
+
208
+void toggle_pin_n(const uint8_t pin)
209
+{
210
+	switch(pin) {
211
+		case 0: toggle_pin(0); return;
212
+		case 1: toggle_pin(1); return;
213
+		case 2: toggle_pin(2); return;
214
+		case 3: toggle_pin(3); return;
215
+		case 4: toggle_pin(4); return;
216
+		case 5: toggle_pin(5); return;
217
+		case 6: toggle_pin(6); return;
218
+		case 7: toggle_pin(7); return;
219
+		case 8: toggle_pin(8); return;
220
+		case 9: toggle_pin(9); return;
221
+		case 10: toggle_pin(10); return;
222
+		case 11: toggle_pin(11); return;
223
+		case 12: toggle_pin(12); return;
224
+		case 13: toggle_pin(13); return;
225
+		case 14: toggle_pin(14); return;
226
+		case 15: toggle_pin(15); return;
227
+		case 16: toggle_pin(16); return;
228
+		case 17: toggle_pin(17); return;
229
+		case 18: toggle_pin(18); return;
230
+		case 19: toggle_pin(19); return;
231
+		case 20: toggle_pin(20); return;
232
+		case 21: toggle_pin(21); return;
233
+	}
234
+}
235
+
236
+
237
+bool get_pin_n(const uint8_t pin)
238
+{
239
+	switch(pin) {
240
+		case 0: return get_pin(0);
241
+		case 1: return get_pin(1);
242
+		case 2: return get_pin(2);
243
+		case 3: return get_pin(3);
244
+		case 4: return get_pin(4);
245
+		case 5: return get_pin(5);
246
+		case 6: return get_pin(6);
247
+		case 7: return get_pin(7);
248
+		case 8: return get_pin(8);
249
+		case 9: return get_pin(9);
250
+		case 10: return get_pin(10);
251
+		case 11: return get_pin(11);
252
+		case 12: return get_pin(12);
253
+		case 13: return get_pin(13);
254
+		case 14: return get_pin(14);
255
+		case 15: return get_pin(15);
256
+		case 16: return get_pin(16);
257
+		case 17: return get_pin(17);
258
+		case 18: return get_pin(18);
259
+		case 19: return get_pin(19);
260
+		case 20: return get_pin(20);
261
+		case 21: return get_pin(21);
262
+	}
263
+	return false;
264
+}
265
+
266
+
267
+bool is_low_n(const uint8_t pin)
268
+{
269
+	return !get_pin_n(pin);
270
+}
271
+
272
+
273
+bool is_high_n(const uint8_t pin)
274
+{
275
+	return get_pin_n(pin);
276
+}

+ 213 - 0
lib/iopins.h View File

@@ -0,0 +1,213 @@
1
+#pragma once
2
+
3
+//
4
+// * Utilities for pin aliasing / numbering. *
5
+//
6
+// Designed for Arduino.
7
+//
8
+// If you know the pin number beforehand, you can use the macros.
9
+//
10
+// If you need to use a variable for pin number, use the `_n` functions.
11
+// They are much slower, so always check if you really need them
12
+// - and they aren't fit for things where precise timing is required.
13
+//
14
+
15
+#include <avr/io.h>
16
+#include <stdbool.h>
17
+#include <stdint.h>
18
+
19
+#include "calc.h"
20
+
21
+
22
+// type: pointer to port
23
+typedef volatile uint8_t* PORT_P;
24
+
25
+
26
+/** Pin numbering reference */
27
+#define D0 0
28
+#define D1 1
29
+#define D2 2
30
+#define D3 3
31
+#define D4 4
32
+#define D5 5
33
+#define D6 6
34
+#define D7 7
35
+#define D8 8
36
+#define D9 9
37
+#define D10 10
38
+#define D11 11
39
+#define D12 12
40
+#define D13 13
41
+#define D14 14
42
+#define D15 15
43
+#define D16 16
44
+#define D17 17
45
+#define D18 18
46
+#define D19 19
47
+#define D20 20
48
+#define D21 21
49
+#define A0 14
50
+#define A1 15
51
+#define A2 16
52
+#define A3 17
53
+#define A4 18
54
+#define A5 19
55
+#define A6 20
56
+#define A7 21
57
+
58
+
59
+#define _ddr(pin)  _DDR_##pin
60
+#define _pin(pin)  _PIN_##pin
61
+#define _pn(pin)   _PN_##pin
62
+#define _port(pin) _PORT_##pin
63
+
64
+
65
+/** Set pin direction */
66
+#define set_dir(pin, d)  set_bit( _ddr(pin), _pn(pin), d )
67
+void    set_dir_n(const uint8_t pin, const uint8_t d);
68
+
69
+
70
+/** Configure pin as input */
71
+#define as_input(pin)    cbi( _ddr(pin), _pn(pin) )
72
+void    as_input_n(const uint8_t pin);
73
+
74
+
75
+/** Configure pin as input, with pull-up enabled */
76
+#define as_input_pu(pin) { as_input(pin); pin_high(pin); }
77
+void    as_input_pu_n(const uint8_t pin);
78
+
79
+
80
+/** Configure pin as output */
81
+#define as_output(pin)   sbi( _ddr(pin), _pn(pin) )
82
+void    as_output_n(const uint8_t pin);
83
+
84
+
85
+/** Write value to a pin */
86
+#define set_pin(pin, v) set_bit( _port(pin), _pn(pin), v )
87
+void    set_pin_n(const uint8_t pin, const uint8_t v);
88
+
89
+
90
+/** Write 0 to a pin */
91
+#define pin_low(pin)    cbi( _port(pin), _pn(pin) )
92
+void    pin_low_n(const uint8_t pin);
93
+
94
+
95
+/** Write 1 to a pin */
96
+#define pin_high(pin)   sbi( _port(pin), _pn(pin) )
97
+void    pin_high_n(const uint8_t pin);
98
+
99
+
100
+/** Toggle a pin state */
101
+#define toggle_pin(pin)   sbi( _pin(pin), _pn(pin) )
102
+void    toggle_pin_n(const uint8_t pin);
103
+
104
+
105
+/** Read a pin value */
106
+#define get_pin(pin)  get_bit( _pin(pin), _pn(pin) )
107
+bool    get_pin_n(const uint8_t pin);
108
+
109
+
110
+/** CHeck if pin is low */
111
+#define is_low(pin)   (get_pin(pin) == 0)
112
+bool    is_low_n(const uint8_t pin);
113
+
114
+
115
+/** CHeck if pin is high */
116
+#define is_high(pin)  (get_pin(pin) != 0)
117
+bool    is_high_n(const uint8_t pin);
118
+
119
+
120
+
121
+// Helper macros
122
+
123
+#define _PORT_0  PORTD
124
+#define _PORT_1  PORTD
125
+#define _PORT_2  PORTD
126
+#define _PORT_3  PORTD
127
+#define _PORT_4  PORTD
128
+#define _PORT_5  PORTD
129
+#define _PORT_6  PORTD
130
+#define _PORT_7  PORTD
131
+#define _PORT_8  PORTB
132
+#define _PORT_9  PORTB
133
+#define _PORT_10 PORTB
134
+#define _PORT_11 PORTB
135
+#define _PORT_12 PORTB
136
+#define _PORT_13 PORTB
137
+#define _PORT_14 PORTC
138
+#define _PORT_15 PORTC
139
+#define _PORT_16 PORTC
140
+#define _PORT_17 PORTC
141
+#define _PORT_18 PORTC
142
+#define _PORT_19 PORTC
143
+#define _PORT_20 PORTC
144
+#define _PORT_21 PORTC
145
+
146
+#define _PIN_0  PIND
147
+#define _PIN_1  PIND
148
+#define _PIN_2  PIND
149
+#define _PIN_3  PIND
150
+#define _PIN_4  PIND
151
+#define _PIN_5  PIND
152
+#define _PIN_6  PIND
153
+#define _PIN_7  PIND
154
+#define _PIN_8  PINB
155
+#define _PIN_9  PINB
156
+#define _PIN_10 PINB
157
+#define _PIN_11 PINB
158
+#define _PIN_12 PINB
159
+#define _PIN_13 PINB
160
+#define _PIN_14 PINC
161
+#define _PIN_15 PINC
162
+#define _PIN_16 PINC
163
+#define _PIN_17 PINC
164
+#define _PIN_18 PINC
165
+#define _PIN_19 PINC
166
+#define _PIN_20 PINC
167
+#define _PIN_21 PINC
168
+
169
+#define _DDR_0  DDRD
170
+#define _DDR_1  DDRD
171
+#define _DDR_2  DDRD
172
+#define _DDR_3  DDRD
173
+#define _DDR_4  DDRD
174
+#define _DDR_5  DDRD
175
+#define _DDR_6  DDRD
176
+#define _DDR_7  DDRD
177
+#define _DDR_8  DDRB
178
+#define _DDR_9  DDRB
179
+#define _DDR_10 DDRB
180
+#define _DDR_11 DDRB
181
+#define _DDR_12 DDRB
182
+#define _DDR_13 DDRB
183
+#define _DDR_14 DDRC
184
+#define _DDR_15 DDRC
185
+#define _DDR_16 DDRC
186
+#define _DDR_17 DDRC
187
+#define _DDR_18 DDRC
188
+#define _DDR_19 DDRC
189
+#define _DDR_20 DDRC
190
+#define _DDR_21 DDRC
191
+
192
+#define _PN_0  0
193
+#define _PN_1  1
194
+#define _PN_2  2
195
+#define _PN_3  3
196
+#define _PN_4  4
197
+#define _PN_5  5
198
+#define _PN_6  6
199
+#define _PN_7  7
200
+#define _PN_8  0
201
+#define _PN_9  1
202
+#define _PN_10 2
203
+#define _PN_11 3
204
+#define _PN_12 4
205
+#define _PN_13 5
206
+#define _PN_14 0
207
+#define _PN_15 1
208
+#define _PN_16 2
209
+#define _PN_17 3
210
+#define _PN_18 4
211
+#define _PN_19 5
212
+#define _PN_20 6
213
+#define _PN_21 7

+ 365 - 0
lib/lcd.c View File

@@ -0,0 +1,365 @@
1
+#include <stdbool.h>
2
+#include <stdint.h>
3
+#include <avr/io.h>
4
+#include <avr/pgmspace.h>
5
+#include <util/delay.h>
6
+
7
+#include "calc.h"
8
+#include "iopins.h"
9
+#include "nsdelay.h"
10
+#include "lcd.h"
11
+#include "lcd_config.h"
12
+
13
+// Start address of rows
14
+const uint8_t LCD_ROW_ADDR[] = {0x00, 0x40, 0x14, 0x54};
15
+
16
+
17
+// Shared stream instance
18
+static STREAM _lcd_singleton;
19
+STREAM* lcd;
20
+
21
+
22
+// Internal prototypes
23
+void _lcd_mode_r();
24
+void _lcd_mode_w();
25
+void _lcd_clk();
26
+void _lcd_wait_bf();
27
+void _lcd_write_byte(uint8_t bb);
28
+uint8_t _lcd_read_byte();
29
+
30
+
31
+// Write utilities
32
+#define _lcd_write_low(bb)  _lcd_write_nibble((bb) & 0x0F)
33
+#define _lcd_write_high(bb) _lcd_write_nibble(((bb) & 0xF0) >> 4)
34
+#define _lcd_write_nibble(nib) do {                \
35
+	set_pin(LCD_D7, get_bit((nib), 3));     \
36
+	set_pin(LCD_D6, get_bit((nib), 2));     \
37
+	set_pin(LCD_D5, get_bit((nib), 1));     \
38
+	set_pin(LCD_D4, get_bit((nib), 0));     \
39
+} while(0)
40
+
41
+
42
+// 0 W, 1 R
43
+bool _lcd_mode;
44
+
45
+struct
46
+{
47
+	uint8_t x;
48
+	uint8_t y;
49
+} _pos;
50
+
51
+enum
52
+{
53
+	TEXT = 0,
54
+	CG = 1
55
+} _addrtype;
56
+
57
+
58
+/** Initialize the display */
59
+void lcd_init()
60
+{
61
+	// configure pins as output
62
+	as_output(LCD_E);
63
+	as_output(LCD_RW);
64
+	as_output(LCD_RS);
65
+	_lcd_mode = 1;  // force data pins to output
66
+	_lcd_mode_w();
67
+
68
+	// Magic sequence to invoke Cthulhu (or enter 4-bit mode)
69
+	_delay_ms(16);
70
+	_lcd_write_nibble(0b0011);
71
+	_lcd_clk();
72
+	_delay_ms(5);
73
+	_lcd_clk();
74
+	_delay_ms(5);
75
+	_lcd_clk();
76
+	_delay_ms(5);
77
+	_lcd_write_nibble(0b0010);
78
+	_lcd_clk();
79
+	_delay_us(100);
80
+
81
+	// Configure the display
82
+	lcd_command(LCD_IFACE_4BIT_2LINE);
83
+	lcd_command(LCD_DISABLE);
84
+	lcd_command(LCD_CLEAR);
85
+	lcd_command(LCD_MODE_INC);
86
+
87
+	// mark as enabled
88
+	lcd_enable();
89
+
90
+	_lcd_singleton.tx = &lcd_write;
91
+	_lcd_singleton.rx = &lcd_read;
92
+
93
+	// Stream
94
+	lcd = &_lcd_singleton;
95
+
96
+	_pos.x = 0;
97
+	_pos.y = 0;
98
+	_addrtype = TEXT;
99
+}
100
+
101
+
102
+/** Send a pulse on the ENABLE line */
103
+void _lcd_clk()
104
+{
105
+	pin_high(LCD_E);
106
+	delay_ns(450);
107
+	pin_low(LCD_E);
108
+}
109
+
110
+
111
+/** Enter READ mode */
112
+void _lcd_mode_r()
113
+{
114
+	if (_lcd_mode == 1) return;  // already in R mode
115
+
116
+	pin_high(LCD_RW);
117
+
118
+	as_input_pu(LCD_D7);
119
+	as_input_pu(LCD_D6);
120
+	as_input_pu(LCD_D5);
121
+	as_input_pu(LCD_D4);
122
+
123
+	_lcd_mode = 1;
124
+}
125
+
126
+
127
+/** Enter WRITE mode */
128
+void _lcd_mode_w()
129
+{
130
+	if (_lcd_mode == 0) return;  // already in W mode
131
+
132
+	pin_low(LCD_RW);
133
+
134
+	as_output(LCD_D7);
135
+	as_output(LCD_D6);
136
+	as_output(LCD_D5);
137
+	as_output(LCD_D4);
138
+
139
+	_lcd_mode = 0;
140
+}
141
+
142
+
143
+/** Read a byte */
144
+uint8_t _lcd_read_byte()
145
+{
146
+	_lcd_mode_r();
147
+
148
+	uint8_t res = 0;
149
+
150
+	_lcd_clk();
151
+	res = (get_pin(LCD_D7) << 7) | (get_pin(LCD_D6) << 6) | (get_pin(LCD_D5) << 5) | (get_pin(LCD_D4) << 4);
152
+
153
+	_lcd_clk();
154
+	res |= (get_pin(LCD_D7) << 3) | (get_pin(LCD_D6) << 2) | (get_pin(LCD_D5) << 1) | (get_pin(LCD_D4) << 0);
155
+
156
+	return res;
157
+}
158
+
159
+
160
+/** Write an instruction byte */
161
+void lcd_command(uint8_t bb)
162
+{
163
+	_lcd_wait_bf();
164
+	pin_low(LCD_RS);  // select instruction register
165
+	_lcd_write_byte(bb);    // send instruction byte
166
+}
167
+
168
+
169
+/** Write a data byte */
170
+void lcd_write(uint8_t bb)
171
+{
172
+	if (_addrtype == TEXT)
173
+	{
174
+		if (bb == '\r')
175
+		{
176
+			// CR
177
+			_pos.x = 0;
178
+			lcd_xy(_pos.x, _pos.y);
179
+			return;
180
+		}
181
+
182
+		if (bb == '\n')
183
+		{
184
+			// LF
185
+			_pos.y++;
186
+			lcd_xy(_pos.x, _pos.y);
187
+			return;
188
+		}
189
+
190
+		_pos.x++;
191
+	}
192
+
193
+	_lcd_wait_bf();
194
+	pin_high(LCD_RS);  // select data register
195
+	_lcd_write_byte(bb);  // send data byte
196
+}
197
+
198
+
199
+/** Read BF & Address */
200
+uint8_t lcd_read_bf_addr()
201
+{
202
+	pin_low(LCD_RS);
203
+	return _lcd_read_byte();
204
+}
205
+
206
+
207
+/** Read CGRAM or DDRAM */
208
+uint8_t lcd_read()
209
+{
210
+	if (_addrtype == TEXT) _pos.x++;
211
+
212
+	pin_high(LCD_RS);
213
+	return _lcd_read_byte();
214
+}
215
+
216
+
217
+/** Write a byte using the 4-bit interface */
218
+void _lcd_write_byte(uint8_t bb)
219
+{
220
+	_lcd_mode_w();  // enter W mode
221
+
222
+	_lcd_write_high(bb);
223
+	_lcd_clk();
224
+
225
+	_lcd_write_low(bb);
226
+	_lcd_clk();
227
+}
228
+
229
+
230
+
231
+/** Wait until the device is ready */
232
+void _lcd_wait_bf()
233
+{
234
+	uint8_t d = 0;
235
+	while (d++ < 120 && lcd_read_bf_addr() & _BV(7))
236
+		_delay_us(1);
237
+}
238
+
239
+
240
+/** Send a string to LCD */
241
+void lcd_puts(char* str_p)
242
+{
243
+	char c;
244
+	while ((c = *str_p++))
245
+		lcd_putc(c);
246
+}
247
+
248
+
249
+/** Print from progmem */
250
+void lcd_puts_P(const char* str_p)
251
+{
252
+	char c;
253
+	while ((c = pgm_read_byte(str_p++)))
254
+		lcd_putc(c);
255
+}
256
+
257
+
258
+/** Sedn a char to LCD */
259
+void lcd_putc(const char c)
260
+{
261
+	lcd_write(c);
262
+}
263
+
264
+
265
+/** Set cursor position */
266
+void lcd_xy(const uint8_t x, const uint8_t y)
267
+{
268
+	_pos.x = x;
269
+	_pos.y = y;
270
+	lcd_addr(LCD_ROW_ADDR[y] + (x));
271
+}
272
+
273
+
274
+uint8_t _lcd_old_cursor = CURSOR_NONE;
275
+bool _lcd_enabled = false;
276
+
277
+/** Set LCD cursor. If not enabled, only remember it. */
278
+void lcd_cursor(uint8_t type)
279
+{
280
+	_lcd_old_cursor = (type & CURSOR_BOTH);
281
+
282
+	if (_lcd_enabled) lcd_command(LCD_CURSOR_NONE | _lcd_old_cursor);
283
+}
284
+
285
+
286
+/** Display display (preserving cursor) */
287
+void lcd_disable()
288
+{
289
+	lcd_command(LCD_DISABLE);
290
+	_lcd_enabled = false;
291
+}
292
+
293
+
294
+/** Enable display (restoring cursor) */
295
+void lcd_enable()
296
+{
297
+	_lcd_enabled = true;
298
+	lcd_cursor(_lcd_old_cursor);
299
+}
300
+
301
+
302
+/** Go home */
303
+void lcd_home()
304
+{
305
+	lcd_command(LCD_HOME);
306
+	_pos.x = 0;
307
+	_pos.y = 0;
308
+	_addrtype = TEXT;
309
+}
310
+
311
+
312
+/** Clear the screen */
313
+void lcd_clear()
314
+{
315
+	lcd_command(LCD_CLEAR);
316
+	_pos.x = 0;
317
+	_pos.y = 0;
318
+	_addrtype = TEXT;
319
+}
320
+
321
+
322
+/** Define a glyph */
323
+void lcd_glyph(const uint8_t index, const uint8_t* array)
324
+{
325
+	lcd_addr_cg(index * 8);
326
+	for (uint8_t i = 0; i < 8; ++i)
327
+	{
328
+		lcd_write(array[i]);
329
+	}
330
+
331
+	// restore previous position
332
+	lcd_xy(_pos.x, _pos.y);
333
+	_addrtype = TEXT;
334
+}
335
+
336
+
337
+/** Define a glyph */
338
+void lcd_glyph_P(const uint8_t index, const uint8_t* array)
339
+{
340
+	lcd_addr_cg(index * 8);
341
+	for (uint8_t i = 0; i < 8; ++i)
342
+	{
343
+		lcd_write(pgm_read_byte(&array[i]));
344
+	}
345
+
346
+	// restore previous position
347
+	lcd_xy(_pos.x, _pos.y);
348
+	_addrtype = TEXT;
349
+}
350
+
351
+
352
+/** Set address in CGRAM */
353
+void lcd_addr_cg(const uint8_t acg)
354
+{
355
+	_addrtype = CG;
356
+	lcd_command(0b01000000 | ((acg) & 0b00111111));
357
+}
358
+
359
+
360
+/** Set address in DDRAM */
361
+void lcd_addr(const uint8_t add)
362
+{
363
+	_addrtype = TEXT;
364
+	lcd_command(0b10000000 | ((add) & 0b01111111));
365
+}

+ 146 - 0
lib/lcd.h View File

@@ -0,0 +1,146 @@
1
+#pragma once
2
+
3
+//  HD44780 LCD display driver - 4-bit mode
4
+//
5
+//  LCD pins are configured using a file lcd_config.h, which you
6
+//  have to add next to your main.c file.
7
+//
8
+//  Content can be something like this:
9
+//
10
+//
11
+
12
+#include <stdint.h>
13
+#include <stdbool.h>
14
+
15
+#include "stream.h"
16
+
17
+// Your file with configs
18
+#include "lcd_config.h"
19
+/*
20
+	#define LCD_RS 10
21
+	#define LCD_RW 11
22
+	#define LCD_E  12
23
+	#define LCD_D4 13
24
+	#define LCD_D5 14
25
+	#define LCD_D6 15
26
+	#define LCD_D7 16
27
+*/
28
+
29
+
30
+
31
+// Shared LCD stream object
32
+// Can be used with functions from stream.h once LCD is initialized
33
+extern STREAM* lcd;
34
+
35
+
36
+// --- Commands ---
37
+
38
+// Clear screen (reset)
39
+#define LCD_CLEAR 0b00000001
40
+// Move cursor to (0,0), unshift...
41
+#define LCD_HOME  0b00000010
42
+
43
+// Set mode: Increment + NoShift
44
+#define LCD_MODE_INC         0b00000110
45
+// Set mode: Increment + Shift
46
+#define LCD_MODE_INC_SHIFT   0b00000111
47
+
48
+// Set mode: Decrement + NoShift
49
+#define LCD_MODE_DEC         0b00000100
50
+// Set mode: Decrement + Shift
51
+#define LCD_MODE_DEC_SHIFT   0b00000101
52
+
53
+// Disable display (data remains untouched)
54
+#define LCD_DISABLE          0b00001000
55
+
56
+// Disable cursor
57
+#define LCD_CURSOR_NONE      0b00001100
58
+// Set cursor to still underscore
59
+#define LCD_CURSOR_BAR       0b00001110
60
+// Set cursor to blinking block
61
+#define LCD_CURSOR_BLINK     0b00001101
62
+// Set cursor to both of the above at once
63
+#define LCD_CURSOR_BOTH      (LCD_CURSOR_BAR | LCD_CURSOR_BLINK)
64
+
65
+// Move cursor
66
+#define LCD_MOVE_LEFT  0b00010000
67
+#define LCD_MOVE_RIGHT 0b00010100
68
+
69
+// Shift display
70
+#define LCD_SHIFT_LEFT  0b00011000
71
+#define LCD_SHIFT_RIGHT 0b00011100
72
+
73
+// Set iface to 5x7 font, 1-line
74
+#define LCD_IFACE_4BIT_1LINE 0b00100000
75
+#define LCD_IFACE_8BIT_1LINE 0b00110000
76
+// Set iface to 5x7 font, 2-line
77
+#define LCD_IFACE_4BIT_2LINE 0b00101000
78
+#define LCD_IFACE_8BIT_2LINE 0b00111000
79
+
80
+
81
+/** Initialize the display */
82
+void lcd_init();
83
+
84
+/** Write an instruction byte */
85
+void lcd_command(uint8_t bb);
86
+
87
+/** Write a data byte */
88
+void lcd_write(uint8_t bb);
89
+
90
+/** Read BF & Address */
91
+uint8_t lcd_read_bf_addr();
92
+
93
+/** Read CGRAM or DDRAM */
94
+uint8_t lcd_read();
95
+
96
+/** Send a string to LCD */
97
+void lcd_puts(char* str_p);
98
+
99
+/** Send a string to LCD from program memory */
100
+void lcd_puts_P(const char* str_p);
101
+
102
+/** Sedn a char to LCD */
103
+void lcd_putc(const char c);
104
+
105
+/** Show string at X, Y */
106
+#define lcd_puts_xy(x, y, str_p) do { lcd_xy((x), (y)); lcd_puts((str_p)); } while(0)
107
+
108
+/** Show string at X, Y */
109
+#define lcd_puts_xy_P(x, y, str_p) do { lcd_xy((x), (y)); lcd_puts_P((str_p)); } while(0)
110
+
111
+/** Show char at X, Y */
112
+#define lcd_putc_xy(x, y, c) do { lcd_xy((x), (y)); lcd_putc((c)); } while(0)
113
+
114
+/** Set cursor position */
115
+void lcd_xy(const uint8_t x, const uint8_t y);
116
+
117
+/** Set LCD cursor. If not enabled, only remember it. */
118
+#define CURSOR_NONE  0b00
119
+#define CURSOR_BAR   0b10
120
+#define CURSOR_BLINK 0b01
121
+#define CURSOR_BOTH  0b11
122
+void lcd_cursor(uint8_t type);
123
+
124
+/** Display display (preserving cursor) */
125
+void lcd_disable();
126
+
127
+/** Enable display (restoring cursor) */
128
+void lcd_enable();
129
+
130
+/** Go home */
131
+void lcd_home();
132
+
133
+/** Clear the screen */
134
+void lcd_clear();
135
+
136
+/** Define a glyph - 8 bytes, right 5 bits are used */
137
+void lcd_glyph(const uint8_t index, const uint8_t* array);
138
+
139
+/** Define a glyph that's in PROGMEM */
140
+void lcd_glyph_P(const uint8_t index, const uint8_t* array);
141
+
142
+/** Set address in CGRAM */
143
+void lcd_addr_cg(const uint8_t acg);
144
+
145
+/** Set address in DDRAM */
146
+void lcd_addr(const uint8_t add);

+ 21 - 0
lib/nsdelay.h View File

@@ -0,0 +1,21 @@
1
+#pragma once
2
+
3
+//
4
+// Functions for precise delays (nanoseconds / cycles)
5
+//
6
+
7
+#include <avr/io.h>
8
+#include <util/delay_basic.h>
9
+#include <stdint.h>
10
+
11
+/* Convert nanoseconds to cycle count */
12
+#define ns2cycles(ns)  ( (ns) / (1000000000L / (signed long) F_CPU) )
13
+
14
+/** Wait c cycles */
15
+#define delay_c(c)  (((c) > 0) ? __builtin_avr_delay_cycles(c) :  __builtin_avr_delay_cycles(0))
16
+
17
+/** Wait n nanoseconds, plus c cycles  */
18
+#define delay_ns_c(ns, c)  delay_c(ns2cycles(ns) + (c))
19
+
20
+/** Wait n nanoseconds  */
21
+#define delay_ns(ns)  delay_c(ns2cycles(ns))

+ 248 - 0
lib/onewire.c View File

@@ -0,0 +1,248 @@
1
+#include <avr/io.h>
2
+#include <util/delay.h>
3
+#include <stdint.h>
4
+#include <stdbool.h>
5
+
6
+#include "iopins.h"
7
+#include "onewire.h"
8
+
9
+
10
+/** Perform bus reset. Returns true if any device is connected */
11
+bool ow_reset(const uint8_t pin)
12
+{
13
+	as_output_n(pin);
14
+	pin_low_n(pin);
15
+	_delay_us(480);
16
+
17
+	as_input_pu_n(pin);
18
+	_delay_us(70);
19
+
20
+	const bool a = get_pin_n(pin);
21
+
22
+	_delay_us(410);
23
+
24
+	return a;
25
+}
26
+
27
+
28
+/** Send a single bit */
29
+void _ow_tx_bit(const uint8_t pin, const bool bit)
30
+{
31
+	as_output_n(pin);
32
+	pin_low_n(pin);
33
+
34
+	if (bit)
35
+	{
36
+		_delay_us(6);
37
+		as_input_pu_n(pin);
38
+		_delay_us(64);
39
+	}
40
+	else
41
+	{
42
+		_delay_us(60);
43
+		as_input_pu_n(pin);
44
+		_delay_us(10);
45
+	}
46
+}
47
+
48
+
49
+/** Send a single byte */
50
+void ow_send(const uint8_t pin, const uint8_t byte)
51
+{
52
+	for (uint8_t i = 0; i < 8; i++)
53
+	{
54
+		_ow_tx_bit(pin, (byte >> i) & 0x01);
55
+	}
56
+}
57
+
58
+
59
+/** Read a single bit */
60
+bool _ow_rx_bit(const uint8_t pin)
61
+{
62
+	as_output_n(pin);
63
+	pin_low_n(pin);
64
+	_delay_us(6);
65
+
66
+	as_input_pu_n(pin);
67
+	_delay_us(9);
68
+
69
+	const bool a = get_pin_n(pin);
70
+
71
+	_delay_us(55);
72
+
73
+	return a;
74
+}
75
+
76
+
77
+/** Read a single byte */