/*
 * SPI_Arduino.c
 *
 * Created: 12.06.2016 10:09:39
 * Author : Johannes
 */ 



#define F_CPU 16000000UL // for _delay_ms(); _delay_us()
#define FOSC 16000000UL // for Baudrate
#define EXTERN

/* -- includes -- */
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "spi.h"
#include "setbit.h"
#include "nrf24.h"
#include "global.h"

/* -- USART -- */
#define USART_BAUD 1200
#define USART_MYUBRR FOSC/16/USART_BAUD-1
/* --  -- */



/* -- functions -- */
ISR (TIMER0_OVF_vect);
ISR (USART_RX_vect);
ISR (INT0_vect);
void timer_interrupt_init(void);
void usart_init(unsigned int ubrr);
void extern_interrupt_init(void);
void usart_transmit_char(unsigned char data);
void usart_transmit_string (char *s);
void transmit(void);
void receive(void);


/* -- volatile variables -- */
volatile unsigned int sekunde_over = 0; // just for tests
volatile unsigned char usart_data;

uint8_t i;
uint8_t spi_temp;
uint8_t spi_q = 0;
char spi_itoabuffer[33];
uint8_t spi_var =0;
uint8_t spi_data_array[4];
uint8_t spi_tx_address[5] = {0xD7,0xD7,0xD7,0xD7,0xD7};
uint8_t spi_rx_address[5] = {0xE7,0xE7,0xE7,0xE7,0xE7};


int main(void){
	timer_interrupt_init(); // Timer0 -> 1ms
	extern_interrupt_init();
	usart_init(USART_MYUBRR);
	usart_transmit_string("RX devices ready \r\n"); 
	
	nrf24_init(); // initialize hardware pins
	nrf24_config(2,4); // Channel #2, payload length: 4
	/* set the device addresses */
	nrf24_tx_address(spi_tx_address);
	nrf24_rx_address(spi_rx_address);

	sei(); // Global Interrupts activate
	//unsigned int rv = 0;
	while (1){
		//receive();
		transmit();
		usart_transmit_string("transmission over \r\n");
		_delay_ms(2000);
	}
}


void extern_interrupt_init(void){
	DDRD &= ~(1 << DDD2);     // Clear the PD2 pin	
	PORTD |= (1 << PORTD2);    // turn On the Pull-up
	// PD2 is now an input with pull-up enabled
	
	EICRA |= (1 << ISC00);    // set INT0 to trigger on ANY logic change
	EIMSK |= (1 << INT0);     // Turns on INT0
}

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<<TX_DS)){ // IRQ: Package has been sent
		usart_transmit_string("Package has been sent \r\n");
		nrf24_configRegister(STATUS, (1<<TX_DS));
		PTX = 0;
	}

	if (status & (1<<MAX_RT)){ // IRQ: Package has not been sent, send again
		usart_transmit_string("Package has not been sent, send again \r\n");
		nrf24_configRegister(STATUS, (1<<MAX_RT));
		wl_module_CE_hi; // Start transmission
		_delay_us(10);
		wl_module_CE_lo;
	}

	if (status & (1<<TX_FULL)){ // TX_FIFO Full < this isnt an IRQ
		usart_transmit_string("TX_FIFO Full\r\n");
		wl_module_CSN_lo; // Pull down chip select
		spi_fast_shift(FLUSH_TX); // Flush TX-FIFO
		wl_module_CSN_hi; // Pull up chip select
	}
}


void receive(void){
	usart_transmit_string("\r\nnew data: ");
	if(nrf24_dataReady()){
		nrf24_getData(spi_data_array);
		usart_transmit_string("> ");
		for(i=0; 0<4; i++){
			spi_var = spi_data_array[i];
			usart_transmit_char(spi_var);
			usart_transmit_string("; ");
		}
	usart_transmit_string(" \r\n");
	}
}


void transmit(void){
	/* Fill the data buffer */
	spi_data_array[0] = 0x11;
	spi_data_array[1] = 0x55;
	spi_data_array[2] = 0xAA;
	spi_data_array[3] = 0xFF;//spi_q++;
	
	/* 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\r\n");
	}
	else if(spi_temp == NRF24_MESSAGE_LOST)
	{
		usart_transmit_string("> Message is lost ...\r\n");
	}
	
	nrf24_powerUpRx(); // go back to RX mode ...
}

void timer_interrupt_init(void){ // Timer 0
	TCCR0A = (1 << WGM01); // CTC Modus
	TCCR0B =  (1 << CS01) | (1 << CS00); // clk/64 -> = 250kHz
	OCR0A = 250-1; // -> 1ms Interrupt

	// Compare Match Interrupt enable
	TIMSK0 |= (1 << OCIE0A);
}


void usart_init(unsigned int ubrr){
	/* Set Baud-Rate */
	UBRR0H = (unsigned char) (ubrr >> 8);
	UBRR0L = (unsigned char) ubrr;
	/* Enable Receiver and Transmitter and receiver-interrupt*/
	UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
	/* Set Frame format: 8 data, 2 stop bit */
	UCSR0C = (1 << USBS0) | (1 << UCSZ01) | (1 << UCSZ00);
}

void usart_transmit_char(unsigned char data){
	/* Wait for empty transmit buffer */
	while ( !( UCSR0A & (1<<UDRE0)) );
	/* Put data into buffer, sends the data */
	UDR0 = 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(TIMER0_COMPA_vect){
	static unsigned int	millisekunde = 0;
	static unsigned int sekunde = 0;
	
	millisekunde++;

	if(millisekunde == 1000){
		millisekunde = 0;
		sekunde++;
		sekunde_over = 1;
		if(sekunde == 60){
			sekunde = 0;
		}
	}
}

ISR(USART_RX_vect){
	usart_data = UDR0;
}