/****************************************************************************/
/* Copyright 2014 MBARI.                                                    */
/* Monterey Bay Aquarium Research Institute Proprietary Information.        */
/* All rights reserved.                                                     */
/****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#include <modbus.h>

#define SLAVE_ID        0x01
#define DEFAULT_BAUD    19200L
#define TOTAL_COILS     16
#define MODBUS_DEBUG    TRUE

int main(int argc, char *argv[])
{
   int ret, i;
   int start;
   int ncoils;
   uint8_t coils[TOTAL_COILS];

   modbus_t *ctx;
   long baud;

   if (argc < 4)
   {
      printf("RCOIL compiled with libmodbus version %s on %s at %s\n\n",
             LIBMODBUS_VERSION_STRING, __DATE__, __TIME__);
      
      printf("Usage: rcoil port start ncoils [baud]\n");
      printf("Default baud is %ld\n\n", DEFAULT_BAUD);
      printf("Example:\n");
      printf("./rcoil com1  1 4\n");
      return -1;
   }

   /* start coil  */
   start = atoi(argv[2])-1;//for libmodbus address shift

   /* total coils to read */
   ncoils = atoi(argv[3]);

   /* check the coil count */
   if (ncoils > TOTAL_COILS)
   {
      printf("ERROR exceed max coils of 64\n");
      exit(1);
   }

   /* set the buad rate */
   baud = DEFAULT_BAUD;
   if (argc == 5)
   {
      baud = atol(argv[4]);
      switch (baud)
      {
         case 9600:     break;
         case 19200:    break;
         case 38400:    break;
         case 57600:    break;
         case 115200:   break;
         default:
            printf("Invalid baud: %ld\n", baud);
            printf("Supported bauds: 9600, 19200, 38400, 57600, 115200\n");
            return -1;
      }
   }

   /* init the modbus interface */
   ctx = modbus_new_rtu(argv[1], baud, 'N', 8, 2);

   if (ctx == NULL)
   {
      fprintf(stderr, "Unable to allocate libmodbus context\n");
      return -1;
   }

   modbus_set_debug(ctx, MODBUS_DEBUG);
   modbus_set_error_recovery(ctx, MODBUS_ERROR_RECOVERY_LINK);
   modbus_set_slave(ctx, SLAVE_ID);

   if (modbus_connect(ctx) == -1)
   {
      fprintf(stderr, "ERROR Connection failed: %s\n",
              modbus_strerror(errno));
      modbus_free(ctx);
      return -1;
   }

   /* read the coils */
   if (MODBUS_DEBUG)
      printf("modbus_read_bits(SLAVE %d, START %d, NCOILS %d): ", 
             SLAVE_ID, start, ncoils);

   ret = modbus_read_bits(ctx, start, ncoils, coils);

   /* check for errors */
   if (ret != ncoils) 
   {
      printf("FAILED\n");

      ret = -1;
   }
   else
   {
      printf("OK\n");

      for (i = 0; i < ncoils; ++i)
         printf("COIL %02d = %d\n", (i + start), (int)coils[i]);

      ret = 0;
   }

   /* Close the connection */
   modbus_close(ctx);
   modbus_free(ctx);

   return ret;
}
