├── .gitignore
├── LICENSE
├── README.md
├── SBUS_inverter.png
├── SPort_OSD.ino
├── charset.png
├── max7456.cpp
├── max7456.h
└── max7456registers.h
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files
2 | *.slo
3 | *.lo
4 | *.o
5 |
6 | # Compiled Dynamic libraries
7 | *.so
8 | *.dylib
9 |
10 | # Compiled Static libraries
11 | *.lai
12 | *.la
13 | *.a
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | MinimOSD firmware using FrSky SPort telemetry as source
2 | =======================================================
3 |
4 | This code allows you to use a MinimOSD to overlay FrSky SPort telemetry data on your FPV video feed.
5 |
6 | It uses the following libraries:
7 | * my FrSky SPort library for Arduino at https://github.com/zendes/SPort
8 | * a max7456 library from theboredengineers.com/2012/12/a-max7456-library-for-arduino/
9 |
10 | To connect this to your Arduino, you'll need an inverter cable such as http://www.hobbyking.com/hobbyking/store/__24523__ZYX_S_S_BUS_Connection_Cable.html, or you can build your own using a TTL inverter or the schematic in the included SBUS_inverter.png file.
11 |
12 | Basic Installation
13 | ------------------
14 | ```
15 | $ cd
16 | $ git clone https://github.com/zendes/SPort_OSD.git
17 | $ cd libraries
18 | $ git clone https://github.com/zendes/SPort.git
19 | ```
20 |
21 | Then restart your Arduino IDE and open SPort_OSD.ino
--------------------------------------------------------------------------------
/SBUS_inverter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zendes/SPort_OSD/a4f3512a0412543cbb4eb2974c7ecaabca6b25c6/SBUS_inverter.png
--------------------------------------------------------------------------------
/SPort_OSD.ino:
--------------------------------------------------------------------------------
1 | #include
2 | SPort sport(Serial);
3 |
4 | #include
5 | #include "max7456.h"
6 | Max7456 osd;
7 | // Offset: 48,18
8 | // Dimensions: 0,0 to 25,12
9 |
10 | ISR(TIMER2_COMPA_vect) {
11 | sport.process();
12 | }
13 |
14 | void setup() {
15 | sport.begin();
16 |
17 | SPI.begin();
18 | osd.init(10);
19 | osd.setDisplayOffsets(48,18);
20 | osd.activateOSD();
21 |
22 | //consumption
23 | osd.print("0", 4, 10);
24 | osd.printMax7456Char(0x82, 6, 10);
25 |
26 | //current
27 | osd.print("0.00", 1, 11);
28 | osd.printMax7456Char(0x8F, 6, 11);
29 |
30 | //voltage
31 | osd.print("0.00", 1, 12);
32 | osd.printMax7456Char(0x8E, 6, 12);
33 |
34 | //velocity
35 | osd.print("0", 23, 10);
36 | osd.printMax7456Char(0x88, 25, 10);
37 |
38 | //altitude
39 | osd.print("0.0", 21, 11);
40 | osd.printMax7456Char(0x85, 25, 11);
41 |
42 | //time
43 | osd.print("00:00", 19, 12);
44 | osd.printMax7456Char(0xB3, 25, 12);
45 | }
46 |
47 |
48 | void loop() {
49 | //consumption
50 | if (sport.getVfasConsumption() < 10) {
51 | osd.print((int)sport.getVfasConsumption(), 4, 10, 1, 0);
52 | } else if (sport.getVfasConsumption() < 100) {
53 | osd.print((int)sport.getVfasConsumption(), 3, 10, 2, 0);
54 | } else if (sport.getVfasConsumption() < 1000) {
55 | osd.print((int)sport.getVfasConsumption(), 2, 10, 3, 0);
56 | } else {
57 | osd.print((int)sport.getVfasConsumption(), 1, 10, 4, 0);
58 | }
59 |
60 | //current
61 | if (sport.getVfasCurrent() < 10000) {
62 | osd.print(" ", 0, 11);
63 | osd.print((float)sport.getVfasCurrent() / 1000, 1, 11, 1, 2);
64 | } else {
65 | osd.print((float)sport.getVfasCurrent() / 1000, 0, 11, 2, 2);
66 | }
67 |
68 | //voltage
69 | if (sport.getVfasVoltage() < 10000) {
70 | osd.print(" ", 0, 12);
71 | osd.print((float)sport.getVfasVoltage() / 1000, 1, 12, 1, 2);
72 | } else {
73 | osd.print((float)sport.getVfasVoltage() / 1000, 0, 12, 2, 2);
74 | }
75 |
76 | //velocity
77 |
78 | //altitude
79 | osd.print(" ", 18, 11);
80 | if (sport.getVarioAltitude() < -1000) {
81 | osd.print((float)sport.getVarioAltitude() / 100, 19, 11, 2, 1);
82 | } else if (sport.getVarioAltitude() < 0) {
83 | osd.print((float)sport.getVarioAltitude() / 100, 20, 11, 1, 1);
84 | } else if (sport.getVarioAltitude() < 1000) {
85 | osd.print((float)sport.getVarioAltitude() / 100, 21, 11, 1, 1);
86 | } else if (sport.getVarioAltitude() < 10000) {
87 | osd.print((float)sport.getVarioAltitude() / 100, 20, 11, 2, 1);
88 | } else if (sport.getVarioAltitude() < 100000) {
89 | osd.print((float)sport.getVarioAltitude() / 100, 19, 11, 3, 1);
90 | } else {
91 | osd.print((float)sport.getVarioAltitude() / 100, 18, 11, 4, 1);
92 | }
93 |
94 | //time
95 | long counter = millis()/1000;
96 | osd.print(int(counter/60), 19, 12, 2, 0);
97 | osd.print(int(counter%60), 22, 12, 2, 0);
98 |
99 | delay(100);
100 | }
101 |
--------------------------------------------------------------------------------
/charset.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zendes/SPort_OSD/a4f3512a0412543cbb4eb2974c7ecaabca6b25c6/charset.png
--------------------------------------------------------------------------------
/max7456.cpp:
--------------------------------------------------------------------------------
1 | #include "max7456.h"
2 | #include
3 | #include
4 |
5 |
6 | //-----------------------------------------------------------------------------
7 | // Implements Max7456::Max7456
8 | //-----------------------------------------------------------------------------
9 | Max7456::Max7456(byte pinCS)
10 | {
11 | this->init(pinCS);
12 | }
13 |
14 | //-----------------------------------------------------------------------------
15 | // Implements Max7456::setBlinkParams
16 | //-----------------------------------------------------------------------------
17 | void Max7456::setBlinkParams(byte blinkBase, byte blinkDC)
18 | {
19 | _regVm1.bits.blinkingTime = blinkBase;
20 | _regVm1.bits.blinkingDutyCycle = blinkDC;
21 | digitalWrite(_pinCS, LOW);
22 | SPI.transfer(VM1_ADDRESS_WRITE);
23 | SPI.transfer(_regVm1.whole);
24 | digitalWrite(_pinCS, HIGH);
25 | }
26 |
27 |
28 | //-----------------------------------------------------------------------------
29 | // Implements Max7456::setDisplayOffsets
30 | //----------------------------------------------------------------------------
31 | void Max7456::setDisplayOffsets(byte horizontal, byte vertical)
32 | {
33 |
34 | _regHos.whole = 0;
35 | _regVos.whole = 0;
36 |
37 | _regHos.bits.horizontalPositionOffset = horizontal;
38 | _regVos.bits.verticalPositionOffset = vertical;
39 |
40 | digitalWrite(_pinCS, LOW);
41 | SPI.transfer(HOS_ADDRESS_WRITE);
42 | SPI.transfer(_regHos.whole);
43 |
44 | SPI.transfer(VOS_ADDRESS_WRITE);
45 | SPI.transfer(_regVos.whole);
46 |
47 | digitalWrite(_pinCS, HIGH);
48 | }
49 |
50 | //-----------------------------------------------------------------------------
51 | // Implements Max7456::Max7456
52 | //-----------------------------------------------------------------------------
53 | Max7456::Max7456()
54 | {
55 | }
56 |
57 |
58 | //-----------------------------------------------------------------------------
59 | // Implements Max7456::sendCharacter
60 | //-----------------------------------------------------------------------------
61 | void Max7456::sendCharacter(const charact chara, byte x, byte y)
62 | {
63 | byte charAddress;
64 | if (y < 0)
65 | charAddress = x;
66 | else
67 | charAddress = x + (y << 4);
68 | activateOSD(false);
69 | //datasheet p38
70 | digitalWrite(_pinCS, LOW);
71 | SPI.transfer(CMAH_ADDRESS_WRITE);
72 | SPI.transfer(charAddress);
73 |
74 | for (byte i = 0 ; i < 54 ; i++)
75 | {
76 | SPI.transfer(CMAL_ADDRESS_WRITE);
77 | SPI.transfer(i);
78 | SPI.transfer(CMDI_ADDRESS_WRITE);
79 | SPI.transfer(chara[i]);
80 | }
81 |
82 | _regCmm = 0xA0; //To write the NVM array
83 | SPI.transfer(CMM_ADDRESS_WRITE);
84 | SPI.transfer(_regCmm);
85 | //while STAT[5] is not good, we wait.
86 | _regStat.bits.characterMemoryStatus = 1;
87 | while ( _regStat.bits.characterMemoryStatus == 1)
88 | {
89 | SPI.transfer(STAT_ADDRESS_READ);
90 | _regStat.whole = SPI.transfer(0x00);
91 | }
92 |
93 |
94 | digitalWrite(_pinCS, HIGH);
95 | }
96 |
97 |
98 | //-----------------------------------------------------------------------------
99 | // Implements Max7456::getCharacter
100 | //-----------------------------------------------------------------------------
101 | void Max7456::getCharacter(charact chara, byte x, byte y)
102 | {
103 | byte charAddress;
104 |
105 |
106 | if (y <= 0)
107 | charAddress = x;
108 | else
109 | charAddress = x + y * 16;
110 |
111 | activateOSD(false);
112 | //datasheet p38
113 | digitalWrite(_pinCS, LOW);
114 |
115 |
116 | SPI.transfer(CMAH_ADDRESS_WRITE);
117 | SPI.transfer(charAddress);
118 |
119 | _regCmm = 0x50; //To read from the NVM array
120 | SPI.transfer(CMM_ADDRESS_WRITE);
121 | SPI.transfer(_regCmm);
122 |
123 |
124 | for (byte i = 0 ; i < 54 ; i++)
125 | {
126 | SPI.transfer(CMAL_ADDRESS_WRITE);
127 | SPI.transfer(i);
128 |
129 | SPI.transfer(CMDO_ADDRESS_READ); //read from device through spi
130 | chara[i] = SPI.transfer(0x00);
131 | }
132 |
133 | digitalWrite(_pinCS, HIGH);
134 |
135 | }
136 | //-----------------------------------------------------------------------------
137 | // Implements Max7456::printCharacterToSerial
138 | //-----------------------------------------------------------------------------
139 | void Max7456::printCharacterToSerial(const charact array, bool img)
140 | {
141 |
142 | if (img)
143 | {
144 | CARACT car ;
145 | car = Max7456::byteArray2CARACT(array);
146 |
147 | Serial.println("------------");
148 | for (int i = 0 ; i < 18 ; i++)
149 | {
150 | for (int j = 0 ; j < 3 ; j++)
151 | {
152 | printPixel(car.line[i].pixels[j].pix0);
153 | printPixel(car.line[i].pixels[j].pix1);
154 | printPixel(car.line[i].pixels[j].pix2);
155 | printPixel(car.line[i].pixels[j].pix3);
156 | }
157 |
158 | Serial.println("");
159 | }
160 | Serial.println("------------");
161 | }
162 |
163 | else
164 | {
165 | Serial.print("{");
166 | for (unsigned int i = 0 ; i < 53 ; i++)
167 | {
168 | Serial.print("0x");
169 | Serial.print(String(array[i], HEX));
170 | Serial.print(", ");
171 | }
172 | Serial.print("0x");
173 | Serial.print(String(array[53], HEX));
174 | Serial.println("};");
175 | }
176 | }
177 |
178 | void Max7456::printPixel(byte value)
179 | {
180 | switch (value )
181 | {
182 | case COLOR_BLACK :
183 | Serial.print("#");
184 | return;
185 | case COLOR_WHITE :
186 | Serial.print("*");
187 | return;
188 | default:
189 | Serial.print(" ");
190 | return;
191 | }
192 | }
193 |
194 |
195 | //-----------------------------------------------------------------------------
196 | // Implements Max7456::print
197 | //-----------------------------------------------------------------------------
198 | void Max7456::print(const char string[], byte x, byte y, byte blink, byte inv)
199 | {
200 | char currentChar;
201 | byte size;
202 | byte *chars = NULL;
203 |
204 | if (!string) return;
205 |
206 | size = 0;
207 | currentChar = string[0];
208 |
209 | while (currentChar != '\0')
210 | {
211 | currentChar = string[++size];
212 | }
213 |
214 | chars = (byte*) malloc(size * sizeof(byte));
215 |
216 | for (byte i = 0 ; i < size ; i++)
217 | {
218 | chars[i] = Max7456::giveMax7456CharFromAsciiChar(string[i]);
219 | }
220 |
221 | printMax7456Chars(chars, size, x, y, blink , inv );
222 | free(chars);
223 | }
224 |
225 |
226 | void Max7456::printMax7456Char(const byte address, byte x, byte y, byte blink, byte inv)
227 | {
228 | byte ad = address;
229 | printMax7456Chars(&ad, 1, x, y, blink, inv);
230 | }
231 |
232 | //-----------------------------------------------------------------------------
233 | // Implements Max7456::printMax7456Chars
234 | //-----------------------------------------------------------------------------
235 | void Max7456::printMax7456Chars(byte chars[], byte size, byte x, byte y, byte blink , byte inv )
236 | {
237 | byte currentCharMax7456;
238 | byte posAddressLO;
239 | byte posAddressHI;
240 | unsigned int posAddress;
241 |
242 | posAddress = 30 * y + x;
243 |
244 | posAddressHI = posAddress >> 8;
245 | posAddressLO = posAddress;
246 |
247 | _regDmm.whole = 0x01;
248 |
249 | _regDmm.bits.INV = inv;
250 | _regDmm.bits.BLK = blink;
251 |
252 | digitalWrite(_pinCS, LOW);
253 | SPI.transfer(DMM_ADDRESS_WRITE);
254 |
255 |
256 |
257 | SPI.transfer(_regDmm.whole);
258 |
259 |
260 | SPI.transfer(DMAH_ADDRESS_WRITE); // set start address high
261 | SPI.transfer(posAddressHI);
262 |
263 | SPI.transfer(DMAL_ADDRESS_WRITE); // set start address low
264 | SPI.transfer(posAddressLO);
265 |
266 |
267 | for (int i = 0; i < size ; i++)
268 | {
269 | currentCharMax7456 = chars[i];
270 | SPI.transfer(DMDI_ADDRESS_WRITE);
271 | SPI.transfer(currentCharMax7456);
272 |
273 | }
274 |
275 | //end character (we're done).
276 | SPI.transfer(DMDI_ADDRESS_WRITE);
277 | SPI.transfer(0xff);
278 |
279 | /*
280 | _regVm0.bits.
281 | SPI.transfer(VM0_ADDRESS_WRITE);
282 | SPI.transfer(0x4c);*/
283 |
284 |
285 | digitalWrite(_pinCS, HIGH);
286 | }
287 |
288 |
289 | //-----------------------------------------------------------------------------
290 | // Implements Max7456::print
291 | //-----------------------------------------------------------------------------
292 |
293 | void Max7456::print(double value, byte x, byte y, byte before, byte after, byte blink, byte inv)
294 | {
295 | char *strValue = NULL;
296 |
297 | strValue = (char*) malloc((before + after + 2) * sizeof(char));
298 |
299 |
300 | if (after == 0)
301 | dtostrf(value, before + after, after, strValue);
302 | else
303 | dtostrf(value, before + after + 1, after, strValue);
304 |
305 | for (int i = 0 ; i < before + after + 1; i++)
306 | {
307 | if (strValue[i] == ' ' || strValue[i] == '-')
308 | strValue[i] = '0';
309 | }
310 | if (value < 0)
311 | strValue[0] = '-';
312 | if (after == 0) //If the result is bigger, we truncate it so the OSD won't be falsed.
313 | strValue[before] = '\0';
314 | else
315 | strValue[before + after + 1] = '\0';
316 |
317 | print(strValue, x, y, blink, inv);
318 |
319 | free(strValue);
320 | }
321 |
322 |
323 | //-----------------------------------------------------------------------------
324 | // Implements Max7456::giveMax7456CharFromAsciiChar
325 | //-----------------------------------------------------------------------------
326 | byte Max7456::giveMax7456CharFromAsciiChar(char ascii)
327 | {
328 | #ifdef MAX7456_TABLE_ASCII
329 | if (ascii >= ' ' && ascii <= 'z')
330 | return ascii - ' ';
331 | else
332 | return ascii;
333 | #else
334 | return ascii;
335 | #endif
336 | }
337 |
338 |
339 | //-----------------------------------------------------------------------------
340 | // Implements Max7456::clearScreen
341 | //-----------------------------------------------------------------------------
342 | void Max7456::clearScreen()
343 | {
344 | _regDmm.bits.clearDisplayMemory = 1 ;
345 |
346 | digitalWrite(_pinCS, LOW);
347 |
348 | SPI.transfer(DMM_ADDRESS_WRITE);
349 | SPI.transfer(_regDmm.whole);
350 |
351 | //wait for operation to be complete.
352 | while (_regDmm.bits.clearDisplayMemory == 1 )
353 | {
354 | SPI.transfer(DMM_ADDRESS_READ);
355 | _regDmm.whole = SPI.transfer(0x00);
356 | }
357 | digitalWrite(_pinCS, HIGH); //disable device
358 | }
359 |
360 |
361 | //-----------------------------------------------------------------------------
362 | // Implements Max7456::init
363 | //-----------------------------------------------------------------------------
364 | void Max7456::init(byte iPinCS)
365 | {
366 | _pinCS = iPinCS;
367 | _isActivatedOsd = false;
368 |
369 | _regVm1.whole = 0b01000111;
370 | pinMode(iPinCS, OUTPUT);
371 | digitalWrite(iPinCS, HIGH); //disable device
372 | delay(100); //power up time
373 |
374 | digitalWrite(_pinCS, LOW);
375 | SPI.transfer(VM0_ADDRESS_WRITE);
376 |
377 | _regVm0.whole = 0x00;
378 | _regVm0.bits.videoSelect = 1; //PAL
379 | _regVm0.bits.softwareResetBit = 1;
380 | SPI.transfer(_regVm0.whole);
381 | digitalWrite(_pinCS, HIGH);
382 | delay(500);
383 |
384 |
385 | digitalWrite(_pinCS, LOW);
386 | for (int x = 0 ; x < 16 ; x++)
387 | {
388 | _regRb[x].whole = 0x00;
389 | _regRb[x].bits.characterWhiteLevel = 2;
390 | SPI.transfer(x + RB0_ADDRESS_WRITE);
391 | SPI.transfer(_regRb[x].whole);
392 | }
393 |
394 | _regVm0.whole = 0x00;
395 |
396 | _regVm0.bits.verticalSynch = 1;
397 |
398 | SPI.transfer(VM0_ADDRESS_WRITE);
399 |
400 | SPI.transfer(_regVm0.whole);
401 |
402 |
403 | // digitalWrite(_pinCS,HIGH);
404 | //
405 | // digitalWrite(_pinCS,LOW);
406 | //SPI.transfer(VM1_ADDRESS_WRITE);
407 | //SPI.transfer(0x0C);
408 |
409 | digitalWrite(_pinCS, HIGH);
410 |
411 | }
412 |
413 |
414 | //-----------------------------------------------------------------------------
415 | // Implements Max7456::activateOSD
416 | //-----------------------------------------------------------------------------
417 | void Max7456::activateOSD(bool act)
418 | {
419 | if (_isActivatedOsd != act)
420 | {
421 |
422 | _regVm0.bits.videoSelect = 1;
423 | if (act)
424 | _regVm0.bits.enableOSD = 1;
425 | else
426 | _regVm0.bits.enableOSD = 0;
427 |
428 | digitalWrite(_pinCS, LOW);
429 | SPI.transfer(VM0_ADDRESS_WRITE);
430 | SPI.transfer(_regVm0.whole);
431 | digitalWrite(_pinCS, HIGH);
432 | _isActivatedOsd = act;
433 | }
434 | }
435 |
436 |
437 | //-----------------------------------------------------------------------------
438 | // Implements Max7456::activateExternalVideo
439 | //-----------------------------------------------------------------------------
440 | void Max7456::activateExternalVideo(bool activExtVid)
441 | {
442 | if (!activExtVid)
443 | _regVm0.bits.synchSelect = 3; //11
444 | else
445 | _regVm0.bits.synchSelect = 0; //0
446 |
447 | digitalWrite(_pinCS, LOW);
448 | SPI.transfer(VM0_ADDRESS_WRITE);
449 | SPI.transfer(_regVm0.whole);
450 | digitalWrite(_pinCS, HIGH);
451 | }
452 |
453 |
454 | //-----------------------------------------------------------------------------
455 | // Implements Max7456::CARACT2ByteArray
456 | //-----------------------------------------------------------------------------
457 | byte* Max7456::CARACT2ByteArray(const CARACT car)
458 | {
459 | byte *array = NULL;
460 | array = new charact;
461 | for (int i = 0 ; i < 54 ; i++)
462 | array[i] = car.whole[i];
463 |
464 | return array;
465 | }
466 |
467 |
468 | //-----------------------------------------------------------------------------
469 | // Implements Max7456::byteArray2CARACT
470 | //-----------------------------------------------------------------------------
471 | CARACT Max7456::byteArray2CARACT(const charact array)
472 | {
473 | CARACT car;
474 | for (int i = 0 ; i < 54 ; i++)
475 | car.whole[i] = array[i];
476 |
477 | return car;
478 | }
479 |
480 |
481 | //-----------------------------------------------------------------------------
482 | // Implements Max7456::getCARACFromProgMem
483 | //-----------------------------------------------------------------------------
484 | void Max7456::getCARACFromProgMem(const prog_uchar *table, byte i, charact car)
485 | {
486 | unsigned long index;
487 | byte read;
488 | index = i * 54;
489 | for (unsigned long j = 0 ; j < 54 ; j++)
490 | {
491 | read = pgm_read_byte_near(table + index + j );
492 | car[j] = read;
493 | if (car[j] == 0x55)
494 | car[j] = 0xff;
495 | }
496 | }
497 |
498 |
499 |
--------------------------------------------------------------------------------
/max7456.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file
3 | * max7456.h
4 | *
5 | * Created on: 10 oct. 2012
6 | * Author: Benoit
7 | */
8 |
9 | #ifndef MAX7456_H
10 | #define MAX7456_H
11 |
12 |
13 | //def next only if you changed your table for an ascii one
14 | //i.e address 0x00 -> ' '
15 | //....
16 | // address 0x5A -> 'z'
17 | //#define MAX7456_TABLE_ASCII
18 |
19 | #include "max7456registers.h"
20 |
21 |
22 |
23 | /**
24 | * @mainpage Max7456 Arduino library
25 | */
26 |
27 | /**
28 | * @example Max7456WriteTable.cpp
29 | */
30 |
31 |
32 | /**
33 | * @class Max7456
34 | * @brief Represents a max7456 device communicating through SPI port
35 | */
36 | class Max7456
37 | {
38 | public:
39 |
40 |
41 | /**
42 | * Default constructor
43 | */
44 | Max7456();
45 |
46 |
47 | /**
48 | * Constructor
49 | * Initialize communications and device
50 | * @param pinCS : pin ~CS of the arduino where max7456 is plugged.
51 | */
52 | Max7456(byte pinCS);
53 |
54 |
55 | /**
56 | * Initialize communications and device
57 | * @param pinCS : pin ~CS of the arduino where max7456 is plugged.
58 | * @code
59 | * Max7456 osd;
60 | * osd.init(9); //Note it's that it's the same than usinge constructor Max7456(byte pinCS).
61 | * @endcode
62 | */
63 | void init(byte pinCS);
64 |
65 | /**
66 | * Set the base time for blink.
67 | * @param blinkBase : the base time (see datasheet)
68 | * @param blinkDC : blink Duty cycle (see datasheet).
69 | */
70 | void setBlinkParams(byte blinkBase, byte blinkDC);
71 |
72 |
73 | /**
74 | * Set Horizontal and Vertical display offset
75 | * @param horizontal : the horizontal offset in pixels (between 0 and 63).
76 | * @param vertical : the vertical offset in pixels (between 0 and 31).
77 | */
78 | void setDisplayOffsets(byte horizontal, byte vertical);
79 |
80 |
81 | /**
82 | * Erase Display Memory.
83 | */
84 | void clearScreen();
85 |
86 |
87 | /**
88 | * Activate osd on screen
89 | * @param act :
90 | * @li if true OSD is activated
91 | * @li if false OSD is deactivated
92 | */
93 | void activateOSD(bool act = true);
94 |
95 |
96 | /**
97 | * Activate input video as a background
98 | * @param activExtVid :
99 | * @li if true external video is displayed
100 | * @li if false external video is not displayed (bakground = grey)
101 | */
102 | void activateExternalVideo(bool activExtVid = true);
103 |
104 |
105 | /**
106 | * Put a character in the memory character of max7456
107 | * @param array : the byte array representing the character (54 bytes long)
108 | * @param x : the horizontal position of character in memory
109 | * @param y : the vertical position of character in memory.
110 | * @code
111 | * charact c={0x44,....} //Whatever charact here
112 | * max.sendCharacter(c,4,5); //put c at 4th line 5th column ie. address 54.
113 | * max.sendCharacter(c,0x43); //put c in mem at address 43.
114 | * @endcode
115 | */
116 | void sendCharacter(const charact array, byte x, byte y);
117 |
118 |
119 | /**
120 | * Get a character from the character memory of max7456
121 | * @param array : the byte array representing the character (54 bytes long)
122 | * @param x : the horizontal position of character in character memory
123 | * @param y : the vertical position of character in character memory
124 | */
125 | void getCharacter(charact array, byte x, byte y);
126 |
127 |
128 | /**
129 | * Put a string in the display memory of max7456
130 | * @param string : The string to be displayed
131 | * @param x : the horizontal position of the string on screen
132 | * @param y : the vertical position of the string on screen
133 | * @param blink : if 1 then character will blink
134 | * @param inv : if 1 then color character will be inverted
135 | * @note : In order to have this function working,
136 | * you must rewrite your Max7456 Eeprom memory and make the first
137 | * characters the ascii characters between ' ' and 'z'
138 | * (' ' being at address 0x00, z being at address 'z'-' ').
139 | */
140 | void print(const char string[], byte x, byte y, byte blink = 0, byte inv = 0);
141 |
142 |
143 |
144 | /**
145 | * Put a float in the display memory of max7456
146 | * @param value : The value to be displayed
147 | * @param x : the horizontal position of the value on screen
148 | * @param y : the vertical position of the value on screen
149 | * @param before : number of digits before comma
150 | * @param after : number of digits after comma
151 | * @param blink : if 1 then character will blink
152 | * @param inv : if 1 then color character will be inverted
153 | * @note The number of printed characters will be : before + after + 1.
154 | * @note Be aware of having a coherence between the number of digits you
155 | * enter in the function and the max. value of your double. If not may
156 | * result in unpredictable printed string.
157 | * @code
158 | * max.print(3.14,x,y,3,4);
159 | * //Will print "003.1400" on screen
160 | * @endcode
161 | */
162 | void print(double value, byte x, byte y, byte before, byte after, byte blink = 0, byte inv = 0);
163 |
164 |
165 | /**
166 | * Put some characters in the display memory of max7456.
167 | * The characters are given by their address in the
168 | * character memory of the max7456.
169 | * @param chars : The characters address array to display
170 | * @param size : the array size
171 | * @param x : the horizontal position of the value on screen
172 | * @param y : the vertical position of the value on screen
173 | * @param blink : if 1 then character will blink
174 | * @param inv : if 1 then color character will be inverted
175 | * @code
176 | * char chars[0x04,0x45,0x54]; //the chars addresses array to be send to function.
177 | * max.printMax7456Chars(chars,3,x,y);
178 | * @endcode
179 | */
180 | void printMax7456Chars(byte chars[], byte size, byte x, byte y, byte blink = 0, byte inv = 0);
181 |
182 |
183 | /**
184 | * Put one character from the character memory in the display memory of max7456
185 | * @param address : The address in character memory of the character to be displayed
186 | * @param x : the horizontal position of the string on screen
187 | * @param y : the vertical position of the string on screen
188 | * @param blink : if 1 then character will blink
189 | * @param inv : if 1 then color character will be inverted
190 | */
191 | void printMax7456Char(const byte address, byte x, byte y, byte blink = 0, byte inv = 0);
192 |
193 | /**
194 | * Print a character to Serial port
195 | * @param array : the byte array representing the character (54 bytes long)
196 | * @param img :
197 | * @li true : the character will be displayed as a picture
198 | * @li false : the character will be displayed as a byte array
199 | */
200 | static void printCharacterToSerial(const charact array, bool img = true);
201 |
202 |
203 | /**
204 | * Converts a CARACT character to a byte array representation.
205 | * @param car : the CARACT character
206 | * @return : the byte array representing the character (54 bytes long)
207 | */
208 | static byte* CARACT2ByteArray(const CARACT car);
209 |
210 |
211 | /**
212 | * Converts a byte array to a CARACT character.
213 | * @param array : the byte array representing the character (54 bytes long)
214 | * @return : the CARACT character
215 | */
216 | static CARACT byteArray2CARACT(const charact array);
217 |
218 |
219 | /**
220 | * Get the ith character from program memory
221 | * @param table the address of the array in prog memory
222 | * @param i the index of character.
223 | * @param c the returned character.
224 | * @note The table must be in program memory as an array of bytes (a multiple of 54).
225 | * @note When accessing this array, 0x55 are interpreted as 0xFF (you can't have 0xFF in program memory.
226 | * @note See file example for more informations.
227 | */
228 | static void getCARACFromProgMem(const prog_uchar *table, byte i, charact c);
229 |
230 | private:
231 |
232 | byte giveMax7456CharFromAsciiChar(char ascii);
233 | static void printPixel(byte value);
234 |
235 | byte _pinCS;
236 | bool _isActivatedOsd;
237 | //registers (only here for convenience : not forced to be used).
238 | REG_VM0 _regVm0;
239 | REG_VM1 _regVm1;
240 | REG_HOS _regHos;
241 | REG_VOS _regVos;
242 | REG_DMM _regDmm;
243 | REG_DMAH _regDmah; // not used yet
244 | REG_DMAL _regDmal; // not used yet
245 | REG_DMDI _regDmdi; // not used yet
246 | REG_CMM _regCmm;
247 | REG_CMAH _regCmah; // not used yet
248 | REG_CMAL _regCmal; // not used yet
249 | REG_CMDI _regCmdi; // not used yet
250 | REG_OSDM _regOsdm; // not used yet
251 | REG_RBN _regRb[16]; // not used yet
252 | REG_OSDBL _regOsdbl; // not used yet
253 | REG_STAT _regStat; // not used yet
254 | DMDO _regDmdo; // not used yet
255 | REG_CMDO _regCmdo; // not used yet
256 | };
257 |
258 |
259 | #endif /* MAX7456_H_ */
260 |
261 |
262 |
--------------------------------------------------------------------------------
/max7456registers.h:
--------------------------------------------------------------------------------
1 | /*
2 | * max7456Registers.h
3 | *
4 | * Created on: 13 oct. 2012
5 | * Author: Benoit
6 | */
7 |
8 | #ifndef MAX7456REGISTERS_H_
9 | #define MAX7456REGISTERS_H_
10 |
11 |
12 | #include
13 |
14 |
15 | /**
16 | * @typedef charact
17 | * @brief Represents a character as stored in max7456 character memory.
18 | */
19 | typedef byte charact[54];
20 |
21 | #define VM0_ADDRESS_WRITE 0x00
22 | #define VM0_ADDRESS_READ 0x80
23 |
24 | /**
25 | * @union REG_VM0
26 | * @brief Represents a Video Mode 0 Register value
27 | */
28 | union REG_VM0
29 | {
30 | /**@brief The whole value*/
31 | unsigned char whole ;
32 | /**
33 | * @var bits
34 | * @brief access to individual bits*/
35 | struct
36 | {
37 | /**@brief Video BUffer Enable
38 | * @li 0 = Enable
39 | * @li 1 = Disable(VOUT is high impedance)
40 | */
41 | unsigned char videoBuffer : 1;
42 |
43 | /**@brief Software Reset Bit
44 | * @li When bit set all register are set to default.
45 | */
46 | unsigned char softwareResetBit : 1;
47 |
48 | /**@brief Vertical Synchronization of On-Screen Data
49 | * @li 0 = Enable osd immediately
50 | * @li 1 = Enable osd at the next ~VSYNC
51 | */
52 | unsigned char verticalSynch : 1;
53 |
54 | /**@brief Enable Display of OSD Image
55 | * @li 0 = Off
56 | * @li 1 = On
57 | */
58 | unsigned char enableOSD : 1;
59 |
60 | /**@brief Synch Select Mode
61 | * @li 0x (0 ou 1) = Autosynch select
62 | * @li 10 (2) = external
63 | * @li 11 (3) = internal
64 | */
65 | unsigned char synchSelect : 2;
66 |
67 | /**@brief Video Standard Select
68 | * @li 0 = NTSC
69 | * @li 1 = PAL
70 | */
71 | unsigned char videoSelect : 1;
72 |
73 | /**@brief don't care*/
74 | unsigned char unused : 1;
75 |
76 | } bits;
77 | };
78 |
79 |
80 | #define VM1_ADDRESS_WRITE 0x01
81 | #define VM1_ADDRESS_READ 0x81
82 |
83 | /**@union REG_VM1
84 | * @brief Represents a Video Mode 1 Register value.
85 | */
86 | union REG_VM1
87 | {
88 | /**@brief The whole register value*/
89 | unsigned char whole;
90 | /**
91 | * @var bits
92 | * @brief access to individual bits*/
93 | struct
94 | {
95 |
96 | /**@brief Blinking Duty Cycle (On:Off)
97 | * @li b00 (0) = BT:BT
98 | * @li b01 (1) = BT:(2*BT)
99 | * @li b10 (2) = BT:(3*BT)
100 | * @li b11 (3) = (3*BT):BT
101 | */
102 | unsigned char blinkingDutyCycle : 2;
103 |
104 |
105 | /**@brief Blinking Time (BT)
106 | * @li b00 (0) = 2 fields (NTSC = 33ms ; PAL = 40ms)
107 | * @li b01 (1) = 4 fields (NTSC = 67ms ; PAL = 80ms)
108 | * @li b10 (2) = 6 fields (NTSC = 100ms ; PAL = 120ms)
109 | * @li b11 (3) = 8 fields (NTSC = 133ms ; PAL = 160ms)
110 | */
111 | unsigned char blinkingTime : 2;
112 |
113 |
114 | /**@brief Background Mode Brightness
115 | * @li b000 (0) = 0%
116 | * @li b001 (1) = 7%
117 | * @li b010 (2) = 14%
118 | * @li b011 (3) = 21%
119 | * @li b100 (4) = 28%
120 | * @li b101 (5) = 35%
121 | * @li b110 (6) = 43%
122 | * @li b111 (7) = 49%
123 | */
124 | unsigned char backgroundModeBrightness : 3;
125 |
126 | /**@brief Background Mode
127 | * @li 0 = DMM[5] & DMM[7] sets the state of each character background
128 | * @li 1 = Sets all displayed background pixel to gray
129 | */
130 | unsigned char backgroundMode : 1;
131 | } bits;
132 | };
133 |
134 | #define HOS_ADDRESS_WRITE 0x02
135 | #define HOS_ADDRESS_READ 0x82
136 |
137 | /**@union REG_HOS
138 | * @brief Represents a Horizontal Offset Register value.
139 | */
140 | union REG_HOS
141 | {
142 | /**@brief The whole register value*/
143 | unsigned char whole;
144 | /**
145 | * @var bits
146 | * @brief access to individual bits*/
147 | struct
148 | {
149 | /**@brief Vertical Position Offset
150 | * @li b00 0000 (0) = Farthest left (-32 pixels)
151 | * @li .
152 | * @li .
153 | * @li b10 0000 (32) = No horizontal offset
154 | * @li .
155 | * @li .
156 | * @li b11 1111 (31) = Farthest right (+31pixels)
157 | */
158 | unsigned char horizontalPositionOffset : 6;
159 |
160 | /**@brief Don't care*/
161 | unsigned char unsused : 2;
162 |
163 | } bits;
164 | };
165 |
166 |
167 | #define VOS_ADDRESS_WRITE 0x03
168 | #define VOS_ADDRESS_READ 0x83
169 |
170 | /**@union REG_VOS
171 | * @brief Represents a Vertical Offset Register value.
172 | */
173 | union REG_VOS
174 | {
175 | /**@brief The whole register value*/
176 | unsigned char whole;
177 | /**
178 | * @var bits
179 | * @brief access to individual bits*/
180 | struct
181 | {
182 | /**@brief Vertical Position Offset
183 | * @li b0 0000 (0) = Farthest up (+16 pixels)
184 | * @li .
185 | * @li .
186 | * @li b1 0000 (16) = No vertical offset
187 | * @li .
188 | * @li .
189 | * @li b1 1111 (31) = Farthest down (-15 pixels)
190 | */
191 | unsigned char verticalPositionOffset : 5;
192 | /**@brief Don't care*/
193 | unsigned char unsused : 3;
194 |
195 | } bits;
196 | };
197 |
198 | #define DMM_ADDRESS_WRITE 0x04
199 | #define DMM_ADDRESS_READ 0x84
200 | /**@union REG_DMM
201 | * @brief Represents a Display Memory Mode value.
202 | */
203 | union REG_DMM
204 | {
205 | /**@brief The whole register value*/
206 | unsigned char whole;
207 | /**
208 | * @var bits
209 | * @brief access to individual bits*/
210 | struct
211 | {
212 | /**@brief Auto-Increment Mode
213 | * @li 0 = Disabled
214 | * @li 1 = Enabled
215 | * @note When this bit is enabled for the first time, data in the Display Memory Address (DMAH[0] and
216 | DMAL[7:0]) registers are used as the starting location to which the data is written. When performing
217 | the auto-increment write for the display memory, the 8-bit address is internally generated, and
218 | therefore only 8-bit data is required by the SPI-compatible interface (Figure 21). The content is to
219 | be interpreted as a Character Address byte if DMAH[1] = 0 or a Character Attribute byte if
220 | DMAH[1] = 1. This mode is disabled by writing the escape character 1111 1111.
221 | If the Clear Display Memory bit is set, this bit is reset internally.
222 | */
223 | unsigned char autoIncrementMode : 1;
224 | /**@brief Vertical Sync Clear (Valid only when clear display memory = 1, (DMM[2] = 1) )
225 | * @li 0 = Immediately applies the clear display-memory command, DMM[2] = 1
226 | * @li 1 = Applies the clear display-memory command, DMM[2] = 1, at the next VSYNC time
227 | */
228 | unsigned char verticalSynchClear : 1;
229 | /**@brief Clear Display Memory
230 | * @li 0 = Inactive
231 | * @li 1 = Clear (fill all display memories with zeros)
232 | * @note This bit is automatically cleared after the operation is completed (the operation requires
233 | * 20us). The user does not need to write a 0 afterwards. The status of the bit can be checked by
234 | * reading this register.
235 | * This operation is automatically performed:
236 | * a) On power-up
237 | * b) Immediately following the rising edge of RESET
238 | * c) Immediately following the rising edge of CS after VM0[1] has been set to 1
239 | */
240 | unsigned char clearDisplayMemory : 1;
241 | /**@brief Invert Bit (applies to characters written in 16-bit operating mode)
242 | * @li 0 = Normal (white pixels display white, black pixels display black)
243 | * @li 1 = Invert (white pixels display black, black pixels display white)
244 | */
245 | unsigned char INV : 1;
246 | /**@brief Blink Bit (applies to characters written in 16-bit operating mode)
247 | * @li 0 = Blinking off
248 | * @li 1 = Blinking on
249 | * @note Blinking rate and blinking duty cycle data in the Video Mode 1 (VM1) register are used for blinking control
250 | */
251 | unsigned char BLK : 1;
252 | /**@brief Local Background Control Bit (applies to characters written in 16-bit operating mode)
253 | * @li 0 = sets the background pixels of the character to the video input (VIN) when in external sync mode.
254 | * @li 1 = sets the background pixels of the character to the background mode brightness level defined by VM1[6:4] in external or internal sync mode.
255 | * @note In internal sync mode, the local background control bit behaves as if it is set to 1
256 | */
257 | unsigned char LBC : 1;
258 | /**@brief Operation Mode Selection
259 | * @li 0 = 16-bit operation mode
260 | * @li 1 = 8-bit operation mode
261 | */
262 | unsigned char operationModeSelection : 1;
263 |
264 | /**@brief Don't care*/
265 | unsigned char unsused : 1;
266 |
267 |
268 |
269 | } bits;
270 | };
271 |
272 |
273 | #define DMAH_ADDRESS_WRITE 0x05
274 | #define DMAH_ADDRESS_READ 0x85
275 | /**@union REG_DMAH
276 | * @brief Represents a Display Memory Address High Register value
277 | */
278 | union REG_DMAH
279 | {
280 | /**@brief The whole register value*/
281 | unsigned char whole;
282 | /**
283 | * @var bits
284 | * @brief access to individual bits*/
285 | struct
286 | {
287 | /**@brief 8th bit for Display Memory Address.
288 | */
289 | unsigned char DisplayMemoryAdressBit8 : 1;
290 | unsigned char byteSelectionBit : 1;
291 | /**@brief Don't care*/
292 | unsigned char unsused : 6;
293 | } bits;
294 | };
295 |
296 |
297 | #define DMAL_ADDRESS_WRITE 0x06
298 | #define DMAL_ADDRESS_READ 0x86
299 | typedef unsigned char REG_DMAL;
300 |
301 |
302 | #define DMDI_ADDRESS_WRITE 0x07
303 | #define DMDI_ADDRESS_READ 0x87
304 | typedef unsigned char REG_DMDI;
305 |
306 | #define CMM_ADDRESS_WRITE 0x08
307 | #define CMM_ADDRESS_READ 0x88
308 | typedef unsigned char REG_CMM;
309 |
310 | #define CMAH_ADDRESS_WRITE 0x09
311 | #define CMAH_ADDRESS_READ 0x89
312 |
313 | /**@typedef REG_CMAH
314 | * @brief Represents a Character Memory Address HIGH value
315 | */
316 | typedef unsigned char REG_CMAH;
317 |
318 | #define CMAL_ADDRESS_WRITE 0x0A
319 | #define CMAL_ADDRESS_READ 0x8A
320 | /**@typedef REG_CMAL
321 | * @brief Represents a Character Memory Address Low value
322 | */
323 | typedef unsigned char REG_CMAL;
324 |
325 | #define CMDI_ADDRESS_WRITE 0x0B
326 | #define CMDI_ADDRESS_READ 0x8B
327 |
328 | /**@union REG_CMDI
329 | * @brief Represents a Character Memory Data In Register value
330 | */
331 | union REG_CMDI
332 | {
333 | /**@brief The whole register value*/
334 | unsigned char whole;
335 | /**
336 | * @var bits
337 | * @brief access to individual bits*/
338 | struct
339 | {
340 |
341 | /**@brief value of the right most pixel*/
342 | unsigned char rightMostPixel : 2;
343 |
344 | /**@brief value of the right center pixel*/
345 | unsigned char rightCenterPixel : 2;
346 |
347 | /**@brief value of the left center pixel*/
348 | unsigned char leftCenterPixel : 2;
349 |
350 | /**@brief value of the left most pixel*/
351 | unsigned char leftMostPixel : 2;
352 |
353 | } bits;
354 | };
355 |
356 |
357 | #define OSDM_ADDRESS_WRITE 0x0C
358 | #define OSDM_ADDRESS_READ 0x8C
359 |
360 | /**@union REG_OSDM
361 | * @brief Represents an OSD Insersion Mux Register value
362 | */
363 | union REG_OSDM
364 | {
365 | /**@brief The whole register value*/
366 | unsigned char whole;
367 | /**
368 | * @var bits
369 | * @brief access to individual bits
370 | * */
371 | struct
372 | {
373 | /**@brief OSD Insersion Mux Switching Time
374 | * @li b000 (0) : 30ns (maximum sharpness/maximum crosscolor artifacts )
375 | * @li b001 (1) : 35ns
376 | * @li b010 (2) : 50ns
377 | * @li b011 (3) : 75ns
378 | * @li b100 (4) : 100ns
379 | * @li b101 (5) : 120ns (minimum sharpness/minimum crosscolor artifacts)
380 | */
381 | unsigned char osdInsertionMuxSwitchingTime : 3;
382 |
383 |
384 | /**@brief OSD Rise And Fall Time
385 | * @li b000 (0) : 20ns (maximum sharpness/maximum crosscolor artifacts )
386 | * @li b001 (1) : 30ns
387 | * @li b010 (2): 35ns
388 | * @li b011 (3) : 60ns
389 | * @li b100 (4) : 80ns
390 | * @li b101 (5) : 110ns (minimum sharpness/minimum crosscolor artifacts)
391 | */
392 | unsigned char osdRiseAndFallTime : 3;
393 |
394 |
395 | /**@brief don't care*/
396 | unsigned char unused : 2;
397 |
398 | } bits;
399 | };
400 |
401 |
402 | #define RB0_ADDRESS_WRITE 0x10
403 | #define RB0_ADDRESS_READ 0x90
404 |
405 | #define RB1_ADDRESS_WRITE 0x11
406 | #define RB1_ADDRESS_READ 0x91
407 |
408 | #define RB2_ADDRESS_WRITE 0x12
409 | #define RB2_ADDRESS_READ 0x92
410 |
411 | #define RB3_ADDRESS_WRITE 0x13
412 | #define RB3_ADDRESS_READ 0x93
413 |
414 | #define RB4_ADDRESS_WRITE 0x14
415 | #define RB4_ADDRESS_READ 0x94
416 |
417 | #define RB5_ADDRESS_WRITE 0x15
418 | #define RB5_ADDRESS_READ 0x95
419 |
420 | #define RB6_ADDRESS_WRITE 0x16
421 | #define RB6_ADDRESS_READ 0x96
422 |
423 | #define RB7_ADDRESS_WRITE 0x17
424 | #define RB7_ADDRESS_READ 0x97
425 |
426 | #define RB8_ADDRESS_WRITE 0x18
427 | #define RB8_ADDRESS_READ 0x98
428 |
429 | #define RB9_ADDRESS_WRITE 0x19
430 | #define RB9_ADDRESS_READ 0x99
431 |
432 | #define RBA_ADDRESS_WRITE 0x1A
433 | #define RBA_ADDRESS_READ 0x9A
434 |
435 | #define RBB_ADDRESS_WRITE 0x1B
436 | #define RBB_ADDRESS_READ 0x9B
437 |
438 | #define RBC_ADDRESS_WRITE 0x1C
439 | #define RBC_ADDRESS_READ 0x9C
440 |
441 | #define RBD_ADDRESS_WRITE 0x1D
442 | #define RBD_ADDRESS_READ 0x9D
443 |
444 | #define RBE_ADDRESS_WRITE 0x1E
445 | #define RBE_ADDRESS_READ 0x9E
446 |
447 | #define RBF_ADDRESS_WRITE 0x1F
448 | #define RBF_ADDRESS_READ 0x9F
449 |
450 | /**@union REG_RBN
451 | * @brief Represents a Row Brithness Register value (15 of them)
452 | */
453 | union REG_RBN
454 | {
455 | /**@brief The whole register value*/
456 | unsigned char whole;
457 | /**
458 | * @var bits
459 | * @brief access to individual bits*/
460 | struct
461 | {
462 | /**@brief Character white level
463 | * @li b00 (0) = 120%
464 | * @li b01 (1) = 100%
465 | * @li b10 (2) = 90%
466 | * @li b11 (3) = 80%
467 | */
468 | unsigned char characterWhiteLevel : 2;
469 |
470 | /**@brief Character black level
471 | * @li b00 (0) = 0%
472 | * @li b01 (1) = 10%
473 | * @li b10 (2) = 20%
474 | * @li b11 (3) = 20%
475 | */
476 | unsigned char characterBlackLevel : 2;
477 |
478 | /**@brief don't care*/
479 | unsigned char unused : 4;
480 | } bits;
481 | };
482 |
483 | #define OSDBL_ADDRESS_WRITE 0x6C
484 | #define OSDBL_ADDRESS_READ 0xEC
485 |
486 | /**@union REG_OSDBL
487 | * @brief Represents an OSD Black Level Register value
488 | */
489 | union REG_OSDBL
490 | {
491 | /**@brief The whole register value*/
492 | unsigned char whole;
493 | /**
494 | * @var bits
495 | * @brief access to individual bits*/
496 | struct
497 | {
498 | /**@brief do not change those bits : factory preset*/
499 | unsigned char doNotChange : 4;
500 | /**@brief OSD Image Black Level Control.
501 | * @li 0 = automatic.
502 | * @li 1 = manual.
503 | */
504 | unsigned char osdImageBlackLevelControl : 1;
505 |
506 | /**@brief don't care*/
507 | unsigned char unused : 3;
508 | } bits;
509 | };
510 |
511 | #define STAT_ADDRESS_READ 0xA0 //Read only
512 |
513 | /**@union REG_STAT
514 | * @brief Represents a Status Register value
515 | */
516 | union REG_STAT
517 | {
518 | /**@brief The whole register value*/
519 | unsigned char whole;
520 | /**
521 | * @var bits
522 | * @brief access to individual bits*/
523 | struct
524 | {
525 | /**@brief Detected PAL.
526 | * @li 0 = PAL signal is not detected ad VIN.
527 | * @li 1 = PAL signal is detected at VIN.
528 | */
529 | unsigned char PALDetected : 1;
530 | /**@brief Detected NTSC.
531 | * @li 0 = NTSC signal is not detected ad VIN.
532 | * @li 1 = NTSC signal is detected at VIN.
533 | */
534 | unsigned char NTSCDetected : 1;
535 | /**@brief Loos-Of-Sync.
536 | * @li 0 = Sunc Active. Asserted after 32 consecutive input video lines.
537 | * @li 1 = No Sync. Asserted after 32 consecutive missing input video lines.
538 | */
539 | unsigned char LOS : 1;
540 | /**@brief ~HSYNC Ouput Level.
541 | * @li 0 = Active during horizontal synch time.
542 | * @li 1 = inactive otherwise.
543 | */
544 | unsigned char NOTHsynchOutputLevel : 1;
545 | /**@brief ~VSYNC Ouput Level.
546 | * @li 0 = Active during vertical synch time.
547 | * @li 1 = inactive otherwise.
548 | */
549 | unsigned char NOTVsynchOutputLevel : 1;
550 | /**@brief Character Memory Status.
551 | * @li 0 = Available access.
552 | * @li 1 = Unavailable access.
553 | */
554 | unsigned char characterMemoryStatus : 1;
555 | /**@brief Reset Mode.
556 | * @li 0 = Clear when power up reset mode is complete.
557 | * @li 1 = Set when in power-up reset mode.
558 | */
559 | unsigned char resetMode : 1;
560 | /**@brief don't care.*/
561 | unsigned char unused : 1;
562 | } bits;
563 | };
564 |
565 |
566 | #define DMDO_ADDRESS_READ 0xB0
567 |
568 | /**@typedef DMDO
569 | * @brief represents a Display Memory Data Out Register value.
570 | */
571 | typedef unsigned char DMDO;
572 |
573 | #define CMDO_ADDRESS_READ 0xC0
574 |
575 | /**@union REG_CMDO
576 | * @brief Represents a Character Memory Data Out value.
577 | */
578 | union REG_CMDO
579 | {
580 | /**@brief The whole register value*/
581 | unsigned char whole;
582 | /**
583 | * @var bits
584 | * @brief access to individual bits*/
585 | struct
586 | {
587 | /**@brief right most pixel*/
588 | unsigned char rightMostPowel : 2;
589 | /**@brief right center pixel*/
590 | unsigned char rightCenterPixel : 2;
591 | /**@brief left center pixel*/
592 | unsigned char leftCenterPixel : 2;
593 | /**@brief left most pixel*/
594 | unsigned char leftMostPixel : 2;
595 | } bits;
596 | };
597 |
598 |
599 |
600 |
601 | /**\def COLOR_BLACK
602 | * \brief Black value for a pixel (2bits)
603 | */
604 | #define COLOR_BLACK 0
605 |
606 |
607 | /**\def COLOR_WHITE
608 | * \brief White value for a pixel (2bits)
609 | */
610 | #define COLOR_WHITE 2
611 |
612 |
613 | /**\def COLOR_TRANSPARENT
614 | * \brief Transparent value for a pixel (2bits)
615 | */
616 | #define COLOR_TRANSPARENT 1
617 |
618 |
619 | /**\def COLOR_GREY
620 | * \brief Grey value for a pixel (2bits)
621 | */
622 | #define COLOR_GREY COLOR_TRANSPARENT
623 |
624 |
625 | /**@struct PIXEL
626 | * @brief represent a 4-pixels value
627 | */
628 | struct PIXEL
629 | {
630 | /**@brief 4th pixel*/
631 | byte pix3 : 2;
632 | /**@brief 3rd pixel*/
633 | byte pix2 : 2;
634 | /**@brief 2nd pixel*/
635 | byte pix1 : 2;
636 |
637 |
638 | /**@brief 1st pixel*/
639 | byte pix0 : 2;
640 |
641 | };
642 |
643 | /**@union LINE
644 | * @brief Represents a line in a max7456 character ie. 12 pixels
645 | */
646 | union LINE
647 | {
648 | /**@brief the whole line*/
649 | byte whole[3];
650 | /**@brief individual 4-pixels access*/
651 | struct PIXEL pixels[3];
652 | };
653 |
654 |
655 | /**
656 | * @union CARACT
657 | * @brief Represents a character with lines and pixels.
658 | * example : myCarac.line[3].pixels[2].pix2 = COLOR_TRANSPARENT ;
659 | */
660 | union CARACT
661 | {
662 | /**@brief the whole CARACT as in max7456 Character Memory*/
663 | charact whole;
664 | /**@brief acces with lines*/
665 | union LINE line[18];
666 | };
667 |
668 |
669 | enum {
670 | _BT_BT = 0,
671 | _BT_2BT,
672 | _BT_3BT,
673 | _3BT_BT
674 | };
675 |
676 | enum {
677 | _2fields = 0,
678 | _4fields,
679 | _6fields,
680 | _8fields
681 | };
682 |
683 |
684 | #endif /* MAX7456REGISTERS_H_ */
685 |
--------------------------------------------------------------------------------