/*
 * ocr.c
 *
 * Ocean Multi-spectral radiometer   Seabird OCR-504  https://www.seabird.com/multispectral-radiometers/product?id=60762467731
 * Fast sampling rate (7–24 Hz optional), 10 degree fov, 4 wavelengths available, UV wavelengths of 305, 325, 340, and 380 nm
 *
 *  Created on: Nov 15, 2021
 *      Author: tm
 */

#include "system.h"
#include "uartstdio.h"
#include "user_io.h"
#include "uart3.h"
#include "ocr.h"

/*
 * New Driver Instructions
 *
 * Driver name - ocr.c, ocr.h (could have been ocr-504.c)
 *
 * ocr_init (from optode_init)
 *
 * ocr driver primitives (getc, putc, etc), wrappers on uart3 primitives
 *
 * ocr comm test (make callable from "Communicate with Instrument" test menu in test.c)
 *
 *
 */



extern unsigned long Timer_1ms(bool reset);

struct ocrDriver ocr;   // struct defd in ocr.h

// Uses UART3 (same as Optode) on J7 MFET or MPHOX

void ocr_init(void)
{
    uart3_init();

    uart3_setup(OCR_BAUD, 16000000);

    uart3_echo_set(0);
}


/*
 * Apply power to the OCR and prepare uart3 and driver state vars.
 * Assumes ocr_init is called.
 */
void ocr_open(void)
{
    // on MPHOX, triple rs232 level translator is enabled for Optode J7, Console J6, and CTD J8 by console_enable/shutdown
    // on MFET, dual rs232 level translator is enabled for Optode J7 and Console J6 by console_enable/shutdown

#if BOARD_MFET >= 2  || BOARD_MPHOX >= 1
    // turn on 5v supply on J7 MFET rev B
    ROM_GPIOPinWrite(GPIO_PORTL_BASE, GPIO_PIN_2, 0xff);    // PL2, pin 106 is 5vON
#endif

    ocr.state = 0;
    ocr.bufIndx = 0;

}


void ocr_close(void)
{

#if BOARD_MFET >= 2  || BOARD_MPHOX >= 1
    // turn off 5v supply on J7 MFET rev B
    ROM_GPIOPinWrite(GPIO_PORTL_BASE, GPIO_PIN_2, 0x00);    // PL2, pin 106 is 5vON
#endif

}


// ocr driver primitives, wrap uart3 primitives

unsigned char ocr_getc(void)
{
    unsigned char c;

    c = uart3_rx_byte();
    return c;
}

void ocr_putc(unsigned char c)
{
    uart3_tx_byte(c);
}

int ocr_rxBytesAvail(void)
{
    return(uart3_rx_bytes_avail());
}

void ocr_flushRx(void)
{
    uart3_rx_bufr_flush();
}

void ocr_flushTx(bool bDiscard)
{
    uart3_tx_bufr_flush(bDiscard);
}

int ocr_write(const char *pcBuf, uint32_t ui32Len)
{
    return(uart3_write(pcBuf, ui32Len));
}

// maxlen is buffer max, returns only when newline chars are received (0x0D or 0x0A)
int ocr_rx_str(char *pcBuf, uint32_t ui32Len)
{
    return(uart3_rx_str(pcBuf, ui32Len));
}

// returns after receiving ui32Len bytes
int ocr_rx_buf(unsigned char *pcBuf, uint32_t ui32Len)
{
    return(uart3_rx_buf(pcBuf, ui32Len));
}


#ifdef NOCODE


Satlantic OCR-504 Multispectral Radiometer
Copyright (C) 2011, Satlantic Inc. All rights reserved.
Firmware version: 5.1.0 - SatNet Type B
Instrument: SATDI4
S/N: 2247

Reset Source: Power
Press <Ctrl+C> for command console.
Initializing system. Please wait...

Autonomous operation enabled.

