/* comatos8515.h - Header file for the COMATOS operating system 
 Modifed for 8 MHz by BRL 
 
 modified for faster scheduler loop
 
 Ben Greenblatt - Adapted from assembly version of Fall 1999 
 Revision history: 
 6/12/00: First working version - Message passing and timeout confirmed
 6/13/00: Added serial I/O code from Atmel Application Note AVR306
 Included debugging code for:
 1. Sending UART info about bad return codes
 2. Sending UART info about failure to return
 Note on failure to return: Bug in compiler results in the inability to use
 C to access data from the hardware stack (cannot input and shift IO registers  without 
 dropping the high byte of the address, similar to function pointer problem). Solution  
 was to use embedded assembly. Concern: assembly hard codes offsets in software  stack for
 eBuf[] array locations. If we change the system clock, be aware that these may  need to be
 modified 
 Fixed some bugs involving message passing:
 1. Message source is cleared after a task is run in case it did not clear them  with OSGetMess
 2. A compiler bug caused the loops generating the masks for clearing/setting PCBMessSrc  to fail,
 when the mask was overwritten after each loop iteration. The solution was more  elegant anyway
 and involved using a shift by the number of the sending task. I don't really know  why I didn't
 do it that way to begin with. 
 Modified serial I/O code so that OSUARTDataInRxBuffer() returns the number of  characters in the buffer
 Added OSUARTReceiveBytes, which reads a specified number of data bytes. It is  non-blocking. If fewer
 than the requested number of bytes have been received, the function returns what  is in the buffer
 and specifies the number read.
 6/15/00: Turned on interrupts during system timer 
 1/29/01: Modified as an AT90S8515 Version
 */ 
   #ifndef __COMT
   #define __COMT
   #define CLOCKSPEED 4000000
   
   #define begin {
   #define end } 
   /* OSStatus Bit Assignments */
   #define txdone 1 /* Indicates completion of a UART transmit */
/* Timer Constants */
   #define T0Prescale 0x03 /* Prescaler of 1/64 */ 
   #define TIMER0INTON 0x02 /* TIMSK value for timer0 overflow interrupt */
   //#define OSTIMER0START 256-125 /* Start timer0 at a value to get 125 counts    */
   #define OSTIMER0START 256-62 /* Start timer0 at a value to get 125 counts */
/* Debugger Constants */
   #define OSRegDumpFlag 252
   #define OSTimeoutCrash 251
   #define OSPCDumpFlag 250
   #define OSNoTasksFlag 249
   #define OSBadCode 248
#define OSNoDebug 0
   #define OSDebug 1
/* UART Control Register Bit Definitions */
   #define RXCIE 7
   #define TXCIE 6
   #define UDRIE 5
   #define RXEN 4
   #define TXEN 3
   #define CHR9 2
   #define RXB8 1
   #define TXB8 0
/* UART Status Register Bit Definitions */
   #define RXC 7
   #define TXC 6
   #define UDRE 5
   #define FE 4
   #define OVR 3
/* UART Buffer Defines */
   #define UART_RX_BUFFER_SIZE 32 /* 1,2,4,8,16,32,64,128 or 256 bytes */
   #define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1 )
#define UART_TX_BUFFER_SIZE 32 /* 1,2,4,8,16,32,64,128 or 256 bytes */
   #define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1 )
/* KeyPad Buffer Define */
   #define KEYPAD_BUFFERSIZE 8 
   #define DebounceTime 30
   #define NoKeyPadMessage 0
#define KEYSTATE_NoPush 0
   #define KEYSTATE_MaybePush 1
   #define KEYSTATE_Pushed 2
   #define KEYSTATE_DebouncePress 3 
   #define KEYSTATE_Waiting 4 
   #define KEYSTATE_Done 10
   #define KEYSTATE_error 5
   #define KEYSTATE_StillPressed 6 
