summaryrefslogtreecommitdiffhomepage
path: root/analog/motor-power-avr/src/mp_pwm_L_.c
blob: 085f2bcc4a564e4144deb5ac111d27d3198cf8d7 (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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/* "mp_pwm_L_.c"
 * this file contains routines for managing the _L_ channel of mp board
 * the command sed -e 's/_L_/_R_/g' can be used for generating the _R_ file
 */

#include "mp_pwm_LR_.h"
#include "mp_pwm_L_.h"
#include "io.h"

// static variables
static uint8_t state_L_;
static uint8_t state_L_cmd = 0x03;
static uint8_t pwm_L_;

// Le PC, afin de faire le saut calculé
//#define PC PC_REG

// init
void init_pwm_L_ (void) {
    state_L_cmd = 0x40;
    pwm_L_ = 0x00;
}

// rising edge = timer overflow = TOV interrupt (TODO : à programmer)
void rise (void) {
    // programs the state which is ordered by the core code
    state_L_ = state_L_cmd;

    // the falling of the other side may have delayed a few our IT
    OCR_L_ = pwm_L_ + TCNT_L_;	// TODO: OCR_L_value shall be > than x%

    //PC = PC + state_L_;	// j'aurais bien aimé faire un calculated jump

    switch (state_L_) 
      {
      case 0x00:
	// dir 0
	//rise_L_label0:
	_L_BH_0;
	_L_BL_1;
	_L_AL_0;
	_L_AH_1;
	sei();	// set back interrupts
	return;
	break;

      case 0x01:
	// dir 1
	//org rise_L_label0 + 0x10
	_L_AH_0;
	_L_AL_1;
	_L_BL_0;
	_L_BH_1;
	sei(); 	// set back interrupts
	return;
	break;

      case 0x02:
	// switch to forced low steady state
	//org rise_L_label0 + 0x20
	_L_AH_0;
	_L_AL_1;
	_L_BH_0;
	_L_BL_1;
	sei(); 	// set back interrupts
	return;
	break;

      case 0x03:
	// switch to high impedance steady state
	//org rise_L_label0 + 0x30
	_L_AL_0;
	_L_AH_0;
	_L_BL_0;
	_L_BH_0;
	sei(); 	// set back interrupts
	return;
	break;

      }
}

// falling edge = timer crossing OCR : OCn interrupt (TODO : à programmer)
void fall_L_ (void) {
    //	PC = PC + state_L_; TODO :saut calculé ?

    switch (state_L_) 
      {
      case 0x00:
	// in the case we are in 0x00 direction
	//fall_L_label0:
	_L_AH_0;
	_L_AL_1;
	sei(); 	// set back interrupts
	return;
	break;

      case 0x01:
	// in the case we are in 0x10 direction
	//org fall_L_label0 + 0x10
	_L_BH_0;
	_L_BL_1;
	sei(); 	// set back interrupts
	return;
	break;

      case 0x02:
	// forced low
	//org fall_L_label0 + 0x20
	sei(); 	// set back interrupts
	return;
	break;

      case 0x03:
	// left high Z
	//org fall_L_label0 + 0x30
	sei(); 	// set back interrupts
	return;
	break;
      }
}


// overcurrent detected by comparators
void ovc_L_ (void) {
    _L_AL_0;
    _L_AH_0;
    _L_BL_0;
    _L_BH_0;
    sei(); 	// set back interrupts
    // following line orders to keep high Z state when faling edge will arrive
    state_L_ = 0x30;
    return;
}

// starts the motor
void start_motor_L_ (uint8_t pwmspeed, uint8_t direction) {
    // checking direction
    if (direction) 
      {
	state_L_cmd = 0x10;
      }
    else
      {
	state_L_cmd = 0x00;
      }

    // setting pwm value
    if (pwmspeed == 0)
      {// brake
	state_L_cmd = 0x20;
	pwm_L_ = 0;
      }
    else
      {
	// adding offset
	pwmspeed = pwmspeed + PWM_OFFSET_LR_;
	
	if (pwmspeed > PWM_MAX_LR_) 
	  {// over PWM_MAX_LR_
	    pwm_L_ = PWM_MAX_LR_;
	  }
	else if (pwmspeed < PWM_MIN_LR_) 
	  {// under PWM_MIN_LR_
	    pwm_L_ = PWM_MIN_LR_;
	  }
      }
}

// puts motor in high Z
void stop_motor_L_ (void) {
    state_L_ = 0x30;
}