SATDI422470000000.59ÿ{üý÷ú%Àÿ$@Å
SATDI422470000000.72ÿ{ü³@þÀúÀÿ%¿«
SATDI422470000059.33{{qÀ~Àz@6ÀÂ¡¬G
SATDI422470000059.46{{tÀ}q@z@(Á­Ò
SATDI422470000059.60{{Ø~z      À1@Ã®
SATDI422470000059.74{{ÝÀ~Àz%@-Á¯!
SATDI422470000059.88{{ÐÀ}wÀz4%Ã°x
SATDI422470000060.01{{Õ~z9)Â±t


#endif


void ocr_comm_test(void)
{
    unsigned char inChar;
    unsigned char drvChar;
    unsigned int indx;
    int debugFlg;
    int cnt;

    debugFlg = 0;


    // Tested with Seabird / Satlantic OCR-504

    //uprintf("                               \t5860\t29\t-0.003\t16.892\t0.009\t998.802\t1472.435\t\n");
    uprintf("\n\n*Press CTRL-X to stop communicating with the OCR-504 Instrument.\n\n");
    uprintf("\n Instructions for OCR-504 Configuration (silent wake, polled, short frame, calibration enabled:\n\n");
    uprintf("  Press CTRL-C to start Config mode, look for [Auto]$ prompt\n\n");

    uprintf("    [Auto]$ set -?                 [ List config params]\n\n");

    uprintf("    [Auto]$ set initsm on          [SILENT MODE ON - suppress power on header]\n\n");

    uprintf("    [Auto]$ set initat off         [AUTOTELEMETRY OFF - polled by <ENTER> or <SPACE.]\n\n");

    uprintf("    [Auto]$ set frametype short    [ASCII Data, tab delimited, terminated CR-LF]\n\n");

    uprintf("    [Auto]$ set usecal on          [ Utilize factory calibration]\n\n");

    uprintf("    [Auto]$ save                   [ Save config settings ]\n\n");

    uprintf("    [Auto]$ show all               [ Show all config settings]\n\n");

    uprintf("    [Auto]$ exit                   [ Exit to polled sampling mode, press <ENTER> to sample]\n\n");

#ifdef OCR_SETUP

    [Auto]$ show all [AS SHIPPED FROM FACTORY]

    Sensor Type: irradiance
    Serial Number: 2247
    Frame Type: binary
    Header: SATDI4
    Telemetry Baud Rate: 57600 bps
    Maximum Frame Rate: AUTO
    Initialize Silent Mode: off
    Initialize Power Down: off
    Initialize Automatic Telemetry: on
    Network Mode: off
    Network Address: 001
    Network Baud Rate: 19200 bps
    Averaging: off
    Immersed: on
    Calibrated Output: off
    Sensor Latency: 0
    Cal Coefficients:
     Optical Channel 1:
            a0:2146709830.0 [2146709830]
            a1:1.66144579217e-007 [1.66144e-07]
            im:1.161 [1.161]

     Optical Channel 2:
            a0:2147299079.0 [2147299079]
            a1:1.99579905307e-007 [1.99579e-07]
            im:1.410 [1.41]

     Optical Channel 3:
            a0:2147102221.6 [2147102221]
            a1:2.12413218205e-007 [2.12413e-07]
            im:1.365 [1.365]

     Optical Channel 4:
            a0:2147428518.5 [2147428518]
            a1:3.40295031944e-006 [3.40295e-06]
            im:1.359 [1.359]


     [Auto]$ set -?

    Usage: set [parameter] [value]

    set telbaud [telemetry baud rate (bps)]
    set maxrate [maximum frame rate (Hz)]
    set initsm [initialize silent mode (on|off)]
    set initpd [initialize power down (on|off)]
    set initat [initialize auto telemetry (on|off)]
    set netmode [network mode (on|off)]
    set netadd [network address (1-255)]
    set netbaud [network baud rate (bps)]
    set avg [on|off]
    set usecal [on|off]
    set immersed [on|off]
    set latency [value]
    set frametype [binary|short|long]
    set a0ch[1-4] [value]
    set a1ch[1-4] [value]
    set imch[1-4] [value]


    [Auto]$ set initsm on  [SILENT MODE ON - suppress power on header]

    [Auto]$ set initat off   [AUTOTELEMETRY OFF - polled by <ENTER> or <SPACE.]

    [Auto]$ set frametype short   [ASCII Data, tab delimited, terminated CR-LF]

    [Auto]$ set usecal on       [ Data uses factor calibration]

    [Auto]$ save

    Configuration parameters saved.



    [Auto]$ show all

    Sensor Type: irradiance
    Serial Number: 2247
    Frame Type: short
    Header: SATFI4
    Telemetry Baud Rate: 57600 bps
    Maximum Frame Rate: AUTO
    Initialize Silent Mode: on
    Initialize Power Down: off
    Initialize Automatic Telemetry: off
    Network Mode: off
    Network Address: 001
    Network Baud Rate: 19200 bps
    Averaging: off
    Immersed: on
    Calibrated Output: on
    Sensor Latency: 0
    Cal Coefficients:
     Optical Channel 1:
            a0:2146709830.0 [2146709830]
            a1:1.66144579217e-007 [1.66144e-07]
            im:1.161 [1.161]

     Optical Channel 2:
            a0:2147299079.0 [2147299079]
            a1:1.99579905307e-007 [1.99579e-07]
            im:1.410 [1.41]

     Optical Channel 3:
            a0:2147102221.6 [2147102221]
            a1:2.12413218205e-007 [2.12413e-07]
            im:1.365 [1.365]

     Optical Channel 4:
            a0:2147428518.5 [2147428518]
            a1:3.40295031944e-006 [3.40295e-06]
            im:1.359 [1.359]


    [Auto]$ sample
    Usage: sample [ADC channel ((1-4)|vreg|temp|all)]

    [Auto]$ sample all

    Power voltage regulated: 196
    Temperature sensor: 152

    Optical Channel 1: 2147255872
    Optical Channel 2: 2147361600
    Optical Channel 3: 2147094144
    Optical Channel 4: 2147425216


#endif


    //set up the optode
    ocr_init();
    ocr_open();               // power on ocr
    ROM_SysCtlDelay(100);       //100 is a guess


    UARTEchoSet(false);
    while(1)
    {
        if( ocr_rxBytesAvail() )      // ocr
        {
            uprintf( "%c", ocr_getc() );
        }


        if(UARTRxBytesAvail())
        {
            inChar = UARTgetc();

            if((inChar == 24) || (inChar == 25) || (inChar == 26)  )  // Ctrl-X or Ctrl-Y or Ctrl-Z
            {
                UARTEchoSet(true);
                break;
            }
            else
            {
                ocr_putc(inChar);       // else send to OCR
            }
        }  // if(UARTRxBytesAvail())


    } // while(1)



    ocr_close();  // Close up the ocr


#ifdef NOCODE
    //set up the optode
    ocr_init();
    ocr_open();               // power on ocr
    ROM_SysCtlDelay(100);       //100 is a guess

    for(indx=0; indx<30; indx++)
    {
        cnt = ocr_rx_str(ocr.buf, 64);  //
        uprintf("%02u: [%02d] %s\n", indx, cnt, ocr.buf );
    }

    //for(indx=0; indx<100; indx++)
    while(1)
    {
        cnt = ocr_rx_buf(ocr.buf, 45);  //
        uprintf("%02u: [%02d] %s\n", indx, cnt, ocr.buf );

        //if user types anything, send it to the ocr--exit on CTRL-X
        if(UARTRxBytesAvail())
        {
            inChar = UARTgetc();

            if(inChar == 0x03) // Ctrl-C (sent below)
            {
                ocr_putc(0x03);     // Send Ctrl-C

                UARTEchoSet(false);
                while(1)
                {
                    if( ocr_rxBytesAvail() )      // ocr
                    {
                        uprintf( "%c", ocr_getc() );
                    }


                    if(UARTRxBytesAvail())
                    {
                        inChar = UARTgetc();

                        if((inChar == 24) || (inChar == 25) || (inChar == 26)  )  // Ctrl-X or Ctrl-Y or Ctrl-Z
                        {
                            break;
                        }
                        else
                        {
                            ocr_putc(inChar);       // else send to OCR
                        }
                    }
                } // while(1)
            }

            if(inChar == 13)     // If user hit carriage return, add a line feed
            {
                ocr_putc(13);  // CR
                ocr_putc(10);     // LF
            }
            else if(inChar == 24)   // Ctrl-X
            {
                UARTEchoSet(true);
                break;
            }

            else
            {
                ocr_putc(inChar);
            }
        }   // if(UARTRxBytesAvail())


    } // while(1)

    ocr_close();  // Close up the ocr
#endif

}


