Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
730 woggle 1
/*****************************************************************************
2
 *   Copyright (C) 2009 Peter "woggle" Mack, mac@denich.net                  *
3
 *                                                                           *
4
 *   This program is free software; you can redistribute it and/or modify    *
5
 *   it under the terms of the GNU General Public License as published by    *
6
 *   the Free Software Foundation; either version 2 of the License.          *
7
 *                                                                           *
8
 *   This program is distributed in the hope that it will be useful,         *
9
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
10
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
11
 *   GNU General Public License for more details.                            *
12
 *                                                                           *
13
 *   You should have received a copy of the GNU General Public License       *
14
 *   along with this program; if not, write to the                           *
15
 *   Free Software Foundation, Inc.,                                         *
16
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.               *
17
 *                                                                           *
18
 *****************************************************************************/
19
 
20
#include <avr/io.h>
21
#include <avr/interrupt.h>
22
#include <avr/pgmspace.h>
23
#include <string.h>
24
#include <util/twi.h>
25
 
26
#include "main.h"
27
#include "motortest.h"
28
#include "lcd.h"
29
#include "usart.h"
30
#include "timer.h"
31
 
32
 
33
uint8_t m;
34
 
35
 
36
#define SCL_FREQ  200000L
37
 
38
#define I2C_STATE_TX_ADDRESS    0
39
#define I2C_STATE_TX_DATA                       1
40
#define I2C_STATE_TX_STOP                       2
41
#define I2C_STATE_RX_ADDRESS    3
42
#define I2C_STATE_RX_1BYTE              4
43
#define I2C_STATE_RX_2BYTE              5
44
 
45
volatile uint8_t i2c_state;
46
volatile uint8_t motor_addr = 0;
47
 
48
//*****************************************************************************
49
// 
50
void I2C_Init(void)
51
{
52
        uint8_t sreg = SREG;
53
        cli();
54
 
55
        DDRC  &= ~(1<<DDC1);    // SDA is input
56
        DDRC |= (1<<DDC0);              // SCL is output
57
        PORTC |= (1<<PORTC0)|(1<<PORTC1);       // pull up SDA and SCL
58
 
59
        // prescaler 1 (TWPS1 = 0, TWPS0 = 0)
60
        TWSR &= ~((1<<TWPS1)|(1<<TWPS0));
61
 
62
        TWBR = ((F_CPU/SCL_FREQ)-16)/2;
63
 
64
        i2c_state = I2C_STATE_TX_ADDRESS;
65
 
66
        SREG = sreg;
67
}
68
 
69
//*****************************************************************************
70
// 
71
void I2C_Start(uint8_t start_state)
72
{
73
        i2c_state = start_state;
74
 
75
        // generate start condition and enable interrupts
76
        TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN) | (1<<TWIE);
77
}
78
 
79
//*****************************************************************************
80
// 
81
void I2C_Stop(uint8_t start_state)
82
{
83
        i2c_state = start_state;
84
 
85
        // generate stop condition and disable interrupt
86
        TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
87
}
88
 
89
//*****************************************************************************
90
// 
91
void I2C_WriteByte(int8_t b)
92
{
93
        TWDR = b;
94
        // clear interrupt flag (TWINT = 1)
95
        // enable i2c bus (TWEN = 1)
96
        // enable interrupt (TWIE = 1)
97
        TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
98
}
99
 
100
//*****************************************************************************
101
// 
102
void I2C_ReceiveByte(void)
103
{
104
        TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWEA);
105
}
106
 
107
//*****************************************************************************
108
// 
109
void I2C_ReceiveLastByte(void)
110
{
111
        TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
112
}
113
 
114
 
115
//*****************************************************************************
116
// 
117
ISR (TWI_vect)
118
{
119
        int8_t mrCurrent;
120
        int8_t mrMaxpwm;
121
 
122
        switch (i2c_state++)
123
        {
124
                // TWI Master Transmit
125
                case I2C_STATE_TX_ADDRESS:
126
                        I2C_WriteByte(0x52 + (motor_addr * 2) ); // select slave adress in tx mode
127
                        break;
128
 
129
                case I2C_STATE_TX_DATA:
130
                        I2C_WriteByte(m);
131
                        break;
132
 
133
                case I2C_STATE_TX_STOP:
134
                        if(TWSR == TW_MT_DATA_NACK) // Data transmitted, NACK received
135
                        {
136
                                // error occured
137
                        }
138
                        I2C_Stop(I2C_STATE_TX_ADDRESS);
139
                        I2C_Start(I2C_STATE_RX_ADDRESS); // Repeated start -> switch slave or switch Master Transmit -> Master Receive
140
                        break;
141
 
142
                        // Master Receive Data
143
                case I2C_STATE_RX_ADDRESS:
144
                        I2C_WriteByte(0x53 + (motor_addr * 2) ); // select slave adress in rx mode
145
                        if(TWSR != TW_MR_SLA_ACK) //  SLA+R transmitted, if not ACK received
146
                        {       // no response from the addressed slave received
147
                                I2C_Stop(I2C_STATE_TX_ADDRESS);
148
                        }
149
                        else
150
                        {
151
                                I2C_ReceiveByte(); //Transmit 1st byte
152
                        }
153
                        break;
154
 
155
                case I2C_STATE_RX_1BYTE: //Read 1st byte and transmit 2nd Byte
156
                        mrCurrent = TWDR;
157
                        I2C_ReceiveLastByte(); // nack
158
                        break;
159
 
160
                case I2C_STATE_RX_2BYTE:
161
                        //Read 2nd byte
162
                        mrMaxpwm = TWDR;;
163
                        I2C_Stop(I2C_STATE_TX_ADDRESS);
164
                        break;
165
 
166
                default:
167
                        I2C_Stop(I2C_STATE_TX_ADDRESS);
168
                        break;
169
        }
170
}
171
 
