Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 729 → Rev 730

/Transportables_Koptertool/trunk/motortest.c
0,0 → 1,281
/*****************************************************************************
* Copyright (C) 2009 Peter "woggle" Mack, mac@denich.net *
* *
* 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. *
* *
* 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 <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <string.h>
#include <util/twi.h>
 
#include "main.h"
#include "motortest.h"
#include "lcd.h"
#include "usart.h"
#include "timer.h"
 
 
uint8_t m;
 
 
#define SCL_FREQ 200000L
 
#define I2C_STATE_TX_ADDRESS 0
#define I2C_STATE_TX_DATA 1
#define I2C_STATE_TX_STOP 2
#define I2C_STATE_RX_ADDRESS 3
#define I2C_STATE_RX_1BYTE 4
#define I2C_STATE_RX_2BYTE 5
 
volatile uint8_t i2c_state;
volatile uint8_t motor_addr = 0;
 
//*****************************************************************************
//
void I2C_Init(void)
{
uint8_t sreg = SREG;
cli();
DDRC &= ~(1<<DDC1); // SDA is input
DDRC |= (1<<DDC0); // SCL is output
PORTC |= (1<<PORTC0)|(1<<PORTC1); // pull up SDA and SCL
// prescaler 1 (TWPS1 = 0, TWPS0 = 0)
TWSR &= ~((1<<TWPS1)|(1<<TWPS0));
 
TWBR = ((F_CPU/SCL_FREQ)-16)/2;
i2c_state = I2C_STATE_TX_ADDRESS;
 
SREG = sreg;
}
 
//*****************************************************************************
//
void I2C_Start(uint8_t start_state)
{
i2c_state = start_state;
 
// generate start condition and enable interrupts
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN) | (1<<TWIE);
}
 
//*****************************************************************************
//
void I2C_Stop(uint8_t start_state)
{
i2c_state = start_state;
 
// generate stop condition and disable interrupt
TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
}
 
//*****************************************************************************
//
void I2C_WriteByte(int8_t b)
{
TWDR = b;
// clear interrupt flag (TWINT = 1)
// enable i2c bus (TWEN = 1)
// enable interrupt (TWIE = 1)
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
}
 
//*****************************************************************************
//
void I2C_ReceiveByte(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWEA);
}
 
//*****************************************************************************
//
void I2C_ReceiveLastByte(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
}
 
 
//*****************************************************************************
//
ISR (TWI_vect)
{
int8_t mrCurrent;
int8_t mrMaxpwm;
switch (i2c_state++)
{
// TWI Master Transmit
case I2C_STATE_TX_ADDRESS:
I2C_WriteByte(0x52 + (motor_addr * 2) ); // select slave adress in tx mode
break;
 
case I2C_STATE_TX_DATA:
I2C_WriteByte(m);
break;
 
case I2C_STATE_TX_STOP:
if(TWSR == TW_MT_DATA_NACK) // Data transmitted, NACK received
{
// error occured
}
I2C_Stop(I2C_STATE_TX_ADDRESS);
I2C_Start(I2C_STATE_RX_ADDRESS); // Repeated start -> switch slave or switch Master Transmit -> Master Receive
break;
 
// Master Receive Data
case I2C_STATE_RX_ADDRESS:
I2C_WriteByte(0x53 + (motor_addr * 2) ); // select slave adress in rx mode
if(TWSR != TW_MR_SLA_ACK) // SLA+R transmitted, if not ACK received
{ // no response from the addressed slave received
I2C_Stop(I2C_STATE_TX_ADDRESS);
}
else
{
I2C_ReceiveByte(); //Transmit 1st byte
}
break;
 
case I2C_STATE_RX_1BYTE: //Read 1st byte and transmit 2nd Byte
mrCurrent = TWDR;
I2C_ReceiveLastByte(); // nack
break;
 
case I2C_STATE_RX_2BYTE:
//Read 2nd byte
mrMaxpwm = TWDR;;
I2C_Stop(I2C_STATE_TX_ADDRESS);
break;
default:
I2C_Stop(I2C_STATE_TX_ADDRESS);
break;
}
}
 
//*****************************************************************************
//
void motor_i2c (void)
{
uint8_t blc = 0;
lcd_cls ();
m = 0;
lcd_printp (PSTR("I2C Motor Test"), 0);
lcd_printpns_at (0, 7, PSTR("dec inc Exit Off"), 0);
lcd_printp (PSTR("BLC #"), 0);
do
{
if ((get_key_press (1 << KEY_PLUS) || get_key_rpt (1 << KEY_PLUS)) && (m < 254))
{
m++;
}
if ((get_key_press (1 << KEY_MINUS) || get_key_rpt (1 << KEY_MINUS)) && (m > 0))
{
lcd_frect (GX, GY, (m * 108) / 255, 10, 0);
m--;
}
if (get_key_press (1 << KEY_ENTER))
{
lcd_frect (GX, GY, (m * 108) / 255, 10, 0);
m = 0;
}
}
while (!get_key_press (1 << KEY_ESC));
// switch all engines off at exit !
}
 
 
//*****************************************************************************
//
void motor (uint8_t m)
{
memset (buffer, m, 16);
#if 0
buffer[0] = m; // 0
buffer[1] = m; // 1
buffer[2] = m; // 2
buffer[3] = m; // 3
buffer[4] = m; // 4
buffer[5] = m; // 5
buffer[6] = m; // 6
buffer[7] = m; // 7
buffer[8] = m; // 8
buffer[9] = m; // 9
buffer[10] = m; // 10
buffer[11] = m; // 11
buffer[12] = m; // 12
buffer[13] = m; // 13
buffer[14] = m; // 14
buffer[15] = m; // 15
#endif
SendOutData('t', ADDRESS_FC, 1, buffer, 16);
// hier könnte man noch eine I2C-Ausgabe einbauen...
lcd_frect (GX, GY, (m * 108) / 255, 10, 1);
write_ndigit_number_u (MX, MY, m, 3, 0);
}
 
//*****************************************************************************
//
void motor_test (void)
{
//uint8_t m;
 
lcd_cls ();
m = 0;
 
lcd_printp (PSTR("Motor Test"), 0);
lcd_printpns_at (0, 7, PSTR("dec inc Exit Off"), 0);
 
if (hardware == NC && current_hardware == NC)
{
SwitchToFC();
}
motor (m);
 
do
{
if ((get_key_press (1 << KEY_PLUS) || get_key_rpt (1 << KEY_PLUS)) && (m < 254))
{
m++;
}
if ((get_key_press (1 << KEY_MINUS) || get_key_rpt (1 << KEY_MINUS)) && (m > 0))
{
lcd_frect (GX, GY, (m * 108) / 255, 10, 0);
m--;
}
if (get_key_press (1 << KEY_ENTER))
{
lcd_frect (GX, GY, (m * 108) / 255, 10, 0);
m = 0;
}
motor (m);
}
while (!get_key_press (1 << KEY_ESC));
 
// switch all engines off at exit !
motor (0);
}