<repo_name>rovkit/Organet<file_sep>/queue.h
/*
 * IncFile1.h
 *
 * Created: 22.05.2015 14:05:09
 *  Author: Viktor
 */ 


#ifndef INCFILE1_H_
#define INCFILE1_H_

//#include <stdio.h>

#define MAX_SIZE    32        // Define maximum length of the queue
#include <stdint.h>
typedef struct{
	uint16_t head, tail;	// Declare global indices to head and tail of queue
	char theQueue[MAX_SIZE];	// The queue
}queue;

// List Function Prototypes
void initQueue(queue *q);             // Initialize the queue
void clearQueue(queue *q);            // Remove all items from the queue
char enqueue(queue *q,char ch);         // Enter an item in the queue
char dequeue(queue *q);               // Remove an item from the queue
char isEmpty(queue *q);                // Return true if queue is empty
char isFull(queue *q);                 // Return true if queue is full






#endif /* INCFILE1_H_ */<file_sep>/comhelper.h
#ifndef COMHELPER_H_
#define COMHELPER_H_
#include "SoftUart2.h"
#include "queue.h"


/*##############################################################
This is the comhelper. It manages the incoming bytes from the uart_port and returns them as messages to the organet client.

So somehow a layer between the actual software and the uart library. Used fot controlling the uart library.

Todo: 

	-port four pins have to be changed

	-every port should get its own debug led.
	
	-at uart init there is a comment: not using port d for anything else. this is not true anymore with multiple com lines.
	
	-rewrite the print char method.
	
	-the timer interrupt has to be 4 times faster.
################################################################
*/

//here, as a macro the transmission (tx) and receiving (rx) pins are set as macros.
#define PORTONERX PIND2;
#define PORTONETX PIND3;

#define PORTTWORX PIND4;
#define PORTTWOTX PIND5;

#define PORTTHREERX PIND6;
#define PORTTHREETX PIND7;

#define PORTFOURRX PIND0; //probably not a good idea. has to be changed
#define PORTFOURTX PIND1;

//not yet used. maybe not needed after all.
typedef struct{						
	
	uint8_t txpin;

	uint8_t rxpin;

	unsigned char name;

	unsigned char incoming_chars_buffer[32];

	unsigned char outgoin_chars_buffer[32];
} comhelper;
//this as well is not needed. maybe not after all.

//comhelper comhelpers[4];



//a very basic message, with receipient and sender and a short routestack to save the past relay stations.
typedef struct{			
	char receipient;
	char sender;
	unsigned char routestack[5];
}message;

queue incoming_port[4];




void com_helper_init(); //initializes all four connection ports, with the pins set on the macros.

char com_helper_send_message(message,comhelper); //not implemented yet.

char com_helper_is_msg(queue *q); //check if chars in buffer represent message

char com_helper_parse_msg(queue *q);


#endif  /* COMHELPER_H_ */ 
<file_sep>/comhelper.c
/*
 * OrganetP.c
 *
 * Created: 24.02.2015 10:07:45
 *  Author: Viktor
 */ 

#include "comhelper.h"




void com_helper_init(){
	
	/************************************************************************/
	/* This method initializes all four connection lines.                                                                     */
	/************************************************************************/
	
	initQueue(&incoming_port[0]);
	initQueue(&incoming_port[1]);
	initQueue(&incoming_port[2]);
	initQueue(&incoming_port[3]);
	
	
	port_rotator = 1;				//this couldnt be done in the header file
	
	port[0].uartrx = PORTONERX;	//load the pins for each line.
	port[0].uarttx = PORTONETX;
	port[0].port_number = 1;
	
	port[1].uartrx = PORTTWORX;
	port[1].uarttx = PORTTWOTX;
	port[1].port_number = 2;
	
	
	port[2].uartrx = PORTTHREERX;
	port[2].uarttx = PORTTHREETX;
	port[2].port_number = 3;
 	
	
	port[3].uartrx = PORTFOURRX;		//right now, this pin is still wrong.
	port[3].uarttx = PORTFOURTX; 
	port[3].port_number = 4;
	
	for(int i = 0;i<4;i++){
		switch (i){			//init each com line
			case 1:
				
				uart_init(&port[0]);
								
				break; 
			case 2:
				uart_init(&port[1]);
				break;
			case 3:
				uart_init(&port[2]);
				break;
			case 4:
				uart_init(&port[3]);
				break;
		}
	}
	
	
}

