/*
 * oscil_can.c
 *
 *  Created on: 24 мая 2020 г.
 *      Author: yura
 */

#include "alarm_log_can.h"

#include "CAN_Setup.h"
#include "global_time.h"
#include "CRC_Functions.h"


#pragma DATA_SECTION(alarm_log_can, ".slow_vars")
ALARM_LOG_CAN alarm_log_can = ALARM_LOG_CAN_CAN_DEFAULTS;



//int oscil_buffer[OSCIL_CAN_NUMBER_CHANNEL][OSCIL_CAN_NUMBER_POINTS];



void alarm_log_clear_buffer(ALARM_LOG_CAN_handle al)
{
   unsigned int i,k;
/*
   for (i=0;i<OSCIL_CAN_NUMBER_CHANNEL;i++)
       for (k=0;k<(OSCIL_CAN_NUMBER_POINTS+OSCIL_CAN_NUMBER_POINTS_ADD);k++)
           oc->oscil_buffer[i][k] = 0;

   for (i=0;i<OSCIL_CAN_NUMBER_CHANNEL;i++)
       for (k=0;k<OSCIL_CAN_NUMBER_POINTS;k++)
           oc->temp_oscil_buffer[i][k] = 0;


   oc->current_position = 0;
 //  oc->enable_rewrite = 1;
*/
}

int compress_size = 0;
void alarm_log_compress_temp_buffer(ALARM_LOG_CAN_handle al)
{


//    compress_size = fastlz_compress_level(1, al->start_adr_real_logs, 100, al->start_adr_temp);
//    compress_size = lzf_compress(al->start_adr_real_logs, 2000, al->start_adr_temp, 2000);


}


void alarm_log_copy_temp_buffer(ALARM_LOG_CAN_handle al)
{
   unsigned int i,k;
   unsigned long clog, temp_length;//real_length
   int *adr_finish_temp, *adr_current;


//   real_length = al->real_points * al->oscills;
  // real_adr = al->start_adr_real_logs;

   temp_length  =  al->temp_points * al->oscills; // сколько данных надо выерезать из лога
   al->temp_log_ready = 0;


   if (al->current_adr_real_log == al->start_adr_real_logs) // мы в начале, логов нету?
       return;

   adr_current = al->current_adr_real_log; // выставили конец лога
   adr_finish_temp = al->start_adr_temp + temp_length; // тут конец лога temp
   // теперь начиная с конца adr_finish скопируем в temp_log
   // с учетом того что мы копируем из циклического буфера в обычный, нужна развертка данных
   for (clog=0; clog<temp_length ;clog++)
   {
       if ( (adr_current >= al->start_adr_real_logs) )
       {
        *adr_finish_temp = *adr_current; // скопирлвали данные
        // едем назад
        adr_current--;
       }
       else
        *adr_finish_temp = 0; // а нету данных!

       // едем назад
       adr_finish_temp--;

       // закольцевались?
       if (adr_current < al->start_adr_real_logs)
       {
           if (al->finish_adr_real_log) // лог прокручивался?
              adr_current = al->finish_adr_real_log; // перешли в конец.
           else
               adr_current = al->start_adr_real_logs - 1;
       }
   }

   al->temp_log_ready = 1;

/*
   for (i=0;i<OSCIL_CAN_NUMBER_CHANNEL;i++)
       for (k=0;k<(OSCIL_CAN_NUMBER_POINTS+OSCIL_CAN_NUMBER_POINTS_ADD);k++)
           oc->oscil_buffer[i][k] = 0;

   for (i=0;i<OSCIL_CAN_NUMBER_CHANNEL;i++)
       for (k=0;k<OSCIL_CAN_NUMBER_POINTS;k++)
           oc->temp_oscil_buffer[i][k] = 0;


   oc->current_position = 0;
 //  oc->enable_rewrite = 1;
*/

}



//#define CAN_BOX_PRIORITY_LOW_MAX_SIZE_BLOCKS 3330L// 9999L

