#include <p24HJ128GP506.h>

#include "functions.h"
#include <string.h>
#include <stdio.h>

#include <libpic30.h>
#define delay_ms(d) {__delay32((unsigned long long)(d)*((FCY)/1000));}   // {__delay32((unsigned long long)(d)*((FCY)/1000)-4);}
#define delay_us(d) {__delay32((unsigned long)(d)*((FCY)/1000000));}       // {__delay32((unsigned long)(d)*((FCY)/1000000)-4);}

#define FOSC            80000000L       
#define FCY             FOSC/2          


void oscConfig(void)
{
  /* FOSC(w/PLL) = FIN*(M/(N1*N2)) [Datenblatt S.122] */
  /* Vorgehensweise (Datenblatt, Oszillator Referenz, AN1229):
      - _FOSCSEL  (FNOSC_FRC);                     -> nach POR mit internem Oszillator starten
      - _FOSC     (FCKSM_CSECMD & POSCMD_XT);      -> danach auf externen Oszillator schalten
      - PLLFBD, PLLPOST, PLLPRE                    -> M, N1, N2 einstellen
      - __builtin_write_OSCCONH(0x03);             -> auf externen Oszillator mit PLL umschalten
      - while (OSCCONbits.COSC != 0b011);          -> warten bis auf richtigen Oszillatormodus umgeschaltet */

  /* FIN = 10 MHz, FOSC(w/PLL) = 40 MHz or 80 MHz, FCY = 20 MHz or 40 MHz
      [FOSC(w/PLL) = FIN*(M/(N1*N2))] */
   
  
  PLLFBD              = 32;           // PLL multiplicator M = 30   -> VCO out = 16*10 MHz = 160 MHz
  CLKDIVbits.PLLPRE   = 0;            // Prescaler         N1 = 2   -> VCO in = FOSC/2 = 5 MHz
  CLKDIVbits.PLLPOST  = 0;            //1;    //1=N2=4 // Postscaler        N2 = 4   -> FOSC = 160 MHz/4 = 40 MHz (20 MIPS)
 
  RCONbits.SWDTEN      = 0;           // disable WDT
 
  __builtin_write_OSCCONH(0x03);      // Initiate Clock Switch to Primary Oscillator with PLL (NOSC=0b011)
  __builtin_write_OSCCONL(0x01);      // Start clock switching
    
  while(OSCCONbits.COSC != 0b011){};   // Wait for Clock switch to occur
  while(OSCCONbits.LOCK != 1){};       // Wait for PLL to lock
}

void ioConfig()
{
  //Alle IOs als Eingang festlegen:
  TRISB = 0xFFFF;
  TRISC = 0xFFFF;
  TRISD = 0xFFFF;
  TRISF = 0xFFFF;  
  TRISG = 0xFFFF;
  
  //Ausgänge Definieren
  
  //Port B:
  TRISBbits.TRISB0 = 0;   // Ausgang für LED
  TRISBbits.TRISB3 = 0;   // Ausgang für RN171-Reset
  
  //Port C:
  TRISCbits.TRISC1 = 0;   //Ausgang für RN171-GPIO6
  TRISCbits.TRISC2 = 0;   //Ausgang für RN171-AWAKE

  
  //Port G:
  TRISGbits.TRISG7 = 0;   //Ausgang für RN171-GPIO5
  TRISGbits.TRISG6 = 0;   //Ausgang für RN171-GPIO5

}

void init_uart1( long int baudrate )
{
  TRISFbits.TRISF3 = 0; // UART1 Tx als Ausgang
  if(baudrate <= 19200)
  {
    U1BRG = ((FCY/baudrate)/16)+2;
    U1MODE = 0x8000;
  }
  else
  {
    U1BRG = ((FCY/baudrate)/4)-1;
    U1MODE = 0x8008; 
  }
  U1STAbits.UTXEN = 1;

  //Interrupts starten
  _U1TXIE = 0x01;
  _U1RXIE = 0x01;
  _U1EIE = 0x00;  //Interrupt wenn UART1 Fehler
  
  //Interrupts einstellen und priorisieren
  _U1RXIP = 5;  //RX Priorität einstellen 
  _U1EIP = 5;   //höchste Interrupt Priorität einstellen
    
}


