/**************************************************************************
 * Filename:     internal.h
 *
 * Authors:      Petter Reinholdtsen <pere@td.org.uit.no>
 *
 * Description:  Prototypes for all internal kernel functions, and name
 *               of all global variables.
 **************************************************************************/

#ifndef _robios_kernel_h
#define _robios_kernel_h

#include "eyebot.h"

/*
 * List of internal kernel functions which is safe to call directly
 * from C
 */

/* Automatically extracted from USER_FUNC macros. */
#include "ckernel.h"

/* mallocs can't be called out of robios, therefore the library inside the user-program is called */
#define UserMalloc (( void* (*) (int size) ) (*(void**)mallocaddr)) 
#define UserFree (( void (*) (void* addr) ) (*(void**)freeaddr)) 


/* bir_driv.s */
BumpHandle TPU_IC_Init(bump_type *data);
int TPU_IC_Release(BumpHandle handle);
int TPU_IC_Check(BumpHandle handle, int *time_stamp);
IRHandle TPU_DIO_Init(ir_type *data);
int TPU_DIO_Release(IRHandle handle);
int TPU_DIO_Read(IRHandle handle);

/* psd_driv.s + asmstubs.c */
PSDHandle PSD_Setup(DeviceSemantics sem, psd_type *data);

/* enc_driv.s */
QuadHandle QUAD_Init_A(quad_type *data);
int QUAD_Release_A(QuadHandle handle);
int QUAD_Reset_A(QuadHandle handle);
int QUAD_Read_A(QuadHandle handle);

/* exhandle.s */
/* The default irq and exception handlers */
extern void notinst(void);
extern void DummyExcep(void);

/* init.s */
void set_cpuspeed(int speed);
void set_waitstates(waitstate_type *states);

/* mystr.c */
void *mymemmove(void *dest, const void *src, int n);
int mystrlen(const char *s);
char *mystrcat(char *dest, const char *src);
char *mystrcpy(char *dest, const char *src);
char *mystrncpy(char *dest, const char *src, int n);
int mytoupper(char ch);
int mystrcasecmp(const char *s1, const char *s2);
int int2str(char *dst, int value, int space, int base, int len,
            int zerofill, int negative);
int float2str(char *buf, float f, int minsp, int decimals, int bufsize);


/* user.s */
int REG_GetCode(int i);
int REG_GetKey(int i);
int REG_SetCode(int code0, int code1);
int REG_SetKey(int key0, int key1);
void hdtreflash(void);
void robiosreflash(void);

/* sm_driv.s */
int MOTOR_PWM_Init(motor_type *hdt_data);
int TPU_PWM_Release(MotorHandle handlemask);
int SVO_Angle(ServoHandle handlemask, int angle);
int SERVO_PWM_Init(servo_type *hdtdata);
int MOT_Speed(MotorHandle handle, int speed);

/* srec.s */
int AutodownloadDetect(int interface);

/* system.s */
void OS_Stop(void);
void precswitch(struct pstat *old, struct pstat *cur);
void precopswitch(struct pstat *old, struct pstat *cur);
void cswitch(struct pstat *old, struct pstat *cur);
int GetStackPointer(void); /* XXX actually returns pointer */

/* compass.s */
#ifdef USE_COMPASS
int COMPASS_Setup(void* dataarea);
#endif

/* ownmath.c */
float own_cos(radians x);
float own_sin(radians x);

/* timer.c */
/* Dummy struct to get the same API as Linux 2.2 */
struct pt_regs;

int request_irq(unsigned int irq,
                void (*handler)(int, void *, struct pt_regs *),
                unsigned long flags,
                const char *device,
                void *dev_id);
void free_irq(unsigned int irq, void *dev_id);

/* libradio/radio.c */
int RADIO_SysSend(BYTE mestype, BYTE id, int byteCount, BYTE* buffer);
int RADIO_SysCheck(void);
int RADIO_SysRecv (BYTE* id, int* bytesReceived, BYTE* buffer);

/* vcaminit.c / qcaminit.c */
char camera_indicator(void);

/* vcamfunc.c / qcaminit.c */
int CAM_Release(void);

/*
 * Complete (?) list of global variables in RoBIOS kernel.  Try to
 * keep this updated, to avoid name conflicts.
 */

/* audio.s */
extern BYTE copy_start1[];
extern void *copy_start2;
extern void *copy_end;

/* enc_driv.s */
extern short block_map;

