summaryrefslogtreecommitdiff
path: root/max7219.c
blob: a1e0da32f0c4ddace6e945005085ddeb19438866 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/************************************************************************/
/*                                                                      */
/*			7 Segment Driver MAX7219			*/
/*			Common Anode Display				*/
/*                                                                      */
/*              Author: Peter Dannegger                                 */
/*                      danni@specs.de                                  */
/*                                                                      */
/************************************************************************/

#include "main.h"
#include "max7219.h"

u8 brightness = 5;

u8 code digits[] = { DIGITS };

u8 displaymem[8] = { CHAR_SPACE,	// 8 digits, msb first
		     CHAR_SPACE,
		     CHAR_SPACE,
		     CHAR_SPACE,
		     CHAR_SPACE,
		     CHAR_SPACE,
		     CHAR_SPACE,
		     CHAR_SPACE };

u8 code charset[] = {		// Definition Character Set
	_A+_B+_C+_D+_E+_F   ,		// CHAR_0
	   _B+_C	    ,		// CHAR_1
	_A+_B+   _D+_E+   _G,		// CHAR_2
	_A+_B+_C+_D+      _G,		// CHAR_3
	   _B+_C+      _F+_G,		// CHAR_4
	_A+   _C+_D+   _F+_G,		// CHAR_5
	_A+   _C+_D+_E+_F+_G,		// CHAR_6
	_A+_B+_C            ,		// CHAR_7
	_A+_B+_C+_D+_E+_F+_G,		// CHAR_8
	_A+_B+_C+_D   +_F+_G,		// CHAR_9
	_A+_B+_C+   _E+_F+_G,		// CHAR_A
	      _C+_D+_E+_F+_G,		// CHAR_b
		 _D+_E+   _G,		// CHAR_c	;'c'
	   _B+_C+_D+_E+   _G,		// CHAR_d
	_A+      _D+_E+_F+_G,		// CHAR_E
	_A+         _E+_F+_G,		// CHAR_F
	0                   ,		// 16 = SPACE
			  _G,		// 17 = MINUS
	_A+_B+         _F+_G,		// 18 = GRAD
	_A+      _D+_E+_F   ,		// 19 = CHAR_C2	;'C'
		    _E+   _G,		// 20 = CHAR_r
	      _C+_D+_E+   _G,		// 21 = CHAR_o
	   _B+_C+   _E+_F+_G,		// 22 = H
		 _D+_E+_F   ,		// 23 = L
		 _D	    ,		// 24 = _
	_A		    ,		// 25 = upper "-"
	_A+_B+      _E+_F+_G,		// CHAR_P
	   _B+_C+_D+_E+_F   ,		// CHAR_U
	_A+_B+_C+   _E+_F   		// CHAR_M
	};


void display_write( u16 dc )
{
  u8 i;

  MAX7219_DDR |= 1<<MAX7219_DO;
  MAX7219_DDR |= 1<<MAX7219_SCK;
  MAX7219_DDR |= 1<<MAX7219_STB;
  MAX7219_PORT &= ~(1<<MAX7219_STB);

  for( i = 12; i; i-- ){
    MAX7219_PORT &= ~(1<<MAX7219_SCK);
    MAX7219_PORT |= 1<<MAX7219_DO;
    if( (dc & 0x0800) == 0 )
      MAX7219_PORT &= ~(1<<MAX7219_DO);
    dc <<= 1;
    MAX7219_PORT |= 1<<MAX7219_SCK;
  }

  MAX7219_PORT |= 1<<MAX7219_STB;
}


void display_out( void )
{
  u8 * dptr;
  u8 i, j, byte;

  display_write( 0xC01 );

  dptr = displaymem;
  for( i = 8; i; i-- ){
    j = LPM(charset + (*dptr & 0x3F));		// convert to 7-segment
    if( *dptr & 0x80 )
      j |= _DP;					// set decimal point
    *dptr++ = j;
  }

  for( i = 8; i; i-- ){				// for all segments
    dptr = displaymem;
    byte = 0;
    for( j = 8; j; j-- ){			// collect all digits
      if( *dptr & 1 )
        byte |= LPM(digits+j-1);		// digit order mask
      *dptr >>= 1;				// next segment
      dptr++;
    }
    display_write( byte + i * 256);		// output same segments
  }
}


void display_clear( void )
{
  u8 i;

  for( i = 8; i; i--)
    displaymem[i-1] = CHAR_SPACE;
}


void display_init( void )
{
  display_write( 0xF00 );		// Testmode off
  display_write( 0x900 );		// Decode off
  display_write( 0xB07 );		// 8 Digits
  display_write( 0xC01 );		// Display on
  display_write( 0xA00 | brightness );	// Brightness
}


void display_off( void )
{
  display_write( 0xC00 );
}