/*

dsPIC30F3012 with an LM34 analog temperature sensor.

Copyright 2010 - Michael Kohn
http://www.mikekohn.net/
mike to mikekohn.net

*/


#include <p30f3012.h>

// 7.37 MHz
_FOSC(FRC);
_FWDT(WDT_OFF);
_FBORPOR(PBOR_OFF&MCLR_EN);
_FGS(CODE_PROT_OFF);

// #define USE_RS232

#ifdef USE_RS232
void output_nibble(int n)
{
  while(U1STAbits.UTXBF!=0);
  if (n<10)
  { U1TXREG=n+'0'; }
    else
  { U1TXREG=(n-10)+'A'; }
}

void write_hex(int n)
{
  output_nibble((n>>8)&0x0f);
  output_nibble((n>>4)&0x0f);
  output_nibble(n&0x0f);
}

void write_dec(int n)
{
int d;

  d=n%10;
  n=n/10;
  if (n>0) write_dec(n);
  while(U1STAbits.UTXBF!=0);
  U1TXREG=d+'0';
}
#endif

void bcd_output(int n)
{
unsigned int d;
unsigned int u;

  if (n<0)
  {
    n=-n;
    LATD=0x00;
  }
    else
  {
    LATD=0x01;
  }

  d=n%10;
  u=n/10;

  //d=d|((u&0x01)<<7);
  // geez.. RC15, RC13, RC14.. why?  :(  easier to create crappy code to
  // compensate rather than resolder :(
  //u=u&0x0e;
  //d|=(((u&0x08>>2)|(u&0x01))<<4);
  d|=((((u&0x08)>>2)|(u&0x01))<<4);
  u=(((u&0x04)>>1)|((u&0x02)<<1))<<12;
  LATB=d;
  LATC=u;
}

int main()
{
int temp;

#ifdef USE_RS232
  // 1200=7370000/(16*(BRG+1))
  U1BRG=383/4;
  U1MODE=0x8000;
  U1STA=0x8400;
  U1TXREG='*';
#endif

  TRISB=0x0040;
  TRISC=0x0000;
  TRISD=0x0000;
  LATB=0x0000;
  LATC=0x8000;
  LATD=0x0001;

  ADCON2=0x0000;
  ADCON3=0x1f02;
  ADCHS=0x0006;   // AN6  (channel select)
  ADPCFG=0xffbf;  // PCFG6=0 (port config)
  ADCSSL=0x0000;  // No input selection
  ADCON1=0x80e0;  // ADON, FORM=0, SSRC=111


#ifndef USE_RS232
  for (temp=-99; temp<=99; temp++)
  {
    bcd_output(temp);
    unsigned int a;
    for(a=0; a<16738; a++);
  }
#endif

  while(1)
  {
    ADCON1bits.SAMP=1;
    while (!ADCON1bits.DONE);

    temp=ADCBUF0;

#ifdef USE_RS232
    write_hex(temp);

    while(U1STAbits.UTXBF!=0);
    U1TXREG = ' ';

    write_dec(temp);

    while(U1STAbits.UTXBF!=0);
    U1TXREG = ' ';
#endif

    //int fahr=temp*25/1024*5;
    int fahr=temp*5/41;
    //int cel=(fahr-32)*5/9;

#ifdef USE_RS232
    write_dec(cel);

    while(U1STAbits.UTXBF!=0);
    U1TXREG = '|';
#else
    // bcd_output(cel);
    bcd_output(fahr);
#endif

    unsigned int a,b;
    for(b=0; b<6; b++)
    for(a=0; a<32768; a++);
  }

  return 0;
}