char com_helper_send_message(message msg,comhelper cmhlpr)
{
	
	
	return 0;
}

char com_helper_is_msg(queue *q)
{
	
	return 0;
}


char com_helper_parse_msg(queue *q)
{
	
	
}<file_sep>/SoftUart2.c
/*
 * SoftUart.c
 *
 * Created: 22.02.2015 22:19:11
 *  Author: Viktor
 */ 

#include "SoftUart2.h"


////////////////////////////////////////////////////////////////////////////////////////////
//
// Software uart routines
//
// we need two serial lines, and there's only one usart on the M32
// so we implement another in software
//
// we set up a clock with a timeout of 883 cycles - four times baud rate at 2400 baud -
// and use it to sample an input line and clock an output line
// we also use it to maintain a 20mS tick for timouts and such
//
///////////////////////////////////////////////////////////////////////////////////////////




//this is called periodically, then our periodical routine is called to read/write on the current port, which is afterwards incremented.
ISR(TIMER1_COMPA_vect) 
{		
	
			//DEBUG
	 
	switch (port_rotator){
		case 1:
			do_what_needs_to_be_done(&port[0]);
			break;
		case 2:
			do_what_needs_to_be_done(&port[1]);
			break;
		case 3:
			do_what_needs_to_be_done(&port[2]);
			break;
		case 4:
			do_what_needs_to_be_done(&port[3]);
			break;
	}
	
	if(port_rotator == 4){ // <= rotate the port.
		port_rotator = 1;
	}
	else{
		port_rotator +=1;
	}
	
	
}


//this is the main method for reading/writing

