/*********************************************************************
 *                Microchip USB C18 Firmware Version 1.0
 *********************************************************************
 * FileName:        user.c
 * Dependencies:    See INCLUDES section below
 * Processor:       PIC18
 * Compiler:        C18 2.30.01+
 *****************************************************************************/

/** I N C L U D E S **********************************************************/
#include "system\typedefs.h"
#include <timers.h>
#include "system\usb\usb.h"
#include "io_cfg.h"             // I/O pin mapping
#include "user\user.h"
#include <delays.h>   /* for 'Delay10KTCYx'      */
#include <string.h>
#include <stdlib.h>
#include <math.h>

/** V A R I A B L E S ********************************************************/

char input_buffer[64];
unsigned char output_buffer[64];
int iSamplePeriod=64;   //odpowiada 1.365us
int iBufIdx=0;          //indeks dla output_buffer
rom char welcome[]={"PIC18F4550 Full-Speed USB - CDC RS-232 Emulation Demo\r\n\r\n"};

int tempBufferSize=64;	////ilosc bajtow danych do zbuforowania przed wyslaniem do hosta

/** P R I V A T E  P R O T O T Y P E S ***************************************/
void InitializeUSART(void);
void BlinkUSBStatus(void);


// 1-wire prototypes
void _1w_init(int sensor);
int _1w_in_byte(int sensor);
void _1w_out_byte(int d, int sensor);
void _1w_pin_hi(int sensor);
void _1w_pin_low(int sensor);
void _1w_strong_pull_up(int sensor);	// not used in this routine

// delay routines
void delay_ms(long t);
void delay_10us(int t);



void beep(void);

/** D E C L A R A T I O N S **************************************************/

void UserInit(void)
{
    mInitBuzzer();
    OpenTimer0( TIMER_INT_OFF & T0_16BIT & T0_SOURCE_INT & T0_PS_1_256 );
    //21.33us na cykl timera przy zegarze 48MHz -> 46.8kHz
    TRISD &= ~0x0C;   //wyzerowanie pinu 2 i 3
    PORTD &= ~0x0C;
    beep();
    beep();
}//end UserInit



/******************************************************************************
 * Function:        void ProcessIO(void)
 * PreCondition:    None
 * Overview:        This function is a place holder for other user routines.
 *                  It is a mixture of both USB and non-USB tasks.
 * Note:            None
 *****************************************************************************/
void ProcessIO(void)
{
    static unsigned char iLoopCounter=0;
    char tmp[16];
    char AN1String[16];
    int sensor=0;
    int n;

    int calosci;
    int dziesiate;

    short int read_temp;
    float real_temp,temp_count;
    byte buff[10];
    signed char rt;   //real temperature


    if ((usb_device_state < CONFIGURED_STATE)||(UCONbits.SUSPND==1)) return;
    iSamplePeriod=65000; //1.4s
    if (ReadTimer0()>=iSamplePeriod)   //dzialanie okresowe
    {
        PORTD &= ~0x04;      //zapalenie 1 diody

        _1w_init(sensor);
        _1w_out_byte(0xcc, sensor);  // skip ROM
        _1w_out_byte(0x44, sensor);  // perform temperature conversion
        _1w_strong_pull_up(sensor);
        _1w_init(sensor);
        _1w_out_byte(0xcc, sensor);  // skip ROM
        _1w_out_byte(0xbe, sensor);  // read the result
        for (n=0; n<9; n++)
        {
            buff[n]=_1w_in_byte(sensor);
        }
        //Convert raw data to degree C in accorance with datasheet
        //bajt 0 - liczba
        //bajt 1 - powielony znak na kazdym bicie tego bajtu (tylko info o znaku)
//	   read_temp=(buff[1]<<7) | (buff[0]>>1);
        read_temp=(buff[0]>>1);
        temp_count=(float)(buff[7] - buff[6])/(float)buff[7];
        rt=(buff[1]<<7) | (buff[0]>>1);
        real_temp=((float)rt-0.25)+temp_count;
        if (real_temp>=0)
        {
            strcpypgm2ram(AN1String,"Temp: +");	//same jedynki -> temperatura ujemna
        }
        else
        {
            strcpypgm2ram(AN1String,"Temp: -");	//same jedynki -> temperatura ujemna
        }
        real_temp=fabs(real_temp);
        calosci=(int)real_temp;
        real_temp *=10.0;	//zaraz bedzie sztuczka z ominieciem ftoa
        dziesiate = (int)(real_temp-(float)calosci*10.0);
        itoa(calosci,tmp);
        strcat(AN1String,tmp);
        strcpypgm2ram(tmp,".");
        strcat(AN1String,tmp);
        itoa(dziesiate,tmp);
        strcat(AN1String,tmp);
        strcpypgm2ram(tmp,"C\r\n");
        strcat(AN1String,tmp);

        //PORTD |= 0x08; //zgaszenie diody

        if (mUSBUSARTIsTxTrfReady())
        {
            //PORTD &= ~0x08;      //zapalenie 2 diody
            putsUSBUSART(AN1String);	//puts - z RAMu, putrs - z ROMu, uwaga!!!
        }
        WriteTimer0(0);     //wyzeruj timer, znowu 1.4s przerwy
    }
    PORTD |= 0x04; //zgaszenie diody
}//end ProcessIO