/* init.s */
extern int Kiloram;
extern int RomSize;
extern int Byteram;
extern int HDTBase;
extern int CPUclock;
extern int TPUTimer1;
extern int TPUTimer2;

/* lcd.s */
extern int r_menuOn;

/* srec.s */
extern int progstart;
extern int realsize;
extern short baudrates1[];

/* main.c */
extern int serspeeds[];
/* extern tle tlist[]; */
extern int maxentry;
extern int offset;
extern int boc[];
extern char z;
extern timestamp ostime;
extern info_type *hdrinfo;
/* extern int r_interface; */
/* extern int r_speed; */ 
extern int r_id;
extern int r_remoteOn;
extern int r_imageTransfer;
/* extern int r_radioDebug; */
extern waitstate_type *waitstates;
extern int serspeed;
extern int handshake;
/* extern int interface; */
extern int loadstatus;
extern IPL_CONFIG _IPLConfig;

/* hdt.c */
extern int odo_count[];
extern int odo_click2meter[];
extern HDT_entry_type *HDT;

/* tasking.c */
extern struct tcbq tcb_priq[];
extern struct tcb *cur_thread;
extern struct tcb *idle_thread;
extern BYTE mtmode;
extern BOOL preenable;
extern BOOL schedulerBusy;
extern BOOL use_preswitch;
extern int handle;

/* timer.c */
extern int co2;
extern int co1;
extern int sw;
extern int Hrs;
extern int Mins;
extern int Secs;
extern int Ticks;
extern int Gcount;
extern int Lcount;
/* extern irq_entry irqlist[]; */
extern int nr_irqs;
extern int starthandle;

/* vw_inter.c */
extern PositionType position;
extern SpeedType speed;
extern MotorHandle motorleft;
extern MotorHandle motorright;
extern QuadHandle encoderleft;
extern QuadHandle encoderright;
extern meter wheelDistance;
extern meter wheelDistHalf;
extern meterPerSec maxvl;
extern meterPerSec maxvr;
extern meterPerSec maxv;
extern radPerSec maxw;
extern unsigned int lClicksPerMeter;
extern unsigned int rClicksPerMeter;
extern unsigned int oldposl;
extern unsigned int oldposr;
extern int drive_type;
extern int IRQscale;
extern BOOL IRQ_activated;
extern meterPerSec v_set;
extern meterPerSec v_goal;
extern meterPerSec v_diff_old;
extern meterPerSec va_sum;
extern meterPerSec va[];
extern radPerSec w_set;
extern radPerSec w_goal;
extern radPerSec w_diff_old;
extern radPerSec wa_sum;
extern radPerSec wa[];
extern int avg_pos;
extern float vv;
extern float tv;
extern float vw;
extern float tw;
extern BOOL control_active;
extern meter drive_vgoal;
extern meter drive_vis;
extern radians drive_wgoal;
extern radians drive_wis;
extern BOOL check_active;
extern BOOL drive_positive;
extern int check_type;
extern float sintab[];

/* coding.c */
void WL_SEND(int interface);
void WL_RECV(int interface);
int  WL_CD  (int interface);

/* msgqueue.c */
int queue_init(msgqueue *q, bufElem *e, int size);
BOOL queue_empty(msgqueue *q);
int queue_length(msgqueue *q);
int queue_get(BYTE *type, BYTE* id, int* length, BYTE content[], msgqueue *q);
int queue_put(int priority ,BYTE type, BYTE id, int length, BYTE content[],
              msgqueue *q);
int queue_lock(msgqueue *q);
int queue_unlock(msgqueue *q);
BOOL queue_locked(msgqueue *q);

/* frame.c */
void frame_segment(void);
void frame_acquire(int length, BYTE *buffer);

/* i2c.c */
void i2c_start(void);
void i2c_stop(void);
BOOL i2c_write_byte(BYTE byte);
BYTE i2c_read_byte(void);
BYTE i2c_read_last_byte(void);

/* idt7204.s */
void idt7204_raise_reset(void);
void idt7204_lower_reset(void);
void idt7204_read_block(int length, BYTE *block);

/* ov6620.c */
BOOL ov6620_probe(void);
BOOL ov6620_init(void);
BOOL ov6620_set_frame_rate(int frame_rate);

/* ov7620.c */
BOOL ov7620_probe(void);
BOOL ov7620_init(void);
BOOL ov7620_set_frame_rate(int frame_rate);

/* vv6301.c */
BOOL vv6301_probe(void);
BOOL vv6301_init(void);
BOOL vv6301_set_frame_rate(int frame_rate);

#endif