//probably doesnt work right now, as interrupt has to be 4 times faster.
void do_what_needs_to_be_done(uart_port *curr_port){

	if(curr_port->yeah){								//First of all, the debug led is lit if yeah==1.
														//has to be improved to all ports
		DDRB |= _BV(PINB3);
		PORTB |= _BV(PINB3);
		
	}
	else{
		PORTB &= ~_BV(PINB3);
		
	}
		
	// the interrupt signal on a compare for the timer 1
	
	// we arrive here four times per baud rate
	// we first send the output signal, if there's anything to send,
	// since it needs to be somewhere close to accurate...
	// then we read the incoming signal, if there is one,
	// and finally we update the nearly-real-time clock
	// (we never display the clock but it timestamps the output data)
	
	if (curr_port->uart_status & _BV(txbusy))
	{
		
		// we're transmitting something
		// increment the tick - we only do things every four ticks
		curr_port->uart_txtick++;
		if (curr_port->uart_txtick == 4)
		{
			// okay, we've work to do
			curr_port->uart_txtick = 0;
			
			// is it the start bit?
			if (curr_port->uart_txbit == 0)
			{
				// yes...
				PORTD &= ~(_BV(curr_port->uarttx));		// clear the start bit output
				curr_port->uart_txbit++;
			}
			else
			{
				if (curr_port->uart_txbit != 9)
				{
					// deal with the data bits
					if (curr_port->uart_txd & 1){// low bit set?
						PORTD |= _BV(curr_port->uarttx);	// then set the data stream bit
					}		
					else{
					PORTD &= ~(_BV(curr_port->uarttx));		//Here the tx pin is set as low. This doesnt work properly.
					//_delay_us(5);
					//PORTD &= ~(_BV(curr_port->uarttx));	//maybe we can set it low twice?
					
					}
					
					// or clear, as required
					curr_port->uart_txbit++;				// increment the bit count
					
					// and shift the data right
					curr_port->uart_txd /= 2;
				}
				else
				{
					// deal with the stop bit (stop bit is allways on high.
					PORTD |= _BV(curr_port->uarttx);
					curr_port->uart_txbit++;
					
				}
			}
			
			// and finally, if txbit is more than 9, we're done
			if (curr_port->uart_txbit > 9)
			{
				curr_port->uart_txbit = 0;					// clear the bit counter
				curr_port->uart_status &= ~(_BV(txbusy)); // and the busy status
			}
		}
	}
	
	// we may be receiving something
	// if we're *not* yet receiving, we check every clock tick to see if the input
	// line has gone into a stop bit
	// if it has, we wait for half a bit period and then sample every four ticks
	// to put together the rx data

		

	if ((curr_port->uart_status & _BV(rxbusy)) == 0)
	{
		
		// check to see if there's a start
		if ((PIND & _BV(curr_port->uartrx)) == 0)
		{
			
			
			
			// we found a start bit!
			// set the tick count to 2, so we get the sample near the middle of the bit
			curr_port->uart_rxtick = 2;
			// and flag that we're now busy
			curr_port->uart_status |= _BV(rxbusy);
			// we're expecting the start bit now...
			curr_port->uart_rxbit = 0;
			// and carry on with life
		}
		
	}
	else
	{
		
		// we're receiving something
		// inc the tick count
		curr_port->uart_rxtick++;
		if (curr_port->uart_rxtick == 4)
		{
			// we only sample when the tick = 0
			curr_port->uart_rxtick = 0;
			
			// what we do depends on the bit count
			// 0 = start,
			// 1-8 = data
			// 9 = stop
			if (curr_port->uart_rxbit == 0)
			{
				
				// start bit
				// it had better be 0 or it was a line glitch
				if ((PIND & _BV(curr_port->uartrx)) == 0)
				{
					// it's a real start bit (probably) so deal with it
					// next bit will be data
					curr_port->uart_rxbit ++;
					curr_port->uart_rxd = 0;
				}
				else
				{
					// bad start bit, flag us back as not busy
					curr_port->uart_status |= ~(_BV(rxbusy));
				}
			}
			else
			{
				if (curr_port->uart_rxbit < 9)
				{
					
					// data bit
					// if the data bit is a one, we add the bit value to the rxd value
					
					if (PIND & _BV(curr_port->uartrx))
					{
						curr_port->uart_rxd += uart_bitpattern[curr_port->uart_rxbit];
						
					}
					curr_port->uart_rxbit ++;
				}
				else
				{
					if (curr_port->uart_rxbit == 9)
					{
						// stop bit
						// we're going to assume it's a valid bit, though we could check for
						// framing error here, and simply use this bit to wait for the first
						// stop bit period
						curr_port->uart_rxbit++;
					}
					else
					{
						// finished, ready to start again
						curr_port->uart_status &= ~(_BV(rxbusy));
						// store the data into the buffer
						curr_port->buffer2[curr_port->next_write_2++] = curr_port->uart_rxd;
						if(curr_port->uart_rxd == 0xF0){
							
						}
						if (curr_port->next_write_2 == BUFFERSIZE)
						curr_port->next_write_2 = 0;
						
					}
				}
			}
		}
	}
}
	

	
	
//will be executed multiple times during startup, but who cares.

