
#include "lpc176x.h"
#include "utils.h"
#include "usb_hardware.h"
#include "options.h"

#include <stdio.h>                         

#ifdef USBTMC // #endif в конце файла

#include <math.h>
#include <../usbtmc/gpib_parser.h>
#include "../common/hal.h"
#include "utilits.h"
#include <stdlib.h>
#include "gpib_parser_numutils.h"
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//---------------------------------------------------------------------------- >>> на начало числа
unsigned int StrToInt( const char * str, unsigned int NumberLength,  int * pReturn )
{
  char buffer[11];
  unsigned int result;
  BOOL rc = FALSE;

  if( NumberLength > 10 ) return -1;   // слишком длинное число или неверная длинна ( если принятое отриц число в unsigned, оно больше 0x7FFFFFFF

  s_memcpy( buffer, str, NumberLength );
  buffer[NumberLength] = 0; // null terminator

  result = atoi( buffer );

  if(result==0)  // проверка на валидность результата, если ноль, проверяем валидность числа
    for(int m=0; buffer[m]; m++)  // бежим по массиву до нультерминатора
    {
        if( IsDemicalChar( buffer[m]) )   // если это цифра
          ; // ничего не делаем
        else
        {
            if(buffer[m]==' ')  // если это пробел
              ; // ничего не делаем
            else
              {  // если это не цифра и не пробел, занчи число неверно задано и результат 0
                // означает что число не распознано
                  pReturn = NULL; // результат неверен
                  break;
              }
        }
    }


  if( result != 0 || (result==0 && *buffer == '0' ) )  // число опознано или число нуль ( atoi нуль вернет если число не распознано !)
    if( pReturn != NULL )
       { *pReturn = result; rc = TRUE; }
  return rc;
}