#define OSTimeOut 20
   #define Baudrate 25 
   #define NoMessage 0
   
   #define KEYPAD_maxkeys 16
   /* Structure defining process control blocks */
   struct PCB_t {
   int (*entry_pt)(void); /* Pointer to the code for the task */
   unsigned char PCBTimeoutVal; /* Maximum number of ticks before task is ready    */
   unsigned char PCBCurrentTime; /* Number of ticks until task is ready to run    */
   unsigned char PCBMessMask; /* Indicates which tasks we are waiting on */
   unsigned char PCBMessSrc; /* Incidates which tasks have sent messages */
   unsigned char PCBAck; /* Acknowledge bits */
   unsigned char PCBState; /* State register for passing data between successive    runs of the task */
   unsigned char PCBMessages[8]; /* Message mailboxes */
   } PCBs[8];
// make byte count offsets for indexing in sched loop
   #define entry_ptOffset 0 
   #define PCBTimeoutValOffset 2
   #define PCBCurrentTimeOffset 3 
   #define PCBMessMaskOffset 4
   #define PCBMessSrcOffset 5 
   #define PCBAckOffset 6 
   #define PCBStateOffset 7
   #define PCBMessagesOffset 8
   
   /* Operating system global memory */
   // #asm("_OSStatus:"); 
   #asm
   _OSStatus:
   #endasm
   unsigned char OSStatus; /* Status register */
   unsigned char OSNumTasks; /* Number of tasks running */
   unsigned char OSCurrentTask; /* Currently running task */ 
   unsigned char OSReturnVal; /* Return value of last exiting task */
   unsigned int OSTimeout; /* Ticks left until system times out*/
   unsigned int OSMaxTimeout; /* Maximum ticks allowed to a task before timeout*/
   unsigned long OSGlobalTime; /* Global millisecond counter */
   unsigned char OSUARTCharCnt; /* Number of characters for UART to send */
   unsigned char OSUARTTemp; /* Scratch space for the UART */
/* UART buffer related variables */
   unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
   unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
unsigned char UART_RxHead;
   unsigned char UART_RxTail;
unsigned char UART_TxHead;
   unsigned char UART_TxTail;
/* KeyPad related variables */
   unsigned char KEYPAD_Buffer[KEYPAD_BUFFERSIZE];
   unsigned char KEYPAD_Key;
   unsigned char KEYPAD_butnum;
   unsigned char KEYPAD_KeyFlag; 
   unsigned char KEYPAD_Key_Ready; 
   char KEYPAD_KeyPress; 
   char KEYPAD_index; 
   unsigned char OSNumCharInput;
   unsigned char OSKeyLock;
   unsigned char OSKeyCommand;
   //key pad scan table
   flash unsigned char KEYPAD_keytbl[16]={0xee, 0xed, 0xeb, 0xe7, 0xde, 0xdd, 0xdb,    0xd7, 0xbe, 0xbd, 0xbb, 0xb7, 0x7e, 0x7d, 0x7b, 0x77};
   flash unsigned char KEYPAD_letter[16]={'1','2','3','A','4','5','6','B','7','8','9','C','*','0','#','D'};  
/* Function prototypes */
   void OSInit(unsigned maxTimeout, unsigned char debug); //
   void OSStart(void); // 
   void OSCreateTask(int (*entry_pt_a)(void),unsigned char timeout, unsigned char    messageMask, unsigned char state); //
   unsigned char OSGetMessSrc(void); //
   unsigned char OSGetAck(void); 
   void OSSendAck(unsigned char task);
   void OSSetOwnAck(unsigned char val);
   unsigned char OSGetMess(unsigned char senderTask); 
   void OSSendMess(unsigned char recipTask, unsigned char message);
   void ISRSendMess(unsigned char recipTask, unsigned sendTask, unsigned char message);
   unsigned char OSGetState(void);
   void OSSetState(unsigned char val);
   void OSSetTimeout(unsigned char timeout);
   void OSSetMessMask(unsigned char mask);
/* UART functions */
   void OSInitUART( unsigned char baudrate );
   unsigned char OSUARTReceiveByte( void );
   unsigned int OSUARTReceiveBytes( char *data, unsigned int n );
   void OSUARTTransmitByte( unsigned char data );
   void OSUARTTransmitBytes( unsigned char *data, unsigned int n );
   /* KeyPad functions */
char OSKeyPadDebounce(void); 
   char OSKeyPad_Read(void);
   void OSKeyPadClearBuffer();
   void OSKeyPadWriteBuffer(char Key); 
   unsigned int OSGetKeyCommand(char *data);
#endif