void uart_init (uart_port *curr_port)
{
	
	
	curr_port->next_write_2 = 0;	// set up the buffer pointers
	curr_port->next_read_2 = 0;
	
	curr_port->yeah = 0;			//set up debug char
	
	// we wake up the timer, preset the clock and uart variables, and enable the ocr1a interrupt

	
	TCCR1B = 0;					//resetting TCCR1B.
	TCCR1B |= _BV(CS10);		//clock enabled, prescaling = 1
	TCCR1B |= _BV(WGM12);		// ctc mode is enabled
	TCCR1A = 0;					//nothing special is used.
	
	OCR1AH = 0x03;				//for four connections at the same time: has to be D0
	OCR1AL = 0x41;				//The compare A value is set, right now it is the value it used to be for only one port, has to be four times higher.
		
	OCR1AH = 0x00;
	OCR1AL = 0xD0;
	
	//OCR1AH = 0x01;				//bullshit numbers
	//OCR1AL = 0x59;
		
		
	
	TIMSK1 |= _BV(OCIE1A);		//Timer/Counter Compare Match is enabled.
	
	
	
	curr_port->uart_status = 0;		// nothing happening either tx or rx
	
	//Here, the ports are set and the pullups configured. This implementation worked with one port, maybe changes have to be made so that we only edit "our" pin as a initializing port.
	
	
	DDRD = _BV(curr_port->uarttx);		// and set the input and output pins
	
	PORTD |= _BV(curr_port->uarttx);		// we're not using port d for anything else and
	
	PORTD |= _BV(curr_port->uartrx);	// the usart overrides the pin directions anyway, here the pull up resistor on the rx port is enabled.

}

void uart_out_char (char ch, uart_port *curr_port)
{
	// output the character to the software serial port, waiting until the output
	// buffer is available
	
	while ((curr_port->uart_status & _BV(txbusy)) == 1);		// wait...
	{
		// once the system isn't busy...
		// load the register
		curr_port->uart_txd = ch;
		
		// and tell it there's something to send
		curr_port->uart_status |= _BV(txbusy);
	}
}

void uart_print (char * text)
{
	// print a string of characters to the soft uart
	//for (int q=0; q<strlen(text); q++)
	//ser2_out(text[q]);
}

//checks if a char is waiting to be read.
char uart_ischar (uart_port *curr_port)
{
	// returns true if there is a character available from the soft uart
	// false if there is nothing waiting
	// call ser2_in after this to retrieve the data
	
	if (curr_port->next_read_2 != curr_port->next_write_2)
	return 1;
	else
	return 0;
}


//reads this char. Argument in both methods: a port struct, this struct contains the buffer object where the char is read from (if it exists).
char uart_get_char (uart_port *curr_port)
{
	// return a character from the soft uart
	// do *not* call without first testing with ser2_ischar as it modifies the
	// next_read pointer
	
	char ch;
	ch = curr_port->buffer2[curr_port->next_read_2++];
	if (curr_port->next_read_2 == BUFFERSIZE)
	curr_port->next_read_2 = 0;
	return ch;
}

<file_sep>/README.md
# Organet
This is heavily work in progress. As of the current state, only the concept of the organet and a fully working SoftwareUART class exist. The SoftwareUART Class can send and receive bytes, in the future it is to be encapsulated by the comhelper component and the comhelper to be used by the organet class.
<file_sep>/organet.c
/*
 * CFile1.c
 *
 * Created: 24.02.2015 23:32:03
 *  Author: Viktor
 */ 
#include "organet.h"
#include <util/delay.h>
int main(){ 
		
	com_helper_init(); //initializes all four ports by calling the uart_init method with each port struct as an argument.
	sei();
	
	while(1){
		
		uart_out_char(0xAA,&port[0]);
		_delay_ms(50);
		if(uart_ischar(&port[0])){			//checks if the is a char to be read on port 1
			//activate debug led.
			
			char x = uart_get_char(&port[0]);
			if(x == 0x04){
				port[0].yeah = 1;
				
			}
			
				
			
						
		}
		
		
	}
	
}