/*
unsigned int Float2Str( float * pFloat, unsigned char * pBuffer, unsigned short wBufferLength )
{
  return Float2StrEx( pFloat, pBuffer, wBufferLength, 1000 ); 
}
*/
/*
unsigned int Float2StrEx( float * pFloat, unsigned char * pBuffer, unsigned short wBufferLength, unsigned int accuracy )
{
  int FractAccuracy;        // -- хранит точность числа после запятой, 10-один знак, 100-два
  int dwReturnBytes;        // -- хранит длинну получаемой строки
  long int Integer;              // -- хранит целочисленное представление целой и дробной части
  int counter;              // -- хранит количество позиций ( символов ) целой и дробной частей числа
  int temp;                 // -- временное целое число
  float Float;              // -- хранит 10-ый логарифм целочисленного представления дробной и целой частей числа
  // -----------------------------------------------------
  unsigned int value = accuracy;
  FractAccuracy = 10; while(FractAccuracy<value) FractAccuracy*=10; 
  // -----------------------------------------------------
  dwReturnBytes = 0;
  // ================ Converting integer part ==================
  Integer = (int) *pFloat;                            // получаем целую часть числа
  temp = Integer; if( temp <0 ) temp=-temp;           // сохраняем во временную переменную
  // get symbol count                                 // ... и проверям знак временной переменной для вычисления log
  if(temp>0) {
        Float = log10( temp );                              // вычисляю логарифм части (целой) для подсчета длинны части числа в символах
        counter = (unsigned int)Float;                      // получаю длинну части числа в символах ( 0 == один символ )
        counter++;                                          // увеличиваю длинну в символах, так как имеем десятичный логарифм. для числа 0-9 тоже должен быть символ (counter>1)
  } else {
        counter = 1;

  }                                                   //
  if( *pFloat < 0 )  *(pBuffer++) ='-';               // если число отрицательное, двигаю временно указатель вперед, чтобы сохранить знак '-'
  dwReturnBytes+=counter;                             // увеличиваю предположительную длинну получающейся строки
                                                      // таким образом, в цикле он не затрется
  while( counter-- )     // converting                // начинаем преобразование
  {                                                   // counter уменьшился на 1 в заголовке цикла и указывает на позицию символа в массиве
    pBuffer [ counter ] = (temp % 10) + '0';          // берем остаток от деления на 10 числа, прибавляем к нему ASCII код символа '0', ложим в массив
    temp /= 10;                                       // делим число на 10, передвигаясь к следующей цифре в числе, справа на лево
  }                                                   // дойдем до нуля заголовке, значит часть числа преобразована
                                                      //
  if( *pFloat < 0 )  { dwReturnBytes++;  pBuffer--; } // двигаем обратно указатель, если сохраняли знак '-' и увеличиваем длинну строки с этим учетом

  // ===============================================================


  pBuffer+=dwReturnBytes;                             // оставляем позади преобразованную часть числа
  *(pBuffer++) ='.'; dwReturnBytes++;

  // ================ Converting fractional part ==================
  Float = (float)(*pFloat - (int) *pFloat);           //
  Float = (FractAccuracy) * (Float);                  // берем дробную часть числа с заданной точностью.
  Integer = (int)Float;
  if( Float - (int)Float  > 0.5 ) Integer++;          // 0.15 = 0.14999 -> не должно выводиться 0,14 !
                                                      // 0,14999 * FractAccuracy --> 14.9 - 14 = 0.9; 0.9>0 => Integer++
  temp = Integer; if( temp <0 ) temp=-temp;           // сохраняем во временную переменную
  // get symbol count                                 // ... и проверям знак временной переменной для вычисления log
  if(temp>0) {
        Float = log10( temp );                              // вычисляю логарифм части (целой) для подсчета длинны части числа в символах
        counter = (unsigned int)Float;                      // получаю длинну части числа в символах ( 0 == один символ )
        counter++;                                          // увеличиваю длинну в символах, так как имеем десятичный логарифм. для числа 0-9 тоже должен быть символ (counter>1)
  } else {                                            //
        counter = 1;
  }
  dwReturnBytes+=        counter;                     // увеличиваю предположительную длинну получающейся строки
                                                      //
  while( counter-- ) // converting                    // преобразуем аналогично целой части
  {
    pBuffer [ counter ] = (temp % 10) + '0';          // аналогично, как для целой части
    temp /= 10;
  }
  // ================================================================
  pBuffer [ dwReturnBytes ] = 0;
  // ----------------------------------------------------------------
  return dwReturnBytes;
}
*/
unsigned int temperature_convert ( char * pBufferOut, unsigned short wBufferLen, signed short int dwTempEntry )
{
  float temp;
  float temp2;

  // ---------------------------------------------------------------------------------------------------
  // dwTempEntry - усредненная температура в формате B15 B14 .... B0, где B15-B6 биты содержат температуру
  // с точностью до 0,25град, а биты B5-B0 содержат поправку (усреднение)
  //
  // датчик измеряет с точностью 0,25*С. возвращает регистр формата REG16[ B15.....B6, B5....B0 ]
  // где биты B5...B0 равны нулю. то есть количество дискрет. Эти значения усредняются экспоненциальным
  // окном шириной 24, а значит теперь биты B5...B0 содержат поправку. Если с датчика мы бы просто
  // сдвинули на 6 битов вправо и получили колич дискрет по 0,25, то тут так делать не следует:
  // все биты содержат инф о температуре: надо рассматривать это значения не как количество дискрет
  // по 0,25*С, а как количество дискрет по 0,25/(2^6) !!!
  //  
  // -------------------------------
  // -- check sign               -- проверка знака, если минус, то перевод из дополнительного кода
  temp = 1.000;
  if( dwTempEntry & (1<<15) )     // check sign bit
  {    
       dwTempEntry ^= 0xffffffff;     // converting from additional code
       dwTempEntry += 0x00000001;     // converting from additional code
       temp = -1.000;
  } 
  

  /* ----- способ 1 ----- */
  //temp *= ((float)dwTempEntry) / ((float)(64*4));  // на 4 делим чтобы привести из дискрет по 0,25 к градусу. на 64 естественно делим чтобы сдвинуть значение вправо
  //                                                // если просто сдвинуть в право на 6 разрядов и поделить на 4 мы потеряем усреднение! 
  /* -------------------- */

  /* ----- способ 2 ----- */
  temp2 = ((dwTempEntry & 0xFF00)>>8) + (((dwTempEntry & 0xFF)/256.000));
  temp*=temp2;                                      
  /* -------------------- */
  return GPIB_Float2Str( temp, pBufferOut, wBufferLen, Format_Float2Str_Ndot3 );
  //return snprintf( pBufferOut,wBufferLen,"%.3f", temp);    /*Float2Str( &temp, pBufferOut, wBufferLen);*/
}

#endif