void beep(void)
{
    //buzzer do PB3
    PORTB |= 0b00001000;
    Delay10KTCYx (25);   /* pause for a moment (50 * 4 * 10,000 cycles) */
    PORTB &= 0b11110111;
}

// The following are standard 1-Wire routines.
void _1w_init(int sensor)
{
    _1w_pin_hi(sensor);
    _1w_pin_low(sensor);
    //delay_10us(50);
    delay_10us(55);
    //output_float(PIN_B4);
    _1w_pin_hi(sensor);
    //delay_10us(50);
    delay_10us(30);
}

int _1w_in_byte(int sensor)
{
    int n, i_byte, temp, mask;
    mask = 0xff & (~(0x01<<sensor));
    for (n=0; n<8; n++)
    {
        PORTB=0x00;
        TRISB=mask;
        TRISB=0xff;
        _asm
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        _endasm
        temp=PORTB;
        if (temp & ~mask)  i_byte=(i_byte>>1) | 0x80;	// least sig bit first
        else               i_byte=i_byte >> 1;
        delay_10us(6);
    }
    return(i_byte);
}

void _1w_out_byte(int d, int sensor)
{
    int n, mask;
    mask = 0xff & (~(0x01<<sensor));
    for (n=0; n<8; n++)
    {
        if (d&0x01)
        {
            PORTB=0;			//bylo wszedzie porta
            TRISB=mask;		// momentary low
            TRISB=0xff;
            //delay_us(6);
            delay_10us(6);
        }

        else
        {
            PORTB=0;
            TRISB=mask;
//	       delay_us(6);
            delay_10us(6);

            TRISB=0xff;
        }
        d=d>>1;
    }
}

void _1w_pin_hi(int sensor)
{
    TRISB = 0xff;
}

void _1w_pin_low(int sensor)
{
    PORTB = 0x00;
    TRISB = 0xff & (~(0x01 << sensor));
}

void _1w_strong_pull_up(int sensor)	// bring DQ to strong +5VDC
{
    PORTB = 0x01 << sensor;
    TRISB = 0xff & (~(0x01 << sensor));
    //delay_ms(250);
    delay_ms(500);//500
    TRISB = 0xff;
}

// delay routines
void delay_10us(int t)
{
    while (t>0)
    {
        Delay10TCYx(12);	//120 cykli - 10us@12MHz instr. freq
        t--;
    }
}

void delay_ms(long t)	// delays t millisecs
{
    do
    {
        delay_10us(100);
    }
    while (--t);
}