void init_uart2( long int baudrate )
{
  TRISFbits.TRISF5 = 0; // UART2 Tx als Ausgang
  if(baudrate <= 19200)
  {
    U2BRG = ((FCY/baudrate)/16)+2;
    U2MODE = 0x8000;
  }
  else
  {
    U2BRG = ((FCY/baudrate)/4)-1;
    U2MODE = 0x8008; 
  }
  U2STAbits.UTXEN = 1;

  //Interrupts starten
  _U2TXIE = 0x01;
  _U2RXIE = 0x01;
  _U2EIE = 0x00;  //Interrupt wenn UART2 Fehler
  
  //Interrupts einstellen und priorisieren
  _U2RXIP = 4;  //RX Priorität einstellen 
  _U2EIP = 4;   //zweit höchste Interrupt Priorität einstellen
    
}

void init_rn171_server()
{
  // RN171 Reset Pin
  PORTBbits.RB3 = 1;
  PORTGbits.RG6 = 0;
  
  unsigned int adresse = PORTGbits.RG12;
  adresse <<= 1;
  adresse |= PORTGbits.RG13  ;
  adresse <<= 1;
  adresse |= PORTGbits.RG14;
  unsigned char globBuffer[100];
  
  delay_ms(2000);
  
  uart_send_rn171("$$$\0",0);
  delay_ms(100);

  uart_send_rn171("factory RESET\r\0",0);
  delay_ms(500);

  uart_send_rn171("reboot\r\0",0);
  delay_ms(4000);
  
  
  uart_send_rn171("$$$\0",0);
  delay_ms(100);
      
 // uart_send_rn171("set sys iofunc 0x00\r\0",0);
  delay_ms(100);
  
  uart_send_rn171("set wlan join 7\r\0",0);
  delay_ms(100);  
   
  uart_send_rn171("set wlan channel 4\r\0",0);
  delay_ms(100);
  
  sprintf(globBuffer, "set apmode ssid MCT2_Wlan%i\r\0", adresse);
  uart_send_rn171(globBuffer,0);
  delay_ms(100);
    
  uart_send_rn171("set ip dhcp 0x00\r\0",0);
  delay_ms(100);
 
  uart_send_rn171("set ip address 192.168.1.1\r\0",0);
  delay_ms(100);
  
  uart_send_rn171("set ip gateway 192.168.1.1\r\0",0);
  delay_ms(100);
  
  uart_send_rn171("set ip netmask 255.255.255.0\r\0",0);
  delay_ms(100);
  
  uart_send_rn171("set dns address 192.168.1.1\r\0",0);
  delay_ms(100);
  
  uart_send_rn171("set uart mode 0x00\r\0",0);
  delay_ms(100);
    
  uart_send_rn171("set ip protocol 0x02\r\0",0);
  delay_ms(100);
  
  uart_send_rn171("set ip tcp-mode 0x02\r\0",0);
  delay_ms(100);
  
  uart_send_rn171("set ip flags 0x02\r\0",0);
  delay_ms(100);
  
  uart_send_rn171("set ip flags host 192.168.1.2\r\0",0);
  delay_ms(100);
  
  uart_send_rn171("set ip remote 2000\r\0",0);
  delay_ms(100); 
  
  uart_send_rn171("set wlan tx 12\r\0",0);
  delay_ms(100); 
  
  
  uart_send_rn171("get uart\r\0",0);
  delay_ms(100); 

  uart_send_rn171("save\r\0",0);
  delay_ms(1000);
 
  uart_send_rn171("reboot\r\0",0);
  delay_ms(5000);
  
  uart_send_rn171("$$$\0",0);
  delay_ms(100);
  
  uart_send_rn171("exit\r\0",0);
  delay_ms(100);
   

  
  return; 
  
}

void init_rn171_client()
{
}

unsigned int uart_send_rn171(unsigned char* sendBuffer, unsigned int length)
{
  unsigned int counter = 0;
  
  while(*sendBuffer != '\0')
  {
    while(U1STAbits.UTXBF){}
    U1TXREG = *sendBuffer;
    sendBuffer++;
    counter++;
  }


   
  return counter;
}
unsigned int uart_send_usb(unsigned char* sendBuffer, unsigned int length)
{
  unsigned int counter = 0;
  
  while(*sendBuffer != '\0')
  {
    while(U2STAbits.UTXBF){}
    U2TXREG = *sendBuffer;
    sendBuffer++;
    counter++;
  }
   
  return counter;
}

