af969218c349ad0603345891e8995de6165c03c8
[uccvend-snackrom.git] / ROM2 / display.c
1 /*
2  * display.c - functions for controlling the display on the vending machine.
3  *
4  * Use set_msg(char*) to write a new message to the screen, replacing the
5  * previous one. The message can be at most 255 characters long. Use
6  * set_wrap_mode with one of the WRAP_* options in vend.h to set the scrolling
7  * behaviour. If the message is less than 10 characters, it is not scrolled.
8  * Otherwise, the message will scroll.
9  *
10  */
11
12 #include "vend.h"
13
14 char display_buffer[10];    /* what each byte on the display reads          */
15 char current_message[256];  /* message that is scrolled or switched between */
16 u8   wrap_mode;             /* whether to scroll or alternate between msgs  */
17 u8   scroll_point;          /* how far through the message we have scrolled */
18
19 /* private prototypes */
20 void display_send_byte(char c);
21 void display_reset();
22 void display_update();
23
24 void set_msg(char* newmsg, u8 wrap) {
25         char* dest = current_message;
26         /* equivalent of a string copy */
27         /* while (dest++ = newmsg++); */
28         while (newmsg) {
29                 dest = newmsg;
30                 dest++;
31                 newmsg++;
32         }
33         wrap_mode = wrap;
34         scroll_point = 0;
35         display_update();
36 }
37
38 void set_char(char c, u8 pos) {
39         /* sets a single character */
40         display_buffer[pos] = c;
41         display_update();
42 }
43
44 void display_send_byte(char c) {
45         bset_misc_output(A3800_DISPLAY_WRITE);  /* enable the display clock */
46
47         _io_ports[M6811_SPDR] = c;                  /* load SPI with byte */
48         while(!(_io_ports[M6811_SPDR]&M6811_SPIE)); /* wait for completion */
49         _io_ports[M6811_SPDR];                      /* SPDR read to clear SPIE flag */
50 }
51
52 #define DISPLAY_DELAY  100 /* ms to delay between ops - could be tweaked */
53 void display_reset() {
54         /* lower the reset line for a while */
55         bclr((void*)&_io_ports[M6811_PORTA], PORTA_DISP_RESET);
56         delay(DISPLAY_DELAY);
57         bset((void*)&_io_ports[M6811_PORTA], PORTA_DISP_RESET);
58
59         spi_enable();
60         delay(DISPLAY_DELAY);
61
62         display_send_byte(0xC0 | 10);    /* tell the controller there are 10 digits */
63         display_send_byte(0xE0);    /* set duty cycle to 100%                  */
64
65         spi_disable();
66 }
67
68 void display_update() {
69         u8 i;
70         display_reset();
71         
72         for (i=0; i < 10; i++) {
73                 /* FIXME: we may need to fiddle with the character codes sent to the 
74                  * controller. It doesn't seem like we have to, but datasheets for
75                  * the "pin-for-pin" compatible MSC1937 from OKI suggest a different
76                  * character set
77                  */
78                 display_send_byte(i[display_buffer]&0x7f);
79         }
80 }
81
82 void display_init() {
83         display_reset();
84 }
85

UCC git Repository :: git.ucc.asn.au