172
//*****************************************************************************
173
// 
174
void motor_i2c (void)
175
{
176
        uint8_t blc = 0;
177
 
178
        lcd_cls ();
179
        m = 0;
180
 
181
        lcd_printp (PSTR("I2C Motor Test"), 0);
182
        lcd_printpns_at (0, 7, PSTR("dec  inc    Exit Off"), 0);
183
 
184
        lcd_printp (PSTR("BLC #"), 0);
185
 
186
        do
187
        {
188
                if ((get_key_press (1 << KEY_PLUS) || get_key_rpt (1 << KEY_PLUS)) && (m < 254))
189
                {
190
                        m++;
191
                }
192
                if ((get_key_press (1 << KEY_MINUS) || get_key_rpt (1 << KEY_MINUS)) && (m > 0))
193
                {
194
                        lcd_frect (GX, GY, (m * 108) / 255, 10, 0);
195
                        m--;
196
                }
197
                if (get_key_press (1 << KEY_ENTER))
198
                {
199
                        lcd_frect (GX, GY, (m * 108) / 255, 10, 0);
200
                        m = 0;
201
                }
202
        }
203
        while (!get_key_press (1 << KEY_ESC));
204
 
205
        // switch all engines off at exit !
206
}
207
 
208
 
209
//*****************************************************************************
210
// 
211
void motor (uint8_t m)
212
{
213
        memset (buffer, m, 16);
214
#if 0
215
        buffer[0] = m;  // 0
216
        buffer[1] = m;  // 1
217
        buffer[2] = m;  // 2
218
        buffer[3] = m;  // 3
219
        buffer[4] = m;  // 4
220
        buffer[5] = m;  // 5
221
        buffer[6] = m;  // 6
222
        buffer[7] = m;  // 7
223
        buffer[8] = m;  // 8
224
        buffer[9] = m;  // 9
225
        buffer[10] = m; // 10
226
        buffer[11] = m; // 11
227
        buffer[12] = m; // 12
228
        buffer[13] = m; // 13
229
        buffer[14] = m; // 14
230
        buffer[15] = m; // 15
231
#endif
232
        SendOutData('t', ADDRESS_FC, 1, buffer, 16);
233
 
234
        // hier könnte man noch eine I2C-Ausgabe einbauen...
235
 
236
        lcd_frect (GX, GY, (m * 108) / 255, 10, 1);
237
        write_ndigit_number_u (MX, MY, m, 3, 0);
238
}
239
 
240
//*****************************************************************************
241
// 
242
void motor_test (void)
243
{
244
        //uint8_t m;
245
 
246
        lcd_cls ();
247
        m = 0;
248
 
249
        lcd_printp (PSTR("Motor Test"), 0);
250
        lcd_printpns_at (0, 7, PSTR("dec  inc    Exit Off"), 0);
251
 
252
        if (hardware == NC && current_hardware == NC)
253
        {
254
                SwitchToFC();
255
        }
256
 
257
        motor (m);
258
 
259
        do
260
        {
261
                if ((get_key_press (1 << KEY_PLUS) || get_key_rpt (1 << KEY_PLUS)) && (m < 254))
262
                {
263
                        m++;
264
                }
265
                if ((get_key_press (1 << KEY_MINUS) || get_key_rpt (1 << KEY_MINUS)) && (m > 0))
266
                {
267
                        lcd_frect (GX, GY, (m * 108) / 255, 10, 0);
268
                        m--;
269
                }
270
                if (get_key_press (1 << KEY_ENTER))
271
                {
272
                        lcd_frect (GX, GY, (m * 108) / 255, 10, 0);
273
                        m = 0;
274
                }
275
                motor (m);
276
        }
277
        while (!get_key_press (1 << KEY_ESC));
278
 
279
        // switch all engines off at exit !
280
        motor (0);
281
}