summaryrefslogtreecommitdiffhomepage
path: root/analog/motor-power-avr/src/mp_pwm_L_.c
blob: 1eb04b7167a540aa04bba9e164a0a98bed3c746b (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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/* "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;
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 = CMD_STATE_HIGH_Z;
    pwm_L_ = 0x00;

    // Set outputs to 0 (ie HIGH_Z)
	_L_AL_0;
	_L_AH_0;
	_L_BL_0;
	_L_BH_0;

    // status LEDs
    _L_LED0_1;
    _L_LED1_1;

    // Set IOs as outputs
    _L_ACTIVATE_OUTPUTS;
}

// PWM rising edge on timer overflow IT
ISR(L_OVF_vect) {
    // 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 CMD_STATE_DIR_0:
	// dir 0
	//rise_L_label0:
	_L_BH_0;
	_L_BL_1;
	_L_AL_0;
	_L_AH_1;
	sei();	// set back interrupts

    // Display CMD_STATE on LEDs
    _L_LED0_0;
    _L_LED1_0;

	break;

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

    // Display CMD_STATE on LEDs
    _L_LED0_1;
    _L_LED1_0;

	break;

      case CMD_STATE_BRAKE:
	// 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

    // Display CMD_STATE on LEDs
    _L_LED0_0;
    _L_LED1_1;

	break;

      case CMD_STATE_HIGH_Z:
      default:
	// 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

    // Display CMD_STATE on LEDs
    _L_LED0_1;
    _L_LED1_1;

	break;

      }
}

// PWM falling edge on timer compare IT
ISR(L_COMP_vect) {
    //	PC = PC + state_L_; TODO :saut calculé ?

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

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

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

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


// overcurrent detected by comparators
ISR(ILIM_L_vect) {
    _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_ = CMD_STATE_HIGH_Z;
    return;
}

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

    // setting pwm value
    if (pwmspeed == 0)
      {// brake
	state_L_cmd = CMD_STATE_BRAKE;
	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_ = CMD_STATE_HIGH_Z;
}