firmware/user.c
author cpresser@slime-ws
Sat, 26 Jul 2008 14:22:38 +0200
changeset 25 96f051df5d60
parent 2 2f55e5dd591d
permissions -rw-r--r--
added eeprom code
     1 /*
     2  * Project Frontplatte
     3  *
     4  * user.c  -  Handle incoming commands
     5  *
     6  * This file is released under the GNU General Public License. Refer
     7  * to the COPYING file distributed with this package.
     8  *
     9  * (c) 2007 Carsten Presser cpresser AT fsing.uni-sb.de
    10  */
    11 
    12 /** I N C L U D E S **********************************************************/
    13 #include <p18cxxx.h>
    14 #include "typedefs.h"
    15 #include <pwm.h>
    16 #include <timers.h>
    17 
    18 #include "usb.h"
    19 
    20 #include "io_cfg.h"             // I/O pin mapping
    21 #include "user.h"
    22 #include "t6963.h"
    23 #include "delay.h"
    24 #include "rc5.h"
    25 #include "myi2c.h"
    26 #include "interrupt.h"
    27 
    28 /** R O M   D A T A ***********************************************/
    29 rom unsigned char bitmapfont[] = 
    30 /*Bitmap-Size: 12  *  4 x 48 */
    31 /*            |       0      ||       1      ||       2      ||       3      ||       4      ||       5      ||       6      ||       7      ||       8      ||       9      ||       :      ||     (undef)  | */
    32 /* Row  0 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    33 /* Row  1 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    34 /* Row  2 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    35 /* Row  3 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    36 /* Row  4 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    37 /* Row  5 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xfe\x00\x00\x0f\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    38 /* Row  6 */ "\x00\x0f\xf8\x00\x00\x00\x78\x00\x00\x1f\xfc\x00\x00\x7f\xfc\x00\x00\x00\x0f\x00\x01\xff\xff\xc0\x00\x0f\xfc\x00\x00\x00\x00\x00\x00\x3f\xff\x80\x00\x1f\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    39 /* Row  7 */ "\x00\x3f\xfe\x00\x00\x00\x78\x00\x00\x3f\xff\x00\x00\xff\xff\x00\x00\x00\x1f\x00\x01\xff\xff\xc0\x00\x1f\xfe\x00\x03\xff\xff\xf8\x00\x7f\xff\xc0\x00\x7f\xff\x80\x00\x00\x00\x00\x00\x00\x00\x00"
    40 /* Row  8 */ "\x00\x7f\xff\x00\x00\x00\x78\x00\x00\xff\xff\x80\x01\xff\xff\x80\x00\x00\x1f\x00\x03\xff\xff\xc0\x00\x7f\xff\x00\x03\xff\xff\xf8\x00\xff\xff\xe0\x00\xff\xff\xc0\x00\x00\x00\x00\x00\x00\x00\x00"
    41 /* Row  9 */ "\x00\xff\xff\x80\x00\x00\xf8\x00\x01\xff\xff\xc0\x03\xfc\x7f\x80\x00\x00\x3f\x00\x03\xff\xff\xc0\x00\x7f\xff\x80\x03\xff\xff\xf8\x00\xff\x1f\xe0\x00\xff\x3f\xc0\x00\x00\x00\x00\x00\x00\x00\x00"
    42 /* Row 10 */ "\x01\xfe\x3f\xc0\x00\x03\xf8\x00\x03\xfe\x3f\xe0\x03\xe0\x0f\xc0\x00\x00\x7f\x00\x03\xe0\x00\x00\x00\xff\x1f\xc0\x03\xff\xff\xf8\x01\xf8\x03\xf0\x01\xf8\x07\xe0\x00\x00\x00\x00\x00\x00\x00\x00"
    43 /* Row 11 */ "\x01\xf8\x0f\xc0\x00\x3f\xf8\x00\x03\xf0\x07\xf0\x07\xc0\x07\xc0\x00\x00\x7f\x00\x03\xe0\x00\x00\x01\xfc\x07\xe0\x00\x00\x00\xf8\x01\xf0\x01\xf0\x01\xf0\x03\xf0\x00\x00\x00\x00\x00\x00\x00\x00"
    44 /* Row 12 */ "\x03\xf0\x07\xe0\x00\xff\xf8\x00\x07\xe0\x03\xf0\x07\xc0\x07\xc0\x00\x00\xff\x00\x03\xe0\x00\x00\x01\xf8\x03\xe0\x00\x00\x01\xf0\x01\xf0\x01\xf0\x03\xe0\x01\xf0\x00\x00\x00\x00\x00\x00\x00\x00"
    45 /* Row 13 */ "\x03\xe0\x03\xe0\x00\xff\xf8\x00\x07\xc0\x01\xf0\x07\x80\x03\xc0\x00\x01\xff\x00\x03\xe0\x00\x00\x03\xf0\x03\xe0\x00\x00\x01\xf0\x01\xe0\x00\xf0\x03\xe0\x01\xf0\x00\x00\x00\x00\x00\x00\x00\x00"
    46 /* Row 14 */ "\x03\xe0\x03\xe0\x00\xff\xf8\x00\x07\xc0\x01\xf0\x00\x00\x03\xc0\x00\x01\xef\x00\x03\xe0\x00\x00\x03\xe0\x01\xe0\x00\x00\x03\xe0\x01\xe0\x00\xf0\x03\xe0\x00\xf8\x00\x00\x00\x00\x00\x00\x00\x00"
    47 /* Row 15 */ "\x07\xc0\x01\xf0\x00\xfe\x78\x00\x07\x80\x00\xf0\x00\x00\x03\xc0\x00\x03\xcf\x00\x03\xe0\x00\x00\x03\xe0\x00\x00\x00\x00\x03\xe0\x01\xf0\x01\xf0\x03\xc0\x00\xf8\x00\x01\x80\x00\x00\x00\x00\x00"
    48 /* Row 16 */ "\x07\xc0\x01\xf0\x00\x00\x78\x00\x00\x00\x00\xf0\x00\x00\x07\xc0\x00\x07\xcf\x00\x03\xe0\x00\x00\x07\xe0\x00\x00\x00\x00\x07\xe0\x01\xf0\x01\xf0\x03\xc0\x00\xf8\x00\x03\xc0\x00\x00\x00\x00\x00"
    49 /* Row 17 */ "\x07\xc0\x01\xf0\x00\x00\x78\x00\x00\x00\x01\xf0\x00\x00\x07\xc0\x00\x0f\x8f\x00\x03\xe0\x00\x00\x07\xc0\x00\x00\x00\x00\x07\xc0\x00\xf8\x03\xe0\x03\xc0\x00\xf8\x00\x07\xe0\x00\x00\x00\x00\x00"
    50 /* Row 18 */ "\x07\xc0\x01\xf0\x00\x00\x78\x00\x00\x00\x01\xf0\x00\x00\x0f\x80\x00\x0f\x0f\x00\x03\xe7\xfc\x00\x07\xc0\x00\x00\x00\x00\x07\xc0\x00\xfe\x0f\xe0\x03\xe0\x00\xf8\x00\x07\xe0\x00\x00\x00\x00\x00"
    51 /* Row 19 */ "\x07\xc0\x01\xf0\x00\x00\x78\x00\x00\x00\x01\xf0\x00\x00\x7f\x80\x00\x1e\x0f\x00\x03\xff\xfe\x00\x07\xc7\xfc\x00\x00\x00\x0f\x80\x00\x7f\xff\xc0\x03\xe0\x00\x78\x00\x03\xc0\x00\x00\x00\x00\x00"
    52 /* Row 20 */ "\x07\x80\x00\xf0\x00\x00\x78\x00\x00\x00\x03\xe0\x00\x03\xff\x00\x00\x3e\x0f\x00\x03\xff\xff\x80\x07\xdf\xff\x00\x00\x00\x0f\x80\x00\x3f\xff\x80\x03\xe0\x00\xf8\x00\x01\x80\x00\x00\x00\x00\x00"
    53 /* Row 21 */ "\x07\x80\x00\xf0\x00\x00\x78\x00\x00\x00\x07\xe0\x00\x03\xfc\x00\x00\x3c\x0f\x00\x03\xff\xff\xc0\x07\xff\xff\x80\x00\x00\x1f\x00\x00\x0f\xfe\x00\x03\xf0\x01\xf8\x00\x00\x00\x00\x00\x00\x00\x00"
    54 /* Row 22 */ "\x07\x80\x00\xf0\x00\x00\x78\x00\x00\x00\x0f\xc0\x00\x03\xff\x00\x00\x78\x0f\x00\x03\xfe\x3f\xe0\x07\xff\xff\xc0\x00\x00\x1f\x00\x00\x1f\xff\x00\x01\xf8\x03\xf8\x00\x00\x00\x00\x00\x00\x00\x00"
    55 /* Row 23 */ "\x07\x80\x00\xf0\x00\x00\x78\x00\x00\x00\x1f\x80\x00\x03\xff\xc0\x00\xf8\x0f\x00\x03\xf0\x07\xe0\x07\xfe\x3f\xc0\x00\x00\x3e\x00\x00\x3f\xff\x80\x00\xff\x1f\xf8\x00\x00\x00\x00\x00\x00\x00\x00"
    56 /* Row 24 */ "\x07\x80\x00\xf0\x00\x00\x78\x00\x00\x00\x3f\x00\x00\x00\x3f\xe0\x00\xf0\x0f\x00\x03\xc0\x03\xf0\x07\xf0\x07\xe0\x00\x00\x3e\x00\x00\x7f\xff\xc0\x00\xff\xff\xf8\x00\x00\x00\x00\x00\x3f\xfc\x00"
    57 /* Row 25 */ "\x07\x80\x00\xf0\x00\x00\x78\x00\x00\x00\x7e\x00\x00\x00\x07\xe0\x01\xe0\x0f\x00\x00\x00\x01\xf0\x07\xe0\x03\xf0\x00\x00\x7e\x00\x00\xfe\x0f\xe0\x00\x7f\xff\xf8\x00\x00\x00\x00\x00\x3f\xfc\x00"
    58 /* Row 26 */ "\x07\x80\x00\xf0\x00\x00\x78\x00\x00\x00\xfc\x00\x00\x00\x03\xf0\x03\xe0\x0f\x00\x00\x00\x01\xf0\x07\xc0\x01\xf0\x00\x00\x7c\x00\x01\xf8\x03\xf0\x00\x3f\xfe\xf8\x00\x00\x00\x00\x00\x3f\xfc\x00"
    59 /* Row 27 */ "\x07\x80\x00\xf0\x00\x00\x78\x00\x00\x03\xf8\x00\x00\x00\x01\xf0\x03\xc0\x0f\x00\x00\x00\x01\xf0\x07\x80\x01\xf0\x00\x00\x7c\x00\x03\xf0\x01\xf8\x00\x0f\xf8\xf8\x00\x01\x80\x00\x00\x3f\xfc\x00"
    60 /* Row 28 */ "\x07\xc0\x01\xf0\x00\x00\x78\x00\x00\x07\xf0\x00\x00\x00\x01\xf0\x07\x80\x0f\x00\x00\x00\x00\xf0\x07\xc0\x01\xf0\x00\x00\xf8\x00\x03\xe0\x00\xf8\x00\x00\x00\xf8\x00\x03\xc0\x00\x00\x00\x00\x00"
    61 /* Row 29 */ "\x07\xc0\x01\xf0\x00\x00\x78\x00\x00\x0f\xe0\x00\x00\x00\x00\xf0\x07\xff\xff\xf8\x00\x00\x00\xf0\x07\xc0\x00\xf0\x00\x00\xf8\x00\x03\xe0\x00\xf8\x00\x00\x00\xf8\x00\x07\xe0\x00\x00\x00\x00\x00"
    62 /* Row 30 */ "\x07\xc0\x01\xf0\x00\x00\x78\x00\x00\x3f\xc0\x00\x00\x00\x00\xf0\x07\xff\xff\xf8\x00\x00\x00\xf0\x07\xc0\x00\xf0\x00\x01\xf0\x00\x03\xc0\x00\x78\x00\x00\x01\xf8\x00\x07\xe0\x00\x00\x00\x00\x00"
    63 /* Row 31 */ "\x07\xc0\x01\xf0\x00\x00\x78\x00\x00\x7f\x00\x00\x07\x80\x00\xf0\x07\xff\xff\xf8\x07\x80\x01\xf0\x07\xc0\x00\xf0\x00\x01\xf0\x00\x03\xc0\x00\x78\x00\x00\x01\xf0\x00\x03\xc0\x00\x00\x00\x00\x00"
    64 /* Row 32 */ "\x07\xc0\x01\xf0\x00\x00\x78\x00\x00\xfe\x00\x00\x07\xc0\x01\xf0\x07\xff\xff\xf8\x07\xc0\x01\xf0\x07\xc0\x01\xf0\x00\x03\xe0\x00\x03\xe0\x00\xf8\x01\xe0\x01\xf0\x00\x01\x80\x00\x00\x00\x00\x00"
    65 /* Row 33 */ "\x03\xe0\x03\xe0\x00\x00\x78\x00\x01\xfc\x00\x00\x07\xc0\x01\xf0\x00\x00\x0f\x00\x07\xc0\x03\xf0\x03\xe0\x01\xf0\x00\x03\xe0\x00\x03\xe0\x00\xf8\x01\xf0\x03\xf0\x00\x00\x00\x00\x00\x00\x00\x00"
    66 /* Row 34 */ "\x03\xe0\x03\xe0\x00\x00\x78\x00\x03\xf8\x00\x00\x07\xe0\x03\xf0\x00\x00\x0f\x00\x07\xe0\x03\xe0\x03\xe0\x01\xf0\x00\x07\xe0\x00\x03\xf0\x01\xf8\x01\xf0\x07\xe0\x00\x00\x00\x00\x00\x00\x00\x00"
    67 /* Row 35 */ "\x03\xf0\x07\xe0\x00\x00\x78\x00\x07\xf0\x00\x00\x03\xf0\x07\xe0\x00\x00\x0f\x00\x03\xf0\x0f\xe0\x03\xf0\x03\xe0\x00\x07\xc0\x00\x01\xf8\x03\xf0\x01\xf8\x0f\xe0\x00\x00\x00\x00\x00\x00\x00\x00"
    68 /* Row 36 */ "\x01\xf8\x0f\xc0\x00\x00\x78\x00\x07\xe0\x00\x00\x03\xfe\x3f\xe0\x00\x00\x0f\x00\x03\xfe\x3f\xc0\x01\xf8\x07\xe0\x00\x07\xc0\x00\x01\xff\x1f\xf0\x00\xfe\x3f\xc0\x00\x00\x00\x00\x00\x00\x00\x00"
    69 /* Row 37 */ "\x01\xfe\x3f\xc0\x00\x00\x78\x00\x0f\xff\xff\xf0\x01\xff\xff\xc0\x00\x00\x0f\x00\x01\xff\xff\x80\x00\xff\x3f\xc0\x00\x0f\x80\x00\x00\xff\xff\xe0\x00\x7f\xff\x80\x00\x00\x00\x00\x00\x00\x00\x00"
    70 /* Row 38 */ "\x00\xff\xff\x80\x00\x00\x78\x00\x0f\xff\xff\xf0\x00\xff\xff\x80\x00\x00\x0f\x00\x00\xff\xff\x00\x00\xff\xff\xc0\x00\x0f\x80\x00\x00\x7f\xff\xc0\x00\x7f\xff\x80\x00\x00\x00\x00\x00\x00\x00\x00"
    71 /* Row 39 */ "\x00\x7f\xff\x00\x00\x00\x78\x00\x0f\xff\xff\xf0\x00\x7f\xfe\x00\x00\x00\x0f\x00\x00\x7f\xfe\x00\x00\x7f\xff\x80\x00\x1f\x00\x00\x00\x3f\xff\x80\x00\x1f\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    72 /* Row 40 */ "\x00\x3f\xfe\x00\x00\x00\x78\x00\x0f\xff\xff\xf0\x00\x1f\xf8\x00\x00\x00\x0f\x00\x00\x1f\xf8\x00\x00\x1f\xfe\x00\x00\x1f\x00\x00\x00\x0f\xfe\x00\x00\x0f\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    73 /* Row 41 */ "\x00\x0f\xf8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    74 /* Row 42 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    75 /* Row 43 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    76 /* Row 44 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    77 /* Row 45 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    78 /* Row 46 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    79 /* Row 47 */ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
    80 
    81 
    82 
    83 /** V A R I A B L E S **********************************************/
    84 unsigned char	gg_keys;
    85 unsigned char	gg_ioflags;
    86 unsigned char	gg_pwm1dc	= 0x00;
    87 unsigned char	gg_mode		= MODE_UNMANAGED;
    88 
    89 unsigned char	ee_display;
    90 unsigned char	ee_features;
    91 
    92 unsigned char	nKeys1, nKeys2;
    93 unsigned char	oKeys1, oKeys2;
    94 unsigned char	dKeys1, dKeys2;
    95 unsigned char	bKeys1;
    96 
    97 
    98 /** C O D E ********************************************************/
    99 void UserInit(void)
   100 {
   101 	// configure all PortA-Pins as Digital
   102 	ADCON0	= 0x00; // disable AD
   103 	ADCON1	= 0x0F;	// AD-Converter see page 254
   104 	CMCON	= 0x07;	// disable Comperator see page 264
   105 	SPPCON	= 0x00; // disable SPP-Port see page 187
   106 
   107 	// first: make ALL ports outputs...
   108 	TRISA	= 0x00;
   109 	TRISC	= 0x00;
   110 	TRISD 	= 0x00;
   111 	TRISE	= 0x00;
   112 	TRISB	= 0x00; 	PORTB	= 0xFF;
   113 	// make sure, PC wont start...
   114 	PIN_POWER	= 0;
   115 
   116 	// read saved settings
   117 	ee_display 		= Read_b_eep (EE_ADDR_DISPLAY);
   118 	ee_features		= Read_b_eep (EE_ADDR_FEATURES);
   119 
   120 
   121 	// reset INT settings...
   122 	INTCON			= 0x00;	// first disable all ints..
   123 	PIE1			= 0x00; // and also all perephial ints
   124 	PIE2			= 0x00;
   125 	RCONbits.IPEN	= 1;	// enable interrupt-priority-levels
   126 	IPR1			= 0x00;	// perephials are all low-priority
   127 	IPR2			= 0x00;
   128 
   129 
   130 	// init I2C lines and MSSP (taken from AN991)
   131 	DDR_I2C_SCL		= 1; 	//Configure SCL as Input	
   132 	DDR_I2C_SDA		= 1; 	//Configure SDA as Input
   133 	SSPADD			= 0x40;	//Should be 0x31 for 100kHz
   134 	SSPSTAT			= 0x80;	//Disable SMBus & Slew Rate Control
   135 	SSPCON1			= 0x28;	//Enable MSSP Master
   136 	SSPCON2			= 0x00;	//Clear MSSP Conrol Bits
   137 
   138 
   139 	// portB interrupts (i2c_int on RB5)
   140 	INTCON2bits.RBIP	= 0;	//make this a low-priority-interrupt
   141 	PIN_I2C_INT			= 1;	//switch pin to high-level (doesnt really work.. its an open collector. BUT i've got pullups)
   142 	DDR_I2C_INT			= 1;	//woo woo! this one has to be an input, for interrupts to work
   143 	if (ee_features && 0x01)
   144 	{
   145 		nKeys1 				= 0xFF - LDByteReadI2C(pcf8574A_1);		// make sure to reset i2c_int... just in case...
   146 		oKeys1				= nKeys1;
   147 		nKeys2				= 0xFF - LDByteReadI2C(pcf8574A_2);
   148 		oKeys2				= nKeys2;
   149 	}
   150 	INTCONbits.RBIF		= 0;	// then clear the flag!
   151 	INTCONbits.RBIE		= 1;	// Activate PortB interrupts
   152 
   153 
   154 	// enable alarm
   155 	if (ee_features && 0x00)
   156 	{
   157 		LDByteWriteI2C(pcf8583,0x00,0x04);
   158 	}
   159 
   160 
   161 	// Timer3 acts as 'event-ticker'
   162 	WriteTimer3(0x0000);
   163 	OpenTimer3(TIMER_INT_ON & T3_16BIT_RW & T3_PS_1_8 & T3_SYNC_EXT_OFF & T3_SOURCE_INT);
   164 
   165 
   166 	// PWM period =   [(period  ) + 1] x 4 x Tosc x TMR2 prescaler
   167 	SetOutputPWM1(SINGLE_OUT,PWM_MODE_1);					// since CCP1 is ECCP1.. set its mode
   168 	OpenTimer2( TIMER_INT_OFF & T2_PS_1_4 & T2_POST_1_1 );	// set Prescaler to 1/4
   169 	// Set DutyCycle
   170 	SetDCPWM1(gg_pwm1dc << 2);
   171 	SetDCPWM2(0x0040);
   172 	OpenPWM1(0xFF);												
   173 //	OpenPWM2(0xFF);	// Still DOESNT not work :(
   174 	// start PWM
   175 	DDR_PWM1	= 0;										// make PWM-Pins output
   176 	DDR_PWM2	= 0;
   177 
   178 	
   179 	// initialize rc5 decoding
   180 	rc5_init();
   181 	DDR_IR				= 1;	// switch to input...
   182 	INTCON3bits.INT2IE	= 1;	// enable int2 (rc5 decoding)
   183 	INTCON3bits.INT2IP	= 1;	// as high-priority int.
   184 	INTCON2bits.INTEDG2	= 0;	// on falling edge
   185 	INTCON3bits.INT2IF 	= 0;	// and clear the flag.
   186 
   187 
   188 	// interrupts
   189 	INTCONbits.GIEH		= 1;	// globally enable high-pri-int
   190 	INTCONbits.GIEL		= 1;	// globally enable low-prio-int
   191 	
   192 	// reset flags
   193 	gg_ioflags = FLAG_CLEAR;
   194 
   195 
   196 	// init & clear Display
   197 	if (ee_display)
   198 	{
   199 		lcd_InitDisplay();			
   200 		lcd_InitDisplay();			// ugly workaround...
   201 	}
   202 }//end UserInit
   203 
   204 
   205 
   206 void Wstring (char *dat,unsigned char len)
   207 {
   208 	unsigned char i;
   209 	for (i=0; i<len; i++)
   210 	{
   211 		lcd_WriteByte(dat[i]-0x20);
   212 	}
   213 }
   214 
   215 
   216 void Wdebug (unsigned char dat)
   217 {
   218  // Address Pointer Set
   219 /* t6963c_WriteData(0x00);		// byte1
   220  t6963c_WriteData(0x08);		// byte2
   221  t6963c_WriteCommand(0x24);		//set!*/
   222 
   223  if (dat >= 100) {
   224    lcd_WriteByte((dat / 100) + 0x10);
   225    dat = dat % 100;
   226  } else {
   227    lcd_WriteByte(0x10);
   228  }
   229 
   230  if (dat >= 10) {
   231    lcd_WriteByte((dat / 10) + 0x10);
   232    dat = dat % 10;
   233  } else {
   234    lcd_WriteByte(0x10);
   235  }
   236  lcd_WriteByte(0x10 + dat);
   237 }
   238 
   239 
   240 void ReadKeys(void)
   241 {
   242 	// read keys..
   243 	nKeys1	= 0xFF - LDByteReadI2C(pcf8574A_1);
   244 	nKeys2	= 0xFF - LDByteReadI2C(pcf8574A_2);	
   245 
   246 	if ((nKeys1 != oKeys1) || (nKeys2 != oKeys2))	// something happened
   247 	{
   248 		gg_keys 		= 0x00;
   249 		bKeys1 			= nKeys1;			// backup keys...
   250 		dKeys1 			= nKeys1 ^ oKeys1;	// calc diff...
   251 		dKeys2 			= nKeys2 ^ oKeys2;
   252 				
   253 		if (dKeys1 & 0x01)					// rotary event..
   254 		{
   255 			if (dKeys1 & nKeys1)			// press, not release...
   256 			{
   257 				if (nKeys1 == 0x05)	gg_keys = RC5_KEY_UP;
   258 				else				gg_keys = RC5_KEY_DOWN;
   259 			}
   260 			else if (dKeys1 & oKeys1) 		// release
   261 			{
   262 				if (nKeys1 == 0x00)	gg_keys = RC5_KEY_UP;
   263 				else				gg_keys = RC5_KEY_DOWN;
   264 			}
   265 			
   266 		}	// done decoding rotary
   267 		dKeys1 &= 0xFA;				// remove-rotary bits...
   268 		oKeys1 &= 0xFA;
   269 		nKeys1 &= 0xFA;
   270 			
   271 		// expander1
   272 		if (dKeys1 & nKeys1)		// button was pressed...
   273 		{
   274 			switch (dKeys1)
   275 			{
   276 				case 0x08:		gg_keys = RC5_KEY_LEFT; 	break;
   277 				case 0x02:		gg_keys = RC5_KEY_RIGHT;	break;
   278 				case 0x10:		gg_keys = RC5_KEY_BACK;		break;
   279 				case 0x20:		gg_keys = RC5_KEY_OK;		break;
   280 				case 0x40:		gg_keys = RC5_KEY_MENU;		break;
   281 				default:		gg_keys = 0x00;
   282 			}
   283 		}
   284 		if (dKeys2 & nKeys2)		// button was pressed...
   285 		{
   286 			switch (dKeys2)
   287 			{
   288 				case 0x04:		gg_keys = RC5_KEY_RED;		 break;
   289 				case 0x08:		gg_keys = RC5_KEY_GREEN;	 break;
   290 				case 0x02:		gg_keys = RC5_KEY_YELLOW;	 break;
   291 				case 0x01:		gg_keys = RC5_KEY_BLUE;		 break;
   292 				default:		gg_keys = 0x00;
   293 			}
   294 		}
   295 
   296 /*		if (dKeys2 & oKeys2) 		// release
   297 		{
   298 			Wdebug (dKeys2);
   299 			Wstring(rel,3);
   300 		}
   301 		if (dKeys1 & oKeys1) 		// release
   302 		{
   303 			Wdebug (dKeys1);
   304 			Wstring(rel,3);
   305 		}*/
   306 
   307 		if (gg_keys != 0x00)
   308 		{
   309 			gg_ioflags	|= FLAG_KEY;
   310 		}
   311 		// in any case: reset internal key-state
   312 		oKeys1 = bKeys1;
   313 		oKeys2 = nKeys2;
   314 	}
   315 }
   316 
   317 void ReadClock(void)
   318 {
   319 	unsigned char input[16];
   320 
   321 	LDPageReadI2C(pcf8583, 0x00, input, 0x10);
   322 	if (input[CLK_ALARM_CTRL] & 0x80) // highest bist it the alarm-if
   323 	{
   324 		gg_ioflags |= FLAG_ALARM;
   325 	}
   326 }
   327 
   328 
   329 void DrawTime (void) {
   330 	unsigned char time[0x05];
   331 	unsigned char clk[0x10];
   332 	unsigned int ram_address;
   333 	unsigned int x,y;
   334 
   335 	LDPageReadI2C(pcf8583, 0x00, clk, 0x10);
   336 
   337 	time[0] = ((clk[CLK_HOURS] & 0xF0) >> 4);
   338 	time[1] = ((clk[CLK_HOURS] & 0x0F));
   339 	time[2] = 0x0A;
   340 	time[3] = ((clk[CLK_MIN] & 0xF0) >> 4);
   341 	time[4] = ((clk[CLK_MIN] & 0x0F));
   342 
   343 /* D R A W    T I M E */
   344 	for (y = 0; y < FONT_HEIGHT; y++)
   345 	{
   346 		// set RAM address
   347 		ram_address = (30 * (y + TIME_Y_START)) + TIME_X_START;
   348 		lcd_WriteData((unsigned char)(ram_address % 256));	// lower byte
   349 		lcd_WriteData((unsigned char)(ram_address / 256));	// lower byte
   350 		lcd_WriteCommand(0x24);								//set!
   351 
   352 		// write 5 chars...
   353 		for (x = 0; x < 5; x++)
   354 		{
   355 			// jump to according position in bitmapfont
   356 			ram_address = (FONT_HEIGHT * y) + FONT_WIDTH * (unsigned int)(time[x] & 0x0F);
   357 			lcd_WriteByte(bitmapfont[ram_address++]);
   358 			lcd_WriteByte(bitmapfont[ram_address++]);
   359 			lcd_WriteByte(bitmapfont[ram_address++]);
   360 			lcd_WriteByte(bitmapfont[ram_address++]);
   361 		}
   362 	}
   363 
   364 
   365 /* D A T E */
   366 	lcd_WriteData(0x00);	// byte1
   367  	lcd_WriteData(0x08);	// byte2
   368  	lcd_WriteCommand(0x24);	// set!
   369 	lcd_WriteByte(0x00);
   370 	lcd_WriteByte(((clk[CLK_YEARDAY]  & 0x30) >> 4) + 0x10);
   371 	lcd_WriteByte(( clk[CLK_YEARDAY]  & 0x0F)       + 0x10);
   372 	lcd_WriteByte(0x0E);
   373 	lcd_WriteByte(((clk[CLK_WEEKDMON] & 0x10) >> 4) + 0x10);
   374 	lcd_WriteByte(( clk[CLK_WEEKDMON] & 0x0F)       + 0x10);
   375 	lcd_WriteByte(0x0E);
   376 	lcd_WriteByte(0x12);	// 2
   377 	lcd_WriteByte(0x10);	// 0
   378 	lcd_WriteByte(0x10);	// 0
   379 	lcd_WriteByte(((clk[CLK_WEEKDMON] & 0xA0) >> 6)  + 0x10 + 0x08); // 8 + x
   380 	
   381 
   382 /* T I M E R   I N F O */
   383 	lcd_WriteData(0xD2);	// byte1
   384  	lcd_WriteData(0x08);	// byte2
   385  	lcd_WriteCommand(0x24);	// set!
   386 	lcd_WriteByte(0x00);	// 
   387 	lcd_WriteByte(0x2E);	// N
   388 	lcd_WriteByte(0x45);	// e
   389 	lcd_WriteByte(0x58);	// x
   390 	lcd_WriteByte(0x54);	// t
   391 	lcd_WriteByte(0x00);	// 
   392 	lcd_WriteByte(0x34);	// T
   393 	lcd_WriteByte(0x49);	// i
   394 	lcd_WriteByte(0x4D);	// m
   395 	lcd_WriteByte(0x45);	// e
   396 	lcd_WriteByte(0x52);	// r
   397 	lcd_WriteByte(0x1A);	// :
   398 	lcd_WriteByte(0x00);	//
   399 
   400 	if (time[CLK_ALARM_CTRL] == 0xB0)		// dated alarm, interrupt enabled
   401 	{
   402 		lcd_WriteByte(((clk[CLK_YEARDAY + 0x08]  & 0x30) >> 4) + 0x10);
   403 		lcd_WriteByte(( clk[CLK_YEARDAY + 0x08]  & 0x0F)       + 0x10);
   404 		lcd_WriteByte(0x0E);
   405 		lcd_WriteByte(((clk[CLK_WEEKDMON + 0x08] & 0x10) >> 4) + 0x10);
   406 		lcd_WriteByte(( clk[CLK_WEEKDMON + 0x08] & 0x0F)       + 0x10);
   407 		lcd_WriteByte(0x0E);
   408 		lcd_WriteByte(0x12);	// 2
   409 		lcd_WriteByte(0x10);	// 0
   410 		lcd_WriteByte(0x10);	// 0
   411 		lcd_WriteByte(((clk[CLK_WEEKDMON + 0x08] & 0xA0) >> 6)  + 0x10 + 0x08); // 8 + x
   412 
   413 		lcd_WriteByte(0x00);
   414 		lcd_WriteByte(((clk[CLK_HOURS] & 0xF0) >> 4) + 0x10);
   415 		lcd_WriteByte(( clk[CLK_HOURS] & 0x0F)       + 0x10);
   416 		lcd_WriteByte(0x1A);	// :
   417 		lcd_WriteByte(((clk[CLK_MIN]   & 0xF0) >> 4) + 0x10);
   418 		lcd_WriteByte(( clk[CLK_MIN]   & 0x0F)       + 0x10);
   419 	}
   420 	else
   421 	{
   422 		lcd_WriteByte(0x2E);	// N
   423 		lcd_WriteByte(0x4F);	// o
   424 		lcd_WriteByte(0x4E);	// n
   425 		lcd_WriteByte(0x45);	// e
   426 		lcd_WriteByte(0x00);	// Pad some spaces... i am just too lazy to clear the whole screen :D
   427 		lcd_WriteByte(0x00);
   428 		lcd_WriteByte(0x00);
   429 		lcd_WriteByte(0x00);
   430 		lcd_WriteByte(0x00);
   431 		lcd_WriteByte(0x00);
   432 		lcd_WriteByte(0x00);
   433 		lcd_WriteByte(0x00);
   434 		lcd_WriteByte(0x00);
   435 		lcd_WriteByte(0x00);
   436 		lcd_WriteByte(0x00);
   437 		lcd_WriteByte(0x00);
   438 		lcd_WriteByte(0x00);
   439 		lcd_WriteByte(0x00);
   440 		lcd_WriteByte(0x00);
   441 		lcd_WriteByte(0x00);
   442 	}
   443 	
   444 
   445 } //DrawTime