void check_for_new_chars(){
	if(uart_ischar(&port[0])){
		enqueue(&incoming_port[0], uart_get_char(&port[0]));
		
		if(com_helper_is_msg(&incoming_port[0])){
			com_helper_parse_msg(&incoming_port[0]);
		}
	}
	if(uart_ischar(&port[1])){
		enqueue(&incoming_port[1], uart_get_char(&port[1]));
		
		if(com_helper_is_msg(&incoming_port[1])){
			com_helper_parse_msg(&incoming_port[1]);
		}
	}
	if(uart_ischar(&port[2])){
		enqueue(&incoming_port[0], uart_get_char(&port[2]));
		
		if(com_helper_is_msg(&incoming_port[2])){
			com_helper_parse_msg(&incoming_port[2]);
		}
	}
	if(uart_ischar(&port[3])){
		enqueue(&incoming_port[0], uart_get_char(&port[3]));
		
		if(com_helper_is_msg(&incoming_port[3])){
			com_helper_parse_msg(&incoming_port[3]);
		}
	}
	  
}

void parse_message(){
	//check if message is for me
		//if nessesary send a response message
	
	//if not for me, send the message on the other 3 ports.
	
}

void send_message(){
	//on which ports?
	
	//add message to cue
	
}



void manage_transmissions(){
	//is uart currently sending a byte?
		//yes: return
		
		//no: is a message currently being sent?
			//yes: uart_send next byte of message
			
			//no: take next message from message cue, send first byte.
	
}<file_sep>/SoftUart2.h
/*
 * SoftUart2.h
 *
 * Created: 24.02.2015 09:57:33
 *  Author: Viktor
 */ 


#ifndef SOFTUART_H_
#define SOFTUART_H_

#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>


/*
################################################################################
This is a full duplex software Uart library.

IMPORTANT: set port_rotator to 1 when doing first init.

Todo: Output buffer
#############################################################################
*/



#define BUFFERSIZE 32
#define txbusy 0				// set if a byte is in transmission
#define rxbusy 1				// set if a byte is being received
#define rxframe 2

static uint8_t uart_bitpattern[9] = {0,1,2,4,8,16,32,64,128}; //this is used to know the actual value of a incoming bit in the final char. Read only, so no need to put it in every uart_port object.

volatile char port_rotator;   // this variable determines on which port the read/send method will be executed at the moment.
							// it is incremented/set to 0 after each interrupt. The interrupt is called by a timer periodically.


//this is the uart_port struct. A port represents a physical uart port, made of two pins on the arduino.
//The set of uart_port attributes are where the state of a port is saved, the method for reading exists only once, but the port which is given as an argument changes.
//Therefore, depending on which uart_port object is given to the read/write method, the according port is used.

//Addition: A uart_message consist of more than just one bit, so the bits have to be saved for each port. This happens in the buffer2 of every uart_port object.
typedef struct {
	char port_number;			//The port number as an actual number.
	volatile uint8_t yeah;		//if true, this port lights the debug led.
	volatile uint8_t	uart_rxd;		// the byte being received
	volatile uint8_t	uart_txd;		// the byte being transmitted
	volatile uint8_t	uart_txtick;	// tick count for the transmitter
	volatile uint8_t	uart_rxtick;	// tick count for the receiver
	volatile uint8_t	uart_txbit;		// bit count for tx
	volatile uint8_t	uart_rxbit;		// bit count for rx
	volatile uint8_t	uart_status;	// uart status
	volatile uint8_t next_read_2;
	volatile uint8_t next_write_2;	// the pointers to the receive2 buffer
	volatile uint8_t uartrx;			//the pin used by the port to receive something.
	volatile uint8_t uarttx;			//the pin used by the port to send something.

	volatile unsigned char buffer2[BUFFERSIZE];	// circular buffer for receiver 2

}uart_port;

//this is our port array:
//it has positions 0-3 althoug the port numbers are 1-4. attention!
//in this port array, all four port objects are saved.
uart_port port[4];

//######################################################################
//
//			METHODS
//
//######################################################################


void uart_init (uart_port *curr_port); //Used for initialization, argument is a port object, in which for example tha pins to use are specified. where specified? at com_helper_init().

