├── .gitattributes
├── .gitignore
├── AS7
├── README.md
├── blink
│ ├── BareMinimumTemplate.zip
│ ├── Sketches
│ │ ├── BareMinimum
│ │ │ ├── BareMinimum.componentinfo.xml
│ │ │ ├── BareMinimum.cppproj
│ │ │ └── main.cpp
│ │ └── Blink
│ │ │ ├── Blink.componentinfo.xml
│ │ │ ├── Blink.cppproj
│ │ │ └── main.cpp
│ ├── Snipets
│ │ └── special_serial.xml
│ ├── bareblinkOS
│ │ └── bareblinkOS
│ │ │ ├── bareblinkOS.componentinfo.xml
│ │ │ ├── bareblinkOS.cppproj
│ │ │ ├── blinkos.h
│ │ │ ├── main.cpp
│ │ │ └── pixelcolor.h
│ ├── blink.atsln
│ ├── blinkcore
│ │ ├── blinkcore.componentinfo.xml
│ │ └── blinkcore.cppproj
│ ├── blinklib
│ │ ├── WMath.cpp
│ │ ├── blinkos.componentinfo.xml
│ │ └── blinkos.cppproj
│ └── blinkstate
│ │ ├── blinklib.componentinfo.xml
│ │ └── blinklib.cppproj
├── blinklib
│ └── blinklib
│ │ ├── blinklib.componentinfo.xml
│ │ └── blinklib.cppproj
└── blinkos
│ └── blinkos
│ ├── blinkos.componentinfo.xml
│ └── blinkos.cppproj
├── Getting-started.md
├── LICENSE
├── Layers.md
├── Production.MD
├── README.md
├── Service Port.MD
├── Tools.md
├── _config.yml
├── avrdude.conf
├── boards.txt
├── bootloaders
├── BlinkBIOS.hex
└── readme.MD
├── cores
└── blinklib
│ ├── Arduino.h
│ ├── ArduinoTypes.h
│ ├── DummySerial.h
│ ├── Print.cpp
│ ├── Print.h
│ ├── Serial.cpp
│ ├── Serial.h
│ ├── Timer.cpp
│ ├── blinklib.cpp
│ ├── blinklib.h
│ ├── main.cpp
│ ├── run.h
│ ├── shared
│ ├── BlinkBIOS.hex
│ ├── blinkbios_shared_button.h
│ ├── blinkbios_shared_functions.h
│ ├── blinkbios_shared_irdata.h
│ ├── blinkbios_shared_millis.h
│ ├── blinkbios_shared_pixel.h
│ ├── blinkbios_shared_volatile.h
│ └── readme.MD
│ ├── sp.cpp
│ ├── sp.h
│ └── startup.S
├── keywords.txt
├── libraries
├── Examples01
│ ├── dummy.hpp
│ ├── examples
│ │ ├── A-BareMinimum
│ │ │ └── A-BareMinimum.ino
│ │ ├── B-ButtonPress
│ │ │ └── B-ButtonPress.ino
│ │ ├── C-ButtonCycleColors
│ │ │ └── C-ButtonCycleColors.ino
│ │ ├── D-TimerFlash
│ │ │ └── D-TimerFlash.ino
│ │ ├── E-TimerBlink
│ │ │ └── E-TimerBlink.ino
│ │ ├── F-ColorWheel
│ │ │ └── F-ColorWheel.ino
│ │ └── G-StartState
│ │ │ └── G-StartState.ino
│ └── library.properties
├── Examples02
│ ├── dummy.hpp
│ ├── examples
│ │ ├── A-ColorByNeighbor
│ │ │ └── A-ColorByNeighbor.ino
│ │ ├── B-ColorRamps
│ │ │ └── B-ColorRamps.ino
│ │ ├── C-SerialNumberPrinter
│ │ │ └── C-SerialNumberPrinter.ino
│ │ ├── D-SerialTest
│ │ │ └── D-SerialTest.ino
│ │ ├── E-ButtonGym
│ │ │ └── E-ButtonGym.ino
│ │ ├── F-SimpleDatagramDemo
│ │ │ └── F-SimpleDatagramDemo.ino
│ │ ├── G-IRButtonPressTester
│ │ │ └── G-IRButtonPressTester.ino
│ │ └── H-IRLinkTester
│ │ │ └── H-IRLinkTester.ino
│ └── library.properties
├── Examples03
│ ├── dummy.hpp
│ ├── examples
│ │ ├── Astro
│ │ │ └── Astro.ino
│ │ ├── Berry
│ │ │ └── Berry.ino
│ │ ├── BombBrigade
│ │ │ └── BombBrigade.ino
│ │ ├── FlicFlop
│ │ │ └── FlicFlop.ino
│ │ ├── Fracture
│ │ │ └── Fracture.ino
│ │ ├── Honey
│ │ │ └── Honey.ino
│ │ ├── Mortals
│ │ │ └── Mortals.ino
│ │ ├── Puzzle101
│ │ │ └── Puzzle101.ino
│ │ ├── SpeedRacer
│ │ │ └── SpeedRacer.ino
│ │ ├── WHAM
│ │ │ └── WHAM.ino
│ │ ├── Widgets
│ │ │ └── Widgets.ino
│ │ └── ZenFlow
│ │ │ └── ZenFlow.ino
│ └── library.properties
├── Examples04
│ ├── dummy.hpp
│ └── library.properties
└── Examples05
│ ├── dummy.hpp
│ └── library.properties
├── linkscripts
├── avr5.xn
└── readme.MD
├── package_move38.com-blinks_index.json
├── platform.txt
├── programmers.txt
└── variants
└── standard
└── dummy.txt
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | [Dd]ebug/
3 | [Rr]elease/
4 | .vs*
5 |
--------------------------------------------------------------------------------
/AS7/README.md:
--------------------------------------------------------------------------------
1 | # AS7
2 |
3 | This directory holds an Atmel Studio 7 Solution and Project with all the firmware files.
4 |
5 | All files are included as links to the arduino directories, so any updates you make in AS7 will be reflected in the arduino structure.
6 |
7 | There is a project temple here called `` that makes it easy to create new sketches that use the `blinkslib` library. You need to import this zip file into Atmel Studio...
8 |
9 | http://www.atmel.com/webdoc/atmelstudio/atmelstudio.GettingStarted.ProjectImporter.TemplateImporter.html
10 |
11 | ...and then you can use "Add New Project..." to quickly make new sketches with all the setting and directories right.
12 |
13 | After you are done, you can copy and paste the source code into a INO file in the Arduino IDE.
14 |
15 | I much prefer working in AS7 to the Arduino IDE so it was worth the effort to make this.
16 |
--------------------------------------------------------------------------------
/AS7/blink/BareMinimumTemplate.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Move38/Blinks-SDK/2fd2e45e02ffd8c4ac6468d7cb420dcd29306c9f/AS7/blink/BareMinimumTemplate.zip
--------------------------------------------------------------------------------
/AS7/blink/Sketches/BareMinimum/BareMinimum.componentinfo.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Device
8 | Startup
9 |
10 |
11 | Atmel
12 | 1.2.0
13 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs
14 |
15 |
16 |
17 |
18 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.132\include
19 |
20 | include
21 | C
22 |
23 |
24 | include
25 |
26 |
27 |
28 |
29 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.132\include\avr\iom168pb.h
30 |
31 | header
32 | C
33 | L5o1bjrhZ5Pw/8Zpd6GGNw==
34 |
35 | include/avr/iom168pb.h
36 |
37 |
38 |
39 |
40 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.132\templates\main.c
41 | template
42 | source
43 | C Exe
44 | GD1k8YYhulqRs6FD1B2Hog==
45 |
46 | templates/main.c
47 | Main file (.c)
48 |
49 |
50 |
51 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.132\templates\main.cpp
52 | template
53 | source
54 | C Exe
55 | OiG8MbOIHSxLATGuTbJvtg==
56 |
57 | templates/main.cpp
58 | Main file (.cpp)
59 |
60 |
61 |
62 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.132\gcc\dev\atmega168pb
63 |
64 | libraryPrefix
65 | GCC
66 |
67 |
68 | gcc/dev/atmega168pb
69 |
70 |
71 |
72 |
73 | ATmega_DFP
74 | C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/ATmega_DFP/1.2.132/Atmel.ATmega_DFP.pdsc
75 | 1.2.132
76 | true
77 | ATmega168PB
78 |
79 |
80 |
81 | Resolved
82 | Fixed
83 | true
84 |
85 |
86 |
--------------------------------------------------------------------------------
/AS7/blink/Sketches/BareMinimum/BareMinimum.cppproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 2.0
5 | 7.0
6 | com.Atmel.AVRGCC8.CPP
7 | {89039130-47b6-4762-beb5-52050924dfe0}
8 | ATmega168PB
9 | none
10 | Executable
11 | CPP
12 | $(MSBuildProjectName)
13 | .elf
14 | $(MSBuildProjectDirectory)\$(Configuration)
15 | BareMinimum
16 | BareMinimum
17 | BareMinimum
18 | Native
19 | true
20 | false
21 | true
22 | true
23 |
24 |
25 | true
26 |
27 | 2
28 | 0
29 |
30 |
31 |
32 |
33 | -mmcu=atmega168pb -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\gcc\dev\atmega168pb"
34 | True
35 | True
36 | True
37 | True
38 | False
39 | True
40 | True
41 |
42 |
43 | NDEBUG
44 |
45 |
46 |
47 |
48 | %24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\include
49 |
50 |
51 | Optimize for size (-Os)
52 | True
53 | True
54 | True
55 | True
56 | True
57 |
58 |
59 | NDEBUG
60 |
61 |
62 |
63 |
64 | %24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\include
65 |
66 |
67 | Optimize for size (-Os)
68 | True
69 | True
70 | True
71 |
72 |
73 | libm
74 |
75 |
76 |
77 |
78 | %24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\include
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | -mmcu=atmega168pb -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\gcc\dev\atmega168pb"
88 | True
89 | True
90 | True
91 | True
92 | False
93 | True
94 | True
95 |
96 |
97 | DEBUG
98 |
99 |
100 |
101 |
102 | %24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\include
103 |
104 |
105 | Optimize (-O1)
106 | True
107 | True
108 | Default (-g2)
109 | True
110 | True
111 | True
112 |
113 |
114 | DEBUG
115 |
116 |
117 |
118 |
119 | %24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\include
120 | ../../../../../libraries/blinklib/src
121 | ../../../../../cores/blinkcore
122 |
123 |
124 | Optimize (-O1)
125 | True
126 | True
127 | Default (-g2)
128 | True
129 |
130 |
131 | libm
132 |
133 |
134 |
135 |
136 | %24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\include
137 |
138 |
139 | Default (-Wa,-g)
140 |
141 |
142 |
143 |
144 |
145 | compile
146 |
147 |
148 |
149 |
150 | blinkcore
151 | {dce6c7e3-ee26-4d79-826b-08594b9ad897}
152 | True
153 |
154 |
155 | blinklib
156 | {c03aa8ca-16e3-4a37-9986-eeaa5cbcefd6}
157 | True
158 |
159 |
160 |
161 |
--------------------------------------------------------------------------------
/AS7/blink/Sketches/BareMinimum/main.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * BareMinimum.cpp
3 | *
4 | */
5 |
6 | #include
7 |
8 | #include "blink.h"
9 |
10 | void setup() {
11 | // put your start up code here, it will run
12 | // every time this blink wakes up
13 |
14 | }
15 |
16 | void loop() {
17 | // put your main code here, to run repeatedly
18 | // every time a new frame of pixels is displayed
19 | // on the front of this blink
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/AS7/blink/Sketches/Blink/Blink.componentinfo.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Device
8 | Startup
9 |
10 |
11 | Atmel
12 | 1.2.0
13 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs
14 |
15 |
16 |
17 |
18 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\include
19 |
20 | include
21 | C
22 |
23 |
24 | include
25 |
26 |
27 |
28 |
29 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\include\avr\iom168pb.h
30 |
31 | header
32 | C
33 | yAkfp/rOk1YuAUNFypsCqg==
34 |
35 | include/avr/iom168pb.h
36 |
37 |
38 |
39 |
40 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\templates\main.c
41 | template
42 | source
43 | C Exe
44 | GD1k8YYhulqRs6FD1B2Hog==
45 |
46 | templates/main.c
47 | Main file (.c)
48 |
49 |
50 |
51 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\templates\main.cpp
52 | template
53 | source
54 | C Exe
55 | YXFphlh0CtZJU+ebktABgQ==
56 |
57 | templates/main.cpp
58 | Main file (.cpp)
59 |
60 |
61 |
62 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega168pb
63 |
64 | libraryPrefix
65 | GCC
66 |
67 |
68 | gcc/dev/atmega168pb
69 |
70 |
71 |
72 |
73 | ATmega_DFP
74 | C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/ATmega_DFP/1.2.209/Atmel.ATmega_DFP.pdsc
75 | 1.2.209
76 | true
77 | ATmega168PB
78 |
79 |
80 |
81 | Resolved
82 | Fixed
83 | true
84 |
85 |
86 |
--------------------------------------------------------------------------------
/AS7/blink/Sketches/Blink/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #define F_CPU 8000000
4 |
5 | #include
6 |
7 | //#include "bitfun.h"
8 |
9 | //#include "adc.h"
10 |
11 | #include "Serial.h"
12 |
13 | ServicePortSerial sp;
14 |
15 |
16 | void setup() {
17 |
18 | sp.begin();
19 |
20 | }
21 |
22 |
23 | // Returns the previous conversion result (call adc_startConversion() to start a conversion).
24 | // Blocks if you call too soon and conversion not ready yet.
25 |
26 | uint8_t adc_readLastVccX10(void) { // Return Vcc x10
27 |
28 | while (TBI(ADCSRA,ADSC)) ; // Wait for any pending conversion to complete
29 |
30 | uint8_t lastReading = (255*11 / ADCH); // Remember the result from the last reading.
31 |
32 | sp.println(lastReading);
33 |
34 | return( lastReading );
35 |
36 | }
37 |
38 | #define DELAY_BLINK_MS 200 // Delay between flashes
39 | #define DELAY_DIGIT_MS 750 // Delay between 10's and 1's digits
40 | #define DELAY_READ_MS 1000 // Delay between consecutive readings
41 |
42 |
43 |
44 | enum phase_t { READ , TENS, ONES };
45 |
46 | enum state_t { S_OFF , S_ON };
47 |
48 | static phase_t phase=READ;
49 | static state_t state=S_OFF;
50 |
51 | static Timer next;
52 |
53 | static uint8_t c=0;
54 |
55 | static uint8_t lastReading=24;
56 |
57 | void loop() {
58 | /*
59 | if (next.isExpired()) {
60 |
61 | if (state==S_ON) {
62 |
63 | setColor( OFF );
64 |
65 | state=S_OFF;
66 |
67 | } else {
68 | setColor( BLUE );
69 |
70 | state=S_ON;
71 |
72 | }
73 |
74 | next.set(500);
75 |
76 | }
77 |
78 | return;
79 | */
80 |
81 | if (phase==READ) {
82 |
83 | adc_startConversion();
84 |
85 | lastReading = adc_readLastVccX10();
86 |
87 | c = lastReading/10; // Tens digit
88 |
89 | if (c==0) c=10;
90 |
91 | phase = TENS;
92 |
93 | state = S_OFF;
94 |
95 | next.set(2000); // Show immediately
96 |
97 | }
98 |
99 | if (c==0) { // Done with this digit
100 |
101 | if (phase==TENS) {
102 |
103 | c = lastReading%10; // Ones digit
104 |
105 | if (c==0) c=10;
106 |
107 | phase = ONES;
108 |
109 | next.set( DELAY_DIGIT_MS );
110 |
111 | } else {
112 |
113 | phase = READ;
114 |
115 | next.set( DELAY_READ_MS );
116 | }
117 |
118 | } else {
119 |
120 | if (next.isExpired()) {
121 |
122 | if (state==S_OFF) {
123 |
124 | setColor( RED );
125 |
126 | state = S_ON;
127 |
128 | next.set( DELAY_BLINK_MS );
129 |
130 | } else { // state==ON
131 |
132 | setColor( OFF );
133 |
134 | state = S_OFF;
135 |
136 | c--;
137 |
138 | next.set( DELAY_BLINK_MS );
139 |
140 | }
141 |
142 | }
143 |
144 | }
145 |
146 | } // loop()
147 |
148 |
149 |
--------------------------------------------------------------------------------
/AS7/blink/Snipets/special_serial.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 | Special serial debuging snippet
7 |
8 |
9 |
10 |
18 | #define SP_SERIAL_CTRL_REG UCSR0A
19 | #define SP_SERIAL_DATA_REG UDR0
20 | #define SP_SERIAL_READY_BIT RXC0
21 |
22 | static void sp_serial_tx(uint8_t b) {
23 |
24 | while (!TBI(SP_SERIAL_CTRL_REG,UDRE0)); // Wait for buffer to be clear so we don't overwrite in progress
25 |
26 | SP_SERIAL_DATA_REG=b; // Send new byte
27 |
28 | }
29 |
30 | /* TO HERE */
31 |
32 |
33 |
34 | ]]>
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/AS7/blink/bareblinkOS/bareblinkOS/bareblinkOS.componentinfo.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Device
8 | Startup
9 |
10 |
11 | Atmel
12 | 1.2.0
13 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs
14 |
15 |
16 |
17 |
18 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\include
19 |
20 | include
21 | C
22 |
23 |
24 | include
25 |
26 |
27 |
28 |
29 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\include\avr\iom168pb.h
30 |
31 | header
32 | C
33 | yAkfp/rOk1YuAUNFypsCqg==
34 |
35 | include/avr/iom168pb.h
36 |
37 |
38 |
39 |
40 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\templates\main.c
41 | template
42 | source
43 | C Exe
44 | GD1k8YYhulqRs6FD1B2Hog==
45 |
46 | templates/main.c
47 | Main file (.c)
48 |
49 |
50 |
51 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\templates\main.cpp
52 | template
53 | source
54 | C Exe
55 | CAoCZxJJ1rIlxmxWa+AEaw==
56 |
57 | templates/main.cpp
58 | Main file (.cpp)
59 |
60 |
61 |
62 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega168pb
63 |
64 | libraryPrefix
65 | GCC
66 |
67 |
68 | gcc/dev/atmega168pb
69 |
70 |
71 |
72 |
73 | ATmega_DFP
74 | C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/ATmega_DFP/1.2.209/Atmel.ATmega_DFP.pdsc
75 | 1.2.209
76 | true
77 | ATmega168PB
78 |
79 |
80 |
81 | Resolved
82 | Fixed
83 | true
84 |
85 |
86 |
--------------------------------------------------------------------------------
/AS7/blink/bareblinkOS/bareblinkOS/bareblinkOS.cppproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 2.0
5 | 7.0
6 | com.Atmel.AVRGCC8.CPP
7 | {b750fa7b-22de-43c4-a796-f95418271edd}
8 | ATmega168PB
9 | none
10 | Executable
11 | CPP
12 | $(MSBuildProjectName)
13 | .elf
14 | $(MSBuildProjectDirectory)\$(Configuration)
15 | bareblinkOS
16 | bareblinkOS
17 | bareblinkOS
18 | Native
19 | true
20 | false
21 | true
22 | true
23 | 0x20000000
24 |
25 | true
26 | exception_table
27 | 2
28 | 0
29 | 0
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | com.atmel.avrdbg.tool.ispmk2
44 | 0000B3020609
45 | 0x1E9415
46 | ISP
47 | 250000
48 |
49 |
50 |
51 | 250000
52 |
53 | ISP
54 |
55 | com.atmel.avrdbg.tool.ispmk2
56 | 0000B3020609
57 | AVRISP mkII
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | -mmcu=atmega168pb -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega168pb"
68 | True
69 | True
70 | True
71 | True
72 | False
73 | True
74 | True
75 |
76 |
77 | NDEBUG
78 |
79 |
80 |
81 |
82 | %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
83 |
84 |
85 | Optimize for size (-Os)
86 | True
87 | True
88 | True
89 | True
90 | True
91 |
92 |
93 | NDEBUG
94 |
95 |
96 |
97 |
98 | %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
99 |
100 |
101 | Optimize for size (-Os)
102 | True
103 | True
104 | True
105 |
106 |
107 | libm
108 |
109 |
110 |
111 |
112 | %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 | -mmcu=atmega168pb -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega168pb"
122 | True
123 | True
124 | True
125 | True
126 | False
127 | True
128 | True
129 |
130 |
131 | DEBUG
132 |
133 |
134 |
135 |
136 | %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
137 |
138 |
139 | Optimize (-O1)
140 | True
141 | True
142 | Default (-g2)
143 | True
144 | True
145 | True
146 |
147 |
148 | DEBUG
149 |
150 |
151 |
152 |
153 | %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
154 |
155 |
156 | Optimize (-O1)
157 | True
158 | True
159 | Default (-g2)
160 | True
161 |
162 |
163 | libm
164 |
165 |
166 |
167 |
168 | %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
169 |
170 |
171 | Default (-Wa,-g)
172 |
173 |
174 |
175 |
176 |
177 | compile
178 |
179 |
180 |
181 |
--------------------------------------------------------------------------------
/AS7/blink/bareblinkOS/bareblinkOS/blinkos.h:
--------------------------------------------------------------------------------
1 | /*
2 | * blinkOS.h
3 | *
4 | * This defines a high-level interface to the blinks operating system.
5 | *
6 | */
7 |
8 |
9 | // Gets us uintx_t
10 | // Not sure why, but it MUST be in the header and not the cpp
11 | #include
12 | #include "pixelcolor.h"
13 |
14 | #define IR_FACE_COUNT 6
15 | #define IR_FACE_BITMASK 0b00111111 // 1's in each bit for every face (will break if we ever make a nonagon or higher)
16 |
17 | #define PIXEL_FACE_COUNT 6
18 |
19 | // TODO: Change time to uint24 _t
20 | // Supported!!! https://gcc.gnu.org/wiki/avr-gcc#types
21 | // typedef __uint24 millis_t;
22 |
23 | typedef uint32_t millis_t;
24 |
25 | // loopstate is passed in and out of the user program on each pass
26 | // through the main event loop
27 |
28 | // I know this is ugly, but keeping them in a single byte lets us pass them by value
29 | // and also lets us OR them together. Efficiency in the updater trumps since it
30 | // runs every millisecond.
31 |
32 | #define BUTTON_BITFLAG_PRESSED 0b00000001
33 | #define BUTTON_BITFLAG_LONGPRESSED 0b00000010
34 | #define BUTTON_BITFLAG_RELEASED 0b00000100
35 | #define BUTTON_BITFLAG_SINGLECLICKED 0b00001000
36 | #define BUTTON_BITFLAG_DOUBLECLICKED 0b00010000
37 | #define BUTTON_BITFLAG_MULITCLICKED 0b00100000
38 | #define BUTTON_BITFLAG_DUMMY 0b01000000
39 |
40 | struct buttonstate_t {
41 |
42 | uint8_t down; // 1 if button is currently down
43 |
44 | uint8_t bitflags;
45 |
46 | uint8_t clickcount; // Number of clicks on most recent multiclick
47 |
48 | };
49 |
50 |
51 | struct ir_data_buffer_t {
52 |
53 | const uint8_t *data;
54 | uint8_t len;
55 | uint8_t ready_flag; // 1 if new packet received. Call markread_data_buffer();
56 |
57 | };
58 |
59 | // Sends immediately. Blocks until send is complete.
60 | // Higher level should provide some collision control.
61 | // Returns 0 if it was not able to send because there was already an RX in progress on this face
62 |
63 | uint8_t ir_send_userdata( uint8_t face, const uint8_t *data , uint8_t len );
64 |
65 | struct loopstate_in_t {
66 |
67 | ir_data_buffer_t ir_data_buffers[IR_FACE_COUNT];
68 |
69 | buttonstate_t buttonstate; // Note that the flags in here are cleared after every pass though the loop
70 |
71 | uint8_t woke_flag; // Have we slept and woke?
72 |
73 |
74 | millis_t millis; // elapsed milliseconds since start
75 |
76 | uint8_t futureexapansion[20]; // Save some space for future expansion
77 |
78 | };
79 |
80 | // Mark a packet as consumed so the buffer can receive the next one.
81 | // Done automatically each time loopEntry() returns, but this can let you free up the packet sooner
82 | // for better throughput
83 |
84 | // Mark a packet as consumed so the buffer can receive the next one.
85 | // Done automatically each time loopEntry() returns, but this can let you free up the packet sooner
86 | // for better throughput
87 |
88 | void ir_mark_packet_read( uint8_t face );
89 |
90 | struct loopstate_out_t {
91 |
92 | pixelColor_t colors[PIXEL_FACE_COUNT]; // Current RGB colors of all faces. 5 bits each.
93 | // Topmost bit set indicates it changed
94 |
95 | uint8_t futureexapansion[20]; // Save some space for future expansion
96 |
97 | };
98 |
99 |
100 | // These are provided by blinklib
101 |
102 | //void setupEntry();
103 | void loopEntry( loopstate_in_t const *loopstate_in , loopstate_out_t *loopstate_out);
104 |
--------------------------------------------------------------------------------
/AS7/blink/bareblinkOS/bareblinkOS/main.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * bareblinkOS.cpp
3 | *
4 | * An example that runs directly on the blinkOS without blinklib
5 | *
6 | */
7 |
8 |
9 | #include "blinkos.h"
10 | //#include "bootloader.h"
11 |
12 | //#include // memcmp()
13 |
14 |
15 | void setupEntry() {
16 |
17 | // Blank
18 |
19 | };
20 |
21 | Timer next_send_pull_request;
22 |
23 | void loopEntry() {
24 |
25 | if (next_send_pull_request.isExpired()) {
26 |
27 | // Time to send next pull request
28 |
29 | blinkboot_packet p;
30 |
31 | p.header = P
32 |
33 | }
34 |
35 | }
36 |
37 |
38 |
39 | /*
40 | //uint8_t *cookie = (uint8_t *) "Josh is a *very* nice, good guy."; // 32 bytes long (includes trailing null)
41 | //#define COOKIE_SIZE 32
42 |
43 | uint8_t cookie[] = {0b10110111}; // Non repeating bit pattern to detect errors.
44 | #define COOKIE_SIZE 1
45 |
46 | #define TX_PROBE_TIME_MS 250 // How often to do a blind send when no RX has happened recently to trigger ping pong
47 |
48 | #define MISSED_RX_SHOW_TIME_MS 500 // How long to show blue when a RX timeout happens
49 | #define RX_TIMEOUT_RX 200 // If we do not see a message in this long, then show a timeout
50 |
51 | // Note these all init to 0's, which is what we want.
52 |
53 | struct face_t {
54 |
55 | millis_t next_tx_ms; // Next time to transmit
56 | millis_t last_rx_ms; // Last time a good packet seen
57 |
58 | uint8_t errorFlag;
59 | };
60 |
61 | face_t faces[IR_FACE_COUNT];
62 |
63 | void loopEntry( loopstate_in_t const *loopstate_in , loopstate_out_t *loopstate_out) {
64 |
65 | millis_t now_ms = loopstate_in->millis;
66 |
67 | // Clear out any errors on button press
68 |
69 | if ( loopstate_in->buttonstate.bitflags & BUTTON_BITFLAG_PRESSED ) {
70 |
71 | for( uint8_t f=0; f< IR_FACE_COUNT; f++ ) {
72 |
73 | if ( faces[f].errorFlag ) {
74 |
75 | faces[f].errorFlag=0;
76 |
77 | }
78 |
79 | }
80 |
81 | }
82 |
83 |
84 | for( uint8_t f=0; f< IR_FACE_COUNT; f++ ){
85 |
86 | // Look for received packet....
87 |
88 | if ( loopstate_in->ir_data_buffers[f].ready_flag ) {
89 |
90 | if ( (loopstate_in->ir_data_buffers[f].len == COOKIE_SIZE ) && !memcmp( loopstate_in->ir_data_buffers[f].data , cookie , COOKIE_SIZE) ) {
91 |
92 | // Got a good packet!
93 |
94 | faces[f].last_rx_ms = now_ms;
95 |
96 | faces[f].next_tx_ms = now_ms; // pong
97 |
98 | } else {
99 |
100 | // Either len or cookie was wrong, so data transmission error
101 |
102 | faces[f].errorFlag = 1;
103 |
104 | }
105 |
106 | }
107 |
108 | // Update shown color
109 |
110 | if (faces[f].errorFlag) {
111 |
112 | // Red on error
113 | loopstate_out->colors[f] = pixelColor_t( 20 , 0, 0 , 1 );
114 |
115 | } else {
116 |
117 | millis_t elapsed_ms = now_ms - faces[f].last_rx_ms; // Elapsed time since last RX
118 |
119 | if (elapsed_ms < 200) {
120 |
121 | // Less than 200ms since last good RX, so show green
122 | loopstate_out->colors[f] = pixelColor_t( 0 , 20, 0 , 1 );
123 |
124 | } else if ( elapsed_ms < 500 ) {
125 |
126 | // More then 200ms since last good RX, so show red for 300ms
127 | loopstate_out->colors[f] = pixelColor_t( 0 , 0, 20 , 1 );
128 |
129 |
130 | } else {
131 |
132 | // Been long enough that we assume no one is there
133 | loopstate_out->colors[f] = pixelColor_t( 0 , 0, 0 , 1 );
134 |
135 | }
136 |
137 | }
138 |
139 |
140 | if ( faces[f].next_tx_ms < now_ms ) {
141 |
142 | // Time to send on this face
143 |
144 | if (ir_send_userdata( f , cookie , COOKIE_SIZE )) {
145 |
146 | // Schedule a blind send in case we don't see a ping soon
147 | faces[f].next_tx_ms = now_ms + TX_PROBE_TIME_MS;
148 | }
149 | } // for(f)
150 |
151 |
152 | }
153 |
154 | }
155 |
156 | */
--------------------------------------------------------------------------------
/AS7/blink/bareblinkOS/bareblinkOS/pixelcolor.h:
--------------------------------------------------------------------------------
1 | /*
2 | * pixel.h
3 | *
4 | * All the functions for showing colors on the 6 RGB LEDs on the tile face.
5 | * Also timekeeping functions since we use the same timer as for the LEDs.
6 | *
7 | */
8 |
9 | #ifndef RGB_PIXELCOLOR_H_
10 | #define RGB_PIXELCOLOR_H_
11 | // Each pixel has 32 brightness levels for each of the three colors (red,green,blue)
12 | // These brightness levels are normalized to be visually linear with 0=off and 31=max brightness
13 |
14 | // Note use of anonymous union members to let us switch between bitfield and int
15 | // https://stackoverflow.com/questions/2468708/converting-bit-field-to-int
16 |
17 | union pixelColor_t {
18 |
19 | struct {
20 | uint8_t reserved:1;
21 | uint8_t r:5;
22 | uint8_t g:5;
23 | uint8_t b:5;
24 | };
25 |
26 | uint16_t as_uint16;
27 |
28 | pixelColor_t();
29 | pixelColor_t(uint8_t r_in , uint8_t g_in, uint8_t b_in );
30 | pixelColor_t(uint8_t r_in , uint8_t g_in, uint8_t b_in , uint8_t reserverd_in );
31 |
32 | };
33 |
34 | inline pixelColor_t::pixelColor_t(uint8_t r_in , uint8_t g_in, uint8_t b_in ) {
35 |
36 | r=r_in;
37 | g=g_in;
38 | b=b_in;
39 |
40 | }
41 |
42 | inline pixelColor_t::pixelColor_t(uint8_t r_in , uint8_t g_in, uint8_t b_in , uint8_t reserverd_in ) {
43 |
44 | r=r_in;
45 | g=g_in;
46 | b=b_in;
47 | reserved = reserverd_in;
48 |
49 | }
50 |
51 |
52 | inline pixelColor_t::pixelColor_t() {
53 |
54 | r=0;
55 | g=0;
56 | b=0;
57 |
58 | }
59 |
60 |
61 | #endif /* RGB_PIXELS_H_ */
--------------------------------------------------------------------------------
/AS7/blink/blink.atsln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Atmel Studio Solution File, Format Version 11.00
4 | VisualStudioVersion = 14.0.23107.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{E66E83B9-2572-4076-B26E-6BE79FF3018A}") = "Blink", "Sketches\Blink\Blink.cppproj", "{C3728EB0-DD95-4D36-9694-C16A953BBF73}"
7 | EndProject
8 | Project("{E66E83B9-2572-4076-B26E-6BE79FF3018A}") = "blinklib", "..\blinklib\blinklib\blinklib.cppproj", "{1D617D28-32B2-45AB-BA7F-EE884B221598}"
9 | EndProject
10 | Project("{E66E83B9-2572-4076-B26E-6BE79FF3018A}") = "bareblinkOS", "bareblinkOS\bareblinkOS\bareblinkOS.cppproj", "{B750FA7B-22DE-43C4-A796-F95418271EDD}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|AVR = Debug|AVR
15 | Release|AVR = Release|AVR
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {C3728EB0-DD95-4D36-9694-C16A953BBF73}.Debug|AVR.ActiveCfg = Debug|AVR
19 | {C3728EB0-DD95-4D36-9694-C16A953BBF73}.Debug|AVR.Build.0 = Debug|AVR
20 | {C3728EB0-DD95-4D36-9694-C16A953BBF73}.Release|AVR.ActiveCfg = Release|AVR
21 | {C3728EB0-DD95-4D36-9694-C16A953BBF73}.Release|AVR.Build.0 = Release|AVR
22 | {1D617D28-32B2-45AB-BA7F-EE884B221598}.Debug|AVR.ActiveCfg = Debug|AVR
23 | {1D617D28-32B2-45AB-BA7F-EE884B221598}.Debug|AVR.Build.0 = Debug|AVR
24 | {1D617D28-32B2-45AB-BA7F-EE884B221598}.Release|AVR.ActiveCfg = Release|AVR
25 | {1D617D28-32B2-45AB-BA7F-EE884B221598}.Release|AVR.Build.0 = Release|AVR
26 | {B750FA7B-22DE-43C4-A796-F95418271EDD}.Debug|AVR.ActiveCfg = Debug|AVR
27 | {B750FA7B-22DE-43C4-A796-F95418271EDD}.Debug|AVR.Build.0 = Debug|AVR
28 | {B750FA7B-22DE-43C4-A796-F95418271EDD}.Release|AVR.ActiveCfg = Release|AVR
29 | {B750FA7B-22DE-43C4-A796-F95418271EDD}.Release|AVR.Build.0 = Release|AVR
30 | EndGlobalSection
31 | GlobalSection(SolutionProperties) = preSolution
32 | HideSolutionNode = FALSE
33 | EndGlobalSection
34 | EndGlobal
35 |
--------------------------------------------------------------------------------
/AS7/blink/blinkcore/blinkcore.componentinfo.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Device
8 | Startup
9 |
10 |
11 | Atmel
12 | 1.2.0
13 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs
14 |
15 |
16 |
17 |
18 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\include
19 |
20 | include
21 | C
22 |
23 |
24 | include
25 |
26 |
27 |
28 |
29 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\include\avr\iom168pb.h
30 |
31 | header
32 | C
33 | yAkfp/rOk1YuAUNFypsCqg==
34 |
35 | include/avr/iom168pb.h
36 |
37 |
38 |
39 |
40 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\templates\library.c
41 | template
42 | source
43 | C Lib
44 | 2/NZD/YM3hWVTzqme3bDXw==
45 |
46 | templates/library.c
47 | Main file (.c)
48 |
49 |
50 |
51 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\templates\library.cpp
52 | template
53 | source
54 | C Lib
55 | Ztu2zWWQnYWBswuEN+3iHQ==
56 |
57 | templates/library.cpp
58 | Main file (.cpp)
59 |
60 |
61 |
62 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega168pb
63 |
64 | libraryPrefix
65 | GCC
66 |
67 |
68 | gcc/dev/atmega168pb
69 |
70 |
71 |
72 |
73 | ATmega_DFP
74 | C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/ATmega_DFP/1.2.209/Atmel.ATmega_DFP.pdsc
75 | 1.2.209
76 | true
77 | ATmega168PB
78 |
79 |
80 |
81 | Resolved
82 | Fixed
83 | true
84 |
85 |
86 |
--------------------------------------------------------------------------------
/AS7/blink/blinklib/WMath.cpp:
--------------------------------------------------------------------------------
1 | /* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2 |
3 | /*
4 | Part of the Wiring project - http://wiring.org.co
5 | Copyright (c) 2004-06 Hernando Barragan
6 | Modified 13 August 2006, David A. Mellis for Arduino - http://www.arduino.cc/
7 |
8 | This library is free software; you can redistribute it and/or
9 | modify it under the terms of the GNU Lesser General Public
10 | License as published by the Free Software Foundation; either
11 | version 2.1 of the License, or (at your option) any later version.
12 | This library is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | Lesser General Public License for more details.
16 | You should have received a copy of the GNU Lesser General
17 | Public License along with this library; if not, write to the
18 | Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19 | Boston, MA 02111-1307 USA
20 |
21 | */
22 |
23 | extern "C" {
24 | #include "stdlib.h"
25 | }
26 |
27 | void randomSeed(unsigned long seed)
28 | {
29 | if (seed != 0) {
30 | srandom(seed);
31 | }
32 | }
33 |
34 | long random(long howbig)
35 | {
36 | if (howbig == 0) {
37 | return 0;
38 | }
39 | return random() % howbig;
40 | }
41 |
42 | long random(long howsmall, long howbig)
43 | {
44 | if (howsmall >= howbig) {
45 | return howsmall;
46 | }
47 | long diff = howbig - howsmall;
48 | return random(diff) + howsmall;
49 | }
50 |
51 | long map(long x, long in_min, long in_max, long out_min, long out_max)
52 | {
53 | return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
54 | }
55 |
56 | unsigned int makeWord(unsigned int w) { return w; }
57 | unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8) | l; }
--------------------------------------------------------------------------------
/AS7/blink/blinklib/blinkos.componentinfo.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Device
8 | Startup
9 |
10 |
11 | Atmel
12 | 1.2.0
13 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs
14 |
15 |
16 |
17 |
18 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\include
19 |
20 | include
21 | C
22 |
23 |
24 | include
25 |
26 |
27 |
28 |
29 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\include\avr\iom168pb.h
30 |
31 | header
32 | C
33 | yAkfp/rOk1YuAUNFypsCqg==
34 |
35 | include/avr/iom168pb.h
36 |
37 |
38 |
39 |
40 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\templates\library.c
41 | template
42 | source
43 | C Lib
44 | 2/NZD/YM3hWVTzqme3bDXw==
45 |
46 | templates/library.c
47 | Main file (.c)
48 |
49 |
50 |
51 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\templates\library.cpp
52 | template
53 | source
54 | C Lib
55 | Ztu2zWWQnYWBswuEN+3iHQ==
56 |
57 | templates/library.cpp
58 | Main file (.cpp)
59 |
60 |
61 |
62 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega168pb
63 |
64 | libraryPrefix
65 | GCC
66 |
67 |
68 | gcc/dev/atmega168pb
69 |
70 |
71 |
72 |
73 | ATmega_DFP
74 | C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/ATmega_DFP/1.2.209/Atmel.ATmega_DFP.pdsc
75 | 1.2.209
76 | true
77 | ATmega168PB
78 |
79 |
80 |
81 | Resolved
82 | Fixed
83 | true
84 |
85 |
86 |
--------------------------------------------------------------------------------
/AS7/blink/blinkstate/blinklib.componentinfo.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Device
8 | Startup
9 |
10 |
11 | Atmel
12 | 1.2.0
13 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs
14 |
15 |
16 |
17 |
18 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\include
19 |
20 | include
21 | C
22 |
23 |
24 | include
25 |
26 |
27 |
28 |
29 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\include\avr\iom168pb.h
30 |
31 | header
32 | C
33 | yAkfp/rOk1YuAUNFypsCqg==
34 |
35 | include/avr/iom168pb.h
36 |
37 |
38 |
39 |
40 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\templates\library.c
41 | template
42 | source
43 | C Lib
44 | 2/NZD/YM3hWVTzqme3bDXw==
45 |
46 | templates/library.c
47 | Main file (.c)
48 |
49 |
50 |
51 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\templates\library.cpp
52 | template
53 | source
54 | C Lib
55 | Ztu2zWWQnYWBswuEN+3iHQ==
56 |
57 | templates/library.cpp
58 | Main file (.cpp)
59 |
60 |
61 |
62 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega168pb
63 |
64 | libraryPrefix
65 | GCC
66 |
67 |
68 | gcc/dev/atmega168pb
69 |
70 |
71 |
72 |
73 | ATmega_DFP
74 | C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/ATmega_DFP/1.2.209/Atmel.ATmega_DFP.pdsc
75 | 1.2.209
76 | true
77 | ATmega168PB
78 |
79 |
80 |
81 | Resolved
82 | Fixed
83 | true
84 |
85 |
86 |
--------------------------------------------------------------------------------
/AS7/blink/blinkstate/blinklib.cppproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 2.0
5 | 7.0
6 | com.Atmel.AVRGCC8.CPP
7 | {c7103c5c-377a-4589-89b5-ee449b21a39a}
8 | ATmega168PB
9 | none
10 | StaticLibrary
11 | CPP
12 | lib$(MSBuildProjectName)
13 | .a
14 | $(MSBuildProjectDirectory)\$(Configuration)
15 |
16 |
17 | blinkstate
18 | blinklib
19 | blinkstate
20 | Native
21 | true
22 | false
23 | true
24 | true
25 |
26 |
27 | true
28 |
29 | 2
30 | 0
31 | 0
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | -mmcu=atmega168pb -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega168pb"
54 | True
55 | True
56 | True
57 | True
58 | False
59 | True
60 | True
61 |
62 |
63 | NDEBUG
64 |
65 |
66 |
67 |
68 | %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
69 |
70 |
71 | Optimize for size (-Os)
72 | True
73 | True
74 | True
75 | True
76 | True
77 |
78 |
79 | NDEBUG
80 |
81 |
82 |
83 |
84 | %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
85 |
86 |
87 | Optimize for size (-Os)
88 | True
89 | True
90 | True
91 |
92 |
93 | libm
94 |
95 |
96 |
97 |
98 | %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | -mmcu=atmega168pb -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega168pb"
108 | True
109 | True
110 | True
111 | True
112 | False
113 | True
114 | True
115 |
116 |
117 | DEBUG
118 |
119 |
120 |
121 |
122 | ../../../../variants/standard
123 | %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
124 |
125 |
126 | Optimize (-O1)
127 | True
128 | True
129 | Default (-g2)
130 | True
131 | True
132 | True
133 |
134 |
135 | DEBUG
136 |
137 |
138 |
139 |
140 | ../../../../libraries/blinklib/src
141 | ../../../../cores/blinkcore
142 | %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
143 |
144 |
145 | Optimize (-O1)
146 | True
147 | True
148 | Default (-g2)
149 | True
150 |
151 |
152 | libm
153 |
154 |
155 |
156 |
157 | %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
158 |
159 |
160 | Default (-Wa,-g)
161 |
162 |
163 |
164 |
165 |
--------------------------------------------------------------------------------
/AS7/blinklib/blinklib/blinklib.componentinfo.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Device
8 | Startup
9 |
10 |
11 | Atmel
12 | 1.2.0
13 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs
14 |
15 |
16 |
17 |
18 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\include
19 |
20 | include
21 | C
22 |
23 |
24 | include
25 |
26 |
27 |
28 |
29 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\include\avr\iom168pb.h
30 |
31 | header
32 | C
33 | yAkfp/rOk1YuAUNFypsCqg==
34 |
35 | include/avr/iom168pb.h
36 |
37 |
38 |
39 |
40 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\templates\library.c
41 | template
42 | source
43 | C Lib
44 | 2/NZD/YM3hWVTzqme3bDXw==
45 |
46 | templates/library.c
47 | Main file (.c)
48 |
49 |
50 |
51 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\templates\library.cpp
52 | template
53 | source
54 | C Lib
55 | XxwIOzelgjmEqvoplf+/zA==
56 |
57 | templates/library.cpp
58 | Main file (.cpp)
59 |
60 |
61 |
62 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega168pb
63 |
64 | libraryPrefix
65 | GCC
66 |
67 |
68 | gcc/dev/atmega168pb
69 |
70 |
71 |
72 |
73 | ATmega_DFP
74 | C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/ATmega_DFP/1.2.209/Atmel.ATmega_DFP.pdsc
75 | 1.2.209
76 | true
77 | ATmega168PB
78 |
79 |
80 |
81 | Resolved
82 | Fixed
83 | true
84 |
85 |
86 |
--------------------------------------------------------------------------------
/AS7/blinkos/blinkos/blinkos.componentinfo.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Device
8 | Startup
9 |
10 |
11 | Atmel
12 | 1.2.0
13 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs
14 |
15 |
16 |
17 |
18 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\include
19 |
20 | include
21 | C
22 |
23 |
24 | include
25 |
26 |
27 |
28 |
29 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\include\avr\iom168pb.h
30 |
31 | header
32 | C
33 | yAkfp/rOk1YuAUNFypsCqg==
34 |
35 | include/avr/iom168pb.h
36 |
37 |
38 |
39 |
40 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\templates\library.c
41 | template
42 | source
43 | C Lib
44 | 2/NZD/YM3hWVTzqme3bDXw==
45 |
46 | templates/library.c
47 | Main file (.c)
48 |
49 |
50 |
51 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\templates\library.cpp
52 | template
53 | source
54 | C Lib
55 | k0XODgvtMPZr5NdihYUf6A==
56 |
57 | templates/library.cpp
58 | Main file (.cpp)
59 |
60 |
61 |
62 | C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega168pb
63 |
64 | libraryPrefix
65 | GCC
66 |
67 |
68 | gcc/dev/atmega168pb
69 |
70 |
71 |
72 |
73 | ATmega_DFP
74 | C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/ATmega_DFP/1.2.209/Atmel.ATmega_DFP.pdsc
75 | 1.2.209
76 | true
77 | ATmega168PB
78 |
79 |
80 |
81 | Resolved
82 | Fixed
83 | true
84 |
85 |
86 |
--------------------------------------------------------------------------------
/Getting-started.md:
--------------------------------------------------------------------------------
1 |
2 | ## Getting Started
3 |
4 | This core requires at least Arduino IDE v1.6.2, where v1.6.5+ is recommended.
5 | * [Programmers](#programmers)
6 | * **[How to install](#how-to-install)**
7 | - [Boards Manager Installation](#boards-manager-installation)
8 | - [Manual Installation](#manual-installation)
9 | * **[Getting started](#getting-started)**
10 |
11 | * **[Digging deeper](#digging-deeper)**
12 | - [Hardware Abstraction Layer](#hardware-abstraction-layer)
13 |
14 | ## Programmers
15 |
16 | Since there is no bootloader in a tile, all code must be programmed rather than downloaded.
17 |
18 | Each Blink has a standard 6-pin ISP connector. The arrow marks pin #1.
19 |
20 | You can use any AVR programmer supported by AVRDUDE and the Arduino IDE.
21 |
22 | This one is cheap...
23 | http://amzn.to/2u5ZHw6
24 |
25 | This one is fast and comes with nice cables...
26 | http://amzn.to/2u5Wo7M
27 |
28 | Just connect your programmer and select it in the "Programmers" menu, and connect the 6-pin ISP to the tile. I like to use this pogo pin fixture to make the connections...
29 |
30 | https://www.sparkfun.com/products/11591
31 |
32 | ...but you can also just hold a 6-pin header onto the tile, or solder on a 6-pin header if you want to leave the programmer attached.
33 |
34 | If you do not have a programmer, you can also use an Arduino and a couple of wires.
35 |
36 | You can then use the "Sketch-Upload to Programmer" menu choice or just press the Play button to compile your code and program it into the connected tile. (Both the menu option and the button do the same thing with a tile.)
37 |
38 | ## How to install
39 | Click on the "Download ZIP" button in the upper right corner of this repo on Github...
40 |
41 | https://github.com/bigjosh/Move38-Arduino-Platform
42 |
43 | You can switch to the `dev` branch if you want to live on the bleeding edge and get new features quickly.
44 |
45 | Extract the ZIP file, and move the extracted files to the location "**~/Documents/Arduino/hardware/Move38-manual/avr**". Create the folder if it doesn't exist. This readme file should be located at "**~/Documents/Arduino/hardware/Move38-manual/avr/README.md**" when you are done.
46 |
47 | Open Arduino IDE, and a new category in the boards menu called "Move38-manual" will show up.
48 |
49 | ##### Notes
50 |
51 | * We called the "vendor/maintainer" folder `Move38-manual` so that you can also use the boards manager and you will be able to tell the two apart in the boards menu.
52 |
53 | * You must manually create the `avr` folder and you must also manually move the files out from this repo into this folder. We could not automatically have the folds inside the repo match the Arduino required folder layout because in in the boards manager, the architecture is in the JSON file rather than the folder structure. Arg.
54 |
55 | * The "**~/Documents/Arduino/hardware/Move38-manual/avr**" folder is a Git repo and is also set up for easy editing in Atmel Studio with a solution inside the `\AS7` sub-folder.
56 |
57 | * If you want to leave the git repo in a directory that is not inside the Arduino tree (I do), then you can add a directory symlink from the Arduino tree to the repo tree. This repo needs to be at `arduino\hardware\move38\avr` where `arduino` is your Arduino home directory as set in `File->Preferences->Sketchbook Location` in the IDE. You have to manually create `hardware` and then `move38` and then put the `avr` symlink in then. On my windows machine the command for that was `D:\Documents\Arduino\hardware\move38\avr>mklink /D avr "D:\Github\Move38-Arduino-Platform"`
58 |
59 | ## Helllo Blink!
60 |
61 | * Open the **Tools > Board** menu item, and select `Blink` from the `Move38` submenu.
62 | * Select what kind of programmer you're using under the **Programmers** menu.
63 | * Select "File->Examples->Examples for Blink->Getting Started" and choose "F-ColorWheel".
64 | * Hit the Play button.
65 |
66 | The IDE should compile the code and program the Blinks tile... and you should see pretty blinking lights!
67 |
--------------------------------------------------------------------------------
/Layers.md:
--------------------------------------------------------------------------------
1 | ## Layers
2 |
3 | ### 1. Cold power up
4 |
5 | This typically only happens when a new battery is installed or when the foreground software locks up.
6 |
7 | The chip resets all the ports according to the the datasheet and then jumps to the reset vector, which typically points to the GCC bootstrap code. This code initializes global variables and does a bit of hardware setup.
8 |
9 | Here is an example on how to run code before the bootstrap (very esoteric)...
10 |
11 | https://github.com/bigjosh/Ognite-firmware/blob/master/Atmel%20Studio/Candle0005.c#L440
12 |
13 | ### 2. main()
14 |
15 | After all the C setup is complete, the bootstrap jumps to the `main()` function. This function is in `cores/blinkcore/main.c`
16 |
17 | Here we...
18 |
19 | 1. Initialize the binks hardware systems and turn them on.
20 | 2. Jump to the `run()` function.
21 | 3. Re-run `run()` forever if it returns.
22 |
23 | The blinks `main()` function is weakly defined, so you can make your own if you want to take over before the blinks hardware gets started up.
24 |
25 | ### 3. run()
26 |
27 | Once all the hardware is up and running, then `run()` function takes over. This code lives in `libraries\blinklib\src\blinklib.cpp`.
28 |
29 | Here we...
30 |
31 | 1. Call the user-supplied `setup()` function.
32 | 2. Repeatedly...
33 | a. Clears the cached `millis()` snapshot
34 | b. Calls the user-suppled `loop()` function
35 | c. Atomically updates the values shown on the LEDs to match any changes made in `loop()`
36 | d. Processes new IR data that has been recieved, and potentially sends IR data.
37 |
38 |
39 | Then `run()` function is weakly defined, so you can override it if you want more control over these.
40 |
41 | ### 4. `setup()` and `loop()`
42 |
43 | These are the idiomatic entry points provided by Arduino sketches.
44 |
45 | `setup()` is called once, typically right after a tile has had a battery change.
46 |
47 | `loop()` is called at the current frame rate, which is currently about 18 times per second. You `loop()` function should complete before the next frame starts, so should not have any blocking code in it. The tile sleeps for the time between when `loop()` returns and the next frame, so the faster you can complete your work and return from loop, the longer batteries will last.
48 |
49 |
50 |
--------------------------------------------------------------------------------
/Production.MD:
--------------------------------------------------------------------------------
1 | ## Production Programming
2 |
3 | Each virgin blink needs to be programmed with...
4 |
5 | 1. The correct FUSE settings
6 | 2. The BIOS code that lives in the flash bootloader area
7 | 3. The application code that lives in the application flash area.
8 |
9 | ### Fuses
10 |
11 | BOOTSZ = 1024W_1C00
12 | BOOTRST = [X]
13 | RSTDISBL = [ ]
14 | DWEN = [ ]
15 | SPIEN = [X]
16 | WDTON = [ ]
17 | EESAVE = [ ]
18 | BODLEVEL = DISABLED
19 | CKDIV8 = [X]
20 | CKOUT = [ ]
21 | SUT_CKSEL = INTRCOSC_8MHZ_6CK_14CK_65MS
22 |
23 | EXTENDED = 0xF8 (valid)
24 | HIGH = 0xDF (valid)
25 | LOW = 0x62 (valid)
26 |
27 | Note that the `high` and `low` fuses are the same as their default values from the factory, but the `extended` fuse must be reprogrammed from the default value.
28 |
29 | ### Bootloader
30 |
31 | The bootloader code comes from a different repo and can be found in the [`bootloaders`](/bootloaders) directory here.
32 |
33 | ### Application
34 |
35 | The application code is generated by compiling a sketch in the Arduino IDE.
36 |
37 | ## Combining the bootloader and application
38 |
39 | You can minimize the number of production programming steps by combining the application code and bootloader into a single HEX file using the `Sketch->Export Compiled Binary` option from the IDE menus. This will create a file called `SKETCHNAME.ino.with_bootloader.standard.hex` in the current sketch folder that contains both the application and the bootloader.
40 |
41 | ### Example
42 |
43 | Here is and example command that will program a blink using the `AVRDUDE` utility and the `USBtiny` programmer...
44 |
45 | ```
46 | avrdude -B 5 -v -patmega168pb -cusbtiny -Uflash:w:SKETCHNAME.ino.with_bootloader.standard.hex:i -Uefuse:w:0xf8:m -u
47 | ```
48 |
49 | `-B` sets the clock programming speed. This must be less than 1/4 of the chip clock speed, which is 1Mhz by default, but here we make it slightly slower to account for chips that might have an extra slow internal clock.
50 | `-v` verifies the programming when complete
51 | `-p` specifies the chip model
52 | `-Uflash` specifies the file to program into flash memory (both bootloader and application in this case)
53 | `-Uefuse` specifies the new value for the extended fuse (note that the high and low fuses are left with their default values)
54 | `-u` disables AVRDUDE's normal behavior that blocks changing fuses.
55 |
56 | Note that this assumes that `avrdude` is in your search path and that it can find its config file. See `avrdude` docs for details.
57 |
58 | ### Optimizing
59 |
60 | We can slightly reduce cycle using a command like this...
61 |
62 | ```
63 | avrdude -B 4 -D -v -patmega168pb -cusbtiny -Uflash:w:D-TimerFlashX.ino.with_bootloader.standard.hex:i -Uefuse:w:0xf8:m -u
64 | ```
65 |
66 | `-D` skips erasing the flash before programming it. If you are programming virgin chips then the flash should be blank.
67 | `-B` lowered to 4 slightly increases the programmer clock. Some out of spec chips might fall to program at this speed.
68 |
69 | Note that these new options are both safe because the verify will fail if anything goes wrong.
70 |
71 | ### QA
72 |
73 | Some programming errors may pass functional testing, but still contain latent errors, so you must check that the programming cycle verified successfully before passing a programmed unit.
74 |
75 | You can use the error code returned by AVRDUDE to check if the verify succeeded.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Move38 Blinks for the Arduino IDE
2 | An Arduino core for the Blinks gaming tile. More info at...
3 | http://move38.com
4 |
5 | ## Roadmap
6 |
7 | This core requires at least Arduino IDE v1.6.2, where v1.6.5+ is recommended.
8 | * [Programmers](#programmers)
9 | * **[How to install](#how-to-install)**
10 | * **[Getting started](#getting-started)**
11 |
12 | Covers installing this repo so that you can write and download code into a Blinks tile using the Arduino IDE.
13 |
14 | Ends with loading a `HelloBlink` program it a tile.
15 |
16 | ### Writing games
17 |
18 | The best way to start writing games is to work your way though the examples in the "File->Examples->Examples for Blink Tile" menu in the Arduino IDE (after you have installed this repo as described in the Getting Started above).
19 |
20 |
21 | ### [Service Port](Service Port.MD)
22 |
23 | Describes the service port connector on each blink. Lets you add `print` statements to your programs, which can be very helpful during development.
24 |
25 | ## How to install
26 |
27 | Click on the "Download ZIP" button in the upper right corner of this repo. Extract the ZIP file, and move the extracted files to the location "**~/Documents/Arduino/hardware/Move38-manual/avr**". Create the folder if it doesn't exist. This readme file should be located at "**~/Documents/Arduino/hardware/Move38-manual/avr/README.md**" when you are done.
28 |
29 | Open Arduino IDE, and a new category in the boards menu called "Move38-manual" will show up.
30 |
31 | In the future, we'll offer a simplified Arduino Boards Manager install path.
32 |
33 | ### Notes
34 |
35 | * We called the "vendor/maintainer" folder `Move38-manual` so that you can also use the boards manager and you will be able to tell the two apart in the boards menu.
36 |
37 | * You must manually create the `avr` folder and you must also manually move the files out from this repo into this folder. We could not automatically have the folds inside the repo match the Arduino required folder layout because in in the boards manager, the architecture is in the JSON file rather than the folder structure. Arg.
38 |
39 | * The "**~/Documents/Arduino/hardware/Move38-manual/avr**" folder is a Git repo and is also set up for easy editing in Atmel Studio with a solution inside the `\AS7` sub-folder.
40 |
41 | ### API Layers
42 |
43 | The blinks hardware can do incredible things, and you can have unfettered access to it at any level you want. This documents describes those layers from bare metal up.
44 |
45 |
46 |
47 | #### Hardware Abstraction Layer
48 |
49 | Most programmers will want to use the high level `blinks` API, but if you want to get closer to the hardware you can directly call into the `HAL` (Hardware Abstraction Layer) that the `blinks` API is built on top of. Documentation for this layer is in the [README.md](cores/blinkcore/README.md) in the `cores/blinkscore` folder.
50 |
--------------------------------------------------------------------------------
/Service Port.MD:
--------------------------------------------------------------------------------
1 |
2 | > *"The most effective debugging tool is still careful thought, coupled with judiciously placed print statements."*
3 |
4 | -Brian Kernighan, "Unix for Beginners" (1979)
5 |
6 |
7 | #### Service Port
8 |
9 | Each Blink tile has a service port to make developing and debugging easier. For example:
10 |
11 | * See print statements
12 | * Accept type in values and commands
13 | * Output precise timing signals to an oscilloscope
14 |
15 |
16 | ### Seeing output
17 |
18 | When writing normal game code, you can use the the service port as a serial connection to the host computer.
19 |
20 | #### Connection
21 |
22 | Get yourself a Blinks Dev Candy board, which converts the service port connector into a 6-pin header that connects to a USB serial converter like this...
23 |
24 | http://amzn.to/2ptPUv5
25 |
26 | #### Use
27 |
28 | * Connect the USB serial port adapter to the computer
29 | * Open Arduino IDE
30 | * Pick the correct serial port from `Tools->Port`
31 | * Open the monitor with "Tools->Serial Port Monitor"
32 | * Pick `1000000 baud`. (Yes, it is that fast! :) )
33 |
34 | You will now see anything that the tile prints out.
35 |
36 | You can also use any other serial monitor program with the same port and baud settings.
37 |
38 | #### Instrumentation
39 |
40 | The easiest way to get prints out the serial port is to use the `ServicePortSerial` class like this...
41 |
42 | ~~~
43 | /*
44 | * Prints a welcoming message to the servie port.
45 | *
46 | * To see the message, connect a serial terminal to the Blinks service port.
47 | * More info on how to do that here...
48 | * https://github.com/bigjosh/Move38-Arduino-Platform/blob/master/Service%20Port.MD
49 | */
50 |
51 | #include "Serial.h"
52 |
53 | ServicePortSerial Serial;
54 |
55 | void setup() {
56 |
57 | Serial.begin();
58 |
59 | }
60 |
61 |
62 | void loop() {
63 |
64 | Serial.println("Hello Serial port!");
65 |
66 | };
67 | ~~~
68 |
69 | #### Input
70 |
71 | The Serial class also has several read functions that let you input data from the serial terminal. Check out the Tile World example to see one way to do this.
72 |
73 | Note that that by default Arduino serial monitor does not send what you type until you press enter.
--------------------------------------------------------------------------------
/Tools.md:
--------------------------------------------------------------------------------
1 | # Tools
2 | ## Programmers
3 | - Pocket AVR Programmer - [$14.95 on Sparkfun](https://www.sparkfun.com/products/9825)
4 | - ISP Pogo Adapter - [$9.95 on Sparkfun](https://www.sparkfun.com/products/11591)
5 | - ISP Pogo Adapter - [$6.50 on Tindie](https://www.tindie.com/products/madworm/tiny-avr-isp-pogo-pin-programming-adapter/)
6 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-minimal
--------------------------------------------------------------------------------
/boards.txt:
--------------------------------------------------------------------------------
1 | # See: http://code.google.com/p/arduino/wiki/Platforms
2 |
3 | menu.cpu=Processor
4 |
5 | ##############################################################
6 |
7 | blink.name=Blink
8 |
9 | blink.vid.0=0x2341
10 | blink.pid.0=0x0043
11 | blink.vid.1=0x2341
12 | blink.pid.1=0x0001
13 | blink.vid.2=0x2A03
14 | blink.pid.2=0x0043
15 | blink.vid.3=0x2341
16 | blink.pid.3=0x0243
17 |
18 | blink.upload.tool=avrdude
19 | blink.upload.protocol=arduino
20 |
21 | # This is the maximum size of a program image. It comes from
22 | # `blinkbios.h` and is the result of `FLASH_PAGES_PER_IMAGE` * `FLASH_BYTES_PER_PAGE`
23 | # Used only for printing the "Sketch uses... of program stroage space..." message.
24 | blink.upload.maximum_size=5888
25 | blink.upload.maximum_data_size=1024
26 | blink.upload.speed=115200
27 |
28 | #blink.bootloader.tool=avrdude
29 | #blink.bootloader.low_fuses=0xFF
30 | #blink.bootloader.high_fuses=0xDE
31 | #blink.bootloader.extended_fuses=0xFD
32 | #blink.bootloader.unlock_bits=0x3F
33 | #blink.bootloader.lock_bits=0x0F
34 |
35 | # Note that the folder `bootloaders` seems to be hardcoded into the Ardunio IDE
36 |
37 | blink.bootloader.file=BlinkBIOS.hex
38 |
39 | blink.build.mcu=atmega168pb
40 | blink.build.f_cpu=8000000L
41 | blink.build.board=AVR_BLINK
42 | blink.build.core=blinklib
43 | blink.build.variant=standard
44 |
45 | ##############################################################
46 |
47 |
--------------------------------------------------------------------------------
/bootloaders/readme.MD:
--------------------------------------------------------------------------------
1 | This folder contains the BlinkBIOS bootloader HEX file. This file is created by the BlinkBIOS repo...
2 |
3 | https://github.com/bigjosh/Move38-BlinkBIOS
4 |
5 | ..and then copied here after each compile by an Atmel Studio post-build event. Note that the this bootloader directory is hardcoded into the text of that event.
6 |
7 | This file is used by...
8 |
9 | 1. The `upload` and `program` recipes to download a new sketch to a blink. Note that we could make upload only update the actual program and not the BIOS for faster turnaround during development, but I do not want to change this behavior now. The path to the bootloader is hardcoded into the recipes but is relative to the platform folder.
10 | 2. The `Export Binary` function which creates a single HEX file with both the current sketch and the BIOS. In this case, the folder name must be `bootloader` as this is hardcoded into the IDE.
11 |
12 |
13 |
--------------------------------------------------------------------------------
/cores/blinklib/Arduino.h:
--------------------------------------------------------------------------------
1 | // Reworked for Blinks platform.
2 | // Really should be renamed Blinks.h, but Arduino.h seems to be hardcoded lots of places.
3 |
4 | /*
5 | Arduino.h - Main include file for the Arduino SDK
6 | Copyright (c) 2005-2013 Arduino Team. All right reserved.
7 |
8 | This library is free software; you can redistribute it and/or
9 | modify it under the terms of the GNU Lesser General Public
10 | License as published by the Free Software Foundation; either
11 | version 2.1 of the License, or (at your option) any later version.
12 |
13 | This library is distributed in the hope that it will be useful,
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public
19 | License along with this library; if not, write to the Free Software
20 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 | */
22 |
23 |
24 | #ifndef Arduino_h
25 |
26 | #define Arduino_h
27 |
28 | #include
29 | #include
30 | #include
31 |
32 | #include "ArduinoTypes.h"
33 |
34 | #define HIGH 0x1
35 | #define LOW 0x0
36 |
37 | #define PI 3.1415926535897932384626433832795
38 | #define HALF_PI 1.5707963267948966192313216916398
39 | #define TWO_PI 6.283185307179586476925286766559
40 | #define DEG_TO_RAD 0.017453292519943295769236907684886
41 | #define RAD_TO_DEG 57.295779513082320876798154814105
42 | #define EULER 2.718281828459045235360287471352
43 |
44 |
45 | #define LSBFIRST 0
46 | #define MSBFIRST 1
47 |
48 | // undefine stdlib's abs if encountered
49 | #ifdef abs
50 | #undef abs
51 | #endif
52 |
53 | #define min(a,b) ((a)<(b)?(a):(b))
54 | #define max(a,b) ((a)>(b)?(a):(b))
55 | #define abs(x) ((x)>0?(x):-(x))
56 | #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
57 | #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
58 | #define radians(deg) ((deg)*DEG_TO_RAD)
59 | #define degrees(rad) ((rad)*RAD_TO_DEG)
60 | #define sq(x) ((x)*(x))
61 |
62 | #define lowByte(w) ((uint8_t) ((w) & 0xff))
63 | #define highByte(w) ((uint8_t) ((w) >> 8))
64 |
65 | #define bitRead(value, bit) (((value) >> (bit)) & 0x01)
66 | #define bitSet(value, bit) ((value) |= (1UL << (bit)))
67 | #define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
68 | #define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
69 |
70 | #define bit(b) (1UL << (b))
71 |
72 | // Don't judge me
73 | // I know this is so ugly, but only other way to make it so people do not need to do a
74 | // manual #include in their sketches would be to throw all the library code into one giant
75 | // directory... and that is even uglier, right?
76 |
77 | #include "blinklib.h"
78 |
79 | #endif
80 |
--------------------------------------------------------------------------------
/cores/blinklib/ArduinoTypes.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Some types used in idiomatic Arduino code and Arduino compatible function signatures.
4 | We break them out into thier own header so we can implement against them without having to
5 | include the toxic Arduino.h itself.
6 |
7 | */
8 |
9 |
10 | #ifndef ArduinoTypes_h
11 |
12 | #define ArduinoTypes_h
13 |
14 |
15 | #include
16 | typedef bool boolean;
17 | typedef uint8_t byte;
18 | typedef unsigned int word;
19 |
20 | typedef uint32_t ulong;
21 |
22 | #endif
--------------------------------------------------------------------------------
/cores/blinklib/DummySerial.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | A very simplified serial port built to look like Arduino's Serial class.
4 |
5 | This serial port lives on the service port on new boards. It is really intended for debugging.
6 |
7 | The port always runs at a fixed 1M baud. Dev Candy Adapter boards and cables are available to
8 | connect to a USB port and then use the Arduino IDE's serial monitor to interact with your tile.
9 |
10 | */
11 |
12 | #include
13 |
14 | #include "ArduinoTypes.h"
15 |
16 | #ifndef Serial_h
17 |
18 | #define Serial_h
19 |
20 | #include "Print.h"
21 |
22 | class ServicePortSerial : public Print
23 | {
24 |
25 | public:
26 |
27 | //inline ServicePortSerialSerial(void);
28 | void begin(void);
29 | void end();
30 |
31 | virtual int available(void);
32 |
33 | // Input buffer is only 1 byte so if an interrupts happens while data is streaming, you will loose any incoming data.
34 | // Best to limit yourself interactions with plenty of time (or an ACK) between each incoming byte.
35 |
36 | virtual int read(void); // Read a byte - returns byte read or -1 if no byte ready.
37 | virtual uint8_t readWait(void); // Blocking read (faster)
38 |
39 | virtual size_t write(uint8_t);
40 | void flush(void); // Block until all pending transmits complete
41 |
42 | using Print::write; // pull in write(str) and write(buf, size) from Print
43 |
44 |
45 | };
46 |
47 | #endif
48 |
49 |
50 |
51 | // Public Methods //////////////////////////////////////////////////////////////
52 |
53 | void ServicePortSerial::begin(void)
54 | {
55 | }
56 |
57 | void ServicePortSerial::end()
58 | {
59 | }
60 |
61 | // We only use the 1 byte hardware buffer
62 |
63 | inline int ServicePortSerial::available(void) {
64 | return(0);
65 | }
66 |
67 | inline int ServicePortSerial::read(void)
68 | {
69 | return -1;
70 | }
71 |
72 | inline byte ServicePortSerial::readWait(void)
73 | {
74 | return 0;
75 | }
76 |
77 | // We don't implement flush because it would require adding a flag to remember if we ever sent.
78 | // This is because the hardware only gives us a bit that tells us when a tx completes, not if
79 | // no TX was ever started. Ardunio does this with the `_writen` flag.
80 | // If you can convince me that we really need flush, LMK and it can be added.
81 |
82 | inline size_t ServicePortSerial::write(uint8_t c)
83 | {
84 |
85 | return(1);
86 |
87 | }
88 |
89 | // Block until all pending transmits complete
90 |
91 | void ServicePortSerial::flush(void)
92 | {
93 | }
--------------------------------------------------------------------------------
/cores/blinklib/Print.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | This is a slimed down version of the Arduino Print class for the tiles platform.
4 | Implements most cases except WStrings and Printables
5 |
6 |
7 | Original header:
8 |
9 | Print.cpp - Base class that provides print() and println()
10 | Copyright (c) 2008 David A. Mellis. All right reserved.
11 |
12 | This library is free software; you can redistribute it and/or
13 | modify it under the terms of the GNU Lesser General Public
14 | License as published by the Free Software Foundation; either
15 | version 2.1 of the License, or (at your option) any later version.
16 |
17 | This library is distributed in the hope that it will be useful,
18 | but WITHOUT ANY WARRANTY; without even the implied warranty of
19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 | Lesser General Public License for more details.
21 |
22 | You should have received a copy of the GNU Lesser General Public
23 | License along with this library; if not, write to the Free Software
24 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 |
26 | Modified 23 November 2006 by David A. Mellis
27 | Modified 03 August 2015 by Chuck Todd
28 | */
29 |
30 | #include
31 | #include
32 | #include
33 |
34 | #include "Print.h"
35 |
36 | // Public Methods //////////////////////////////////////////////////////////////
37 |
38 | /* default implementation: may be overridden */
39 | size_t Print::write(const uint8_t *buffer, size_t size)
40 | {
41 | size_t n = 0;
42 | while (size--) {
43 | if (write(*buffer++)) n++;
44 | else break;
45 | }
46 | return n;
47 | }
48 |
49 | size_t Print::print(const __FlashStringHelper *ifsh)
50 | {
51 | PGM_P p = reinterpret_cast(ifsh);
52 | size_t n = 0;
53 | while (1) {
54 | unsigned char c = pgm_read_byte(p++);
55 | if (c == 0) break;
56 | if (write(c)) n++;
57 | else break;
58 | }
59 | return n;
60 | }
61 |
62 |
63 | size_t Print::print(const char str[])
64 | {
65 | return write(str);
66 | }
67 |
68 | size_t Print::print(char c)
69 | {
70 | return write(c);
71 | }
72 |
73 | size_t Print::print(unsigned char b, int base)
74 | {
75 | return print((unsigned long) b, base);
76 | }
77 |
78 | size_t Print::print(int n, int base)
79 | {
80 | return print((long) n, base);
81 | }
82 |
83 | size_t Print::print(unsigned int n, int base)
84 | {
85 | return print((unsigned long) n, base);
86 | }
87 |
88 | size_t Print::print(long n, int base)
89 | {
90 | if (base == 0) {
91 | return write(n);
92 | } else if (base == 10) {
93 | if (n < 0) {
94 | int t = print('-');
95 | n = -n;
96 | return printNumber(n, 10) + t;
97 | }
98 | return printNumber(n, 10);
99 | } else {
100 | return printNumber(n, base);
101 | }
102 | }
103 |
104 | size_t Print::print(unsigned long n, int base)
105 | {
106 | if (base == 0) return write(n);
107 | else return printNumber(n, base);
108 | }
109 |
110 | size_t Print::print(double n, int digits)
111 | {
112 | return printFloat(n, digits);
113 | }
114 |
115 | size_t Print::println(const __FlashStringHelper *ifsh)
116 | {
117 | size_t n = print(ifsh);
118 | n += println();
119 | return n;
120 | }
121 |
122 |
123 | size_t Print::println(void)
124 | {
125 | return write("\r\n");
126 | }
127 |
128 |
129 | size_t Print::println(const char c[])
130 | {
131 | size_t n = print(c);
132 | n += println();
133 | return n;
134 | }
135 |
136 | size_t Print::println(char c)
137 | {
138 | size_t n = print(c);
139 | n += println();
140 | return n;
141 | }
142 |
143 | size_t Print::println(unsigned char b, int base)
144 | {
145 | size_t n = print(b, base);
146 | n += println();
147 | return n;
148 | }
149 |
150 | size_t Print::println(int num, int base)
151 | {
152 | size_t n = print(num, base);
153 | n += println();
154 | return n;
155 | }
156 |
157 | size_t Print::println(unsigned int num, int base)
158 | {
159 | size_t n = print(num, base);
160 | n += println();
161 | return n;
162 | }
163 |
164 | size_t Print::println(long num, int base)
165 | {
166 | size_t n = print(num, base);
167 | n += println();
168 | return n;
169 | }
170 |
171 | size_t Print::println(unsigned long num, int base)
172 | {
173 | size_t n = print(num, base);
174 | n += println();
175 | return n;
176 | }
177 |
178 | size_t Print::println(double num, int digits)
179 | {
180 | size_t n = print(num, digits);
181 | n += println();
182 | return n;
183 | }
184 |
185 | // Private Methods /////////////////////////////////////////////////////////////
186 |
187 | size_t Print::printNumber(unsigned long n, uint8_t base)
188 | {
189 | char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
190 | char *str = &buf[sizeof(buf) - 1];
191 |
192 | *str = '\0';
193 |
194 | // prevent crash if called with base == 1
195 | if (base < 2) base = 10;
196 |
197 | do {
198 | char c = n % base;
199 | n /= base;
200 |
201 | *--str = c < 10 ? c + '0' : c + 'A' - 10;
202 | } while(n);
203 |
204 | return write(str);
205 | }
206 |
207 | size_t Print::printFloat(double number, uint8_t digits)
208 | {
209 | size_t n = 0;
210 |
211 | if (isnan(number)) return print("nan");
212 | if (isinf(number)) return print("inf");
213 | if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
214 | if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
215 |
216 | // Handle negative numbers
217 | if (number < 0.0)
218 | {
219 | n += print('-');
220 | number = -number;
221 | }
222 |
223 | // Round correctly so that print(1.999, 2) prints as "2.00"
224 | double rounding = 0.5;
225 | for (uint8_t i=0; i 0) {
237 | n += print('.');
238 | }
239 |
240 | // Extract digits from the remainder one at a time
241 | while (digits-- > 0)
242 | {
243 | remainder *= 10.0;
244 | unsigned int toPrint = (unsigned int)(remainder);
245 | n += print(toPrint);
246 | remainder -= toPrint;
247 | }
248 |
249 | return n;
250 | }
--------------------------------------------------------------------------------
/cores/blinklib/Print.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | This is a slimed down version of the Arduino Print class for the tiles platform.
4 | Implements most cases except WStrings and Printables
5 |
6 |
7 | Original header:
8 |
9 | Print.h - Base class that provides print() and println()
10 | Copyright (c) 2008 David A. Mellis. All right reserved.
11 |
12 | This library is free software; you can redistribute it and/or
13 | modify it under the terms of the GNU Lesser General Public
14 | License as published by the Free Software Foundation; either
15 | version 2.1 of the License, or (at your option) any later version.
16 |
17 | This library is distributed in the hope that it will be useful,
18 | but WITHOUT ANY WARRANTY; without even the implied warranty of
19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 | Lesser General Public License for more details.
21 |
22 | You should have received a copy of the GNU Lesser General Public
23 | License along with this library; if not, write to the Free Software
24 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 | */
26 |
27 | #ifndef Print_h
28 | #define Print_h
29 |
30 |
31 | #include // for size_t
32 | #include
33 |
34 | // This lets us use strings stored directly in flash define like `F("this is not copied to RAM")`
35 |
36 | #include
37 |
38 | // an abstract class used as a means to proide a unique pointer type
39 | // but really has no body
40 |
41 | class __FlashStringHelper;
42 | #define FPSTR(pstr_pointer) (reinterpret_cast(pstr_pointer))
43 | #define F(string_literal) (FPSTR(PSTR(string_literal)))
44 |
45 | #define DEC 10
46 | #define HEX 16
47 | #define OCT 8
48 | #ifdef BIN // Prevent warnings if BIN is previously defined in "iotnx4.h" or similar
49 | #undef BIN
50 | #endif
51 | #define BIN 2
52 |
53 | class Print
54 | {
55 | private:
56 | size_t printNumber(unsigned long, uint8_t);
57 | size_t printFloat(double, uint8_t);
58 | public:
59 | virtual size_t write(uint8_t) = 0;
60 | size_t write(const char *str) {
61 | if (str == NULL) return 0;
62 | return write((const uint8_t *)str, strlen(str));
63 | }
64 | virtual size_t write(const uint8_t *buffer, size_t size);
65 | size_t write(const char *buffer, size_t size) {
66 | return write((const uint8_t *)buffer, size);
67 | }
68 |
69 | // default to zero, meaning "a single write may block"
70 | // should be overriden by subclasses with buffering
71 |
72 | size_t print(const __FlashStringHelper *);
73 | size_t print(const char[]);
74 | size_t print(char);
75 | size_t print(unsigned char, int = DEC);
76 | size_t print(int, int = DEC);
77 | size_t print(unsigned int, int = DEC);
78 | size_t print(long, int = DEC);
79 | size_t print(unsigned long, int = DEC);
80 | size_t print(double, int = 2);
81 |
82 | size_t println(const __FlashStringHelper *);
83 | size_t println(const char[]);
84 | size_t println(char);
85 | size_t println(unsigned char, int = DEC);
86 | size_t println(int, int = DEC);
87 | size_t println(unsigned int, int = DEC);
88 | size_t println(long, int = DEC);
89 | size_t println(unsigned long, int = DEC);
90 | size_t println(double, int = 2);
91 | size_t println(void);
92 |
93 | virtual void flush() { /* Empty implementation for backward compatibility */ }
94 | };
95 |
96 |
97 | /** The Printable class provides a way for new classes to allow themselves to be printed.
98 | By deriving from Printable and implementing the printTo method, it will then be possible
99 | for users to print out instances of this class by passing them into the usual
100 | Print::print and Print::println methods.
101 | */
102 |
103 | class Printable
104 | {
105 | public:
106 | virtual size_t printTo(Print& p) const = 0;
107 | };
108 |
109 |
110 | #endif
--------------------------------------------------------------------------------
/cores/blinklib/Serial.cpp:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | A very simplified serial port built to look like Arduino's Serial class.
4 |
5 | This serial port lives on the service port on new boards. It is really intended for debugging.
6 |
7 | The port always runs at a fixed 1M baud. Dev Candy Adapter boards and cables are available to
8 | connect to a USB port and then use the Arduino IDE's serial monitor to interact with your tile.
9 |
10 | */
11 |
12 | //#include
13 | #include
14 | #include
15 | #include
16 |
17 | #include "sp.h"
18 |
19 | #include "Serial.h"
20 |
21 | #include "ArduinoTypes.h"
22 |
23 |
24 | // Public Methods //////////////////////////////////////////////////////////////
25 |
26 | void ServicePortSerial::begin(void)
27 | {
28 |
29 | sp_serial_init();
30 |
31 | }
32 |
33 | void ServicePortSerial::end()
34 | {
35 | // TODO: Is there any reason to turn off the serial port? Power?
36 |
37 | }
38 |
39 | // We only use the 1 byte hardware buffer
40 |
41 | int ServicePortSerial::available(void) {
42 |
43 | if (sp_serial_rx_ready()) {
44 | return(1);
45 | } else {
46 | return(0);
47 | }
48 |
49 | }
50 |
51 | int ServicePortSerial::read(void)
52 | {
53 | if (!sp_serial_rx_ready()) {
54 | return -1;
55 | } else {
56 | return sp_serial_rx();
57 | }
58 | }
59 |
60 | // We don't implement flush because it would require adding a flag to remember if we ever sent.
61 | // This is because the hardware only gives us a bit that tells us when a tx completes, not if
62 | // no TX was ever started. Ardunio does this with the `_writen` flag.
63 | // If you can convince me that we really need flush, LMK and it can be added.
64 |
65 | size_t ServicePortSerial::write(uint8_t c)
66 | {
67 |
68 | sp_serial_tx(c);
69 |
70 | return(1);
71 |
72 | }
73 |
74 | // Block until all pending transmits complete
75 |
76 | void ServicePortSerial::flush(void)
77 | {
78 | sp_serial_flush();
79 | }
--------------------------------------------------------------------------------
/cores/blinklib/Serial.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | A very simplified serial port built to look like Arduino's Serial class.
4 |
5 | This serial port lives on the service port on new boards. It is really intended for debugging.
6 |
7 | The port always runs at a fixed 1M baud. Use the blink Dev Candy board to connect to a USB port
8 | and then use the Arduino IDE's serial monitor to interact with your tile.
9 |
10 | */
11 |
12 |
13 | #ifndef Serial_h
14 |
15 | #define Serial_h
16 |
17 | #include "Print.h"
18 |
19 | #define DEF_SERVICE_PORT_BAUDRATE 1000000
20 |
21 | class ServicePortSerial : public Print
22 | {
23 |
24 | public:
25 |
26 | //inline ServicePortSerialSerial(void);
27 | void begin(void);
28 | void end();
29 |
30 | virtual int available(void);
31 |
32 | // Input buffer is only 1 byte so if an interrupts happens while data is streaming, you will loose any incoming data.
33 | // Best to limit yourself interactions with plenty of time (or an ACK) between each incoming byte.
34 |
35 | virtual int read(void); // Read a byte - returns byte read or -1 if no byte ready.
36 |
37 | virtual size_t write(uint8_t);
38 | void flush(void); // Block until all pending transmits complete
39 |
40 | using Print::write; // pull in write(str) and write(buf, size) from Print
41 |
42 |
43 | };
44 |
45 | #endif
46 |
--------------------------------------------------------------------------------
/cores/blinklib/Timer.cpp:
--------------------------------------------------------------------------------
1 | #include // Get ULONG_MAX for NEVER
2 |
3 | #include "blinklib.h"
4 | // Note we directly access millis() here, which is really bad style.
5 | // The timer should capture millis() in a closure, but no good way to
6 | // do that in C++ that is not verbose and inefficient, so here we are.
7 |
8 | #define NEVER (ULONG_MAX)
9 |
10 | // All Timers come into this world pre-expired, so their expireTime is 0
11 | // Here we leave the constructor empty and depend in the BBS section clearing
12 | // to set it to 0 (the constructor mechanism uses lots of flash).
13 |
14 | bool Timer::isExpired() {
15 | return millis() > m_expireTime;
16 | }
17 |
18 | void Timer::set( uint32_t ms ) {
19 | m_expireTime= millis()+ms;
20 | }
21 |
22 | uint32_t Timer::getRemaining() {
23 |
24 | uint32_t timeRemaining;
25 |
26 | if( millis() >= m_expireTime) {
27 |
28 | timeRemaining = 0;
29 |
30 | } else {
31 |
32 | timeRemaining = m_expireTime - millis();
33 |
34 | }
35 |
36 | return timeRemaining;
37 |
38 | }
39 |
40 | void Timer::add( uint16_t ms ) {
41 |
42 | // Check to avoid overflow
43 |
44 | uint32_t timeLeft = NEVER - m_expireTime;
45 |
46 | if (ms > timeLeft ) {
47 |
48 | m_expireTime = NEVER;
49 |
50 | } else {
51 |
52 | m_expireTime+= ms;
53 |
54 | }
55 | }
56 |
57 | void Timer::never(void) {
58 | m_expireTime=NEVER;
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/cores/blinklib/main.cpp:
--------------------------------------------------------------------------------
1 |
2 | // Here are our magic shared memory links to the BlinkBIOS running up in the bootloader area.
3 | // These special sections are defined in a special linker script to make sure that the addresses
4 | // are the same on both the foreground (this blinklib program) and the background (the BlinkBIOS project compiled to a HEX file)
5 |
6 | #include "shared/blinkbios_shared_button.h"
7 | #include "shared/blinkbios_shared_millis.h"
8 | #include "shared/blinkbios_shared_pixel.h"
9 | #include "shared/blinkbios_shared_irdata.h"
10 |
11 | #include "blinklib.h"
12 |
13 | #include "run.h"
14 |
15 | // Here are the actual allocations for the shared memory blocks
16 |
17 | // We put each in its own section so that the separately compiled blinkos will be able to find them.
18 |
19 | // Note that without the `used` attribute, these blocks get tossed even though they are marked as `KEEP` in the linker script
20 |
21 | blinkbios_pixelblock_t __attribute__ ((section (".ipcram1") , used )) blinkbios_pixel_block;
22 | blinkbios_millis_block_t __attribute__ ((section (".ipcram2") , used )) blinkbios_millis_block;
23 | blinkbios_button_block_t __attribute__ ((section (".ipcram3") , used )) blinkbios_button_block;
24 | blinkbios_irdata_block_t __attribute__ ((section (".ipcram4") , used )) blinkbios_irdata_block;
25 |
26 | // Here is our entry point. We are called by the BlinkBIOS after everything is set up and ready
27 | // Note that this is not a normal startup, we are staring right from flash address 0x000 with no
28 | // vector table at all. We don't need one because all vectors are pointing to the BlinkBIOS
29 | // running up in the bootloader area.
30 |
31 | // We will never return, so don't need any of the extra formality, just give me the straight up code
32 |
33 | #include
34 |
35 | extern "C" void mainx(void) __attribute__ ((used)) __attribute__ ((noreturn));
36 |
37 | extern "C" void mainx(void) {
38 |
39 | run();
40 |
41 | __builtin_unreachable();
42 |
43 | // Don't fall off the edge of the earth here!
44 | // Make sure we stop above!
45 | }
46 |
--------------------------------------------------------------------------------
/cores/blinklib/run.h:
--------------------------------------------------------------------------------
1 |
2 | // Link from mainx() into blinklib.cpp
3 | // Called to start the sketch.
4 |
5 | void __attribute__((noreturn)) run(void);
--------------------------------------------------------------------------------
/cores/blinklib/shared/blinkbios_shared_button.h:
--------------------------------------------------------------------------------
1 | /*
2 | * blinkbios_pixel_block.h
3 | *
4 | * Defines the shared memory block used to check for button presses
5 | *
6 | */
7 |
8 | #ifndef BLINKBIOS_BUTTON_BLOCK_H_
9 | #define BLINKBIOS_BUTTON_BLOCK_H_
10 |
11 | // #define USER_VOLATILE or BIOS_VOLATILE based on the presence of #define BIOS_VOLATILE_FLAG
12 | #include "blinkbios_shared_volatile.h"
13 |
14 | #include
15 |
16 | // I know this is ugly, but keeping them in a single byte lets us pass them by value
17 | // and also lets us OR them together. Efficiency in the updater trumps since it
18 | // runs every millisecond.
19 |
20 | // TODO: Maybe more RAM but less flash to have these as individual bytes?
21 |
22 | #define BUTTON_BITFLAG_PRESSED 0b00000001
23 | #define BUTTON_BITFLAG_LONGPRESSED 0b00000010
24 | #define BUTTON_BITFLAG_RELEASED 0b00000100
25 | #define BUTTON_BITFLAG_SINGLECLICKED 0b00001000
26 | #define BUTTON_BITFLAG_DOUBLECLICKED 0b00010000
27 | #define BUTTON_BITFLAG_MULITCLICKED 0b00100000
28 |
29 | #define BUTTON_BITFLAG_3SECPRESSED 0b01000000
30 | #define BUTTON_BITFLAG_6SECPRESSED 0b10000000
31 |
32 | struct blinkbios_button_block_t {
33 |
34 | USER_VOLATILE uint8_t down; // 1 if button is currently down (debounced)
35 |
36 | BOTH_VOLATILE uint8_t bitflags;
37 |
38 | USER_VOLATILE uint8_t clickcount; // Number of clicks on most recent multiclick
39 |
40 | BOTH_VOLATILE uint8_t wokeFlag; // Set to 0 upon initial start up or waking from sleep
41 |
42 | // The variables below are used to track the intermediate button state
43 | // and probably not interesting to user programs
44 |
45 | uint8_t buttonDebounceCountdown; // How long until we are done bouncing. Only touched in the callback
46 | // Set to BUTTON_DEBOUNCE_MS every time we see a change, then we ignore everything
47 | // until it gets to 0 again
48 |
49 | uint16_t clickWindowCountdown; // How long until we close the current click window. 0=done
50 |
51 | uint8_t clickPendingcount; // How many clicks so far int he current click window
52 |
53 | uint8_t longpressRegisteredFlag; // Did we register a long press since the button went down?
54 | // Avoids multiple long press events from the same down event
55 | // We could keep an independent longpressCountup, but that would be a 16 bit so heavy to increment and compare.
56 |
57 | uint16_t pressCountup; // Start counting up when the button goes down to detect long presses. Has to be 16 bit because long presses are >255 centiseconds.
58 |
59 | // For future use?
60 | uint8_t slack[4];
61 |
62 |
63 | };
64 |
65 | // Everything in here is volatile to the user code
66 |
67 | extern blinkbios_button_block_t blinkbios_button_block;
68 |
69 | #endif /* BLINKBIOS_BUTTON_BLOCK_H_ */
--------------------------------------------------------------------------------
/cores/blinklib/shared/blinkbios_shared_functions.h:
--------------------------------------------------------------------------------
1 | /*
2 | * blinkbios_shared_functions.h
3 | *
4 | * Defines the entry points into the BLINKBIOS called functions
5 | *
6 | */
7 |
8 | // Note: Aesthetically it might seem better to put these function declarations with their functional groups, but ultimately I decided to
9 | // keep them all here in one place to avoid vector collisions. It is not a decision without downside though since a client who, say,
10 | // only wants the IR send funtion gets polluted with the others as well. :/
11 |
12 | // The VECTOR definitions are used on the BIOS side to hook the correct incoming vector.
13 | // The function definitions are used on the caller side to make the actual call to the vector.
14 | // The vector number and the jmp address must be manually matched.
15 |
16 | // The actual vector number is not important as long as it is not used for an actual ISR. We really just use the vector pattern so the
17 | // caller has a well known address to jmp to and vectors are always at a well known address.
18 |
19 | // The `jmp`s just work because the caller will set up the args in the right registers and then make the jmp to the
20 | // interrupt vector. Once there, the vector will directly call the target function with all the args still in place,
21 | // then the target will return back to the original caller. Cool right? The optimizer will even put the target function at
22 | // the vector jump address if it has no other callers, saving a jmp.
23 |
24 | #ifndef BLINKBIOS_SHARED_FUCNTIONS_H_
25 | #define BLINKBIOS_SHARED_FUCNTIONS_H_
26 |
27 | // Send a user data packet
28 | // See what we did here - we do a naked jump into vector_4, which is a jump to the `uint8_t ir_send_userdata( uint8_t face, const uint8_t *data , uint8_t len )` function
29 | // it all works out because the params happened to be in the same registers because of the AVR C calling convention.
30 | // When compiling the BIOS with LTO, it even puts the send packet function right at the target of the vector.
31 |
32 | // We use unused inetrrupt vectors to link between the user and BIOS code since they are at a known place.
33 | // The links are defined as symbols like `boot_vectorX` where X is the number of the unused vector we are taking.
34 | // In the BIOS project, these appear in the vector table in `startup.S`.
35 | // IN the user mode projects, these appear in the linkscript and are hard coded to the correct addressed (based at the bootloader vtable at 0x3800).
36 |
37 | // boot_vector4 is defined in the linkerscript and points to the boot loader's interrupt vector 4 at address 0x3810
38 | // This is just a prototype so gcc knows what args to pass. The linker will resolve it to a jump to the address.
39 |
40 | #define BLINKBIOS_IRDATA_SEND_PACKET_VECTOR boot_vector4 // This lands at base + 4 bytes per vector * 4th vector (init is at 0) = 0x10
41 |
42 | extern "C" uint8_t BLINKBIOS_IRDATA_SEND_PACKET_VECTOR( uint8_t face, const uint8_t *data , uint8_t len ) __attribute__((used)) __attribute__((noinline));
43 |
44 | // Translate and copy the RGB values in the pixel buffer to raw PWM values in the
45 | // raw pixel buffer. Waits for next vertical blanking interval to avoid
46 | // display of partial update.
47 |
48 | #define BLINKBIOS_DISPLAY_PIXEL_BUFFER_VECTOR boot_vector8
49 |
50 | extern "C" void BLINKBIOS_DISPLAY_PIXEL_BUFFER_VECTOR() __attribute__((used)) __attribute__((noinline));
51 |
52 |
53 |
54 | #define BLINKBIOS_BOOTLOADER_SEED_VECTOR boot_vector9
55 |
56 | extern "C" void BLINKBIOS_BOOTLOADER_SEED_VECTOR() __attribute__((used)) __attribute__((noinline));
57 |
58 |
59 | // Push back the inactivity sleep timer
60 | // Can be called with interrupts off, so you can adjust the
61 | // blinkbios_millis_block.millis and then call BLINKBIOS_POSTPONE_SLEEP_VECTOR
62 | // to reset the sleep_time to match the new timebase
63 | // Leaves with interrupts ON
64 |
65 | #define BLINKBIOS_POSTPONE_SLEEP_VECTOR boot_vector10
66 |
67 | extern "C" void BLINKBIOS_POSTPONE_SLEEP_VECTOR() __attribute__((used)) __attribute__((noinline));
68 |
69 |
70 | #define BLINKBIOS_SLEEP_NOW_VECTOR boot_vector12
71 |
72 | extern "C" void BLINKBIOS_SLEEP_NOW_VECTOR() __attribute__((used)) __attribute__((noinline));
73 |
74 | // Fill the flash page buffer using the boot_page_fill() function,
75 | // then call here. Will write the page to flash, wait for it to complete,
76 | // re-enable the rww part of flash, then return - so you can call this from
77 | // the non-bootloader part of memory
78 |
79 | #define BLINKBIOS_WRITE_FLASH_PAGE_VECTOR boot_vector13
80 |
81 | extern "C" void BLINKBIOS_WRITE_FLASH_PAGE_VECTOR(uint8_t page) __attribute__((used)) __attribute__((noinline));
82 |
83 |
84 | // Returns the version of the blinksbios present
85 |
86 | #define BLINKBIOS_VERSION_VECTOR boot_vector14
87 |
88 | extern "C" uint8_t BLINKBIOS_VERSION_VECTOR() __attribute__((used)) __attribute__((noinline));
89 |
90 |
91 | // Error mode. Blinks red until button pressed, then soft reset
92 |
93 | #define BLINKBIOS_ABEND_VECTOR boot_vector15
94 |
95 | extern "C" void BLINKBIOS_ABEND_VECTOR( uint8_t blinkCount ) __attribute__((used)) __attribute__((noinline)) __attribute__((noreturn));
96 |
97 | #endif /* BLINKBIOS_SHARED_FUCNTIONS_H_ */
--------------------------------------------------------------------------------
/cores/blinklib/shared/blinkbios_shared_irdata.h:
--------------------------------------------------------------------------------
1 | /*
2 | * blinkbios_pixel_block.h
3 | *
4 | * Defines the shared memory block used to check for button presses
5 | *
6 | */
7 |
8 | #ifndef BLINKBIOS_IRDATA_BLOCK_H_
9 | #define BLINKBIOS_IRDATA_BLOCK_H_
10 |
11 | // #define USER_VOLATILE or BIOS_VOLATILE based on the presence of #define BIOS_VOLATILE_FLAG
12 | #include "blinkbios_shared_volatile.h"
13 |
14 | #include
15 |
16 | #define IR_FACE_COUNT 6
17 | #define IR_FACE_BITMASK 0b00111111 // Mask for the 6 faces. Fails hard when we start making nonagon tiles.
18 |
19 | // Must be big enough to hold the biggest packet, which internally is PUSH packet.
20 | #define IR_RX_PACKET_SIZE 40
21 |
22 | // State for each receiving IR LED
23 |
24 |
25 | // User programs should only pay attention to messages with the header byte
26 | // they should silently consume any messages with other header bytes.
27 |
28 | #define IR_USER_DATA_HEADER_BYTE 0b00110111
29 |
30 | struct ir_rx_state_t {
31 |
32 | BOTH_VOLATILE uint8_t packetBufferReady; // 1 if we got the trailing sync byte. Foreground reader will set this back to 0 to enable next read.
33 |
34 | BOTH_VOLATILE uint8_t txInProgressFlag; // Are we currently transmitting? If so, then ignore any incoming SYNC.
35 |
36 | USER_VOLATILE uint8_t packetBufferLen; // How many bytes currently in the packet buffer? Does not include checksum when bufferReady is set
37 |
38 |
39 | USER_VOLATILE uint8_t packetBuffer[ IR_RX_PACKET_SIZE+1 ]; // Assemble incoming packet here. +1 to hold the type byte. Type byte comes first, but shoul;d be ignored since the BIOS consumes anything with a type besides USERDATA
40 | // First byte is header, which user code must check for USERDATA
41 |
42 | // These internal variables not interesting to user code.
43 | // They are only updated in ISR, so don't need to be volatile.
44 |
45 | uint8_t windowsSinceLastTrigger; // How long since we last saw a trigger on this IR LED?
46 |
47 | // We add new samples to the bottom and shift up.
48 | // The we look at the pattern to detect data bits
49 | // This is better than using a counter because with a counter we would need
50 | // to check for overflow before incrementing. With a shift register like this,
51 | // 1's just fall off the top automatically and We can keep shifting 0's forever.
52 |
53 | uint8_t byteBuffer; // Buffer for RX byte in progress. Data bits shift up until full byte received.
54 | // We prime with a '1' in the bottom bit when we get a valid start.
55 | // This way we can test for 0 to see if currently receiving a byte, and
56 | // we can also test for '1' in top position to see if full byte received.
57 |
58 |
59 | // This struct should be even power of 2 in length for more efficient array indexing.
60 |
61 | // For future use?
62 | uint8_t slack[4];
63 |
64 |
65 | };
66 |
67 | struct blinkbios_irdata_block_t {
68 |
69 | ir_rx_state_t ir_rx_states[ IR_FACE_COUNT ];
70 |
71 | uint8_t download_in_progress_flag; // Set if a download is in progress so subsequent SEED packets will be ignored
72 |
73 | // For future use?
74 | uint8_t slack[4];
75 |
76 |
77 | };
78 |
79 | extern blinkbios_irdata_block_t blinkbios_irdata_block;
80 |
81 | // You can use this function to see if there is an RX in progress on a face
82 | // Don't transmit if there is an RX in progress or you'll make a collision
83 |
84 | inline uint8_t blinkbios_is_rx_in_progress( uint8_t face ) {
85 |
86 | // This uses the fact that anytime we are actively receiving a byte, the byte buffer will
87 | // be nonzero. Even if we are getting an all-0 byte, the top bit will be marching up.
88 | // This is handy, but it does allow a collision during the leading sync. See below.
89 |
90 | return blinkbios_irdata_block.ir_rx_states[face].byteBuffer;
91 |
92 | }
93 |
94 |
95 | #endif /* BLINKBIOS_IRDATA_BLOCK_H_ */
--------------------------------------------------------------------------------
/cores/blinklib/shared/blinkbios_shared_millis.h:
--------------------------------------------------------------------------------
1 | /*
2 | * blinkbios_millis_block.h
3 | *
4 | * Defines the shared memory block used to keep the millisecond counter
5 | *
6 | */
7 |
8 | #ifndef BLINKBIOS_MILLIS_BLOCK_H_
9 | #define BLINKBIOS_MILLIS_BLOCK_H_
10 |
11 | // C++ implementations should define these macros only when __STDC_LIMIT_MACROS is defined before is included
12 |
13 | #define __STDC_CONSTANT_MACROS
14 | #define __STDC_LIMIT_MACROS
15 |
16 | //C++ implementations should define these macros only when __STDC_LIMIT_MACROS is defined before is included.
17 | // Gets us the UINT*_MAX macros
18 | #define __STDC_LIMIT_MACROS
19 |
20 | #include
21 |
22 | // #define USER_VOLATILE or BIOS_VOLATILE based on the presence of #define BIOS_VOLATILE_FLAG
23 | #include "blinkbios_shared_volatile.h"
24 |
25 | typedef uint32_t millis_t;
26 |
27 | #define MILLIS_MAX ( UINT32_MAX ) // This is a hack because it seems our compiled does not have UINT32_MAX correctly defined. :/
28 |
29 | struct blinkbios_millis_block_t {
30 |
31 | USER_VOLATILE millis_t millis;
32 | USER_VOLATILE uint8_t step_8us; // Carry over of sub-millis since our clock does not go evenly into 1ms. This is the number of 8us steps past the value in millis. Never gets above 125.
33 |
34 | USER_VOLATILE millis_t sleep_time; // When millis>sleep_time, then we go to sleep
35 |
36 | // For future use?
37 | uint8_t slack[4];
38 | };
39 |
40 | extern blinkbios_millis_block_t blinkbios_millis_block;
41 |
42 |
43 | #define MILLIS_NEVER ( MILLIS_MAX ) // A time that will forever be in the future
44 |
45 |
46 | #endif /* BLINKBIOS_MILLIS_BLOCK_H_ */
--------------------------------------------------------------------------------
/cores/blinklib/shared/blinkbios_shared_pixel.h:
--------------------------------------------------------------------------------
1 | /*
2 | * blinkbios_pixel_block.h
3 | *
4 | * Defines the shared memory block used to set the color of the pixels
5 | * and to determine best time to update the values
6 | *
7 | */
8 |
9 | #ifndef BLINKBIOS_PIXEL_BLOCK_H_
10 | #define BLINKBIOS_PIXEL_BLOCK_H_
11 |
12 | // #define USER_VOLATILE or BIOS_VOLATILE based on the presence of #define BIOS_VOLATILE_FLAG
13 | #include "blinkbios_shared_volatile.h"
14 |
15 | /** Display interface ***/
16 |
17 | #define PIXEL_COUNT 6
18 |
19 | // Here are the raw compare register values for each pixel
20 | // These are precomputed from brightness values because we read them often from inside an ISR
21 | // Note that for red & green, 255 corresponds to OFF and 0 is full on
22 |
23 | struct rawpixel_t {
24 | uint8_t rawValueR;
25 | uint8_t rawValueG;
26 | uint8_t rawValueB;
27 | uint8_t paddng; // Adding this padding save about 10 code bytes since x4 (double-doubling) is faster than adding 3.
28 |
29 | rawpixel_t( uint8_t in_raw_r , uint8_t in_raw_g , uint8_t in_raw_b ) {
30 | rawValueR = in_raw_r;
31 | rawValueG = in_raw_g;
32 | rawValueB = in_raw_b;
33 |
34 | }
35 |
36 | rawpixel_t() {};
37 |
38 | };
39 |
40 |
41 | const rawpixel_t RAW_PIXEL_OFF( 0xff , 0xff, 0xff );
42 |
43 | // pixel_color_t is a higher level view RGB encoded of a pixel
44 |
45 | // Each pixel has 32 brightness levels for each of the three colors (red,green,blue)
46 | // These brightness levels are normalized to be visually linear with 0=off and 31=max brightness
47 |
48 | // Note use of anonymous union members to let us switch between bitfield and int
49 | // https://stackoverflow.com/questions/2468708/converting-bit-field-to-int
50 |
51 | union pixelColor_t {
52 |
53 | struct {
54 | uint8_t reserved:1;
55 | uint8_t r:5;
56 | uint8_t g:5;
57 | uint8_t b:5;
58 | };
59 |
60 | uint16_t as_uint16;
61 |
62 | pixelColor_t();
63 | pixelColor_t(uint8_t r_in , uint8_t g_in, uint8_t b_in );
64 | pixelColor_t(uint8_t r_in , uint8_t g_in, uint8_t b_in , uint8_t reserverd_in );
65 |
66 | };
67 |
68 | inline pixelColor_t::pixelColor_t(uint8_t r_in , uint8_t g_in, uint8_t b_in ) {
69 |
70 | r=r_in;
71 | g=g_in;
72 | b=b_in;
73 |
74 | }
75 |
76 | inline pixelColor_t::pixelColor_t(uint8_t r_in , uint8_t g_in, uint8_t b_in , uint8_t reserverd_in ) {
77 |
78 | r=r_in;
79 | g=g_in;
80 | b=b_in;
81 | reserved = reserverd_in;
82 |
83 | }
84 |
85 | /*
86 |
87 | template pixelColor_t preset_pixelcolor_t {
88 | {
89 | pixelColor_t p = pixelColor_t( r , g , b );
90 |
91 |
92 | };
93 |
94 | */
95 |
96 | // Maximum value you can assign to one of the primaries in a pixelColor_t
97 | #define PIXELCOLOR_PRIMARY_FULL 31
98 | #define PIXELCOLOR_PRIMARY_HALF 15
99 |
100 | // So this mess below is my way of emulating constexpr in C++ <11
101 | // These defines will expand and eval at compile time down to a single uint16_t load
102 | // if instead we tried using a `const pixelColor_r`, then it would blow up into
103 | // a constructor call at runtime. Yuck.
104 |
105 | #define PIXEL_COLOR_FULL_GREEN pixelColor_t( 0 , PIXELCOLOR_PRIMARY_FULL , 0 )
106 | #define PIXEL_COLOR_HALF_GREEN pixelColor_t( 0 , PIXELCOLOR_PRIMARY_HALF , 0 )
107 |
108 | #define PIXEL_COLOR_FULL_RED pixelColor_t( PIXELCOLOR_PRIMARY_FULL , 0 , 0 )
109 | #define PIXEL_COLOR_HALF_RED pixelColor_t( PIXELCOLOR_PRIMARY_HALF , 0 , 0 )
110 |
111 | #define PIXEL_COLOR_FULL_BLUE pixelColor_t( 0 , 0 , PIXELCOLOR_PRIMARY_FULL )
112 |
113 | #define PIXEL_COLOR_OFF pixelColor_t()
114 |
115 | inline pixelColor_t::pixelColor_t() {
116 |
117 | // Faster than setting the individual elements?
118 | // We don't need to do this because in bss this will get cleared to 0 anyway.
119 | // as_uint16 = 0;
120 |
121 | }
122 |
123 | // Oh how I hate these defines, but we are not allowed to have nice things like
124 | // scoped enums until C++11, so no better way to makes these fit into uint8_t
125 |
126 | #define BLINKBIOS_START_STATE_POWER_UP 0
127 | #define BLINKBIOS_START_STATE_WE_ARE_ROOT 1
128 | #define BLINKBIOS_START_STATE_DOWNLOAD_SUCCESS 2
129 |
130 | // We need these struct gymnastics because C fixed array typedefs do not work
131 | // as you (I?) think they would...
132 | // https://stackoverflow.com/questions/4523497/typedef-fixed-length-array
133 |
134 | struct blinkbios_pixelblock_t {
135 |
136 | // RGB pixel buffer
137 | // Call displayPixelBuffer() to decode and copy this into the raw pixel buffer
138 | // so it will appear on the LEDs
139 |
140 | BIOS_VOLATILE pixelColor_t pixelBuffer[PIXEL_COUNT];
141 |
142 | // This is cleared when we are done displaying the current buffer values and about to reset and start again
143 | // Once this is cleared, you have one pixel interrupt period to get your new data into the pixel buffer
144 | // before the next refresh cycle starts.
145 |
146 | // We picked to clear this rather than set to 1 because in the ISR is is faster to set to 0 since R1 is always loaded with 0
147 |
148 | BOTH_VOLATILE uint8_t vertical_blanking_interval;
149 |
150 | // Below is some global state that is probably not interesting to user code
151 |
152 | rawpixel_t rawpixels[PIXEL_COUNT];
153 |
154 | uint8_t currentPixelIndex; // Which pixel are we currently lighting? Pixels are multiplexed and only refreshed one at a time in sequence.
155 | uint8_t phase; // Phase up updating the current pixel. There are 5 phases that include lighting each color, charging the charge pump, and resting the charge pump.
156 |
157 |
158 | // Here we keep the value of TCNT0 that was captured at the last watchdog timer interrupt
159 | // We put this here because the pixel code enables and sets up Timer0, and really not other good place for it.
160 | // User code is responsible for enabling the WDT interrupt and then checking this value to see
161 | // when it gets set asynchronously by the bios WDT ISR.
162 |
163 | volatile uint8_t capturedEntropy;
164 |
165 | // This is 1 if we just successfully send a download out
166 | // (not volatile, never changes from client program perspective)
167 |
168 | BIOS_VOLATILE uint8_t start_state;
169 |
170 | // For future use?
171 | uint8_t slack[8];
172 |
173 | };
174 |
175 | extern blinkbios_pixelblock_t blinkbios_pixel_block; // Currently being displayed. You can have direct access to this to save memory,
176 | // but use the vertical retrace to avoid visual tearing on updates
177 |
178 | #endif /* BLINKBIOS_PIXEL_BLOCK_H_ */
--------------------------------------------------------------------------------
/cores/blinklib/shared/blinkbios_shared_volatile.h:
--------------------------------------------------------------------------------
1 | /*
2 | * blinkbios_shared_voltaile.h
3 | *
4 | * This is a workaround to letting the BIOS code and user code have different `volatile` views of the
5 | * shared data structures. While we need some of these shared variables to be seen as volatile to the user code
6 | * since they can be changed by the BIOS code in the background, the BIOS code can never be interrupted by the user code
7 | * so it is wasteful to have it see them as volatile also. All the unneeded reloads are not only slow, but we really need
8 | * to save flash.
9 | *
10 | * To make this work, the BIOS code always `#define`s `BIOS_VOLATILE_FLAG` before including any of the shared files.
11 | *
12 | */
13 |
14 |
15 | #ifndef BLINKBIOS_SHAED_VOLATILE__H_
16 |
17 | #define BLINKBIOS_SHAED_VOLATILE__H_
18 |
19 | #ifdef BIOS_VOLATILE_FLAG
20 |
21 | // BIOS code sees this
22 |
23 | #define BIOS_VOLATILE volatile
24 | #define USER_VOLATILE
25 | #define BOTH_VOLATILE volatile
26 |
27 | #else
28 |
29 | // User code sees this
30 |
31 | #define BIOS_VOLATILE
32 | #define USER_VOLATILE volatile
33 | #define BOTH_VOLATILE volatile
34 |
35 | #endif
36 |
37 |
38 |
39 | #endif
40 |
--------------------------------------------------------------------------------
/cores/blinklib/shared/readme.MD:
--------------------------------------------------------------------------------
1 | Do not manually change these files!
2 |
3 | They come from the `blinkbios` project...
4 |
5 | https://github.com/Move38/Move38-BlinkBIOS
6 |
7 | ...and must travel as a coherent set.
8 |
9 | `BlinkBIOS.hex` contains the compiled image of the BlinkBIOS code. It is loaded in upper flash and takes care of lots of common hardware tasks so that individual games do not need duplicated code.
10 |
11 | We program this file every time download a sketch. We also set the `BOOTRST` fuse so that the chip will jump to the bootload section rather than address 0x000 on RESET. Both of these happen in the `AVRDUDE` the recipes in `platform.txt`.
12 |
13 | To be able to successfully talk to the BIOS code, the blink user code must be compiled against the matching header files.
14 |
--------------------------------------------------------------------------------
/cores/blinklib/sp.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Access the service port
3 | *
4 | * The service port has a high speed (1Mbps) bi-directional serial connection plus an Aux pin that can be used
5 | * as either digitalIO or an analog in.
6 | *
7 | * Mostly useful for debugging, but maybe other stuff to? :)
8 | *
9 | */
10 |
11 |
12 | #include "sp.h"
13 |
14 | #include
15 |
16 | // Serial port hardware on service port
17 |
18 | #define SP_SERIAL_CTRL_REG UCSR0A
19 | #define SP_SERIAL_DATA_REG UDR0
20 | #define SP_SERIAL_READY_BIT RXC0
21 |
22 | // Bit manipulation macros
23 | #define SBI(x,b) (x|= (1<linker
23 |
24 |
25 |
26 | * Created: 10/27/2018 4:05:41 PM
27 | * Author: josh
28 | */
29 |
30 |
31 | /*
32 |
33 | There is nothing here! NO VECTORS here! No __zero_reg! We just jump stright into the code!
34 |
35 | This saves a lot of flash becuase each game can start litterally at address 0x000 and hit the
36 | ground running with no extra crap at the begining.
37 |
38 | The vectors are up in the bootloader area. Code compiled against this blinklib API
39 | is depenent on that BlinkBIOS code running at reset and setting everythign up for us
40 | inclduing the interrupts.
41 |
42 | Note that we do need to init the .data and .bss variables to thier initial values, but that
43 | is taken care of by library code that will link in here automatically.
44 |
45 | */
46 |
47 | // There does not seem to be any good way to avoid this jmp since
48 | // the compiler likes to put the contructors and jump trampolines at the bottom of flash,
49 | // which ended up being 0x0000 when we get rid of all the vectors!
50 |
51 |
52 | .section .vectors,"ax",@progbits
53 | .global __vectors
54 | .func __vectors
55 | __vectors:
56 | jmp __init
57 | .endfunc
58 |
59 |
60 | .section .init0,"ax",@progbits
61 | .func __init
62 | __init:
63 |
64 | .section .init2,"ax",@progbits
65 |
66 | .section .init9,"ax",@progbits
67 |
68 | // Note that we do not need to clear `r1` or set up the stack here
69 | // becuase the BlinkBIOS has already done that by the time we get started.
70 |
71 | jmp mainx
72 |
73 | .endfunc
74 |
--------------------------------------------------------------------------------
/libraries/Examples01/dummy.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2015 Atmel Corp./Thibaut VIARD. All right reserved.
3 |
4 | This library is free software; you can redistribute it and/or
5 | modify it under the terms of the GNU Lesser General Public
6 | License as published by the Free Software Foundation; either
7 | version 2.1 of the License, or (at your option) any later version.
8 |
9 | This library is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 | See the GNU Lesser General Public License for more details.
13 |
14 | You should have received a copy of the GNU Lesser General Public
15 | License along with this library; if not, write to the Free Software
16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 | */
18 |
19 | /*
20 | * Workaround dummy file to obtain the examples present in the IDE menu File->Examples
21 | */
22 |
--------------------------------------------------------------------------------
/libraries/Examples01/examples/A-BareMinimum/A-BareMinimum.ino:
--------------------------------------------------------------------------------
1 | void setup() {
2 | // put your start up code here, it will run
3 | // every time this blink wakes up
4 |
5 | }
6 |
7 | void loop() {
8 | // put your main code here, to run repeatedly
9 | // every time a new frame of pixels is displayed
10 | // on the front of this blink
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/libraries/Examples01/examples/B-ButtonPress/B-ButtonPress.ino:
--------------------------------------------------------------------------------
1 | void setup() {
2 |
3 | // No setup needed for this simple example!
4 |
5 | }
6 |
7 | void loop() {
8 |
9 | if (buttonDown()) {
10 |
11 | setColor( RED );
12 |
13 | } else {
14 |
15 | setColor( GREEN );
16 |
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/libraries/Examples01/examples/C-ButtonCycleColors/C-ButtonCycleColors.ino:
--------------------------------------------------------------------------------
1 | void setup() {
2 |
3 | // No setup needed for this simple example!
4 |
5 | }
6 |
7 | byte counter=0;
8 |
9 | void loop() {
10 |
11 | if (buttonPressed()) {
12 |
13 | counter = counter + 1;
14 |
15 | if ( counter >= 3 ) {
16 |
17 | counter = 0;
18 |
19 | }
20 | }
21 |
22 | if (counter==0) {
23 | setColor(RED);
24 | } else if (counter==1) {
25 | setColor(GREEN);
26 | } else { // if (counter==2)
27 | setColor(BLUE);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/libraries/Examples01/examples/D-TimerFlash/D-TimerFlash.ino:
--------------------------------------------------------------------------------
1 | void setup() {
2 |
3 | // No setup needed for this simple example!
4 |
5 | }
6 |
7 | Timer nextFlash; // Timers are initialized as already being expired, so we will flash the first time loop() called.
8 |
9 | void loop() {
10 |
11 | if (nextFlash.isExpired()) {
12 |
13 | setColor( RED );
14 |
15 | nextFlash.set(200); // Flash again in 200 millseconds
16 |
17 | } else {
18 |
19 | setColor( OFF );
20 |
21 | }
22 |
23 | // Any color set in loop() is guaranteed to show up on the tile for at least one frame,
24 | // which is about 1/60th of a second. It will be a fast flash, but visible.
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/libraries/Examples01/examples/E-TimerBlink/E-TimerBlink.ino:
--------------------------------------------------------------------------------
1 | void setup() {
2 |
3 | // No setup needed for this simple example!
4 |
5 | }
6 |
7 | bool onFlag = false;
8 |
9 | Timer nextChange;
10 |
11 |
12 | void loop() {
13 |
14 | if (nextChange.isExpired()) {
15 |
16 | if (onFlag) {
17 |
18 | setColor( OFF );
19 | onFlag = false;
20 |
21 | } else {
22 |
23 | setColor(BLUE);
24 | onFlag = true;
25 |
26 | }
27 |
28 | nextChange.set(500); // Toggle every 500 milliseconds
29 |
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/libraries/Examples01/examples/F-ColorWheel/F-ColorWheel.ino:
--------------------------------------------------------------------------------
1 | // Spin around in goovy HSB color space
2 | // HSB stands for Hue, Saturation, and Brightness
3 | // https://en.wikipedia.org/wiki/HSL_and_HSV
4 |
5 | void setup() {
6 | // No setup needed for this simple example!
7 | }
8 |
9 | byte hue=0;
10 |
11 | Timer nextStep;
12 |
13 | void loop() {
14 |
15 | if (nextStep.isExpired()) {
16 |
17 | // Spin the hue while keeping color saturation and brightness at max
18 | setColor( makeColorHSB( hue , 255 , 255 ) );
19 |
20 | // Becuase we are using an 8-bit byte for the `hue` variable,
21 | // this will automatically roll over from 255 back down to 0
22 | // (255 is 11111111 in binary, and 11111111 + 00000001 = 00000000)
23 | hue++;
24 |
25 | nextStep.set(10); // Step to (slightly) different color 100 times per second - whole cycle will take 255 steps *10ms = ~2.5 seconds.
26 |
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/libraries/Examples01/examples/G-StartState/G-StartState.ino:
--------------------------------------------------------------------------------
1 | // Show how the current game was loaded
2 | // BLUE - We are the root of a download seed
3 | // GREEN - We downloaded the game from someone else (not root)
4 | // RED - Anything else (battery changed, failed download, etc)
5 |
6 | void setup() {
7 |
8 | // No setup needed for this simple example!
9 |
10 | }
11 |
12 | void loop() {
13 |
14 |
15 | Color color;
16 |
17 | switch ( startState() ) {
18 |
19 | case START_STATE_WE_ARE_ROOT:
20 | color = BLUE;
21 | break;
22 |
23 | case START_STATE_DOWNLOAD_SUCCESS:
24 | color = GREEN;
25 | break;
26 |
27 | default:
28 | color = RED;
29 | break;
30 |
31 | }
32 |
33 | byte brightness = sin8_C( millis() & 0xff ); // throb at about 4 Hz (1000 millis / 256 steps-per-sin8_C-cycle)
34 |
35 | setColor( dim( color , brightness ) );
36 |
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/libraries/Examples01/library.properties:
--------------------------------------------------------------------------------
1 | name=01. Getting Started
2 | version=1.0
3 | author=Move38.com
4 | maintainer=Move38.com
5 | sentence=See something blink
6 | paragraph=
7 | category=Other
8 | url=https://github.com/bigjosh/Move38-Arduino-Platform
9 | architectures=avr
10 | types=Arduino
11 |
--------------------------------------------------------------------------------
/libraries/Examples02/dummy.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2015 Atmel Corp./Thibaut VIARD. All right reserved.
3 |
4 | This library is free software; you can redistribute it and/or
5 | modify it under the terms of the GNU Lesser General Public
6 | License as published by the Free Software Foundation; either
7 | version 2.1 of the License, or (at your option) any later version.
8 |
9 | This library is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 | See the GNU Lesser General Public License for more details.
13 |
14 | You should have received a copy of the GNU Lesser General Public
15 | License along with this library; if not, write to the Free Software
16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 | */
18 |
19 | /*
20 | * Workaround dummy file to obtain the examples present in the IDE menu File->Examples
21 | */
22 |
--------------------------------------------------------------------------------
/libraries/Examples02/examples/A-ColorByNeighbor/A-ColorByNeighbor.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * Color By Number/Neighbor
3 | *
4 | * An example showing how to count the number of neighbors.
5 | *
6 | * Each Blink displays a color based on the number of neighbors around it.
7 | *
8 | */
9 |
10 | // color by number of neighbors
11 | Color colors[] = {
12 | dim(WHITE,40), // 0 neighbors
13 | RED, // 1 neighbors
14 | YELLOW, // 2 neighbors
15 | GREEN, // 3 neighbors
16 | CYAN, // 4 neighbors
17 | BLUE, // 5 neighbors
18 | MAGENTA, // 6 neighbors
19 | };
20 |
21 | void setup() {
22 | // Blank
23 | }
24 |
25 |
26 | void loop() {
27 |
28 | // count neighbors we have right now
29 | int numNeighbors = 0;
30 |
31 | FOREACH_FACE(f) {
32 |
33 | if ( !isValueReceivedOnFaceExpired( f ) ) { // Have we seen an neighbor on this face recently?
34 | numNeighbors++;
35 | }
36 |
37 | }
38 |
39 | // look up the color to show based on number of neighbors
40 | // No need to bounds check here since we know we can never see more than 6 neighbors
41 | // because we only have 6 sides.
42 |
43 | setColor( colors[ numNeighbors ] );
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/libraries/Examples02/examples/B-ColorRamps/B-ColorRamps.ino:
--------------------------------------------------------------------------------
1 | /// Show some soothing color ramps.
2 |
3 | void setup() {
4 |
5 | // No setup needed for this simple example!
6 |
7 | }
8 |
9 |
10 | // There are 255 brightness levels in each ramp.
11 | // We step 30 levels every 10 milliseconds, so...
12 | // Each ramp will take about ((100 ms/step)/(1000 ms/sec)) / ( (255 levels/ramp ) / ( 30 levels/step) ) =
13 | // ~1.17 secs/ramp
14 | // We do an up ramp and then a down ramp for each color
15 |
16 | #define STEP_SIZE 10
17 | #define STEP_TIME_MS 30
18 |
19 | Color colors[] = { BLUE , RED , GREEN };
20 |
21 | byte colorIndex = 0;
22 |
23 | int brightness = 1;
24 |
25 | int step = STEP_SIZE;
26 |
27 | Timer nextStepTimer;
28 |
29 | void loop() {
30 |
31 | if (nextStepTimer.isExpired()) {
32 |
33 | // Change direction if we hit either boundary
34 |
35 | if ( (brightness + step > MAX_BRIGHTNESS ) || (brightness + step < 0 ) ) {
36 |
37 | step = -step;
38 |
39 | if (step>0) { // If we hit bottom, then time to move on to next color
40 |
41 | colorIndex++;
42 |
43 | if (colorIndex >= COUNT_OF( colors ) ) {
44 |
45 | colorIndex =0;
46 |
47 | }
48 |
49 |
50 | }
51 |
52 |
53 | }
54 |
55 | brightness += step;
56 |
57 | setColor( dim( colors[colorIndex] , brightness ) );
58 |
59 | nextStepTimer.set( STEP_TIME_MS );
60 |
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/libraries/Examples02/examples/C-SerialNumberPrinter/C-SerialNumberPrinter.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | NOTE: This sketch is only interesting if you have a Blinks Dev Candy adapter connecting
4 | the blink to your serial port!
5 |
6 | Every blink tile comes into this world with its own untique serial number.
7 |
8 | This sketch prints the current tile's serial number out to the serial port.
9 |
10 | The serial number is 9 bytes long, and is printed with hex numbers like this...
11 |
12 | "For a good time, call:39-11-1-50-4E-38-33-33-39"
13 |
14 | ...or...
15 |
16 | "For a good time, call:30-20-3-50-4E-38-33-33-39"
17 |
18 | The first bytes are more likely to be different than the last bytes, in case
19 | you can't remember the whole thing (it is long).
20 |
21 | */
22 |
23 |
24 |
25 | #include "Serial.h"
26 |
27 | ServicePortSerial sp;
28 |
29 | void setup() {
30 |
31 | sp.begin();
32 |
33 | }
34 |
35 | void loop() {
36 |
37 | sp.print("For a good time, call:");
38 |
39 | // First load the serial number buytes into a buffer
40 |
41 | byte snBuffer[SERIAL_NUMBER_LEN];
42 |
43 | for( byte i=0; i trigger_time_ms + fade_time_ms ) {
39 | return 0;
40 | }
41 |
42 | word age_ms = millis() - trigger_time_ms;
43 |
44 | //word brightness = fade_time_ms - age_ms;
45 |
46 | word inverted_brightness = map( age_ms , 0 , fade_time_ms , 0 , 255 );
47 |
48 | return 255-inverted_brightness;
49 |
50 | }
51 |
52 | public:
53 |
54 | inline void trigger(void) {
55 |
56 | trigger_time_ms = millis();
57 |
58 | }
59 |
60 | inline void show() {
61 | setFaceColor( face , dim( color , get_current_brightness() ) );
62 | }
63 |
64 |
65 | inline void update(void ) {
66 |
67 | if ( (*testFunction)() ) {
68 |
69 | trigger();
70 |
71 | }
72 |
73 | }
74 |
75 | fadingIndicator_t( byte face, Color color , bool (*testFunction)() ) : face(face), color(color) , testFunction( testFunction ) {}
76 |
77 | };
78 |
79 | fadingIndicator_t indicators[] {
80 |
81 | { 0 , RED , buttonPressed },
82 | { 1 , GREEN , buttonReleased },
83 | { 2 , BLUE , buttonSingleClicked },
84 | { 3 , MAGENTA, buttonDoubleClicked },
85 | { 4 , YELLOW , buttonMultiClicked },
86 | { 5 , CYAN , buttonLongPressed },
87 |
88 | };
89 |
90 |
91 | void loop() {
92 |
93 | for(auto &item : indicators ) {
94 |
95 | item.update();
96 | item.show();
97 |
98 | }
99 |
100 | }
101 |
--------------------------------------------------------------------------------
/libraries/Examples02/examples/F-SimpleDatagramDemo/F-SimpleDatagramDemo.ino:
--------------------------------------------------------------------------------
1 | // SimpleDatagramDemo
2 | // Simplest example of how to send and recieve datagrams over the IR link.
3 | // Face shows:
4 | // GREEN when it sees a neighboor and is getting a valid value from it (the number `42` is sent in this demo)
5 | // CYAN when it sees a neighboor and is getting an invalid value from it (anything other than the number `42` in this demo)
6 | // BLUE blink for 250ms when it sees a valid datagram (the three bytes {'C','A','T'} in the demo)
7 | // RED blink for 250ms when it sees an invalid datagram (anything but the three bytes {'C','A','T'} in the demo)
8 | //
9 | // Pressing the button sends the sample datagram on all faces
10 |
11 | // A datagram is a multibyte message that is sent on a best-efforts basis
12 | // Each datagram sent will be recieved at most one time (it might never be recieved)
13 | // Datagrams can be up to `IR_DATAGRAM_LEN` bytes long
14 |
15 | // Send somethign on all faces so we can check that we got it
16 |
17 | #define MAGIC_VALUE 42
18 |
19 | // Leave the current color on this face until this timer expires
20 | static Timer showColorOnFaceTimer[ FACE_COUNT ];
21 |
22 | #define SHOW_COLOR_TIME_MS 250 // Long enough to see
23 |
24 | byte sampleDatagram[] { 'C' , 'A' , 'T' }; // A sample 3 byte long datagram
25 |
26 |
27 | void setup() {
28 | setValueSentOnAllFaces(MAGIC_VALUE);
29 | }
30 |
31 |
32 | /*
33 | * Compare memory regions. Returns 0 if all bytes in the blocks match.
34 | * Lifted from https://github.com/f32c/arduino/blob/master/hardware/fpga/f32c/system/src/memcmp.c
35 | */
36 |
37 | int memcmp(const void *s1, const void *s2, unsigned n)
38 | {
39 | if (n != 0) {
40 | const unsigned char *p1 = s1, *p2 = s2;
41 |
42 | do {
43 | if (*p1++ != *p2++)
44 | return (*--p1 - *--p2);
45 | } while (--n != 0);
46 | }
47 | return (0);
48 | }
49 |
50 |
51 | void loop() {
52 |
53 | // First check all faces for an incoming datagram
54 |
55 | FOREACH_FACE(f) {
56 |
57 | if ( isDatagramReadyOnFace( f ) ) {
58 |
59 | const byte *datagramPayload = getDatagramOnFace(f);
60 |
61 | // Check that the length and all of the data btyes of the recieved datagram match what we were expecting
62 | // Note that `memcmp()` returns 0 if it is a match
63 |
64 | if ( getDatagramLengthOnFace(f)==sizeof( sampleDatagram ) && !memcmp( datagramPayload , sampleDatagram , sizeof( sampleDatagram )) ) {
65 |
66 | // This is the datagram we are looking for!
67 |
68 | setColorOnFace( BLUE , f );
69 |
70 | } else {
71 |
72 | // Oops, we goty a datagram, but not the one we are loooking for
73 |
74 | setColorOnFace( RED , f );
75 |
76 | }
77 |
78 |
79 | showColorOnFaceTimer[f].set( SHOW_COLOR_TIME_MS );
80 |
81 | // We are done with the datagram, so free up the buffer so we can get another on this face
82 | markDatagramReadOnFace( f );
83 |
84 |
85 | } else if ( showColorOnFaceTimer[f].isExpired() ) {
86 |
87 | if ( !isValueReceivedOnFaceExpired( f ) ) {
88 |
89 | // Show green if we do have a neighbor
90 |
91 | if (getLastValueReceivedOnFace(f) == MAGIC_VALUE ) {
92 |
93 | setColorOnFace( GREEN , f );
94 |
95 | } else {
96 |
97 | setColorOnFace( CYAN, f );
98 |
99 |
100 | }
101 |
102 | } else {
103 |
104 | // Or off if no neighbor
105 |
106 | setColorOnFace( OFF , f );
107 |
108 | }
109 |
110 | }
111 |
112 | }
113 |
114 |
115 | if (buttonPressed()) {
116 |
117 | // When the button is click, trigger a datagram send on all faces
118 |
119 | FOREACH_FACE(f) {
120 |
121 | sendDatagramOnFace( &sampleDatagram , sizeof( sampleDatagram ) , f );
122 |
123 | }
124 |
125 | }
126 |
127 | } // loop()
128 |
--------------------------------------------------------------------------------
/libraries/Examples02/examples/G-IRButtonPressTester/G-IRButtonPressTester.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * IR Button Press
3 | *
4 | * Great for testing if blinks work and can communicate over IR
5 | *
6 | * Each face shows:
7 | * YELLOW - No neighbor on this face
8 | * BLUE - Neighbor button UP
9 | * GREEN - Neighbor button DOWN
10 | * RED - Error. Saw unexpected datum on this face. Resets after 0.5 second.
11 | *
12 | */
13 |
14 |
15 | void setup() {
16 | // Blank
17 | }
18 |
19 | // Pick some unlikely values so we are more likely to show an error if a different
20 | // game is runnning on the oposing blink
21 |
22 | #define VALUE_BUTTON_UP 12
23 | #define VALUE_BUTTON_DOWN 21
24 |
25 | // Did we get an error onthis face recently?
26 | Timer errorOnFaceTimer[ FACE_COUNT ];
27 |
28 | const int showErrTime_ms = 500; // Show the errror for 0.5 second so people can see it
29 |
30 | void loop() {
31 |
32 | // Make a little pulsation so we know it is working
33 |
34 | uint8_t brightness = sin8_C( (millis()/4) & 0xff );
35 |
36 | FOREACH_FACE(f) {
37 |
38 | Color color;
39 |
40 | // Set the color on this face based on what we see...
41 |
42 | if ( !isValueReceivedOnFaceExpired( f ) ) { // Have we seen an neighbor on this face recently?
43 |
44 | switch ( getLastValueReceivedOnFace( f ) ) {
45 |
46 | case VALUE_BUTTON_UP :
47 | color = BLUE;
48 | break;
49 |
50 | case VALUE_BUTTON_DOWN:
51 | color=GREEN;
52 | break;
53 |
54 | default:
55 | // anything else is an error
56 | // We set a timer so this face will show red for a little while to make sure it is seen
57 | errorOnFaceTimer[f].set( showErrTime_ms );
58 | break;
59 |
60 | }
61 |
62 | } else {
63 |
64 | // No neighbor on this face right now
65 |
66 | color=YELLOW;
67 |
68 | }
69 |
70 | // The red (error) will cover any other color on the face unil the timer times out
71 |
72 | if ( !errorOnFaceTimer[f].isExpired() ) {
73 |
74 | color = RED;
75 |
76 | }
77 |
78 | setColorOnFace( dim( color , brightness ) , f );
79 |
80 | }
81 |
82 | // Finally update the value we send to others to match our current button state
83 |
84 |
85 | if ( buttonDown() ) {
86 |
87 | setValueSentOnAllFaces( VALUE_BUTTON_DOWN ) ;
88 |
89 | } else {
90 |
91 | setValueSentOnAllFaces( VALUE_BUTTON_UP ) ;
92 |
93 | }
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/libraries/Examples02/examples/H-IRLinkTester/H-IRLinkTester.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * IR Link Tester
3 | *
4 | * Great for testing if blinks work and can communicate over IR
5 | *
6 | * Sends a series of messages with sequence numbers so it can detect a missed message.
7 | * The messages also have a checksum so it can detect corrupted messages.
8 | *
9 | * Each face shows:
10 | * BLUE - No neighbor on this face
11 | * GREEN - Blinks to show good data being received
12 | * ORANGE - Shows that a message was missed
13 | * RED - Shows that an invalid message was received.
14 | *
15 | * Press the button to clear ORANGE and RED.
16 | *
17 | */
18 |
19 |
20 | // Use unsigned long becuase they tak a long time to wrap and have lots of bits that can have errors
21 |
22 | typedef unsigned SeqType;
23 |
24 | struct MessageType {
25 | byte txFace; // The face of the sending blink
26 | SeqType seq;
27 | SeqType inverted; // Inverted bits check
28 | };
29 |
30 | // Next seq to send.
31 | SeqType nextSeqOut[ FACE_COUNT ];
32 |
33 | // Next expected
34 | SeqType nextSeqIn[ FACE_COUNT ];
35 |
36 | // Did we get an error on this face recently?
37 | bool showErrorFlag[ FACE_COUNT ];
38 |
39 | // Did we miss a message on this face recently?
40 | bool showMissedFlag[ FACE_COUNT ];
41 |
42 |
43 | // When should we do next blind send?
44 | // Note that we also send faster by ping ponging when we get a message in
45 | Timer nextSendTimer[ FACE_COUNT ];
46 |
47 | // Has it been so long ince we saw something that we should give up showing is as present?
48 | Timer expireFaceTimer[ FACE_COUNT ];
49 |
50 | //const int ErrorShowTime_ms = 500; //
51 | //const int MissedShowTime_ms = 250; //
52 |
53 | const int ResendTime_ms = 300; // Show the errror for 0.5 second so people can see it
54 | const int ExpireTime_ms = 1000;
55 |
56 |
57 | // Remember the pervious face seen so we don't generate a miss when a dffifernt face is swapped in
58 | byte lastTxFace[FACE_COUNT];
59 |
60 |
61 | void setup() {
62 |
63 | FOREACH_FACE(f) {
64 | nextSeqOut[f]=0x5566;
65 | nextSeqIn[f]=0x5566;
66 | }
67 |
68 | }
69 |
70 | void loop() {
71 |
72 | if (buttonPressed()) {
73 |
74 | FOREACH_FACE(f) {
75 |
76 | showErrorFlag[f] = false;
77 | showMissedFlag[f] = false;
78 |
79 | }
80 | }
81 |
82 |
83 |
84 | FOREACH_FACE(f) {
85 |
86 | // If we have been asleep, then start everything fresh
87 | if (hasWoken()) {
88 |
89 | nextSendTimer[f].set(0);
90 | expireFaceTimer[f].set(0);
91 |
92 | }
93 |
94 | boolean sendNowFlag = false;
95 |
96 | // *** Incomming
97 |
98 | if ( isDatagramReadyOnFace( f ) ) {
99 |
100 | if ( getDatagramLengthOnFace(f) ==sizeof( MessageType ) ) {
101 |
102 | // We got a valid length message
103 |
104 | const MessageType *rxMessagePtr = (MessageType *) getDatagramOnFace(f);
105 |
106 | if ( rxMessagePtr->seq != ~rxMessagePtr->inverted ) {
107 |
108 | // Currupted data. Bad.
109 |
110 | //showErrorTimer[f].set( ErrorShowTime_ms );
111 | showErrorFlag[f] = true;
112 |
113 | } else {
114 |
115 | // If we get here, then packet is the right length and the checksum is correct (valid packet)
116 |
117 | // If the face is expired, or this is a new face from the last message, then no need to show an error on the first message, just sync to it.
118 |
119 | // We check if the seq matches either the expected seq or +1 or +2. This way, we need to miss three or more consecutive packets to show an error.
120 |
121 | if ( !expireFaceTimer[f].isExpired() && lastTxFace[f] == rxMessagePtr->txFace && rxMessagePtr->seq !=nextSeqIn[f] && rxMessagePtr->seq != (nextSeqIn[f]+1) && rxMessagePtr->seq != (nextSeqIn[f]+2) ) {
122 |
123 | showMissedFlag[f] = true;
124 |
125 | }
126 |
127 | // NOTE: Here we depend on overflow to wrap
128 | nextSeqIn[f] = (rxMessagePtr->seq) + 1; // Sync to incomming message
129 |
130 | lastTxFace[f] = rxMessagePtr->txFace;
131 |
132 | }
133 |
134 | // We got something, so we know someone is there
135 | expireFaceTimer[f].set( ExpireTime_ms );
136 |
137 | // Also send our response immedeately (ping pong)
138 | sendNowFlag = true;
139 |
140 |
141 | } else {
142 |
143 | // Invalid packet length
144 | // TODO: Should this be a different kind of error?
145 |
146 | //showErrorTimer[f].set( ErrorShowTime_ms );
147 | showErrorFlag[f] = true;
148 |
149 |
150 | }
151 |
152 | markDatagramReadOnFace(f);
153 |
154 | }
155 |
156 | // *** Outgoing
157 |
158 | if (sendNowFlag || nextSendTimer[f].isExpired()) {
159 |
160 | MessageType txMessage;
161 |
162 | // NOTE: Here we depend on overflow to wrap
163 |
164 | txMessage.txFace = f;
165 | txMessage.seq = nextSeqOut[f];
166 | txMessage.inverted = ~nextSeqOut[f];
167 |
168 | sendDatagramOnFace( &txMessage , sizeof( txMessage ) , f );
169 |
170 | nextSeqOut[f]++;
171 |
172 | nextSendTimer[f].set( ResendTime_ms );
173 |
174 | }
175 |
176 | // *** Display
177 |
178 |
179 | if ( showErrorFlag[f]) {
180 |
181 | setColorOnFace( RED , f );
182 |
183 | } else if ( showMissedFlag[f]) {
184 |
185 | setColorOnFace( dim( ORANGE , 128 ) , f );
186 |
187 | } else if (expireFaceTimer[f].isExpired() ) {
188 |
189 | // No partner on this face, so show blue
190 |
191 | setColorOnFace( dim( BLUE , 128 ) , f );
192 |
193 | } else {
194 |
195 | // Otherwise, everything is hunky-dory
196 |
197 | // Make the green pulse to show the speed of transmitions and also just give a feel that data is really flowing
198 |
199 | //uint8_t brightness = sin8_C( ( nextSeqIn[f] * 16 ) & 0xff );
200 |
201 | uint8_t brightness = (( nextSeqIn[f] & 0x01 ) * 128 ) + 127;
202 |
203 | setColorOnFace( dim( GREEN , brightness ) , f );
204 |
205 | }
206 |
207 |
208 | }
209 |
210 | }
211 |
--------------------------------------------------------------------------------
/libraries/Examples02/library.properties:
--------------------------------------------------------------------------------
1 | name=02. Getting Practical
2 | version=1.0
3 | author=Move38.com
4 | maintainer=Move38.com
5 | sentence=See something blink
6 | paragraph=
7 | category=Other
8 | url=https://github.com/bigjosh/Move38-Arduino-Platform
9 | architectures=avr
10 | types=Arduino
11 |
--------------------------------------------------------------------------------
/libraries/Examples03/dummy.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2015 Atmel Corp./Thibaut VIARD. All right reserved.
3 |
4 | This library is free software; you can redistribute it and/or
5 | modify it under the terms of the GNU Lesser General Public
6 | License as published by the Free Software Foundation; either
7 | version 2.1 of the License, or (at your option) any later version.
8 |
9 | This library is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 | See the GNU Lesser General Public License for more details.
13 |
14 | You should have received a copy of the GNU Lesser General Public
15 | License along with this library; if not, write to the Free Software
16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 | */
18 |
19 | /*
20 | * Workaround dummy file to obtain the examples present in the IDE menu File->Examples
21 | */
22 |
--------------------------------------------------------------------------------
/libraries/Examples03/examples/Berry/Berry.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * Berry
3 | * by VV Studio
4 | * at IndieCade East 2018 Game Jam
5 | * Lead development by Jonathan Bobrow, Move38 Inc.
6 | * original game by ViVi and Vanilla
7 | *
8 | * Rules: https://github.com/Move38/Berry/blob/master/README.md
9 | *
10 | * --------------------
11 | * Blinks by Move38
12 | * Brought to life via Kickstarter 2018
13 | *
14 | * @madewithblinks
15 | * www.move38.com
16 | * --------------------
17 | */
18 |
19 | Color colors[] = { BLUE, RED, YELLOW };
20 | byte currentColorIndex = 0;
21 | byte faceIndex = 0;
22 | byte faceStartIndex = 0;
23 |
24 | bool isWaiting = false;
25 |
26 | #define FACE_DURATION 60
27 | #define WAIT_DURATION 2000
28 |
29 | Timer faceTimer;
30 | Timer waitTimer;
31 |
32 | void setup() {
33 | // put your setup code here, to run once:
34 |
35 | }
36 |
37 | void loop() {
38 | // put your main code here, to run repeatedly:
39 |
40 | if ( buttonSingleClicked() ) {
41 |
42 | currentColorIndex++;
43 |
44 | if (currentColorIndex >= COUNT_OF(colors)) {
45 | currentColorIndex = 0;
46 | }
47 |
48 | }
49 |
50 | if ( waitTimer.isExpired() ) {
51 | if ( faceTimer.isExpired() ) {
52 | faceTimer.set( FACE_DURATION );
53 | faceIndex++;
54 |
55 | if (faceIndex >= 7) {
56 | faceIndex = 0;
57 | waitTimer.set( WAIT_DURATION );
58 | isWaiting = true;
59 |
60 | // shift the starting point
61 | faceStartIndex++;
62 | if (faceStartIndex >= 6) {
63 | faceStartIndex = 0;
64 | }
65 | }
66 | else {
67 | isWaiting = false;
68 | }
69 | }
70 | }
71 |
72 | // display color
73 | setColor( colors[currentColorIndex] );
74 |
75 | // show locked sides
76 | if (isPositionLocked()) {
77 | // show the state of locked animation on all faces
78 | byte bri = 153 + (sin8_C((millis() / 6) % 255)*2)/5;
79 | setColor(dim(colors[currentColorIndex], bri));
80 | }
81 |
82 | // show next color
83 | if (!isWaiting) {
84 | byte nextColorIndex = (currentColorIndex + 1) % 3;
85 | byte face = (faceStartIndex + faceIndex - 1) % FACE_COUNT;
86 | setFaceColor( face, colors[nextColorIndex] );
87 | }
88 | }
89 |
90 | bool isPositionLocked() {
91 | // based on the arrangement of neighbors, am I locked...
92 | bool neighborPattern[6];
93 | bool lockedA[6] = {1, 0, 1, 0, 1, 0};
94 | bool lockedB[6] = {1, 0, 1, 0, 0, 0};
95 |
96 | FOREACH_FACE(f) {
97 | neighborPattern[f] = !isValueReceivedOnFaceExpired(f);
98 | }
99 |
100 | // neighbors across from each other
101 | for (byte i = 0; i < 3; i++) {
102 | if (neighborPattern[i] && neighborPattern[i + 3]) {
103 | return true;
104 | }
105 | }
106 |
107 | // special case lock patterns
108 | if ( isThisPatternPresent(lockedA, neighborPattern)) {
109 | return true;
110 | }
111 | if ( isThisPatternPresent(lockedB, neighborPattern)) {
112 | return true;
113 | }
114 |
115 | return false;
116 | }
117 |
118 | // check to see if pattern is in the array
119 | // return true if the pattern is in fact in the array
120 | // pattern is always 6 bools
121 | // source is always 12 bools (2 x 6 bools)
122 | bool isThisPatternPresent( bool pat[], bool source[]) {
123 |
124 | // first double the source to be cyclical
125 | bool source_double[12];
126 |
127 | for (byte i = 0; i < 12; i++) {
128 | source_double[i] = source[i % 6];
129 | }
130 |
131 | // then find the pattern
132 | byte pat_index = 0;
133 |
134 | for (byte i = 0; i < 12; i++) {
135 | if (source_double[i] == pat[pat_index]) {
136 | // increment index
137 | pat_index++;
138 |
139 | if ( pat_index == 6 ) {
140 | // found the entire pattern
141 | return true;
142 | }
143 | }
144 | else {
145 | // set index back to 0
146 | pat_index = 0;
147 | }
148 | }
149 |
150 | return false;
151 | }
152 |
--------------------------------------------------------------------------------
/libraries/Examples03/examples/FlicFlop/FlicFlop.ino:
--------------------------------------------------------------------------------
1 | /*
2 | FlicFlop
3 | by Move38, Inc. 2019
4 | Lead development by Dan King
5 | original game by Nick Bentley, Jonathan Bobrow, Dan King
6 |
7 | Rules: https://github.com/Move38/Astro/blob/master/README.md
8 |
9 | --------------------
10 | Blinks by Move38
11 | Brought to life via Kickstarter 2018
12 |
13 | @madewithblinks
14 | www.move38.com
15 | --------------------
16 | */
17 |
18 | enum gameStates {FLICKER_UNSCORED, FLICKER_SCORED, FLICKER_DISPLAY, FLOPPER};
19 | byte gameState = FLICKER_UNSCORED;
20 | bool longPressCheck = false;
21 |
22 | #define TEAM_COUNT 3
23 | byte scoringTeam = 0;
24 | byte signalTeam = 0;
25 |
26 | enum celebrationStates {INERT, CELEBRATE, TRANSITION};
27 | byte celebrationState = INERT;
28 |
29 | Timer flopTimer;
30 | #define FLOP_INTERVAL 2000
31 |
32 |
33 | Timer animTimer;
34 | #define ANIMATION_INTERVAL 200
35 | byte animationInterval = ANIMATION_INTERVAL;
36 |
37 | #define ANIMATION_CELEBRATE_INTERVAL 20
38 | Timer celebrationTimer;
39 | #define CELEBRATE_TIME 2000
40 |
41 | byte spinFace = 0;
42 | byte teamHues[4] = {0, 45, 125, 230};
43 |
44 | void setup() {
45 | // put your setup code here, to run once:
46 |
47 | }
48 |
49 | void loop() {
50 |
51 | if (hasWoken()) {
52 | longPressCheck = false;
53 | }
54 |
55 | // put your main code here, to run repeatedly:
56 | if (gameState == FLOPPER) {
57 | flopperLoop();
58 | flopperDisplay();
59 | } else {
60 | flickerLoop();
61 | flickerDisplay();
62 | }
63 |
64 | //animate the spin face
65 | spinFaceAnimator();
66 |
67 | //set up communication
68 | byte sendData = (signalTeam << 4) + (scoringTeam << 2) + (celebrationState);
69 | setValueSentOnAllFaces(sendData);
70 |
71 | if (buttonSingleClicked()) {
72 | beginCelebration();
73 | }
74 |
75 | celebrationLoop();
76 |
77 | if (longPressCheck) {
78 | if (isAlone()) {
79 | setColor(WHITE);
80 | setColorOnFace(OFF, spinFace);
81 | }
82 | }
83 |
84 | //dump button presses
85 | buttonDoubleClicked();
86 | buttonLongPressed();
87 | }
88 |
89 | void flopperLoop() {
90 |
91 | //look for other floppers trying to move us along to the next color
92 | bool hasFlopperNeighbor = false;
93 | bool shouldChange = false;
94 | byte changeTo = signalTeam;
95 | byte lastFlopperFace = 0;
96 | FOREACH_FACE(f) {
97 | if (!isValueReceivedOnFaceExpired(f)) { //a neighbor!
98 | byte neighborData = getLastValueReceivedOnFace(f);
99 | if (getScoringTeam(neighborData) == 0) {//this could be a flopper
100 | if (getSignalTeam(neighborData) != 0) {//it is a flopper
101 | //set the last flopper face
102 | lastFlopperFace = f;
103 | hasFlopperNeighbor = true;
104 |
105 | //check for signal change
106 | if (getSignalTeam(neighborData) == signalTeam + 1) {//it wants me to move
107 | shouldChange = true;
108 | changeTo = getSignalTeam(neighborData);
109 | } else if (signalTeam == 3 && getSignalTeam(neighborData) == 1) {//it wants me to move
110 | shouldChange = true;
111 | changeTo = 1;
112 | }
113 | }
114 | }
115 | }
116 | }
117 |
118 | if (shouldChange) {
119 | signalTeam = changeTo;
120 | flopTimer.set(FLOP_INTERVAL);
121 | //change the spinface
122 | //spinFace = lastFlopperFace;
123 | //animTimer.set(0);
124 | }
125 |
126 | if (flopTimer.isExpired()) {
127 | signalTeam = (signalTeam % TEAM_COUNT) + 1;
128 | flopTimer.set(FLOP_INTERVAL);
129 | //if (hasFlopperNeighbor) {
130 | //spinFace = lastFlopperFace;
131 | //animTimer.set(0);
132 | //}
133 | }
134 |
135 | //change to flicker?
136 | if (buttonLongPressed()) {
137 | if (isAlone()) {
138 | //set the transition boolean to true
139 | longPressCheck = true;
140 | beginCelebration();
141 | }
142 | }
143 |
144 | if (buttonReleased()) {
145 | if (longPressCheck) {
146 | longPressCheck = false;//regardless of outcome, this needs to be false
147 | if (isAlone()) {
148 | scoringTeam = 0;
149 | signalTeam = 0;
150 | gameState = FLICKER_UNSCORED;
151 | }
152 | }
153 | }
154 |
155 | }
156 |
157 | void flickerLoop() {
158 |
159 | if (gameState == FLICKER_UNSCORED) {
160 | //listen for neighbors with signal teams
161 | //become that signal team
162 | FOREACH_FACE(f) {
163 | if (!isValueReceivedOnFaceExpired(f)) { //a neighbor!
164 | byte neighborData = getLastValueReceivedOnFace(f);
165 |
166 | if (getSignalTeam(neighborData) != 0) {//this guy is signalling
167 |
168 | //become scored
169 | gameState = FLICKER_SCORED;
170 | scoringTeam = getSignalTeam(neighborData);
171 | signalTeam = scoringTeam;
172 |
173 | //kick off a celebration
174 | beginCelebration();
175 | }
176 | }
177 | }
178 |
179 | //also, listen for long press to become flopper
180 | if (buttonLongPressed()) {
181 | if (isAlone()) {
182 | //set the transition boolean to true
183 | longPressCheck = true;
184 | beginCelebration();
185 | }
186 | }
187 |
188 | if (buttonReleased()) {
189 | if (longPressCheck) {
190 | longPressCheck = false;//regardless of outcome, this needs to be false
191 | if (isAlone()) {
192 | gameState = FLOPPER;
193 | signalTeam = 1;
194 | scoringTeam = 0;
195 | }
196 | }
197 | }
198 |
199 | } else if (gameState == FLICKER_SCORED) {
200 | //listen for signals to change your signal
201 | FOREACH_FACE(f) {
202 | if (!isValueReceivedOnFaceExpired(f)) {
203 | byte neighborData = getLastValueReceivedOnFace(f);
204 | if (getSignalTeam(neighborData) == signalTeam + 1) {
205 | signalTeam = getSignalTeam(neighborData);
206 | } else if (signalTeam == 3 && getSignalTeam(neighborData) == 1) {
207 | signalTeam = 1;
208 | }
209 | }
210 |
211 | if (isAlone()) {
212 | gameState = FLICKER_DISPLAY;
213 | signalTeam = 0;
214 | }
215 | }
216 |
217 | } else if (gameState == FLICKER_DISPLAY) {
218 | //listen for things with signal teams to rejoin the game
219 | //listen for things with no scoring team to go back to unscored
220 | FOREACH_FACE(f) {
221 | if (!isValueReceivedOnFaceExpired(f)) {//neighbor!
222 | byte neighborData = getLastValueReceivedOnFace(f);
223 |
224 | if (getSignalTeam(neighborData) != 0) { //I have rejoined the game because this neighbor has a signal team
225 | gameState = FLICKER_SCORED;
226 | signalTeam = getSignalTeam(neighborData);
227 |
228 | } else if (getScoringTeam(neighborData) == 0) { //this neighbor has no signal team, and also has no scoring team. Unscored!
229 | gameState = FLICKER_UNSCORED;
230 | scoringTeam = 0;
231 |
232 | }
233 | }
234 | }
235 |
236 | //we can also be double-clicked back to unscored
237 | if (buttonDoubleClicked()) {
238 | gameState = FLICKER_UNSCORED;
239 | scoringTeam = 0;
240 | }
241 | }
242 |
243 | }
244 |
245 | void beginCelebration() {
246 | animTimer.set(0);
247 | celebrationState = CELEBRATE;
248 | animationInterval = ANIMATION_CELEBRATE_INTERVAL;
249 | celebrationTimer.set(CELEBRATE_TIME);
250 | }
251 |
252 | void celebrationLoop() {
253 | //here we check for the INERT/CELEBRATE/TRANSITION stuff
254 | if (celebrationState == INERT) {
255 | FOREACH_FACE(f) {
256 | if (!isValueReceivedOnFaceExpired(f)) {
257 | if (getCelebrationState(getLastValueReceivedOnFace(f)) == CELEBRATE) {
258 | beginCelebration();
259 | }
260 | }
261 | }
262 | } else if (celebrationState == CELEBRATE) {
263 | //only move on to TRANSITION if no neighbors are still INERT
264 | celebrationState = TRANSITION;
265 | FOREACH_FACE(f) {
266 | if (!isValueReceivedOnFaceExpired(f)) {
267 | if (getCelebrationState(getLastValueReceivedOnFace(f)) == INERT) {
268 | celebrationState = CELEBRATE;//revert the change from above
269 | }
270 | }
271 | }
272 | } else if (celebrationState == TRANSITION) {
273 | //only move to INERT if no neighbors are in CELEBRATE
274 | celebrationState = INERT;
275 | FOREACH_FACE(f) {
276 | if (!isValueReceivedOnFaceExpired(f)) {
277 | if (getCelebrationState(getLastValueReceivedOnFace(f)) == CELEBRATE) {
278 | celebrationState = TRANSITION;//revert the change from above
279 | }
280 | }
281 | }
282 | }
283 |
284 | //set the animation interval correctly based on the celebration timer
285 | if (celebrationTimer.isExpired()) {
286 | animationInterval = ANIMATION_INTERVAL;
287 | } else {
288 | animationInterval = map(CELEBRATE_TIME - celebrationTimer.getRemaining(), 0, CELEBRATE_TIME, ANIMATION_CELEBRATE_INTERVAL, ANIMATION_INTERVAL);
289 | }
290 | }
291 |
292 | /////////////////
293 | //DISPLAY LOOPS//
294 | /////////////////
295 |
296 | void spinFaceAnimator() {
297 | if (animTimer.isExpired()) {
298 | spinFace = (spinFace + 1) % 6;
299 | animTimer.set(animationInterval);
300 | }
301 | }
302 |
303 | void flopperDisplay() {
304 | setColor(makeColorHSB(teamHues[signalTeam], 255, 255));
305 | bool multiFlopper = false;
306 |
307 | FOREACH_FACE(f) {
308 | if (!isValueReceivedOnFaceExpired(f)) { //a neighbor!
309 | byte neighborData = getLastValueReceivedOnFace(f);
310 | if (getScoringTeam(neighborData) == 0) { //it's another FLOPPER
311 | //am I celebrating?
312 | if (animationInterval < ANIMATION_INTERVAL) { //I am celebrating
313 | setColorOnFace(makeColorHSB(teamHues[signalTeam], 255, 255), f);
314 | } else {//not celebrating
315 | setColorOnFace(OFF, f);
316 | }
317 | multiFlopper = true;
318 | }
319 | }
320 | }
321 |
322 | if (!multiFlopper) {
323 | setColorOnFace(OFF, spinFace);
324 | }
325 | }
326 |
327 | void flickerDisplay() {
328 | setColor(OFF);
329 |
330 | if (gameState == FLICKER_UNSCORED) {
331 | setColorOnFace(WHITE, spinFace);
332 | } else if (gameState == FLICKER_SCORED) {
333 | setColorOnFace(makeColorHSB(teamHues[scoringTeam], 255, 255), spinFace);
334 | setColorOnFace(makeColorHSB(teamHues[signalTeam], 255, 255), (spinFace + 2) % 6);
335 | setColorOnFace(makeColorHSB(teamHues[signalTeam], 255, 255), (spinFace + 3) % 6);
336 | setColorOnFace(makeColorHSB(teamHues[signalTeam], 255, 255), (spinFace + 4) % 6);
337 | } else if (gameState == FLICKER_DISPLAY) {
338 | setColorOnFace(makeColorHSB(teamHues[scoringTeam], 255, 255), spinFace);
339 | setColorOnFace(makeColorHSB(teamHues[scoringTeam], 255, 255), (spinFace + 2) % 6);
340 | setColorOnFace(makeColorHSB(teamHues[scoringTeam], 255, 255), (spinFace + 4) % 6);
341 | }
342 | }
343 |
344 | /////////////////////////
345 | //CONVENIENCE FUNCTIONS//
346 | /////////////////////////
347 |
348 | byte getSignalTeam(byte data) {
349 | return (data >> 4);//first and second bit
350 | }
351 |
352 | byte getScoringTeam(byte data) {
353 | return ((data >> 2) & 3);//third and fourth bit
354 | }
355 |
356 | byte getCelebrationState(byte data) {
357 | return (data & 3);//5th and 6th bit
358 | }
359 |
--------------------------------------------------------------------------------
/libraries/Examples03/examples/Fracture/Fracture.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * Fracture
3 | * by Move38, Inc. 2019
4 | * Lead development by Jonathan Bobrow, Daniel King
5 | * original game by Celia Pearce, Em Lazer-Walker, Jonathan Bobrow, Joshua Sloane
6 | *
7 | * Rules: https://github.com/Move38/Fracture/blob/master/README.md
8 | *
9 | * --------------------
10 | * Blinks by Move38
11 | * Brought to life via Kickstarter 2018
12 | *
13 | * @madewithblinks
14 | * www.move38.com
15 | * --------------------
16 | */
17 |
18 | #define HAPPY_FLASH_DURATION 500
19 | #define EDGE_FADE_DURAION 500
20 | #define SPARKLE_OFFSET 80
21 | #define SPARKLE_DURATION 800
22 | #define SPARKLE_CYCLE_DURATION 1600
23 |
24 | Color displayColor;
25 |
26 | //Color teamColors[] = {RED, BLUE, YELLOW, GREEN};
27 | byte teamHues[6] = {22, 49, 82, 99, 160, 200};
28 |
29 | byte teamIndex = 0;
30 |
31 | Timer happyFlashTimer;
32 | bool happyFlashOn;
33 |
34 | byte sparkleOffset[6] = {0, 3, 5, 1, 4, 2};
35 |
36 | Timer edgeTimer[6];
37 | bool edgeAcquired;
38 |
39 | bool hasRecentlySeenNeighbor[6];
40 |
41 | void setup() {
42 | }
43 |
44 | void loop() {
45 |
46 | // change team if triple clicked
47 | if (buttonDoubleClicked()) {
48 | teamIndex++;
49 | if (teamIndex >= COUNT_OF(teamHues)) {
50 | teamIndex = 0;
51 | }
52 | }
53 |
54 | byte numNeighbors = 0;
55 | bool noNeighborsOfSameColor = true;
56 |
57 | // look at neighbors
58 | FOREACH_FACE(f) {
59 | if (!isValueReceivedOnFaceExpired(f)) {
60 |
61 | if (hasRecentlySeenNeighbor[f] == false) {
62 | edgeAcquired = true;
63 | edgeTimer[f].set(EDGE_FADE_DURAION);
64 | }
65 | hasRecentlySeenNeighbor[f] = true;
66 |
67 | numNeighbors++;
68 |
69 | // if their color is the same as mine... not happy
70 | if (getLastValueReceivedOnFace(f) == teamIndex) {
71 | noNeighborsOfSameColor = false;
72 | }
73 | }
74 | else {
75 | if (hasRecentlySeenNeighbor[f] == true) {
76 | edgeAcquired = false;
77 | edgeTimer[f].set(EDGE_FADE_DURAION);
78 | }
79 | hasRecentlySeenNeighbor[f] = false;
80 | }
81 | }
82 |
83 | bool isHappy = false;
84 |
85 | // if I have two neighbors or more and my neighbors are not my color i'm happy
86 | if (numNeighbors >= 2 && noNeighborsOfSameColor) {
87 | isHappy = true;
88 | }
89 |
90 | // if I'm happy
91 | if (isHappy) {
92 | displayHappy();
93 | }
94 | else {
95 | displayNotHappy();
96 | }
97 |
98 | // display fracture animation or mend animation
99 | FOREACH_FACE(f) {
100 | if (!edgeTimer[f].isExpired()) {
101 | if (edgeAcquired) {
102 | // if we just gained a neighbor saturate from white
103 | byte sat = 255 - (255 * edgeTimer[f].getRemaining() ) / EDGE_FADE_DURAION;
104 | setColorOnFace(makeColorHSB(teamHues[teamIndex], sat, 255), f);
105 | }
106 | else {
107 | // if we just lost a neighbor fade up from dark
108 | byte bri = 255 - (255 * edgeTimer[f].getRemaining() ) / EDGE_FADE_DURAION;
109 | setColorOnFace(makeColorHSB(teamHues[teamIndex], 255, bri), f);
110 | }
111 | }
112 | }
113 |
114 | setValueSentOnAllFaces(teamIndex);
115 | }
116 |
117 | void displayHappy() {
118 |
119 | // have the color on the Blink raise and lower to feel more alive
120 | byte bri = 185 + sin8_C( (millis() / 14) % 255) * 70 / 255; // oscillate between values 185and 255
121 | setColor(dim(getColorForTeam(teamIndex), bri));
122 |
123 | // lets do a celebration on each face in an order
124 | word delta = millis() % SPARKLE_CYCLE_DURATION; // 2 second cycle
125 |
126 | if (delta > SPARKLE_DURATION) {
127 | delta = SPARKLE_DURATION;
128 | }
129 |
130 | FOREACH_FACE(f) {
131 |
132 | // if the face has started it's glow
133 | uint16_t sparkleStart = sparkleOffset[f] * SPARKLE_OFFSET;
134 | uint16_t sparkleEnd = sparkleStart + SPARKLE_DURATION - (6 * SPARKLE_OFFSET);
135 |
136 | if ( delta > sparkleStart ) {
137 | // minimum of 125, maximum of 255
138 | word phaseShift = 60 * f;
139 | byte amplitude = 55;
140 | byte midline = 185;
141 | byte rate = 6;
142 | byte lowBri = midline + (amplitude * sin8_C( (phaseShift + millis() / rate) % 255) / 100);
143 | byte brightness;
144 | byte saturation;
145 |
146 | if ( delta < sparkleEnd ) {
147 | brightness = map(delta, sparkleStart, sparkleStart + SPARKLE_DURATION - (6 * SPARKLE_OFFSET), 255, lowBri);
148 | saturation = map(delta, sparkleStart, sparkleStart + SPARKLE_DURATION - (6 * SPARKLE_OFFSET), 0, 255);
149 | }
150 | else {
151 | //brightness = lowBri;
152 | saturation = 255;
153 | }
154 |
155 | Color faceColor = makeColorHSB(teamHues[teamIndex], saturation, 255);
156 | setColorOnFace(faceColor, f);
157 | }
158 | }
159 |
160 | }
161 |
162 | void displayNotHappy() {
163 | // have the color on the Blink raise and lower to feel more alive
164 | byte bri = 185 + sin8_C( (millis() / 14) % 255) * 70 / 255; // oscillate between values 185and 255
165 | setColor(dim(getColorForTeam(teamIndex), bri));
166 | }
167 |
168 |
169 | Color getColorForTeam(byte t) {
170 | return makeColorHSB(teamHues[t], 255, 255);
171 | }
172 |
--------------------------------------------------------------------------------
/libraries/Examples03/library.properties:
--------------------------------------------------------------------------------
1 | name=03. Getting Playful
2 | version=1.0
3 | author=Move38.com
4 | maintainer=Move38.com
5 | sentence=12 Games for Blinks
6 | paragraph=
7 | category=Other
8 | url=https://github.com/Move38/Blinks-SDK
9 | architectures=avr
10 | types=Arduino
11 |
--------------------------------------------------------------------------------
/libraries/Examples04/dummy.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2015 Atmel Corp./Thibaut VIARD. All right reserved.
3 |
4 | This library is free software; you can redistribute it and/or
5 | modify it under the terms of the GNU Lesser General Public
6 | License as published by the Free Software Foundation; either
7 | version 2.1 of the License, or (at your option) any later version.
8 |
9 | This library is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 | See the GNU Lesser General Public License for more details.
13 |
14 | You should have received a copy of the GNU Lesser General Public
15 | License along with this library; if not, write to the Free Software
16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 | */
18 |
19 | /*
20 | * Workaround dummy file to obtain the examples present in the IDE menu File->Examples
21 | */
22 |
--------------------------------------------------------------------------------
/libraries/Examples04/library.properties:
--------------------------------------------------------------------------------
1 | name=04. Getting Testy
2 | version=1.0
3 | author=Move38.com
4 | maintainer=Move38.com
5 | sentence=See something blink
6 | paragraph=
7 | category=Other
8 | url=https://github.com/bigjosh/Move38-Arduino-Platform
9 | architectures=avr
10 | types=Arduino
11 |
--------------------------------------------------------------------------------
/libraries/Examples05/dummy.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2015 Atmel Corp./Thibaut VIARD. All right reserved.
3 |
4 | This library is free software; you can redistribute it and/or
5 | modify it under the terms of the GNU Lesser General Public
6 | License as published by the Free Software Foundation; either
7 | version 2.1 of the License, or (at your option) any later version.
8 |
9 | This library is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 | See the GNU Lesser General Public License for more details.
13 |
14 | You should have received a copy of the GNU Lesser General Public
15 | License along with this library; if not, write to the Free Software
16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 | */
18 |
19 | /*
20 | * Workaround dummy file to obtain the examples present in the IDE menu File->Examples
21 | */
22 |
--------------------------------------------------------------------------------
/libraries/Examples05/library.properties:
--------------------------------------------------------------------------------
1 | name=05. Getting Funky
2 | version=1.0
3 | author=Move38.com
4 | maintainer=Move38.com
5 | sentence=See something blink
6 | paragraph=
7 | category=Other
8 | url=https://github.com/bigjosh/Move38-Arduino-Platform
9 | architectures=avr
10 | types=Arduino
11 |
--------------------------------------------------------------------------------
/linkscripts/readme.MD:
--------------------------------------------------------------------------------
1 | We use a shared data block for communication between the bootloader code and the foreground game. This lets us load that stuff once rather than having to include it in every game image.
2 |
3 | The shared memory block lives at a fixed location at the bottom of RAM.
4 |
5 | We need a custom link script so we can force that block to this known location.
6 |
7 | The linker scripts here were copied from...
8 |
9 | C:\Program Files (x86)\Arduino\hardware\tools\avr\avr\lib\ldscripts
10 |
11 | ...which seems to be hardcoded into `gcc`.
12 |
13 | We add a new group of sections called `ipcram1`-`ipcram9` which hold the shared memory block.
14 |
15 | Note also that we mark these sections as `KEEP`, but they still seem to get garbage collected if not referenced, so we should make sure to reference them in the foreground code or else the foreground will put variables here and overwrite the bootloader's info.
16 |
17 | We had to make a new `.dataX` segment because the origin of the normal `.data` segment seems to be hardcoded into the "specific device" file in gcc...
18 |
19 | https://electronics.stackexchange.com/questions/408115/how-does-avr-gcc-linker-know-to-put-the-datasection-at-0x800100-rather-than
20 |
21 | It is ok, becuase the new script is much cleaner than the stock one, and also moves the `bss` segment down so that both the `ipcram` memory and the normal static variables can all be initialized to `0` in one big block. Note that we only want to zero out the `ipcram` in the BIOS startup, so the linker script for user programs will put the `bss` start above here.
22 |
23 | Another hard won discovery is that if you put anything into .bss, it seems to output the whole thing to the HEX file. We fix this by adding `(NOLOAD)` to the segment. Phew.
24 |
25 | To get Arduino use this custom script, we edit the `platform.txt` to have...
26 |
27 | ```
28 | recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" -Wl,-verbose -Wl,--script="{{build.core}/linkerscripts/avr5.xn" {compiler.c.elf.flags} -mmcu={build.mcu} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm
29 | ```
30 |
31 | But it is better to pre-compile this BIOS code into a HEX file and then have the Arduino code blindly flash it using AVRDUDE during the download. To compile in AS7, we have to add this to the `Toolchain->Linker->Misc->Linker flags`...
32 |
33 | `-Wl,--script="../../../src/linkscripts/avr5.xn"`
34 |
35 | The `-Wl,` means "pass the next arg to the linker and the `--script=` [specifies the linker script](ftp://ftp.gnu.org/pub/old-gnu/Manuals/ld-2.9.1/html_chapter/ld_2.html#SEC3). This sucks that we have to hard code the `avr5` in there but I think the mapping from MCU to those `avrX` code is hardcoded into gcc.
36 |
37 |
38 | To put a variable into this new section, we use...
39 |
40 | ```
41 | byte __attribute__((section ("ipcram1"))) counter=0;
42 | ```
43 |
44 | More info:
45 | https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Variable-Attributes.html
46 |
47 | ### Stack Overflow Detector
48 |
49 | We put the input section `.stackwatcher` after all the other stuff in the `data` memory section. We can then have the code put a special value here and periodically check that value to see if it changed. Since the stack grows down from the top of RAM, it will hit this first and so if anything here changes then we know that the stack got too big and overwrote it.
50 |
51 |
--------------------------------------------------------------------------------
/package_move38.com-blinks_index.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages": [
3 | {
4 | "name": "move38",
5 | "maintainer": "Move38.com",
6 | "websiteURL": "http://move38.com",
7 | "email": "move38arduino@joshreply.com",
8 |
9 | "help": {
10 | "online": "https://github.com/bigjosh/Move38-Arduino-Platform"
11 | },
12 | "platforms": [
13 | {
14 | "name": "Blinks",
15 | "architecture": "avr",
16 | "version": "1.0.0",
17 | "category": "Contributed",
18 | "help": {
19 | "online": "https://github.com/bigjosh/Move38-Arduino-Platform"
20 | },
21 | "url": "https://janedeveloper.github.io/myboard/myboard-1.0.0.zip",
22 | "archiveFileName": "myboard-1.0.0.zip",
23 | "checksum": "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1",
24 | "size": "15005",
25 | "boards": [
26 | {"name": "Blinks Tile"},
27 | ],
28 | "toolsDependencies": [
29 | {
30 | "packager": "arduino",
31 | "name": "avr-gcc",
32 | "version": "4.8.1-arduino5"
33 | },
34 | {
35 | "packager": "arduino",
36 | "name": "avrdude",
37 | "version": "6.0.1-arduino5"
38 | }
39 | ]
40 | },
41 | {
42 | "name": "My Board",
43 | "architecture": "avr",
44 | "version": "1.0.1",
45 | "category": "Contributed",
46 | "help": {
47 | "online": "http://janedeveloper.org/forum/myboard"
48 | },
49 | "url": "https://janedeveloper.github.io/myboard/myboard-1.0.1.zip",
50 | "archiveFileName": "myboard-1.0.1.zip",
51 | "checksum": "SHA-256:9c86ee28a7ce9fe33e8b07ec643316131e0031b0d22e63bb398902a5fdadbca9",
52 | "size": "15125",
53 | "boards": [
54 | {"name": "My Board"},
55 | {"name": "My Board Pro"}
56 | ],
57 | "toolsDependencies": [
58 | {
59 | "packager": "arduino",
60 | "name": "avr-gcc",
61 | "version": "4.8.1-arduino5"
62 | },
63 | {
64 | "packager": "arduino",
65 | "name": "avrdude",
66 | "version": "6.0.1-arduino5"
67 | }
68 | ]
69 | }
70 | ],
71 | "tools":[]
72 | }
73 | ]
74 | }
--------------------------------------------------------------------------------
/platform.txt:
--------------------------------------------------------------------------------
1 |
2 | # Arduino AVR Core and platform.
3 | # ------------------------------
4 | #
5 | # For more info:
6 | # https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification
7 |
8 | name=Move38
9 | version=1.1.1
10 |
11 | # AVR compile variables
12 | # ---------------------
13 |
14 | compiler.warning_flags=-w
15 | compiler.warning_flags.none=-w
16 | compiler.warning_flags.default=
17 | compiler.warning_flags.more=-Wall
18 | compiler.warning_flags.all=-Wall -Wextra
19 |
20 | # Default "compiler.path" is correct, change only if you want to override the initial value
21 | compiler.path={runtime.tools.avr-gcc.path}/bin/
22 | compiler.c.cmd=avr-gcc
23 | compiler.c.flags=-c -g -Os {compiler.warning_flags} -std=gnu11 -ffunction-sections -fdata-sections -MMD -flto -fno-fat-lto-objects
24 | compiler.c.elf.flags={compiler.warning_flags} -Os -g -flto -mrelax -fuse-linker-plugin -Wl,--gc-sections
25 | compiler.c.elf.cmd=avr-gcc
26 |
27 | compiler.S.flags=-c -g -x assembler-with-cpp -flto -MMD
28 |
29 | compiler.cpp.cmd=avr-g++
30 | compiler.cpp.flags=-c -g -Os {compiler.warning_flags} -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto
31 |
32 | compiler.ar.cmd=avr-gcc-ar
33 | compiler.ar.flags=rcs
34 |
35 | compiler.objcopy.cmd=avr-objcopy
36 | compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0
37 |
38 | # We need to explicitly remove .BSS from the hex file since the linker inexplicably includes .bss in .text
39 | # when we include .ipcram in .bss.
40 |
41 | # This 0x1700 is is the physical start address of the `built-in` program image area. This is
42 | # defined in the blinkbios as `FLASH_BUILTIN_IMAGE_START_ADDRESS`.
43 | # If you change this, then you must also update the LENGTH of the TEXT
44 | # area in the MEMORY section of linkscripts/avr5.xn to match.
45 | # Finally you must also update `blink.upload.maximum_size` in boards.txt
46 | # so that the Arduino IDE reports the correct values for program size after a compile.
47 | # Also remember that AVR flash memory is 16 bits wide so this number
48 | # is 1/2 what you expect it to be if you are thinking in bytes.
49 | compiler.elf2hex.flags=--change-addresses 0x1700 -O ihex -R .eepromm
50 | compiler.elf2hex.cmd=avr-objcopy
51 | compiler.ldflags=
52 | compiler.size.cmd=avr-size
53 |
54 | # This can be overridden in boards.txt
55 | build.extra_flags=
56 |
57 | # These can be overridden in platform.local.txt
58 | compiler.c.extra_flags=
59 | compiler.c.elf.extra_flags=
60 | compiler.S.extra_flags=
61 | compiler.cpp.extra_flags=
62 | compiler.ar.extra_flags=
63 | compiler.objcopy.eep.extra_flags=
64 | compiler.elf2hex.extra_flags=
65 |
66 | # AVR compile patterns
67 | # --------------------
68 |
69 | ## Compile c files
70 | recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
71 |
72 | ## Compile c++ files
73 | recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
74 |
75 | ## Compile S files
76 | recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.S.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
77 |
78 | ## Create archives
79 | # archive_file_path is needed for backwards compatibility with IDE 1.6.5 or older, IDE 1.6.6 or newer overrides this value
80 | archive_file_path={build.path}/{archive_file}
81 | recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}"
82 |
83 | ## Combine gc-sections, archives, and objects
84 | #recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} {compiler.c.elf.extra_flags} -Wl,--script={runtime.platform.path}/linkscripts/avr5.xn -Wl,-nostartfiles -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm
85 | #recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} {compiler.c.elf.extra_flags} -Wl,--print-gc-sections -Wl,--script={runtime.platform.path}/linkscripts/avr5.xn -Wl,-Map,{build.path}/out.map -nostartfiles -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm
86 | # Ok, I know that hard-coded path to the startup.S.o is ugly, but it took me a full day to figure out that the startup file can not be inside the archive and now I just need it to works so don't judge me.
87 | recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} {compiler.c.elf.extra_flags} -T "{runtime.platform.path}/linkscripts/avr5.xn" -nostartfiles -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm
88 |
89 | ## Create output files (.eep and .hex)
90 | recipe.objcopy.eep.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.objcopy.eep.flags} {compiler.objcopy.eep.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.eep"
91 | recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex"
92 |
93 | ## Save hex
94 | recipe.output.tmp_file={build.project_name}.hex
95 | recipe.output.save_file={build.project_name}.{build.variant}.hex
96 |
97 | ## Compute size
98 | recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
99 | recipe.size.regex=^(?:\.text|\.data|\.bootloader)\s+([0-9]+).*
100 | recipe.size.regex.data=^(?:\.data|\.bss|\.noinit)\s+([0-9]+).*
101 | recipe.size.regex.eeprom=^(?:\.eeprom)\s+([0-9]+).*
102 |
103 | ## Preprocessor
104 | preproc.includes.flags=-w -x c++ -M -MG -MP
105 | recipe.preproc.includes="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.includes.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}"
106 |
107 | preproc.macros.flags=-w -x c++ -E -CC
108 | recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.macros.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{preprocessed_file_path}"
109 |
110 | # AVR Uploader/Programmers tools
111 | # ------------------------------
112 |
113 | tools.avrdude.path={runtime.tools.avrdude.path}
114 | tools.avrdude.cmd.path={path}/bin/avrdude
115 | tools.avrdude.config.path={path}/etc/avrdude.conf
116 |
117 | tools.avrdude.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA
118 |
119 | tools.avrdude.upload.params.verbose=-v
120 | tools.avrdude.upload.params.quiet=-q -q
121 | # tools.avrdude.upload.verify is needed for backwards compatibility with IDE 1.6.8 or older, IDE 1.6.9 or newer overrides this value
122 | tools.avrdude.upload.verify=
123 | tools.avrdude.upload.params.noverify=-V
124 |
125 | # We replace the upload pattern with the program pattern because for now blinks code comes via programmer,
126 | # so putting this here lets us push the convenient "Upload" button rather than having to do the "Via Programmer" menu pick.
127 | # The -B 5 speeds up the clock to 200KHz which is the fastest we can go with the currently programmed 1MHz MCU clock at startup
128 | #Note that this used to be set to 250KHz but I found two different blinks that would not program at this speed
129 |
130 | # The second -U:flash programs the BlinkBIOS image into the bootlader are of the flash (check out the BlinkBIOS project for more info)
131 | # The -U:efuse programs the extended fuse to enable BOOTRST. This makes the chip jump to the bootloader area (with BlinkBIOS) on reset rather than 0x0000
132 | # The -u means "don't change the fuses back to what they were when we started". Silly, yes.
133 | # The -cusbtiny is hardcoded in there becuase the {protocol} does not seem to work with the upload event
134 | tools.avrdude.upload.pattern="{cmd.path}" "-C{config.path}" -B 5 {upload.verbose} {upload.verify} -p{build.mcu} -cusbtiny "-Uflash:w:{build.path}/{build.project_name}.hex:i" "-Uflash:w:{runtime.platform.path}/bootloaders/BlinkBIOS.hex:i" "-Uefuse:w:0xf8:m" -u
135 | #tools.avrdude.upload.pattern="{cmd.path}" "-C{config.path}" {upload.verbose} {upload.verify} -p{build.mcu} -c{upload.protocol} "-P{serial.port}" -b{upload.speed} -D "-Uflash:w:{build.path}/{build.project_name}.hex:i" "-Uflash:w:{build.core}/bootloader/XXXbin/blinkboot.hex:i"
136 |
137 | tools.avrdude.program.params.verbose=-v
138 | tools.avrdude.program.params.quiet=-q -q
139 | # tools.avrdude.program.verify is needed for backwards compatibility with IDE 1.6.8 or older, IDE 1.6.9 or newer overrides this value
140 | tools.avrdude.program.verify=
141 | tools.avrdude.program.params.noverify=-V
142 |
143 | # This just makes the "Upload via programmer" menu option work and do the same thing as the Upload button
144 | # The -B 5 speeds up the clock to 200KHz which is the fastest we can go with the currently programmed 1MHz MCU clock at startup
145 | #Note that this used to be set to 250KHz but I found two different blinks that would not program at this speed
146 | tools.avrdude.program.pattern="{cmd.path}" "-C{config.path}" -B 5 {program.verbose} {program.verify} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{build.path}/{build.project_name}.hex:i" "-Uflash:w:{runtime.platform.path}/bootloaders/BlinkBIOS.hex:i" -u
147 |
148 | tools.avrdude.erase.params.verbose=-v
149 | tools.avrdude.erase.params.quiet=-q -q
150 | tools.avrdude.erase.pattern="{cmd.path}" "-C{config.path}" {erase.verbose} -p{build.mcu} -c{protocol} {program.extra_params} -e -Ulock:w:{bootloader.unlock_bits}:m -Uefuse:w:{bootloader.extended_fuses}:m -Uhfuse:w:{bootloader.high_fuses}:m -Ulfuse:w:{bootloader.low_fuses}:m
151 |
152 | tools.avrdude.bootloader.params.verbose=-v
153 | tools.avrdude.bootloader.params.quiet=-q -q
154 | tools.avrdude.bootloader.pattern="{cmd.path}" "-C{config.path}" {bootloader.verbose} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{runtime.platform.path}/bootloaders/BlinkBIOS.hex:i" "-Uefuse:w:0xf8:m" -u
155 |
156 | tools.avrdude_remote.upload.pattern=/usr/bin/run-avrdude /tmp/sketch.hex {upload.verbose} -p{build.mcu}
157 |
158 | tools.avrdude.upload.network_pattern="{network_cmd}" -address {serial.port} -port {upload.network.port} -sketch "{build.path}/{build.project_name}.hex" -upload {upload.network.endpoint_upload} -sync {upload.network.endpoint_sync} -reset {upload.network.endpoint_reset} -sync_exp {upload.network.sync_return}
159 |
160 | # USB Default Flags
161 | # Default blank usb manufacturer will be filled in at compile time
162 | # - from numeric vendor ID, set to Unknown otherwise
163 | build.usb_manufacturer="Unknown"
164 | build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}'
165 |
--------------------------------------------------------------------------------
/programmers.txt:
--------------------------------------------------------------------------------
1 | avrisp.name=Blinks AVR ISP
2 | avrisp.communication=serial
3 | avrisp.protocol=stk500v1
4 | avrisp.program.protocol=stk500v1
5 | avrisp.program.tool=avrdude
6 | avrisp.program.extra_params=-P{serial.port}
7 |
8 | avrispmkii.name=Blinks AVRISP mkII
9 | avrispmkii.communication=usb
10 | avrispmkii.protocol=stk500v2
11 | avrispmkii.program.protocol=stk500v2
12 | avrispmkii.program.tool=avrdude
13 | avrispmkii.program.extra_params=-Pusb
14 |
15 | usbtinyisp.name=Blinks USBtinyISP
16 | usbtinyisp.protocol=usbtiny
17 | usbtinyisp.program.tool=avrdude
18 | usbtinyisp.program.extra_params=
19 |
20 | arduinoisp.name=Blinks ArduinoISP
21 | arduinoisp.protocol=arduinoisp
22 | arduinoisp.program.tool=avrdude
23 | arduinoisp.program.extra_params=
24 |
25 |
26 | usbasp.name=Blinks USBasp
27 | usbasp.communication=usb
28 | usbasp.protocol=usbasp
29 | usbasp.program.protocol=usbasp
30 | usbasp.program.tool=avrdude
31 | usbasp.program.extra_params=-Pusb
32 |
33 | arduinoasisp.name=Blinks Arduino as ISP
34 | arduinoasisp.communication=serial
35 | arduinoasisp.protocol=arduino
36 | arduinoasisp.speed=19200
37 | arduinoasisp.program.protocol=arduino
38 | arduinoasisp.program.speed=19200
39 | arduinoasisp.program.tool=avrdude
40 | arduinoasisp.program.extra_params=-P{serial.port} -b{program.speed}
41 |
--------------------------------------------------------------------------------
/variants/standard/dummy.txt:
--------------------------------------------------------------------------------
1 | This file is only here so git will make this directory.
--------------------------------------------------------------------------------