#include <exec/exec.h>
#include <clib/exec_protos.h>
#include "I2C.h"

int   I2CStatus ;
char *I2CFehlerText[] = { "kein Fehler",
                          I2C_FEHLER_1,
                          I2C_FEHLER_2,
                          I2C_FEHLER_3,
                          I2C_FEHLER_4,
                          I2C_FEHLER_5,
                          I2C_FEHLER_6,
                          I2C_FEHLER_7,
                          I2C_FEHLER_8,
                          I2C_FEHLER_9,
                          I2C_FEHLER_10,
                          I2C_FEHLER_11,
                          NULL } ;

struct I2CMsg   *I2C_Msg   = 0 ;
struct I2CMsg   *reply     = 0 ;
struct MsgPort  *I2C_Port  = 0 ;
struct MsgPort  *ReplyPort = 0 ;

int
Open_I2C( void )
{
  Forbid() ;
  I2C_Port = FindPort( "I2C_Port" ) ;
  Permit() ;

  if( !I2C_Port )  /* i2cHost noch nicht gestartet */
    return I2CStatus = I2CErr_NoHost ;

  I2C_Msg = (struct I2CMsg *)AllocMem( sizeof(struct I2CMsg), MEMF_PUBLIC | MEMF_CLEAR ) ;

  if( !I2C_Msg )  /* Kein Speicher mehr vorhanden */
    return I2CStatus = I2CErr_NoMsg ;

  ReplyPort = CreateMsgPort() ;

  if( !ReplyPort )  /* Kein ReplyPort */
    return I2CStatus = I2CErr_NoReply ;

  I2C_Msg->Msg.mn_Node.ln_Type = NT_MESSAGE ;
  I2C_Msg->Msg.mn_Length       = sizeof( struct I2CMsg ) ;
  I2C_Msg->Msg.mn_ReplyPort    = ReplyPort ;

  I2C_Msg->Command = I2C_LOGON ;

  PutMsg( I2C_Port, (struct Message *)I2C_Msg);
  WaitPort( ReplyPort ) ;
  reply = (struct I2CMsg *)GetMsg( ReplyPort ) ;
  I2CStatus = reply->Error ;

  return I2CStatus ;
}

void
Close_I2C( void )
{
  if( I2C_Port && I2C_Msg && ReplyPort )
   {
    I2C_Msg->Command = I2C_LOGOFF ;

    PutMsg( I2C_Port, (struct Message *)I2C_Msg);
    WaitPort( ReplyPort ) ;
    reply = (struct I2CMsg *)GetMsg( ReplyPort ) ;
    I2CStatus = reply->Error ;
   }

  if( ReplyPort )
    DeleteMsgPort( ReplyPort ) ;

  if( I2C_Msg )
    FreeMem( I2C_Msg, sizeof( struct I2CMsg ) ) ;

  I2C_Port  = NULL ;
  I2C_Msg   = NULL ;
  ReplyPort = NULL ;
}

BOOL
Send_I2C( int Address, int Anzahl, char *Daten )
{
  if( ReplyPort )
   {
    I2C_Msg->Command = I2C_WRITE ;
    I2C_Msg->Address = Address   ;
    I2C_Msg->Length  = Anzahl    ;
    I2C_Msg->Data    = Daten     ;

    PutMsg( I2C_Port, (struct Message *)I2C_Msg);
    WaitPort( ReplyPort ) ;
    reply = (struct I2CMsg *)GetMsg( ReplyPort ) ;
    I2CStatus = reply->Error ;

    return (BOOL)!I2CStatus ;
   }

  I2CStatus = I2CErr_NoPort ;
  return FALSE ;
}

BOOL
Receive_I2C( int Address, int Anzahl, char *Daten )
{
  if( ReplyPort )
   {
    I2C_Msg->Command = I2C_READ ;
    I2C_Msg->Address = Address  ;
    I2C_Msg->Length  = Anzahl   ;
    I2C_Msg->Data    = Daten    ;

    PutMsg( I2C_Port, (struct Message *)I2C_Msg);
    WaitPort( ReplyPort ) ;
    reply = (struct I2CMsg *)GetMsg( ReplyPort ) ;
    I2CStatus = reply->Error ;

    return (BOOL)!I2CStatus ;
   }

  I2CStatus = I2CErr_NoPort ;
  return FALSE ;
}

void
Reset_I2C( void )
{
  if( ReplyPort )
   {
    I2C_Msg->Command = I2C_RESET ;

    PutMsg( I2C_Port, (struct Message *)I2C_Msg);
    WaitPort( ReplyPort ) ;

    reply = (struct I2CMsg *)GetMsg( ReplyPort ) ;
    I2CStatus = reply->Error ;
   }

  I2CStatus = I2CErr_NoPort ;
}

