summaryrefslogtreecommitdiffhomepage
path: root/digital/beacon/src/laser.c
blob: 585e5739057fd15627301654674f791e86bd4003 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* laser.c */
/* laser sensor management. {{{
 *
 * Copyright (C) 2012 Florent Duchon
 *
 * APBTeam:
 *        Web: http://apbteam.org/
 *      Email: team AT apbteam DOT org
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * }}} */

#include <types.h>
#include <avr/interrupt.h>
#include "debug_avr.h"
#include "laser.h"


/* This function initializes the laser pin input and associated interrupt */
void laser_init(void)
{	
	/* Configure Input compare interrupts for Laser Interrupt*/
	TCCR3B |= (1<<ICNC3)|(1<<ICES3);
	TIMSK3 |= (1<<ICIE3);
	TIMSK3 &= ~(1<<OCIE3B);
	sei(); 
}


/* This function returns the edge type trigged by the AVR IC module*/
TLaser_edge_type laser_get_edge_type(void)
{
	if(RISING_EDGE)
	{
		if(SENDING_ENGAGED)
		{
			return LASER_RISING_EDGE;
		}
		else
		{
			return LASER_FIRST_RISING_EDGE;
		}
	}
	else
	{
		return LASER_FALLING_EDGE;
	}
}


/* This function inverts the trigged edge of the AVR IC module */
void laser_invert_IRQ_edge_trigger(void)
{
	TCCR3B ^= 1<<ICES3;
}


/* This function deactivates the angle sending */
void laser_inhibit_angle_sending(void)
{
	TIMSK3 &= ~(1<<OCIE3B);
	sei(); 
}


/* This function configures the AVR OC3B interrupt that will send the angle LASER_SENDING_OFFSET after the latest rising edge */
void laser_engage_angle_sending(uint16_t value)
{
	OCR3A = value + LASER_SENDING_OFFSET;
	TIMSK3 |= (1<<OCIE3B);
	sei(); 
}


/* Zigbee sending IRQ vector */
ISR(TIMER3_COMPB_vect)
{
// 	TIMSK3 &= ~OCIE3B;
// 	sei(); 
}


/* Laser IRQ vector */
ISR(TIMER3_CAPT_vect)
{
	static uint16_t angle = 0;
	TLaser_edge_type current_edge;
	
	current_edge = laser_get_edge_type();
	
	switch(current_edge)
	{
		case LASER_FIRST_RISING_EDGE:
			angle = ICR3;
			break;
		case LASER_RISING_EDGE:
			laser_inhibit_angle_sending();
			angle = (angle + ICR3) / 2;
			break;
		case LASER_FALLING_EDGE:
			angle = (angle + ICR3) / 2;
			laser_engage_angle_sending(ICR3);
			break;
		default:
			break;
	}
	laser_invert_IRQ_edge_trigger();
}