char uart_ischar (uart_port *curr_port); //checks if there is a new char to be read.

char uart_get_char (uart_port *curr_port); // gets this char, which is to be read.

void uart_out_char (char ch, uart_port *curr_port); // prints a char via the software Uart. Currently the main routine waits until its printed, in the future abuffer will be implemented

void uart_print (char * text); //prints a whole string, doesnt work currently

void do_what_needs_to_be_done(uart_port *curr_port);






#endif /* SOFTUART_H_ */
<file_sep>/organet.h
/*
 * IncFile1.h
 *
 * Created: 25.02.2015 01:05:51
 *  Author: Viktor
 */ 


#ifndef ORGANET_H_
#define ORGANET_H_
#include "comhelper.h"



void check_for_new_chars ();

void parse_message();

void send_message();

void manage_transmissions();



#endif /* ORGANET_H_ */<file_sep>/Debug/makedep.mk
################################################################################
# Automatically-generated file. Do not edit or delete the file
################################################################################

queue.c

organet.c

comhelper.c

SoftUart2.c

<file_sep>/queue.c
/*
 * CFile1.c
 *
 * Created: 22.05.2015 14:05:19
 *  Author: Viktor
 */ 

#include "queue.h"

// Declare these as static so no code outside of this source
// can access them.


//--------------------------------------------
// Function: InitQueue()
// Purpose: Initialize queue to empty.
// Returns: void
//--------------------------------------------
void initQueue(queue *q)
{
	q->head = q->tail = -1;
}

//--------------------------------------------
// Function: ClearQueue()
// Purpose: Remove all items from the queue
// Returns: void
//--------------------------------------------
void clearQueue(queue *q)
{
	q->head = q->tail = -1; // Reset indices to start over
}

//--------------------------------------------
// Function: Enqueue()
// Purpose: Enqueue an item into the queue.
// Returns: TRUE if enqueue was successful
//		or FALSE if the enqueue failed.
// Note: We let head and tail continuing
//		increasing and use [head % MAX_SIZE]
//		and [tail % MAX_SIZE] to get the real
//		indices.  This automatically handles
//		wrap-around when the end of the array
//		is reached.
//--------------------------------------------
char enqueue(queue *q,char ch)
{
	// Check to see if the Queue is full
	if(isFull(q)) return 0;

	// Increment tail index
	q->tail++;
	// Add the item to the Queue
	q->theQueue[q->tail % MAX_SIZE] = ch;
	return 1;
}

//--------------------------------------------
// Function: Dequeue()
// Purpose: Dequeue an item from the Queue.
// Returns: TRUE if dequeue was successful
//		or FALSE if the dequeue failed.
//--------------------------------------------
char dequeue(queue *q)
{
	char ch;

	// Check for empty Queue
	if(isEmpty(q)) return '\0';  // Return null character if queue is empty
	else
	{
		q->head++;
		ch = q->theQueue[q->head % MAX_SIZE];		// Get character to return
		return ch;				// Return popped character
	}
}

//--------------------------------------------
// Function: isEmpty()
// Purpose: Return true if the queue is empty
// Returns: TRUE if empty, otherwise FALSE
// Note: C has no boolean data type so we use
//	the defined int values for TRUE and FALSE
//	instead.
//--------------------------------------------
char isEmpty(queue *q)
{
	return (q->head == q->tail);
}

//--------------------------------------------
// Function: isFull()
// Purpose: Return true if the queue is full.
// Returns: TRUE if full, otherwise FALSE
// Note: C has no boolean data type so we use
//	the defined int values for TRUE and FALSE
//	instead.
//--------------------------------------------
char isFull(queue *q)
{
	// Queue is full if tail has wrapped around
	//	to location of the head.  See note in
	//	Enqueue() function.
	return ((q->tail - MAX_SIZE) == q->head);
}