/*
* 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 not scrolled. Otherwise, the
- * message will scroll.
+ * 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 "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 wrap_mode; /* whether to scroll or alternate between msgs */
+u8 scroll_point; /* how far through the message we have scrolled */
/* private prototypes */
void display_send_byte(char c);
void display_reset();
void display_update();
-
void set_msg(char* newmsg) {
char* dest = current_message;
/* equivalent of a string copy */
dest++;
newmsg++;
}
+ scroll_point = 0;
display_update();
}
}
void display_send_byte(char c) {
- *_misc_output |= A3800_DISPLAY_WRITE; /* enable the display clock */
+ bset_misc_output(A3800_DISPLAY_WRITE); /* enable the display clock */
- _io_ports[M6811_SPDR] = c; /* load SPI with byte */
- while(!(_io_ports[M6811_SPDR]&0x80)); /* wait for completion */
+ _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 */
delay(DISPLAY_DELAY);
_io_ports[M6811_PORTA] |= PORTA_DISP_RESET;
- _io_ports[M6811_SPCR] |= M6811_SPE; /* enable the SPI */
+ spi_enable();
delay(DISPLAY_DELAY);
- display_send_byte(0xCA); /* 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% */
- _io_ports[M6811_SPCR] &= ~M6811_SPE; /* disable the SPI again */
+ spi_disable();
}
void display_update() {
buffered_addr(changer_output)
buffered_addr(misc_output)
+
+inline void spi_enable() {
+ _io_ports[M6811_SPCR] |= M6811_SPE;
+}
+
+inline void spi_disable() {
+ _io_ports[M6811_SPCR] &= ~M6811_SPE;
+}
#include "vend.h"
+int keypad_read_row() {
+ bclr_misc_output(A3800_DISPLAY_WRITE); /* disable the display clock */
+
+ _io_ports[M6811_SPDR] = 0;
+ while(!(_io_ports[M6811_SPDR]&M6811_SPIE)); /* wait for completion */
+
+ return _io_ports[M6811_SPDR];
+}
+
+/* row is 0 or 1 */
+void keypad_select_row(int row) {
+ if (row)
+ _io_ports[M6811_PORTD] |= PORTD_KEYPAD_ROW;
+ else
+ _io_ports[M6811_PORTD] &= ~PORTD_KEYPAD_ROW;
+}
+
typedef unsigned long u32;
typedef signed long s32;
typedef u8 bool;
-typedef u16 addr_t;
+typedef u16 addr_t;
/* addresses of these set at link time */
+/* to add more addresses, define them here with buffered_addr_h, in helpers.c
+ * with buffered_addr, and also in LDFLAGS in the Makefile
+ */
#define buffered_addr_h(a) \
- extern volatile u8* _##a
+ extern volatile u8* _##a; \
+ extern inline void set_##a(u8 b); \
+ extern inline void bset_##a(u8 m); \
+ extern inline void bclr_##a(u8 m); \
buffered_addr_h(switch_input);
buffered_addr_h(misc_input);
buffered_addr_h(changer_output);
buffered_addr_h(misc_output);
+void spi_enable();
+void spi_disable();
+
/******* from display.c *******/
/* scrolling modes */
#define WRAP_SCROLL_L 1 /* scroll to the left */
-#define WRAP_SCROLL_R 1 /* scroll to the right */
-#define WRAP_ALTERNATE 2 /* alternate between text */
+#define WRAP_SCROLL_R 2 /* scroll to the right */
+#define WRAP_ALTERNATE 3 /* alternate between text */
-extern char current_message[1024];
+extern char current_message[256];
void display_init();
void set_msg(char* newmsg);
/******** Some meaningful bits ******/
#define PORTA_DISP_RESET 0x80 /* active low */
+#define PORTD_KEYPAD_ROW 0x20 /* clear for row 0, set for row 1 */
/* Address 3800 bits */
#define A3800_DISPLAY_WRITE 0x04
+/******* from main.c *******/
+int __attribute__((noreturn)) main (void);
+
#endif /* _VEND_H_ */