void alarm_log_send_buffer(ALARM_LOG_CAN_handle al)
{
   static unsigned int old_time = 0;
 //  static int prev_send_to_can = 0;
   static unsigned long old_t  = 0;
   unsigned int i;
   int real_mbox;
   static int flag_send_buf = 0;
   static unsigned long quant_local = 0;
   static unsigned long addr_to = 0;
   static int *start_adr;
   static unsigned int k = 0;


//   if (flag_send_buf)
//      {
//
//
//
//        return;
//      }


   if (al->global_enable==0)
       return;

   real_mbox = get_real_out_mbox(ALARM_LOG_TYPE_BOX, ALARM_LOG_NUMBER_BOX_IN_CAN);

   if (al->stage==1)
   {

       if (CAN_cycle_full_free(real_mbox,CAN_BOX_STAT_ON))
       {
           CAN_cycle_send(
                   ALARM_LOG_TYPE_BOX,
                   ALARM_LOG_NUMBER_BOX_IN_CAN,
                               (unsigned long)(0xfffc*3L),
                               &(al->cmd_fffc[0]),  3, CAN_BOX_EXTENDED_ADR, CAN_BOX_PRIORITY_LOW );

           CAN_cycle_send(
                   ALARM_LOG_TYPE_BOX,
                   ALARM_LOG_NUMBER_BOX_IN_CAN,
                   (unsigned long)(0xfffd*3L),
                               &(al->cmd_fffd[0]),  3, CAN_BOX_EXTENDED_ADR, CAN_BOX_PRIORITY_LOW );

           CAN_cycle_send(
                   ALARM_LOG_TYPE_BOX,
                   ALARM_LOG_NUMBER_BOX_IN_CAN,
                   (unsigned long)(0xfffe*3L),
                               &(al->cmd_fffe[0]),  3, CAN_BOX_EXTENDED_ADR, CAN_BOX_PRIORITY_LOW );

           al->stage = 2;

           quant_local = ((unsigned long)al->oscills * (unsigned long)al->temp_points);
           al->progress_can = quant_local;
           addr_to = 0;
           start_adr = al->start_adr_temp;


       }


       return;
   }


   if (al->stage==2)
   {

       if (CAN_cycle_full_free(real_mbox,CAN_BOX_STAT_OFF) && (get_new_cycle_fifo_load_level()<=2) )
       {
//           if ((unsigned long)quant_local>(unsigned long)CAN_BOX_PRIORITY_LOW_MAX_SIZE_BLOCKS)
//           {
//                k++;
//           }

           al->progress_can = quant_local;
           if ((unsigned long)quant_local > al->can_max_size_one_block)
           {

               al->crc16 = GetCRC16_IBM( al->crc16, (unsigned int *)start_adr, al->can_max_size_one_block);

               CAN_cycle_send(
                                  ALARM_LOG_TYPE_BOX,
                                  ALARM_LOG_NUMBER_BOX_IN_CAN,
                                  addr_to,
                                  start_adr,  al->can_max_size_one_block , CAN_BOX_EXTENDED_ADR, CAN_BOX_PRIORITY_LOW );

               start_adr += al->can_max_size_one_block;
               quant_local -= al->can_max_size_one_block;
               addr_to += al->can_max_size_one_block;

           }
           else
           {
               al->crc16 = GetCRC16_IBM_v2( al->crc16, (unsigned int *)start_adr, ((unsigned long)quant_local) );

               CAN_cycle_send(
                                  ALARM_LOG_TYPE_BOX,
                                  ALARM_LOG_NUMBER_BOX_IN_CAN,
                                  addr_to,
                                              start_adr,  ((unsigned long)quant_local) , CAN_BOX_EXTENDED_ADR, CAN_BOX_PRIORITY_LOW );
               al->stage = 3;
               quant_local = 0;
           }

       }


       return;
   }


   if (al->stage==3)
   {
       al->cmd_ffff[1] = al->crc16; // CRC16

       if (CAN_cycle_full_free(real_mbox,CAN_BOX_STAT_OFF))
       {
           al->progress_can = 0;

           CAN_cycle_send(
               ALARM_LOG_TYPE_BOX,
               ALARM_LOG_NUMBER_BOX_IN_CAN,
                           (unsigned long)(0xffff*3L),
                           &(al->cmd_ffff[0]),  3 , CAN_BOX_EXTENDED_ADR, CAN_BOX_PRIORITY_LOW );
           al->stage = 100;
           k--;
       }


       return;
   }


   if (al->stage==4)
   {
       if (CAN_cycle_full_free(real_mbox,CAN_BOX_STAT_OFF))
       {
           CAN_cycle_send(
                   ALARM_LOG_TYPE_BOX,
                   ALARM_LOG_NUMBER_BOX_IN_CAN,
                               (unsigned long)(0xfffc*3L),
                               &(al->cmd_fffc[0]),  3, CAN_BOX_EXTENDED_ADR, CAN_BOX_PRIORITY_LOW );
           al->stage = 100;
           k--;
       }


       return;
   }


   if (al->stage==100)
   {
       if (CAN_cycle_full_free(real_mbox,CAN_BOX_STAT_ON))
       {
  //         prev_send_to_can = 1;
           al->stage = 0;
           al->timer_send = (global_time.miliseconds - old_t);
       }

       return;
   }

// была команда на отправку посылки и она еще не ушла, тогда сбрасываем счетчик времени паузы между посылками,
// т.е. OSCIL_TIME_WAIT между концом отправки посылки и новой посылки.

//   if (prev_send_to_can && CAN_cycle_full_free(real_mbox,CAN_BOX_STAT_OFF)==0)
//   {
//       old_time = (unsigned int)global_time.miliseconds;
//       return;
//   }
//////
//   if (prev_send_to_can)
//   {
//
//   }
//////
//   prev_send_to_can = 0;


   if ((al->prev_status_alarm != al->status_alarm) && al->status_alarm)
   {
       if (CAN_cycle_full_free(real_mbox,CAN_BOX_STAT_ON))
       {

           al->prepare_data_can(al);

           if (al->copy2temp)
           {
               al->copy_temp_buffer(al);
//               alarm_log_compress_temp_buffer(al);
           if (al->temp_log_ready == 1)
           {
               old_t = global_time.miliseconds;
               al->stage = 1;
           }
           else
           {
               old_t = global_time.miliseconds;
               al->stage = 4;    // передаем пустое сообщение - это ошибка, данных нет!

           }

           }
           else
           {
               old_t = global_time.miliseconds;
               al->stage = 4;    // передаем пустое сообщение - это ошибка, данных нет!

           }


//           flag_send_buf = 1;


//           CAN_cycle_send(
//                   ALARM_LOG_TYPE_BOX,
//                   ALARM_LOG_NUMBER_BOX_IN_CAN,
//                               0xfffc,
//                               &(al->cmd_fffc[0]),  3, CAN_BOX_EXTENDED_ADR, CAN_BOX_PRIORITY_LOW );
//
//           CAN_cycle_send(
//                   ALARM_LOG_TYPE_BOX,
//                   ALARM_LOG_NUMBER_BOX_IN_CAN,
//                               0xfffd,
//                               &(al->cmd_fffd[0]),  3, CAN_BOX_EXTENDED_ADR, CAN_BOX_PRIORITY_LOW );
//
//           CAN_cycle_send(
//                   ALARM_LOG_TYPE_BOX,
//                   ALARM_LOG_NUMBER_BOX_IN_CAN,
//                               0xfffe,
//                               &(al->cmd_fffe[0]),  3, CAN_BOX_EXTENDED_ADR, CAN_BOX_PRIORITY_LOW );
//           al->stage = 1;
//
//           CAN_cycle_send(
//                   ALARM_LOG_TYPE_BOX,
//                   ALARM_LOG_NUMBER_BOX_IN_CAN,
//                               0,
//                               al->start_adr,  ((unsigned long)al->oscills * (unsigned long)al->points) , CAN_BOX_EXTENDED_ADR, CAN_BOX_PRIORITY_LOW );
//           al->stage = 2;
//
//           CAN_cycle_send(
//                   ALARM_LOG_TYPE_BOX,
//                   ALARM_LOG_NUMBER_BOX_IN_CAN,
//                               0xffff,
//                               &(al->cmd_ffff[0]),  3 , CAN_BOX_EXTENDED_ADR, CAN_BOX_PRIORITY_LOW );
//           al->stage = 0;
//
//
//           prev_send_to_can = 1;

       }
   }
   al->prev_status_alarm = al->status_alarm;



/*

   oc->global_enable = TerminalUnites[oc->number_can_box_terminal_oscil][0] & 0x1;
   oc->send_after_cmd =  (TerminalUnites[oc->number_can_box_terminal_oscil][0] & 0x2) >> 1;
   oc->cmd_send =  (TerminalUnites[oc->number_can_box_terminal_oscil][0] & 0x4) >> 2;
   oc->stop_update_on_error =  (TerminalUnites[oc->number_can_box_terminal_oscil][0] & 0x8) >> 3;
   oc->stop_update_on_stop_pwm =  (TerminalUnites[oc->number_can_box_terminal_oscil][0] & 0x10) >> 4;

   TerminalUnites[oc->number_can_box_terminal_oscil][0] &= ~0x4; // clear cmd_send

   oc->number_ch = TerminalUnites[oc->number_can_box_terminal_oscil][1];
   oc->number_points = TerminalUnites[oc->number_can_box_terminal_oscil][2];
   oc->step = TerminalUnites[oc->number_can_box_terminal_oscil][3];


   if (oc->global_enable==0)
       return;

   real_mbox = get_real_out_mbox(TERMINAL_TYPE_BOX, oc->number_can_box_terminal_oscil);

   // была команда на отправку посылки и она еще не ушла, тогда србасываем счетчик времени паузы между посылками,
   // т.е. OSCIL_TIME_WAIT между концом отправки посылки и новой посылки.
   if (prev_send_to_can && CAN_cycle_full_free(real_mbox,CAN_BOX_STAT_OFF)==0)
   {
       old_time = (unsigned int)global_time.miliseconds;
       return;
   }
   prev_send_to_can = 0;

   if (oc->send_after_cmd==0)
   {
    if (!detect_pause_milisec(OSCIL_TIME_WAIT,&old_time))
       return;
   }


   if ( (oc->send_after_cmd==0 || (oc->send_after_cmd==1 &&  oc->cmd_send==1 )   )    )
   {

       oc->cmd_send = 0; // clear cmd

       if (CAN_cycle_full_free(real_mbox,CAN_BOX_STAT_ON))
       {

 //          oc->enable_rewrite = 0;


           old_t = oc->current_position;//
//           old_t = global_time.microseconds;

           oc->prepare_data_can(oc);

//           oc->timer_send = (global_time.microseconds - old_t);
           oc->timer_send = (oc->current_position - old_t);

           flag_send_buf = 1;

           CAN_cycle_send(
                   TERMINAL_TYPE_BOX,
                   oc->number_can_box_terminal_oscil,
                               0,
                               &(oc->temp_oscil_buffer[0][0]),  (oc->number_ch * oc->number_points) , CAN_BOX_EXTENDED_ADR, CAN_BOX_PRIORITY_LOW );

           prev_send_to_can = 1;
 //          while (CAN_cycle_free(real_mbox)==0);

//           oc->timer_send = (global_time.microseconds - old_t)/100;


           oc->enable_rewrite = 1;


//           if (cur_position_buf_modbus16_can >= SIZE_MODBUS_TABLE)
//           {
//               cur_position_buf_modbus16_can = 0;
////               modbus_table_can_out[ADR_CAN_TEST_PLUS_ONE].all++;
//           }
//
//           if ((cur_position_buf_modbus16_can + SIZE_BUF_WRITE_TO_MODBUS16_CAN) >= SIZE_MODBUS_TABLE)
//               count_write_to_modbus_can = SIZE_MODBUS_TABLE - cur_position_buf_modbus16_can;
//           else
//               count_write_to_modbus_can = SIZE_BUF_WRITE_TO_MODBUS16_CAN;
//
//           if (CAN_cycle_free(real_mbox))
//           {
//               CAN_cycle_send(
//                   MPU_TYPE_BOX,
//                   edrk.flag_second_PCH,
//                   cur_position_buf_modbus16_can + 1,
//                   &modbus_table_can_out[cur_position_buf_modbus16_can].all,
//                   count_write_to_modbus_can, 0);
//
//               cur_position_buf_modbus16_can = cur_position_buf_modbus16_can + SIZE_BUF_WRITE_TO_MODBUS16_CAN;
//           }
//
//





       }
   }
*/

}



