// ASYNCH_2.C
//
// copyright, Peter H. Anderson, Baltimore, MD, April, '16

#ifdef DESCRIPTION

Illustrates the transmission of asynchronous 9600 baud.  In this example
I interfaced with my LCD #117 Serial LCD at;

     http://www.phanderson.com/lcd106/lcd107.html
     
The PIC16F1872 has a number of added capabilites. 

  The TX may be configured on RB2 or RB5 (APFCON1, bit txcksel).  See Manual,
     Section 12.  IO Ports.
  RX may be either RB1 or RB2 (APFCON0, bit rxdtsel).
  
  I opted for compatibility with the PIC16F628 / 648 in this example.
  
  From Manual, Sec 25 
  
  The TX may be inverted using BAUDCON, bit sckp
  The baud rate may be set using either SPBRGL alone or SPBRGH & SPBRGL
     (16 bits).  The 16-bit provides better resolution and also provides 
     for lower baud rates.

Program configures the UART for asynch, 9600 baud and continually displays
numbers in signed and unsigned format.

#endif

#case

#device PIC16F1827 ICD=TRUE

#include <defs_1827.h>
#include <string.h>

#rom 0x8007 = {0x09e4, 0x0003}  // Manual Section 4.0

void delay_10us(byte t);
void delay_ms(long t);
void delay_s(long t);

#define TRUE 1
#define FALSE 0

#define MINUS 0
#define POSITIVE 1

#define SUCCESS 1
#define FAILURE 0

void asynch_setup(void);
void print_str(char *s);
void ser_char(char ch);

int main()
{
   char s[13];
   int n;

   ANSELB = 0x00;
   OSCCON = 0x6b; // 4.0 MHz internal
  
   asynch_setup();
   delay_ms(10);

   printf(ser_char, "?f"); // clear LCD
   delay_ms(25);

   n=0;
   while(1)
   {
       printf(ser_char, "Test %d?t%u?n", n, n);
             // display as signed and unsigned
             // ?t is tab, ?n is new line
       ++n;
       delay_ms(500);
   }     
}

void ser_char(char ch)
{
    TXREG = ch;
    while(trmt == 0) // wait for trmt to return to logic one
    {
    }
}


void asynch_setup(void)
{
    txcksel = 0;    // assign TX to RB2
    rxdtsel = 0;    // RX to RB1
    trisb2 = 1;
    trisb1 = 1;    // TX
    
    spen = 1;     // enable serial port
    sync = 0;     // asynchronous
    txen = 1;     // enable transmitter
    
    brgh = 1;
    brg16 = 1;
    SPBRGH = 0x00; 
    SPBRGL = 103; // 9600 at 4.0 MHz clock    
}


void delay_s(long t)
{
   while(t--)
   {
      delay_ms(1000);
   }
}

void delay_ms(long t)   // delays t millisecs
{
   do
   {
     delay_10us(100);
   } while(--t);
}

void delay_10us(byte t)
{
#asm
//      BCF STATUS, RP0
DELAY_10US_1:
      CLRWDT
      NOP
      NOP
      NOP
      NOP
      NOP
      NOP
      DECFSZ t, F
      GOTO DELAY_10US_1
#endasm
}