/*
 * spi.c
 *
 * Created: 09.06.2016 19:17:10
 * Author : Johannes
 */ 

#define F_CPU 8000000UL
#define FOSC 8000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "nRF24L01.h"
#include "nrf24.h"
#include "spi.h"
#include "setbit.h"

/* -- USART -- */
#define USART_BAUD 1200
#define USART_MYUBRR FOSC/16/USART_BAUD-1
/* --  -- */

ISR (TIMER0_OVF_vect);
ISR (INT0_vect);
ISR(USART_RX_vect);
void extern_interrupt_init(void);
void timer_interrupt_init(void);
void io_init(void);
void usart_init(unsigned int ubrr);
void usart_transmit_char(unsigned char data);
void usart_transmit_string (char *s);
void transmitt(void);
void receive(void);

volatile unsigned int sekunde_over = 0;
volatile unsigned char usart_data;

uint8_t spi_temp;
uint8_t spi_q = 0;
char spi_itoabuffer[33];
uint8_t spi_var =0;
uint8_t spi_data_rx_array[4];
uint8_t spi_data_array[4];
uint8_t spi_tx_address[5] = {0xE7,0xE7,0xE7,0xE7,0xE7};
uint8_t spi_rx_address[5] = {0xD7,0xD7,0xD7,0xD7,0xD7};

int main(void){
	extern_interrupt_init(); // INT0 -> falling edge
	usart_init(USART_MYUBRR);
	timer_interrupt_init(); // Timer0 -> 1ms
	io_init(); // PD5 -> output -> low
	spi_init();
	nrf24_init(); // initialize hardware pins
	nrf24_config(2,4); // channel #2, payload length: 4
	SETBIT(PORTD, 5);
	/* Set the device addresses */
	nrf24_tx_address(spi_tx_address);
	nrf24_rx_address(spi_rx_address);


	sei(); // Global Interrupts activate
	//usart_transmit_string("> USART Ready to use \n");
    while (1){
		//receive();
		//TOGGLEBIT(PORTD,5);
	   //transmitt();

		//_delay_ms(2000);		
		while (!nrf24_dataReady());
		usart_transmit_string("\r\n new data: ");
		nrf24_getData(spi_data_array);
		usart_transmit_char(spi_data_array[0]);
		usart_transmit_char(spi_data_array[1]);
		usart_transmit_char(spi_data_array[2]);
		usart_transmit_char(spi_data_array[3]);
		
    }
}

void receive(void){
	while (!nrf24_dataReady());
	usart_transmit_string("\r\n new data: ");
	nrf24_getData(spi_data_array);
	usart_transmit_char(spi_data_array[0]);
	usart_transmit_char(spi_data_array[1]);
	usart_transmit_char(spi_data_array[2]);
	usart_transmit_char(spi_data_array[3]);

}

void transmitt(void){
 /* Automatically goes to TX mode */
 nrf24_send(spi_data_array);
 
 /* Wait for transmission to end */
 while(nrf24_isSending());

 /* Make analysis on last transmission attempt */
 spi_temp = nrf24_lastMessageStatus();
 if(spi_temp == NRF24_TRANSMISSON_OK)
 {
	 usart_transmit_string( " > Tranmission OK\n");
 }
 else if(spi_temp == NRF24_MESSAGE_LOST)
 {
	 usart_transmit_string("> Message is lost ...\n");
 }
}


void usart_init(unsigned int ubrr){
	/* Set Baud-Rate */
	UBRRH = (unsigned char) (ubrr >> 8);
	UBRRL = (unsigned char) ubrr;
	/* Enable Receiver and Transmitter and receiver-interrupt*/
	UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
	/* Set Frame format: 8 data, 2 stop bit */
	UCSRC = (1 << USBS) | (1 << UCSZ1) | (1 << UCSZ0);
}

void usart_transmit_char(unsigned char data){
	/* Wait for empty transmit buffer */
	while ( !( UCSRA & (1<<UDRE)) );
	/* Put data into buffer, sends the data */
	UDR = data;
}

void usart_transmit_string (char *s){
	while (*s)
	{   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
		usart_transmit_char(*s);
		s++;
	}
}

ISR(USART_RX_vect){
	usart_data = UDR;
}

void extern_interrupt_init(void){
	DDRB &= ~(1 << DDD2); // External Interrupt on INT0

	MCUCR |= (1 << ISC01); // INT0 falling edge
	MCUCR &= ~(1 << ISC00); // INT0 falling edge

	GIMSK |= (1 << INT0);  // enable INT0 interrupt
}

void timer_interrupt_init(void){
	// Timer 0
	TCCR0A = (1 << WGM01); // CTC Modus
	TCCR0B = (1 << CS01) ; // prescaler 8 -> 1Mhz/8 = 125kHz
	OCR0A = 125-1; // -> 1ms Interrupt
	TIMSK |= (1 << OCIE0A); // Overflow Interrupt allow
}

void io_init(void){
	// LED as output
	SETBIT(DDRD, 5);
	CLEARBIT(PORTD, 5);
}


ISR (TIMER0_COMPA_vect){
	static unsigned int	millisekunde = 0;
	static unsigned int sekunde = 0;
	
	millisekunde++;

	if(millisekunde == 1000){
		millisekunde = 0;
		sekunde_over = 1;
		sekunde++;
				
		if(sekunde == 60){
			sekunde = 0;
		}
	}
}

ISR(INT0_vect){
	//static unsigned int status;
	//// Read wl_module status
	//wl_module_CSN_lo; // Pull down chip select
	//status = spi_fast_shift(NOP); // Read status register
	//wl_module_CSN_hi; // Pull up chip select
	//
	//if (status & (1<<RX_DR)){ // Message received
	//	while (!nrf24_dataReady());
	//	usart_transmit_string("\r\n new data: ");
	//	nrf24_getData(spi_data_array);
	//	usart_transmit_char(spi_data_array[0]);
	//	usart_transmit_char(spi_data_array[1]);
	//	usart_transmit_char(spi_data_array[2]);
	//	usart_transmit_char(spi_data_array[3]);
	//}
}