#pragma CODE_SECTION(alarm_log_prepare_data_can,".fast_run");
void alarm_log_prepare_data_can(ALARM_LOG_CAN_handle al)
{
    unsigned int old_position, t_position;
    int i, k;
//    unsigned int crc;

    al->crc16 = 0xffff;
//    crc = GetCRC16_IBM( crc, (unsigned int *)al->start_adr_temp, al->temp_points*al->oscills);

//    al->crc16 = crc;

    al->cmd_fffc[0] = 0x1234;
    al->cmd_fffc[1] = 0x5678;
    al->cmd_fffc[2] = 0x9abc;

    al->cmd_fffd[0] = al->post_points;
    al->cmd_fffd[1] = al->step;
    al->cmd_fffd[2] = 0x7777;

    al->cmd_fffe[0] = al->start; // START
    al->cmd_fffe[1] = al->oscills;
    al->cmd_fffe[2] = al->temp_points;

    al->cmd_ffff[0] = al->stop; // STOP
    al->cmd_ffff[1] = al->crc16; // CRC16
    al->cmd_ffff[2] = 0x3333;



    /*
    old_position = oc->current_position;

    for (i=0;i<OSCIL_CAN_NUMBER_CHANNEL;i++)
    {
        t_position = old_position;
        for (k=OSCIL_CAN_NUMBER_POINTS-1;k>=0;k--)
        {
            if (t_position==0)
            {
                t_position = (OSCIL_CAN_NUMBER_POINTS+OSCIL_CAN_NUMBER_POINTS_ADD)-1;
            }
            else
                t_position = t_position - 1;

            oc->temp_oscil_buffer[i][k] = oc->oscil_buffer[i][t_position];

        }

    }
*/

    return;
}

