X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=ROM2%2Fdisplay.c;h=7da3b10ef43bfb526be15550d8af3497057c039b;hb=dc05db765d0f5d7e68f6c786f0572c0da4d7926d;hp=ee3e94b2c5e55eace36c2f2a79273f0a0bb3927d;hpb=4f35424978e202fff48c2331eee9fd01e3da244f;p=uccvend-snackrom.git diff --git a/ROM2/display.c b/ROM2/display.c index ee3e94b..7da3b10 100644 --- a/ROM2/display.c +++ b/ROM2/display.c @@ -1,55 +1,124 @@ /* * display.c - functions for controlling the display on the vending machine. * - * Use set_msg(char*) to write a new message to the screen, replacing the previous - * one. The message can be at most 1023 characters long. Use set_wrap_mode with - * one of the WRAP_* options in vend.h to set the scrolling behaviour. If the - * message is less than 10 characters, it is centered and is not scrolled. + * + * XXX obsolted - with a backend on the server machine, we don't need to + * handle scrolling, etc here. Replaced by display_basic.[cho] + * + * Use set_msg(char*) to write a new message to the screen, replacing the + * previous one. The message can be at most 255 characters long. Use + * set_wrap_mode with one of the WRAP_* options in vend.h to set the scrolling + * behaviour. If the message is less than 10 characters, it is not scrolled. * Otherwise, the message will scroll. * */ - +#include "display.h" #include "vend.h" char display_buffer[10]; /* what each byte on the display reads */ -char current_message[1024]; /* message that is scrolled or switched between */ +char current_message[256]; /* message that is scrolled or switched between */ +u8 msg_length; /* length of current_message */ u8 wrap_mode; /* whether to scroll or alternate between msgs */ +u8 scroll_point; /* how far through the message we have scrolled */ +bool have_scrolled; /* true after one scroll (used for scroll_msg())*/ -void set_msg(char* newmsg) { - char* dest = current_message; - /* while (dest++ = newmsg++); */ +/* private prototypes */ +void display_send_byte(char c); +void display_reset(); +void display_update(); + +void append_msg(char* newmsg, u8 wrap) { + char* dest = current_message+msg_length; + /* equivalent of a string copy */ while (newmsg) { dest = newmsg; dest++; newmsg++; + msg_length++; } + wrap_mode = wrap; } -void __inline__ set_wrap_mode(u8 new_wrap_mode) { - /* in theory it should be inlined anyway? */ - wrap_mode = new_wrap_mode; +void set_msg(char* newmsg, u8 wrap) { + msg_length = 0; + append_msg(newmsg, wrap); + scroll_point = 0; + display_update(); } -void display_send_byte(u8 b) { - bset_3800(A3800_DISPLAY_WRITE); +void scroll_msg(char* newmsg) { + /* puts a message on display and does not return until the message has + * scrolled across once. + */ + set_msg(newmsg, WRAP_SCROLL); + have_scrolled = 0; + while (!have_scrolled); +} + +void display_shift() { + /* update the display for WRAP_SCROLL or WRAP_ALTERNATE modes */ + switch (wrap_mode) { + case WRAP_SCROLL: + case WRAP_ALTERNATE: + scroll_point++; + if (scroll_point >= msg_length) { + scroll_point = 0; + have_scrolled = 1; + } + display_update(); + break; + } +} + +void set_char(char c, u8 pos) { + /* sets a single character */ + display_buffer[pos] = c; + display_update(); +} + +void display_send_byte(char c) { + bset_misc_output(A3800_DISPLAY_WRITE); /* enable the display clock */ + + _io_ports[M6811_SPDR] = c; /* load SPI with byte */ + while(!(_io_ports[M6811_SPDR]&M6811_SPIE)); /* wait for completion */ + _io_ports[M6811_SPDR]; /* SPDR read to clear SPIE flag */ } #define DISPLAY_DELAY 100 /* ms to delay between ops - could be tweaked */ void display_reset() { - /* lower the reset line for 100ms */ - bclr(PORTA, PORTA_DISP_RESET); + /* lower the reset line for a while */ + bclr((void*)&_io_ports[M6811_PORTA], PORTA_DISP_RESET); delay(DISPLAY_DELAY); - bset(PORTA, PORTA_DISP_RESET); + bset((void*)&_io_ports[M6811_PORTA], PORTA_DISP_RESET); - /* enable the SPI */ - bset(SPCR, SPCR_SPE); + spi_enable(); delay(DISPLAY_DELAY); - /* tell the controller there are 10 digits */ + display_send_byte(0xC0 | 10); /* tell the controller there are 10 digits */ + display_send_byte(0xE0); /* set duty cycle to 100% */ + + spi_disable(); +} + +void display_update() { + u8 i; + + for (i=0; i < 10; i++) { + display_buffer[i] = current_message[ + (i+(wrap_mode==WRAP_ALTERNATE?scroll_point/10:scroll_point)) + %msg_length]; + } + + /* hmmm, will this cause some flickering of the display? */ + display_reset(); + for (i=0; i < 10; i++) { + display_send_byte(display_buffer[i]&0x7f); + } } -void display_refresh() { +void display_init() { display_reset(); } +