Subversion Repositories MK3Mag

Compare Revisions

Ignore whitespace Rev 18 → Rev 19

/branches/MK3Mag V0.14 Code Redesign Killagreg/old_macros.h
File deleted
/branches/MK3Mag V0.14 Code Redesign Killagreg/main.lss
File deleted
/branches/MK3Mag V0.14 Code Redesign Killagreg/main.sym
File deleted
/branches/MK3Mag V0.14 Code Redesign Killagreg/main.map
File deleted
/branches/MK3Mag V0.14 Code Redesign Killagreg/Hex-Files/MK3Mag_MEGA168_V0_14.hex
File deleted
/branches/MK3Mag V0.14 Code Redesign Killagreg/analog.c
1,6 → 1,6
/*#######################################################################################
MK3Mag 3D-Magnet sensor
!!! THIS IS NOT FREE SOFTWARE !!!
!!! THIS IS NOT FREE SOFTWARE !!!
#######################################################################################*/
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Copyright (c) 05.2008 Holger Buss
8,15 → 8,15
// + Nur für den privaten Gebrauch
// + www.MikroKopter.com
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + mit unserer Zustimmung zulässig
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
// + AUSNAHME: Ein bei www.mikrokopter.de erworbener vorbestückter MK3Mag darf als Baugruppe auch in kommerziellen Systemen verbaut werden
// + Im Zweifelsfall bitte anfragen bei: info@mikrokopter.de
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
29,19 → 29,19
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
// + this list of conditions and the following disclaimer.
// + * PORTING this software (or parts of it) to systems (other than hardware from www.mikrokopter.de) is NOT allowed
// + * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
// + from this software without specific prior written permission.
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
// + for non-commercial use (directly or indirectly)
// + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
// + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
// + with our written permission
// + Exception: A preassembled MK3Mag, purchased from www.mikrokopter.de may be used as a part of commercial systems
// + In case of doubt please contact: info@MikroKopter.de
// + * If sources or documentations are redistributet on other webpages, our webpage (http://www.MikroKopter.de) must be
// + clearly linked as origin
// + * If sources or documentations are redistributet on other webpages, our webpage (http://www.MikroKopter.de) must be
// + clearly linked as origin
// + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52,31 → 52,44
// + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// + POSSIBILITY OF SUCH DAMAGE.
// + POSSIBILITY OF SUCH DAMAGE.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//#include <stdlib.h>
#include "analog.h"
 
#include "main.h"
 
//############################################################################
//Init ADC
void ADC_Init(void)
{
ADMUX = 0;
ADCSRA = 0x87;
ADMUX = 0;
ADCSRA |= 0x40; // Start Conversion
// set PortC 0,1,2,3 as input
DDRC &= ~((1<<DDC3)|(1<<DDC2)|(1<<DDC1)|(1<<DDC0));
// set PortC 0,1,2,3 and 6,7 as tri state
PORTC &= ~((1<<PORTC3)|(1<<PORTC2)|(1<<PORTC1)|(1<<PORTC0));
 
// port PD5 and PD6 control the current direction of the test coils of the sensors
DDRD |= ((1<<DDD5)|(1<<DDD6));
FLIP_LOW;
 
// disable internal reference voltage and right adjust bits in ADCW
ADMUX = 0x00;
// clear start conversion bit (ADSC = 0)
// disable ADC Auto Trigger Enable (ADATE = 0)
// disable interrupt (ADIE = 0)
ADCSRA &= ~((1<<ADSC)|(1<<ADATE)|(1<<ADIE));
// Enable ADC (ADEN = 1) with SYSCLK/128 (ADPS2 = 1, ADPS1 = 1, ADPS0 = 1) and clear ready flag (ADIF = 1)
ADCSRA |= ((1<<ADEN)|(1<<ADIF)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0));
ADMUX = 0x00; // select ADC0
ADCSRA |= (1<<ADSC); // start conversion
}
 
 
unsigned int MessAD(unsigned char channel)
uint16_t ADC_GetValue(ADChannel_t channel)
{
unsigned int messwert = 0;
ADMUX = channel;
ADCSRA |= 0x10; // Clear Ready-Bit
ADCSRA |= 0x40; // Start Conversion
while (((ADCSRA & 0x10) == 0));
messwert = ADCW;
return(messwert);
uint16_t value = 0;
ADMUX = channel; // set muxer bits
ADCSRA |= (1<<ADIF); // clear ready-flag
ADCSRA |= (1<<ADSC); // start conversion
while (((ADCSRA & (1<<ADIF)) == 0)); // wait for end of conversion
value = ADCW; // read adc result
return(value);
}
 
 
/branches/MK3Mag V0.14 Code Redesign Killagreg/analog.h
1,6 → 1,28
#ifndef _ANALOG_H_
#define _ANALOG_H_
 
extern void ADC_Init(void);
extern void GetAnalogWerte(void);
extern void AdConvert(void);
extern void FastADConvert(void);
extern unsigned int MessAD(unsigned char);
#include <inttypes.h>
#include <avr/io.h>
 
#define FLIP_HIGH PORTD |= ((1<<PORTD5)|(1<<PORTD6))
#define FLIP_LOW PORTD &= ~((1<<PORTD5)|(1<<PORTD6))
 
typedef enum
{
ADC0 = 0,
ADC1 = 1,
ADC2 = 2,
ADC3 = 3,
ADC4 = 4,
ADC5 = 5,
ADC6 = 6,
ADC7 = 7,
REF1V1 = 14,
AGND = 15
} ADChannel_t;
 
void ADC_Init(void);
uint16_t ADC_GetValue(ADChannel_t channel);
 
#endif // _ANALOG_H_
 
/branches/MK3Mag V0.14 Code Redesign Killagreg/led.c
0,0 → 1,67
/*#######################################################################################
MK3Mag 3D-Magnet sensor
!!! THIS IS NOT FREE SOFTWARE !!!
#######################################################################################*/
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Copyright (c) 05.2008 Holger Buss
// + Thanks to Ilja Fähnrich (P_Latzhalter)
// + Nur für den privaten Gebrauch
// + www.MikroKopter.com
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + mit unserer Zustimmung zulässig
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
// + AUSNAHME: Ein bei www.mikrokopter.de erworbener vorbestückter MK3Mag darf als Baugruppe auch in kommerziellen Systemen verbaut werden
// + Im Zweifelsfall bitte anfragen bei: info@mikrokopter.de
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
// + auf anderen Webseiten oder sonstigen Medien veröffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de"
// + eindeutig als Ursprung verlinkt werden
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion
// + Benutzung auf eigene Gefahr
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
// + this list of conditions and the following disclaimer.
// + * PORTING this software (or parts of it) to systems (other than hardware from www.mikrokopter.de) is NOT allowed
// + * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
// + from this software without specific prior written permission.
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
// + for non-commercial use (directly or indirectly)
// + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
// + with our written permission
// + Exception: A preassembled MK3Mag, purchased from www.mikrokopter.de may be used as a part of commercial systems
// + In case of doubt please contact: info@MikroKopter.de
// + * If sources or documentations are redistributet on other webpages, our webpage (http://www.MikroKopter.de) must be
// + clearly linked as origin
// + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// + POSSIBILITY OF SUCH DAMAGE.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include "led.h"
 
 
void Led_Init(void)
{
// Set PD7 as output
DDRD |= (1<<DDD7);
// set port pon to GND
PORTD &= ~((1<<PORTD7));
}
 
/branches/MK3Mag V0.14 Code Redesign Killagreg/led.h
0,0 → 1,12
#ifndef _LED_H_
#define _LED_H_
 
#include <avr/io.h>
 
#define LED_GRN_ON PORTD |= (1<<PORTD7)
#define LED_GRN_OFF PORTD &= ~(1<<PORTD7)
#define LED_GRN_TOGGLE PORTD ^= (1<<PORTD7)
 
void Led_Init(void);
 
#endif //_LED_H_
/branches/MK3Mag V0.14 Code Redesign Killagreg/main.c
1,6 → 1,6
/*#######################################################################################
MK3Mag 3D-Magnet sensor
!!! THIS IS NOT FREE SOFTWARE !!!
!!! THIS IS NOT FREE SOFTWARE !!!
#######################################################################################*/
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Copyright (c) 05.2008 Holger Buss
8,15 → 8,15
// + Nur für den privaten Gebrauch
// + www.MikroKopter.com
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + mit unserer Zustimmung zulässig
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
// + AUSNAHME: Ein bei www.mikrokopter.de erworbener vorbestückter MK3Mag darf als Baugruppe auch in kommerziellen Systemen verbaut werden
// + Im Zweifelsfall bitte anfragen bei: info@mikrokopter.de
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
29,19 → 29,19
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
// + this list of conditions and the following disclaimer.
// + * PORTING this software (or parts of it) to systems (other than hardware from www.mikrokopter.de) is NOT allowed
// + * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
// + from this software without specific prior written permission.
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
// + for non-commercial use (directly or indirectly)
// + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
// + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
// + with our written permission
// + Exception: A preassembled MK3Mag, purchased from www.mikrokopter.de may be used as a part of commercial systems
// + In case of doubt please contact: info@MikroKopter.de
// + * If sources or documentations are redistributet on other webpages, our webpage (http://www.MikroKopter.de) must be
// + clearly linked as origin
// + * If sources or documentations are redistributet on other webpages, our webpage (http://www.MikroKopter.de) must be
// + clearly linked as origin
// + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52,236 → 52,249
// + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// + POSSIBILITY OF SUCH DAMAGE.
// + POSSIBILITY OF SUCH DAMAGE.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include <avr/interrupt.h>
#include <math.h>
#include <stdlib.h>
 
signed int OffsetN, OffsetR, OffsetZ;
 
signed int RawMagnet1a,RawMagnet1b; // raw AD-Data
signed int RawMagnet2a,RawMagnet2b;
signed int RawMagnet3a,RawMagnet3b;
signed int Xmin = 0, Xmax = 0; Ymin = 0, Ymax = 0; Zmin = 0, Zmax = 0;
signed int UncalMagnetN,UncalMagnetR,UncalMagnetZ; // Messwert-Delta ohne Offset- und Verstärker korrektur
signed int MagnetN,MagnetR,MagnetZ;
unsigned int PwmHeading = 0;
unsigned int PC_Connected = 0;
unsigned int Heading;
#include "main.h"
#include "timer0.h"
#include "twislave.h"
#include "led.h"
#include "analog.h"
#include "uart.h"
 
uint16_t eeXmin EEMEM = 0;
uint16_t eeXmax EEMEM = 0;
uint16_t eeYmin EEMEM = 0;
uint16_t eeYmax EEMEM = 0;
uint16_t eeZmin EEMEM = 0;
uint16_t eeZmax EEMEM = 0;
 
int16_t RawMagnet1a, RawMagnet1b; // raw AD-Data
int16_t RawMagnet2a, RawMagnet2b;
int16_t RawMagnet3a, RawMagnet3b;
 
//############################################################################
//
void Wait(unsigned char dauer)
//############################################################################
typedef struct
{
dauer = (unsigned char)TCNT0 + dauer;
while((TCNT0 - dauer) & 0x80);
}
int16_t Range;
int16_t Offset;
} Scaling_t;
 
typedef struct
{
Scaling_t X;
Scaling_t Y;
Scaling_t Z;
} Calibration_t;
 
Calibration_t eeCalibration EEMEM; // calibration data in EEProm
Calibration_t Calibration; // calibration data in RAM
 
 
int16_t UncalMagnetX, UncalMagnetY, UncalMagnetZ; // sensor signal difference without Scaling
int16_t MagnetX, MagnetY, MagnetZ; // rescaled magnetic field readings
 
uint8_t PC_Connected = 0;
 
int16_t Heading;
 
 
void CalcFields(void)
{
UncalMagnetN = (1 * UncalMagnetN + (RawMagnet1a - RawMagnet1b)) / 2;
UncalMagnetR = (1 * UncalMagnetR + (RawMagnet3a - RawMagnet3b)) / 2;
UncalMagnetZ = (1 * UncalMagnetZ + (RawMagnet2a - RawMagnet2b)) / 2;
UncalMagnetX = (1 * UncalMagnetX + (RawMagnet1a - RawMagnet1b)) / 2;
UncalMagnetY = (1 * UncalMagnetY + (RawMagnet3a - RawMagnet3b)) / 2;
UncalMagnetZ = (1 * UncalMagnetZ + (RawMagnet2a - RawMagnet2b)) / 2;
 
OffsetN = (Xmin + Xmax) / 2;
OffsetR = (Ymin + Ymax) / 2;
OffsetZ = (Zmin + Zmax) / 2;
 
MagnetN = (1024L * (long)(UncalMagnetN - OffsetN)) / (Xmax - Xmin);
MagnetR = (1024L * (long)(UncalMagnetR - OffsetR)) / (Ymax - Ymin);
MagnetZ = (1024L * (long)(UncalMagnetZ - OffsetZ)) / (Zmax - Zmin);
MagnetX = (1024L * (int32_t)(UncalMagnetX - Calibration.X.Offset)) / (Calibration.X.Range);
MagnetY = (1024L * (int32_t)(UncalMagnetY - Calibration.Y.Offset)) / (Calibration.Y.Range);
MagnetZ = (1024L * (int32_t)(UncalMagnetZ - Calibration.Z.Offset)) / (Calibration.Z.Range);
}
 
void CalcHeading(void)
{
double nick_rad, roll_rad, Hx, Hy, Cx, Cy, Cz;
int heading;
nick_rad = ((double)ExternData.Winkel[0]) * M_PI / (double)(1800);
roll_rad = ((double)ExternData.Winkel[1]) * M_PI / (double)(1800);
double nick_rad, roll_rad, Hx, Hy, Cx, Cy, Cz;
int16_t heading = -1;
 
Cx = MagnetN;
Cy = MagnetR;
Cz = MagnetZ;
// calculate nick and roll angle i rad
nick_rad = ((double)ExternData.Attitude[NICK]) * M_PI / (double)(1800);
roll_rad = ((double)ExternData.Attitude[ROLL]) * M_PI / (double)(1800);
 
if(ExternData.Orientation == 1)
{
Cx = MagnetR;
Cy = -MagnetN;
Cz = MagnetZ;
}
Cx = MagnetX;
Cy = MagnetY;
Cz = MagnetZ;
 
Hx = Cx * (double)cos(nick_rad) +
Cy * (double)sin(nick_rad) * (double)sin(roll_rad) -
Cz * (double)sin(nick_rad) * (double)cos(roll_rad);
Hy = Cy * (double)cos(roll_rad) +
Cz * (double)sin(roll_rad);
if(Hx == 0 && Hy < 0) heading = 90;
else if(Hx == 0 && Hy > 0) heading = 270;
else if(Hx < 0) heading = 180 - (atan(Hy / Hx) * 180.0) / M_PI;
else if(Hx > 0 && Hy < 0) heading = - (atan(Hy / Hx) * 180.0) / M_PI;
else if(Hx > 0 && Hy > 0) heading = 360 - (atan(Hy / Hx) * 180.0) / M_PI;
if(ExternData.Orientation == 1)
{
Cx = MagnetX;
Cy = -MagnetY;
Cz = MagnetZ;
}
 
if(abs(heading) < 361) Heading = heading;
PwmHeading = Heading + 10;
Hx = Cx * (double)cos(nick_rad) +
Cy * (double)sin(nick_rad) * (double)sin(roll_rad) -
Cz * (double)sin(nick_rad) * (double)cos(roll_rad);
 
Hy = Cy * (double)cos(roll_rad) +
Cz * (double)sin(roll_rad);
 
 
if(Hx == 0 && Hy < 0) heading = 90;
else if(Hx == 0 && Hy > 0) heading = 270;
else if(Hx < 0) heading = 180 - (atan(Hy / Hx) * 180.0) / M_PI;
else if(Hx > 0 && Hy < 0) heading = - (atan(Hy / Hx) * 180.0) / M_PI;
else if(Hx > 0 && Hy > 0) heading = 360 - (atan(Hy / Hx) * 180.0) / M_PI;
 
if(abs(heading) < 361) Heading = heading;
 
}
 
 
void Calibrate(void)
{
unsigned char cal;
if(I2C_WriteCal.CalByte) cal = I2C_WriteCal.CalByte;
else cal = ExternData.CalState;
switch(cal)
{
case 0:
LED_ON;
break;
case 1:
Xmin = 10000;
Xmax = -10000;
Ymin = 10000;
Ymax = -10000;
Zmin = 10000;
Zmax = -10000;
LED_OFF;
break;
case 2:
LED_ON; // find Min and Max of the X- and Y-Sensors
if(UncalMagnetN < Xmin) Xmin = UncalMagnetN;
if(UncalMagnetN > Xmax) Xmax = UncalMagnetN;
if(UncalMagnetR < Ymin) Ymin = UncalMagnetR;
if(UncalMagnetR > Ymax) Ymax = UncalMagnetR;
break;
case 3:
LED_OFF;
break;
case 4:
LED_ON; // find Min and Max of the Z-Sensor
if(UncalMagnetZ < Zmin) Zmin = UncalMagnetZ;
if(UncalMagnetZ > Zmax) Zmax = UncalMagnetZ;
break;
case 5:
LED_OFF; // Save values
if((Xmax - Xmin) > 150 && (Ymax - Ymin) > 150 && (Zmax - Zmin) > 150)
{
eeprom_write_word(&eeXmin, Xmin);
eeprom_write_word(&eeXmax, Xmax);
eeprom_write_word(&eeYmin, Ymin);
eeprom_write_word(&eeYmax, Ymax);
eeprom_write_word(&eeZmin, Zmin);
eeprom_write_word(&eeZmax, Zmax);
Delay_ms(2000);
}
LED_ON;
break;
}
uint8_t cal;
static int16_t Xmin = 0, Xmax = 0, Ymin = 0, Ymax = 0, Zmin = 0, Zmax = 0;
 
// check both sources of communication for calibration request
if(I2C_WriteCal.CalByte) cal = I2C_WriteCal.CalByte;
else cal = ExternData.CalState;
 
// calibration state machine
switch(cal)
{
case 0: // no calibration
LED_GRN_ON;
break;
 
case 1: // 1st step of calibration
// initialize ranges
// used to change the orientation of the MK3MAG in the horizontal plane
LED_GRN_OFF;
Xmin = 10000;
Xmax = -10000;
Ymin = 10000;
Ymax = -10000;
Zmin = 10000;
Zmax = -10000;
break;
 
case 2: // 2nd step of calibration
// find Min and Max of the X- and Y-Sensors during rotation in the horizontal plane
LED_GRN_ON;
if(UncalMagnetX < Xmin) Xmin = UncalMagnetX;
if(UncalMagnetX > Xmax) Xmax = UncalMagnetX;
if(UncalMagnetY < Ymin) Ymin = UncalMagnetY;
if(UncalMagnetY > Ymax) Ymax = UncalMagnetY;
break;
 
case 3: // 3rd step of calibration
// used to change the orietation of the MK3MAG vertical to the horizontal plane
LED_GRN_OFF;
break;
 
case 4:
// find Min and Max of the Z-Sensor
LED_GRN_ON;
if(UncalMagnetZ < Zmin) Zmin = UncalMagnetZ;
if(UncalMagnetZ > Zmax) Zmax = UncalMagnetZ;
break;
 
case 5:
LED_GRN_OFF; // Save values
Calibration.X.Range = Xmax - Xmin;
Calibration.X.Offset = (Xmin + Xmax) / 2;
Calibration.Y.Range = Ymax - Ymin;
Calibration.Y.Offset = (Ymin + Ymax) / 2;
Calibration.Z.Range = Zmax - Zmin;
Calibration.Z.Offset = (Zmin + Zmax) / 2;
if((Calibration.X.Range > 150) && (Calibration.Y.Range > 150) && (Calibration.Z.Range > 150))
{
eeprom_write_block(&Calibration, &eeCalibration, sizeof(Calibration_t));
Delay_ms(2000);
}
LED_GRN_ON;
break;
 
default:
LED_GRN_ON;
break;
}
}
 
 
void SetDebugValues(void)
{
DebugOut.Analog[0] = MagnetN;
DebugOut.Analog[1] = MagnetR;
DebugOut.Analog[2] = MagnetZ;
DebugOut.Analog[3] = UncalMagnetN;
DebugOut.Analog[4] = UncalMagnetR;
DebugOut.Analog[5] = UncalMagnetZ;
DebugOut.Analog[6] = ExternData.Winkel[0];
DebugOut.Analog[7] = ExternData.Winkel[1];
DebugOut.Analog[8] = Xmin;
DebugOut.Analog[9] = Xmax;
DebugOut.Analog[10] = Ymin;
DebugOut.Analog[11] = Ymax;
DebugOut.Analog[12] = Zmin;
DebugOut.Analog[13] = Zmax;
DebugOut.Analog[14] = ExternData.CalState;
DebugOut.Analog[15] = Heading;
DebugOut.Analog[16] = ExternData.UserParameter[0];
DebugOut.Analog[17] = ExternData.UserParameter[1];
DebugOut.Analog[0] = MagnetX;
DebugOut.Analog[1] = MagnetY;
DebugOut.Analog[2] = MagnetZ;
DebugOut.Analog[3] = UncalMagnetX;
DebugOut.Analog[4] = UncalMagnetY;
DebugOut.Analog[5] = UncalMagnetZ;
DebugOut.Analog[6] = ExternData.Attitude[NICK];
DebugOut.Analog[7] = ExternData.Attitude[ROLL];
DebugOut.Analog[8] = Calibration.X.Offset;
DebugOut.Analog[9] = Calibration.X.Range;
DebugOut.Analog[10] = Calibration.Y.Offset;
DebugOut.Analog[11] = Calibration.Y.Range;
DebugOut.Analog[12] = Calibration.Z.Offset;
DebugOut.Analog[13] = Calibration.Z.Range;
DebugOut.Analog[14] = ExternData.CalState;
DebugOut.Analog[15] = Heading;
DebugOut.Analog[16] = ExternData.UserParam[0];
DebugOut.Analog[17] = ExternData.UserParam[1];
}
 
 
//############################################################################
//Hauptprogramm
int main (void)
//############################################################################
{
DDRC = 0x08;
PORTC = 0x08;
DDRD = 0xf4;
PORTD = 0xA0;
DDRB = 0x04;
PORTB = 0x35;
LED_ON;
UART_Init();
Timer0_Init();
Led_Init();
LED_GRN_ON;
TIMER0_Init();
USART0_Init();
ADC_Init();
InitIC2_Slave();
sei();//Globale Interrupts Einschalten
Debug_Timer = SetDelay(100); // Sendeintervall
Xmin = eeprom_read_word(&eeXmin);
Xmax = eeprom_read_word(&eeXmax);
Ymin = eeprom_read_word(&eeYmin);
Ymax = eeprom_read_word(&eeYmax);
Zmin = eeprom_read_word(&eeZmin);
Zmax = eeprom_read_word(&eeZmax);
I2C_Init();
 
VersionInfo.Hauptversion = VERSION_HAUPTVERSION;
VersionInfo.Nebenversion = VERSION_NEBENVERSION;
VersionInfo.PCKompatibel = 7;
sei(); //Globale Interrupts Einschalten
 
Debug_Timer = SetDelay(100); // Sendeintervall
 
// read calibration info from eeprom
eeprom_read_block(&Calibration, &eeCalibration, sizeof(Calibration_t));
 
ExternData.Orientation = 0;
ExternData.CalState = 0;
I2C_WriteCal.CalByte = 0;
 
// main loop
while (1)
{
FLIP_LOW;
Delay_ms(2);
RawMagnet1a = MessAD(0);
RawMagnet2a = -MessAD(1);
RawMagnet3a = MessAD(7);
Delay_ms(1);
{
FLIP_LOW;
Delay_ms(2);
RawMagnet1a = ADC_GetValue(ADC0);
RawMagnet2a = -ADC_GetValue(ADC1);
RawMagnet3a = ADC_GetValue(ADC7);
Delay_ms(1);
 
FLIP_HIGH;
Delay_ms(2);
RawMagnet1b = MessAD(0);
RawMagnet2b = -MessAD(1);
RawMagnet3b = MessAD(7);
Delay_ms(1);
FLIP_HIGH;
Delay_ms(2);
RawMagnet1b = ADC_GetValue(ADC0);
RawMagnet2b = -ADC_GetValue(ADC1);
RawMagnet3b = ADC_GetValue(ADC7);
Delay_ms(1);
 
CalcFields();
if(ExternData.CalState || I2C_WriteCal.CalByte) Calibrate();
else CalcHeading();
BearbeiteRxDaten();
CalcFields();
 
if(PC_Connected)
{
DDRD |= 0x02; // TXD-Portpin
UCR |= (1 << TXEN);
DatenUebertragung();
PC_Connected--;
}
else
{
UCR &= ~(1 << TXEN);
DDRD &= ~0x02; // TXD-Portpin
}
} // while(1)
if(ExternData.CalState || I2C_WriteCal.CalByte) Calibrate();
else CalcHeading();
 
// check data from USART
USART0_ProcessRxData();
 
if(PC_Connected)
{
USART0_EnableTXD();
USART0_TransmitTxData();
PC_Connected--;
}
else
{
USART0_DisableTXD();
}
} // while(1)
}
 
/branches/MK3Mag V0.14 Code Redesign Killagreg/main.h
1,74 → 1,24
#ifndef _MAIN_H
#define _MAIN_H
#ifndef _MAIN_H_
#define _MAIN_H_
 
 
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <avr/boot.h>
#include <avr/wdt.h>
#include <avr/eeprom.h>
#include <inttypes.h>
 
#include "twislave.h"
#include "old_macros.h"
#include "analog.h"
#include "uart.h"
#include "timer0.h"
 
 
#if defined(__AVR_ATmega8__)
# define OC1 PB1
# define DDROC DDRB
# define OCR OCR1A
# define PWM10 WGM10
# define PWM11 WGM11
#endif
 
#define SYSCLK 8000000L //Quarz Frequenz in Hz
 
#define INT0_ENABLE GIMSK |= 0x40
#define INT0_DISABLE GIMSK &= ~0x40
#define TIM0_START TIMSK0 |= _BV(TOIE0)
#define TIM0_STOPP TIMSK0 &= ~_BV(TOIE0)
 
#define ICP_INT_ENABLE TIMSK0 |= 0x20
#define ICP_INT_DISABLE TIMSK0 &= ~0x20
#define TIMER1_INT_ENABLE TIMSK0 |= 0x04
#define TIMER1_INT_DISABLE TIMSK0 &= ~0x04
#define TIMER2_INT_ENABLE TIMSK0 |= 0x40
#define TIMER2_INT_DISABLE TIMSK0 &= ~0x40
#define INT0_POS_FLANKE MCUCR |= 0x01
#define INT0_ANY_FLANKE MCUCR |= 0x01
#define INT0_NEG_FLANKE MCUCR &= ~0x01
#define CLR_INT0_FLAG GIFR &= ~0x40
#define INIT_INT0_FLANKE MCUCR &= ~0x03; MCUCR |= 0x02;
#define TIMER0_PRESCALER TCCR0
#define ICP_POS_FLANKE TCCR1B |= (1<<ICES1)
#define ICP_NEG_FLANKE TCCR1B &= ~(1<<ICES1)
extern uint8_t PC_Connected;
 
#define LED_ON PORTD |= 0x80
#define LED_OFF PORTD &= ~0x80
#define FLIP_HIGH PORTD |= 0x60
#define FLIP_LOW PORTD &= ~0x60
extern int16_t Heading;
 
extern unsigned int PwmHeading;
extern unsigned int PC_Connected;
extern unsigned int Heading;
extern signed int MagnetN,MagnetR,MagnetZ;
extern int16_t MagnetX, MagnetY, MagnetZ;
 
extern uint16_t eeXmin EEMEM;
extern uint16_t eeXmax EEMEM;
extern uint16_t eeYmin EEMEM;
extern uint16_t eeYmax EEMEM;
extern uint16_t eeZmin EEMEM;
extern uint16_t eeZmax EEMEM;
void SetDebugValues(void);
 
#endif //_MAIN_H
#endif //_MAIN_H_
 
 
 
/branches/MK3Mag V0.14 Code Redesign Killagreg/makefile
2,8 → 2,10
# MCU name
MCU = atmega168
#-------------------------------------------------------------------
HAUPT_VERSION = 0
NEBEN_VERSION = 14
VERSION_MAJOR = 0
VERSION_MINOR = 14
 
VERSION_COMPATIBLE = 8 # PC-Kompatibilität
#-------------------------------------------------------------------
 
# Output format. (can be srec, ihex, binary)
10,7 → 12,7
FORMAT = ihex
 
# Target file name (without extension).
TARGET = MK3Mag_MEGA168_V$(HAUPT_VERSION)_$(NEBEN_VERSION)
TARGET = MK3Mag_MEGA168_V$(VERSION_MAJOR)_$(VERSION_MINOR)
 
# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
18,20 → 20,10
 
##########################################################################################################
# List C source files here. (C dependencies are automatically generated.)
SRC = main.c uart.c timer0.c analog.c twislave.c
#printf_P.c
SRC = main.c uart.c timer0.c analog.c twislave.c led.c
##########################################################################################################
 
# If there is more than one source file, append them above, or modify and
# uncomment the following:
#SRC += foo.c bar.c
 
# You can also wrap lines by appending a backslash to the end of the line:
#SRC += baz.c \
#xyzzy.c
 
 
 
# List Assembler source files here.
# Make them always end in a capital .S. Files ending in a lowercase .s
# will not be considered source files but generated files (assembler
69,7 → 61,7
#CFLAGS += -std=c99
CFLAGS += -std=gnu99
 
CFLAGS += -DVERSION_HAUPTVERSION=$(HAUPT_VERSION) -DVERSION_NEBENVERSION=$(NEBEN_VERSION)
CFLAGS += -DVERSION_MAJOR=$(VERSION_MAJOR) -DVERSION_MINOR=$(VERSION_MINOR) -DVERSION_COMPATIBLE=$(VERSION_COMPATIBLE)
 
ifeq ($(AVR_CTRL_PLATINE), 1)
CFLAGS += -DAVR_CTRL_PLATINE=$(AVR_CTRL_PLATINE)
/branches/MK3Mag V0.14 Code Redesign Killagreg/timer0.c
1,6 → 1,6
/*#######################################################################################
MK3Mag 3D-Magnet sensor
!!! THIS IS NOT FREE SOFTWARE !!!
!!! THIS IS NOT FREE SOFTWARE !!!
#######################################################################################*/
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Copyright (c) 05.2008 Holger Buss
8,15 → 8,15
// + Nur für den privaten Gebrauch
// + www.MikroKopter.com
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + mit unserer Zustimmung zulässig
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
// + AUSNAHME: Ein bei www.mikrokopter.de erworbener vorbestückter MK3Mag darf als Baugruppe auch in kommerziellen Systemen verbaut werden
// + Im Zweifelsfall bitte anfragen bei: info@mikrokopter.de
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
29,19 → 29,19
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
// + this list of conditions and the following disclaimer.
// + * PORTING this software (or parts of it) to systems (other than hardware from www.mikrokopter.de) is NOT allowed
// + * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
// + from this software without specific prior written permission.
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
// + for non-commercial use (directly or indirectly)
// + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
// + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
// + with our written permission
// + Exception: A preassembled MK3Mag, purchased from www.mikrokopter.de may be used as a part of commercial systems
// + In case of doubt please contact: info@MikroKopter.de
// + * If sources or documentations are redistributet on other webpages, our webpage (http://www.MikroKopter.de) must be
// + clearly linked as origin
// + * If sources or documentations are redistributet on other webpages, our webpage (http://www.MikroKopter.de) must be
// + clearly linked as origin
// + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52,77 → 52,125
// + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// + POSSIBILITY OF SUCH DAMAGE.
// + POSSIBILITY OF SUCH DAMAGE.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "main.h"
volatile unsigned int CountMilliseconds = 0;
volatile unsigned char Timer0Overflow;
unsigned int I2C_Timeout = 0;
unsigned int SIO_Timeout = 0;
 
enum {
STOP = 0,
CK = 1,
CK8 = 2,
CK64 = 3,
CK256 = 4,
CK1024 = 5,
T0_FALLING_EDGE = 6,
T0_RISING_EDGE = 7
};
volatile uint16_t CountMilliseconds = 0;
volatile uint16_t I2C_Timeout = 0;
 
 
SIGNAL(SIG_OVERFLOW0)
/*****************************************************/
/* Initialize Timer 0 */
/*****************************************************/
void TIMER0_Init(void)
{
static unsigned char cnt;
static unsigned int cmps_cnt;
TCNT0 -= 101; // reload
Timer0Overflow++;
uint8_t sreg = SREG;
 
if(++cmps_cnt == 380)
{
PORTB |= 0x04;
cmps_cnt = 0;
}
else
if(cmps_cnt == PwmHeading)
{
PORTB &= ~0x04;
}
if(!--cnt)
{
cnt = 10;
CountMilliseconds += 1;
if(I2C_Timeout) I2C_Timeout--;
if(SIO_Timeout) SIO_Timeout--;
}
// disable all interrupts before reconfiguration
cli();
 
// set PB2 as output for the PWM used to signal compass heading
DDRB |= (1<<DDB2);
PORTB &= ~(1<<PORTB2);
 
 
// Timer/Counter 0 Control Register A
 
// Normal Timer Counter Mode (Bits WGM02 = 0, WGM01 = 0, WGM00 = 0)
// OC0A disconnected (Bits COM0A1 = 0, COM0A0 = 0)
// OC0B disconnected (Bits COM0B1 = 0, COM0B0 = 0)
TCCR0A &= ~((1<<COM0A1)|(1<<COM0A0)|(1<<COM0B1)|(1<<COM0B0)|(1<<WGM01)|(1<<WGM00));
 
// Timer/Counter 0 Control Register B
 
// set clock devider for timer 0 to SYSKLOCK/8 = 8MHz / 8 = 1MHz
// i.e. the timer increments from 0x00 to 0xFF with an update rate of 2.5 MHz
// hence the timer overflow interrupt frequency is 2.5 MHz / 256 = 9.765 kHz
 
// divider 8 (Bits CS02 = 0, CS01 = 1, CS00 = 0)
TCCR0B &= ~((1<<FOC0A)|(1<<FOC0B)|(1<<WGM02)|(1<<CS02));
TCCR0B = (1<<CS01)|(0<<CS00);
 
// init Timer/Counter 0 Register
TCNT0 = 0;
 
// Timer/Counter 0 Interrupt Mask Register
// enable timer overflow interrupt only
TIMSK0 &= ~((1<<OCIE0B)|(1<<OCIE0A));
TIMSK0 |= (1<<TOIE0);
 
SREG = sreg;
}
 
 
void Timer0_Init(void)
// -----------------------------------------------------------------------
ISR(TIMER0_OVF_vect)
{
TCCR0B = TIMER_TEILER; // Starten des Timers
// TCNT0 = 100; // reload
TIM0_START;
TIMER2_INT_ENABLE;
static uint8_t cnt;
static uint16_t cmps_cnt;
 
// reload timer register so that overflow occurs after 100 increments at 1 MHz
// resulting in a calling rate of this ISR of 10kHz or 0.1 ms.
TCNT0 -= 101;
 
// disable PWM when bad compass heading value
if(Heading < 0)
{
PORTB &= ~(PORTB2);
cmps_cnt = 0;
}
else
{
// if a periode of 38.0 ms is over
if(++cmps_cnt >= 380)
{
// set PWM out to high
PORTB |= PORTB2;
// reset periode counter
cmps_cnt = 0;
}
// if the delay in 0.1 ms is equal to Heading + 10
else if(cmps_cnt >= (Heading + 10))
{
// set PWM out to low
PORTB &= ~(PORTB2);
}
}
 
if(!--cnt)
{
// every 10th run (1kHz or 1ms)
cnt = 10;
CountMilliseconds++;
if(I2C_Timeout) I2C_Timeout--;
}
}
 
 
unsigned int SetDelay(unsigned int t)
// -----------------------------------------------------------------------
uint16_t SetDelay (uint16_t t)
{
return(CountMilliseconds + t - 1);
return(CountMilliseconds + t - 1);
}
 
char CheckDelay (unsigned int t)
// -----------------------------------------------------------------------
int8_t CheckDelay(uint16_t t)
{
return(((t - CountMilliseconds) & 0x8000) >> 8);
return(((t - CountMilliseconds) & 0x8000) >> 8); // check sign bit
}
 
void Delay_ms(unsigned int w)
// -----------------------------------------------------------------------
void Delay_ms(uint16_t wait)
{
unsigned int akt;
akt = SetDelay(w);
while (!CheckDelay(akt));
uint16_t t_stop;
t_stop = SetDelay(wait);
while (!CheckDelay(t_stop));
}
 
 
 
 
/branches/MK3Mag V0.14 Code Redesign Killagreg/timer0.h
1,15 → 1,22
#define TIMER_TEILER CK8
//#define TIMER_RELOAD_VALUE 125
#ifndef _TIMER0_H
#define _TIMER0_H
 
#include <inttypes.h>
 
extern volatile unsigned int CountMilliseconds;
extern volatile unsigned char Timer0Overflow;
extern unsigned int I2C_Timeout;
extern unsigned int SIO_Timeout;
extern volatile uint16_t CountMilliseconds;
extern volatile uint16_t I2C_Timeout;
 
 
void Timer1_Init(void);
void Delay_ms(unsigned int);
unsigned int SetDelay (unsigned int t);
char CheckDelay (unsigned int t);
void TIMER0_Init(void);
uint16_t SetDelay (uint16_t t);
int8_t CheckDelay(uint16_t t);
void Delay_ms(uint16_t wait);
 
 
#endif //_TIMER0_H
 
 
 
 
 
 
/branches/MK3Mag V0.14 Code Redesign Killagreg/twislave.c
1,6 → 1,6
/*#######################################################################################
MK3Mag 3D-Magnet sensor
!!! THIS IS NOT FREE SOFTWARE !!!
!!! THIS IS NOT FREE SOFTWARE !!!
#######################################################################################*/
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Copyright (c) 05.2008 Holger Buss
8,15 → 8,15
// + Nur für den privaten Gebrauch
// + www.MikroKopter.com
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + mit unserer Zustimmung zulässig
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
// + AUSNAHME: Ein bei www.mikrokopter.de erworbener vorbestückter MK3Mag darf als Baugruppe auch in kommerziellen Systemen verbaut werden
// + Im Zweifelsfall bitte anfragen bei: info@mikrokopter.de
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
29,19 → 29,19
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
// + this list of conditions and the following disclaimer.
// + * PORTING this software (or parts of it) to systems (other than hardware from www.mikrokopter.de) is NOT allowed
// + * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
// + from this software without specific prior written permission.
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
// + for non-commercial use (directly or indirectly)
// + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
// + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
// + with our written permission
// + Exception: A preassembled MK3Mag, purchased from www.mikrokopter.de may be used as a part of commercial systems
// + In case of doubt please contact: info@MikroKopter.de
// + * If sources or documentations are redistributet on other webpages, our webpage (http://www.MikroKopter.de) must be
// + clearly linked as origin
// + * If sources or documentations are redistributet on other webpages, our webpage (http://www.MikroKopter.de) must be
// + clearly linked as origin
// + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52,147 → 52,197
// + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// + POSSIBILITY OF SUCH DAMAGE.
// + POSSIBILITY OF SUCH DAMAGE.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/twi.h>
#include "twislave.h"
#include "uart.h"
#include "main.h"
#include "timer0.h"
 
unsigned char I2C_RxBufferSize, I2C_TxBufferSize;
unsigned char *I2C_TxBuffer, *I2C_RxBuffer;
unsigned char Tx_Idx=0, Rx_Idx=0, I2C_Direction;
unsigned char I2C_Command;
unsigned char Tx_Idx, Rx_Idx;
#define TWI_BUS_ERR_1 0x00
#define TWI_BUS_ERR_2 0xF8
 
struct str_I2C_Heading I2C_Heading;
struct str_I2C_WriteNickRoll I2C_WriteNickRoll;
struct str_I2C_Mag I2C_Mag;
struct str_I2C_EEPROM I2C_ReadEEPROM, I2C_WriteEEPROM;
struct str_I2C_Version I2C_Version;
struct str_I2C_WriteCal I2C_WriteCal;
// Status Slave RX Mode
#define SR_SLA_ACK 0x60
#define SR_LOST_ACK 0x68
#define SR_GEN_CALL_ACK 0x70
#define GEN_LOST_ACK 0x78
#define SR_PREV_ACK 0x80
#define SR_PREV_NACK 0x88
#define GEN_PREV_ACK 0x90
#define GEN_PREV_NACK 0x98
#define STOP_CONDITION 0xA0
#define REPEATED_START 0xA0
 
// Status Slave TX mode
#define SW_SLA_ACK 0xA8
#define SW_LOST_ACK 0xB0
#define SW_DATA_ACK 0xB8
#define SW_DATA_NACK 0xC0
#define SW_LAST_ACK 0xC8
 
 
//############################################################################
//I2C (TWI) Interface Init
void InitIC2_Slave(void)
//############################################################################
{
TWAR = I2C_SLAVE_ADDRESS; // Eigene Adresse setzen
uint8_t I2C_RxBufferSize, I2C_TxBufferSize;
uint8_t *I2C_TxBuffer, *I2C_RxBuffer;
uint8_t Tx_Idx = 0, Rx_Idx = 0, I2C_Direction;
uint8_t I2C_Command;
 
 
I2C_Heading_t I2C_Heading;
I2C_WriteAttitude_t I2C_WriteAttitude;
I2C_Mag_t I2C_Mag;
I2C_EEPROM_t I2C_ReadEEPROM, I2C_WriteEEPROM;
I2C_Version_t I2C_Version;
I2C_WriteCal_t I2C_WriteCal;
 
 
void I2C_Init(void)
{
uint8_t sreg = SREG;
cli();
 
//SPI SCK/SCL and MISO/SDA are at put together on the same connector pin in the schematic
 
// set PB4 (SCK) and PB5 (MISO) as input pull up
DDRB &= ~((1<<DDB4)|(1<<DDB5));
PORTB |= ((1<<PORTB4)|(1<<PORTB5));
 
// set PC4 (SDA) and PC5 (SCL) as input pull up
DDRC &= ~((1<<DDC4)|(1<<DDC5));
PORTC |= ((1<<PORTC4)|(1<<PORTC5));
 
// set own address
TWAR = I2C_SLAVE_ADDRESS; // set own address
// TWI Control Register
// clear TWI interrupt flag (TWINT=1)
// enable TWI Acknowledge Bit (TWEA = 1)
// disable TWI START Condition Bit (TWSTA = 0), SLAVE
// disable TWI STOP Condition Bit (TWSTO = 0), SLAVE
// disable TWI Write Collision Flag (TWWC = 0)
// enable i2c (TWEN = 1)
// enable TWI Interrupt (TWIE = 1)
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWEA);
I2C_Version.Hauptversion = VersionInfo.Hauptversion;
I2C_Version.Nebenversion = VersionInfo.Nebenversion;
I2C_Version.Comp = 1;
// update version info
I2C_Version.Major = VERSION_MAJOR;
I2C_Version.Minor = VERSION_MINOR;
I2C_Version.Compatible = I2C_PROTOCOL_COMP;
 
SREG = sreg;
}
 
 
 
#define TWCR_ACK TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|(0<<TWWC)
//############################################################################
//ISR, die bei einem Ereignis auf dem Bus ausgelöst wird. Im Register TWSR befindet
//sich dann ein Statuscode, anhand dessen die Situation festgestellt werden kann.
 
ISR (TWI_vect)
//############################################################################
{
switch (TWSR & 0xF8)
{
case SR_SLA_ACK:
//TWCR |= (1<<TWINT);
{
// check event
switch (TWSR & 0xF8)
{
case SR_SLA_ACK:
Rx_Idx = 0;
TWCR_ACK;
return;
// Daten Empfangen
case SR_PREV_ACK:
if (Rx_Idx == 0)
{ I2C_Command = TWDR;
switch(I2C_Command)
{
case I2C_CMD_VERSION:
I2C_TxBuffer = (unsigned char *)&I2C_Version;
 
case SR_PREV_ACK: // data byte received
 
if (Rx_Idx == 0)
{
I2C_Command = TWDR;
 
switch(I2C_Command)
{
case I2C_CMD_VERSION:
I2C_TxBuffer = (uint8_t *)&I2C_Version;
I2C_TxBufferSize = sizeof(I2C_Version);
I2C_RxBufferSize = 0;
break;
case I2C_CMD_WRITE_EEPROM:
break;
 
case I2C_CMD_WRITE_EEPROM:
I2C_TxBufferSize = 0;
I2C_RxBuffer = (unsigned char *)&I2C_WriteEEPROM;
I2C_RxBuffer = (uint8_t *)&I2C_WriteEEPROM;
I2C_RxBufferSize = sizeof(I2C_WriteEEPROM);
break;
break;
 
case I2C_CMD_WRITE_CAL:
case I2C_CMD_WRITE_CAL:
I2C_TxBufferSize = 0;
I2C_RxBuffer = (unsigned char *)&I2C_WriteCal;
I2C_RxBuffer = (uint8_t *)&I2C_WriteCal;
I2C_RxBufferSize = sizeof(I2C_WriteCal);
break;
break;
 
case I2C_CMD_READ_EEPROM:
I2C_TxBuffer = (unsigned char *)&I2C_ReadEEPROM.Inhalt;
case I2C_CMD_READ_EEPROM:
I2C_TxBuffer = (uint8_t *)&I2C_ReadEEPROM.Content;
I2C_TxBufferSize = 2;
I2C_RxBuffer = (unsigned char *)&I2C_ReadEEPROM;
I2C_RxBuffer = (uint8_t *)&I2C_ReadEEPROM;
I2C_RxBufferSize = 1;
break;
case I2C_CMD_READ_MAG:
I2C_TxBuffer = (unsigned char *)&I2C_Mag;
break;
 
case I2C_CMD_READ_MAG:
I2C_TxBuffer = (uint8_t *)&I2C_Mag;
I2C_TxBufferSize = sizeof(I2C_Mag);
I2C_RxBufferSize = 0;
I2C_Mag.MagX = MagnetN;
I2C_Mag.MagY = MagnetR;
 
I2C_Mag.MagX = MagnetX;
I2C_Mag.MagY = MagnetY;
I2C_Mag.MagZ = MagnetZ;
break;
case I2C_CMD_READ_HEADING:
I2C_TxBuffer = (unsigned char *)&I2C_Heading;
break;
 
case I2C_CMD_READ_HEADING:
I2C_TxBuffer = (uint8_t *)&I2C_Heading;
I2C_TxBufferSize = sizeof(I2C_Heading);
I2C_RxBuffer = (unsigned char *)&I2C_WriteNickRoll;
I2C_RxBufferSize = sizeof(I2C_WriteNickRoll);
I2C_RxBuffer = (uint8_t *)&I2C_WriteAttitude;
I2C_RxBufferSize = sizeof(I2C_WriteAttitude);
// update heading from global variable
I2C_Heading.Heading = Heading;
ExternData.Winkel[NICK] = I2C_WriteNickRoll.Nick;
ExternData.Winkel[ROLL] = I2C_WriteNickRoll.Roll;
break;
}
// copy current attitude from I2C rx buffer to uart rx buffer (this is used for the calulation of the heading)
ExternData.Attitude[NICK] = I2C_WriteAttitude.Nick;
ExternData.Attitude[ROLL] = I2C_WriteAttitude.Roll;
break;
}
}
else
else // Rx_Idx != 0
{
if ((Rx_Idx-1) < I2C_RxBufferSize) I2C_RxBuffer[Rx_Idx-1] = TWDR;
// fill receiver buffer
if ((Rx_Idx - 1) < I2C_RxBufferSize) I2C_RxBuffer[Rx_Idx - 1] = TWDR;
}
// next byte
Rx_Idx++;
 
I2C_Timeout = 500;
//TWCR |= (1<<TWINT);
TWCR_ACK;
TWCR_ACK; // send acknowledge
return;
// Daten Senden
case SW_SLA_ACK:
 
case SW_SLA_ACK: // slave transmitter selected
// reset position in tx buffer
Tx_Idx = 0;
// write first bte o tx buffer to the twi data register
if (I2C_TxBufferSize > 0) TWDR = I2C_TxBuffer[Tx_Idx++];
// TWCR |= (1<<TWINT) | (1<< TWEA);
TWCR_ACK;
return;
// Daten Senden
case SW_DATA_ACK:
// send acknowledge
TWCR_ACK;
return;
 
case SW_DATA_ACK: // send data byte
// put next byte from tx buffer to twi data register
if (Tx_Idx < I2C_TxBufferSize) TWDR = I2C_TxBuffer[Tx_Idx++];
else TWDR = 0x00;
//TWCR |= (1<<TWINT) | (1<< TWEA);
TWCR_ACK;
return;
// Bus-Fehler zurücksetzen
else TWDR = 0x00;
TWCR_ACK; // send acknowledge
return;
 
// clear Bus-Error
case TWI_BUS_ERR_2:
TWCR |=(1<<TWSTO) | (1<<TWINT);
// Bus-Fehler zurücksetzen
TWCR |=(1<<TWSTO) | (1<<TWINT);
// clear Bus-Error
case TWI_BUS_ERR_1:
TWCR |=(1<<TWSTO) | (1<<TWINT);
}
TWCR =(1<<TWEA) | (1<<TWINT) | (1<<TWEN) | (1<<TWIE); // TWI Reset
TWCR |=(1<<TWSTO) | (1<<TWINT);
}
// clear interrupt flag (TWINT = 1)
// enable TWI Acknowledge Bit (TWEA = 1)
// enable TWI (TWEN = 1)
// enable TWI interrpt (TWIE = 1)
TWCR = (1<<TWEA) | (1<<TWINT) | (1<<TWEN) | (1<<TWIE); // TWI Reset
}
 
 
/branches/MK3Mag V0.14 Code Redesign Killagreg/twislave.h
1,86 → 1,72
#ifndef _TWI_SLAVE_H_
#define _TWI_SLAVE_H_
 
#define I2C_SLAVE_ADDRESS 0x50
#include <inttypes.h>
 
#define I2C_CMD_VERSION 0x01
struct str_I2C_Version
{
unsigned char Hauptversion;
unsigned char Nebenversion;
unsigned char Comp;
} ;
#define I2C_SLAVE_ADDRESS 0x50
#define I2C_PROTOCOL_COMP 1
 
#define I2C_CMD_WRITE_EEPROM 0x0A
#define I2C_CMD_READ_EEPROM 0x0B
struct str_I2C_EEPROM
{
unsigned char Adresse;
unsigned int Inhalt;
} ;
#define I2C_CMD_VERSION 0x01
#define I2C_CMD_READ_MAG 0x02
#define I2C_CMD_READ_HEADING 0x03
#define I2C_CMD_WRITE_CAL 0x04
#define I2C_CMD_WRITE_EEPROM 0x0A
#define I2C_CMD_READ_EEPROM 0x0B
 
#define I2C_CMD_READ_MAG 0x02
struct str_I2C_Mag
 
typedef struct
{
int MagX;
int MagY;
int MagZ;
} ;
uint8_t Major;
uint8_t Minor;
uint8_t Compatible;
} I2C_Version_t;
 
#define I2C_CMD_READ_HEADING 0x03
struct str_I2C_WriteNickRoll
 
typedef struct
{
int Nick;
int Roll;
} ;
uint8_t Adress;
uint16_t Content;
} I2C_EEPROM_t;
 
#define I2C_CMD_WRITE_CAL 0x04
struct str_I2C_WriteCal
 
typedef struct
{
unsigned char CalByte;
unsigned char Dummy1;
unsigned char Dummy2;
} ;
int16_t MagX;
int16_t MagY;
int16_t MagZ;
} I2C_Mag_t;
 
struct str_I2C_Heading
 
typedef struct
{
unsigned int Heading;
} ;
int16_t Nick;
int16_t Roll;
} I2C_WriteAttitude_t;
 
 
extern unsigned char Tx_Idx, Rx_Idx, I2C_Direction;
typedef struct
{
uint8_t CalByte;
uint8_t Dummy1;
uint8_t Dummy2;
} I2C_WriteCal_t;
 
extern struct str_I2C_Heading I2C_Heading;
extern struct str_I2C_WriteNickRoll I2C_WriteNickRoll;
extern struct str_I2C_Mag I2C_Mag;
extern struct str_I2C_EEPROM I2C_ReadEEPROM, I2C_WriteEEPROM;
extern struct str_I2C_Version I2C_Version;
extern struct str_I2C_WriteCal I2C_WriteCal;
typedef struct
{
int16_t Heading;
} I2C_Heading_t;
 
 
extern void InitIC2_Slave (void);
extern uint8_t Tx_Idx, Rx_Idx, I2C_Direction;
 
#define TWI_BUS_ERR_1 0x00
#define TWI_BUS_ERR_2 0xF8
extern I2C_Heading_t I2C_Heading;
extern I2C_WriteAttitude_t I2C_WriteNickRoll;
extern I2C_Mag_t I2C_Mag;
extern I2C_Version_t I2C_Version;
extern I2C_WriteCal_t I2C_WriteCal;
 
// Status Slave RX Mode
#define SR_SLA_ACK 0x60
#define SR_LOST_ACK 0x68
#define SR_GEN_CALL_ACK 0x70
#define GEN_LOST_ACK 0x78
#define SR_PREV_ACK 0x80
#define SR_PREV_NACK 0x88
#define GEN_PREV_ACK 0x90
#define GEN_PREV_NACK 0x98
#define STOP_CONDITION 0xA0
#define REPEATED_START 0xA0
void I2C_Init(void);
 
// Status Slave TX mode
#define SW_SLA_ACK 0xA8
#define SW_LOST_ACK 0xB0
#define SW_DATA_ACK 0xB8
#define SW_DATA_NACK 0xC0
#define SW_LAST_ACK 0xC8
 
#endif
#endif // _TWI_SLAVE_H_
 
/branches/MK3Mag V0.14 Code Redesign Killagreg/uart.c
1,6 → 1,6
/*#######################################################################################
MK3Mag 3D-Magnet sensor
!!! THIS IS NOT FREE SOFTWARE !!!
!!! THIS IS NOT FREE SOFTWARE !!!
#######################################################################################*/
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Copyright (c) 05.2008 Holger Buss
8,15 → 8,15
// + Nur für den privaten Gebrauch
// + www.MikroKopter.com
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + Die Portierung der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur
// + mit unserer Zustimmung zulässig
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation),
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist.
// + AUSNAHME: Ein bei www.mikrokopter.de erworbener vorbestückter MK3Mag darf als Baugruppe auch in kommerziellen Systemen verbaut werden
// + Im Zweifelsfall bitte anfragen bei: info@mikrokopter.de
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht,
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
29,19 → 29,19
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
// + Redistributions of source code (with or without modifications) must retain the above copyright notice,
// + this list of conditions and the following disclaimer.
// + * PORTING this software (or parts of it) to systems (other than hardware from www.mikrokopter.de) is NOT allowed
// + * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
// + from this software without specific prior written permission.
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
// + * The use of this project (hardware, software, binary files, sources and documentation) is only permittet
// + for non-commercial use (directly or indirectly)
// + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
// + Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted
// + with our written permission
// + Exception: A preassembled MK3Mag, purchased from www.mikrokopter.de may be used as a part of commercial systems
// + In case of doubt please contact: info@MikroKopter.de
// + * If sources or documentations are redistributet on other webpages, our webpage (http://www.MikroKopter.de) must be
// + clearly linked as origin
// + * If sources or documentations are redistributet on other webpages, our webpage (http://www.MikroKopter.de) must be
// + clearly linked as origin
// + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52,61 → 52,70
// + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// + POSSIBILITY OF SUCH DAMAGE.
// + POSSIBILITY OF SUCH DAMAGE.
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include "main.h"
#include "uart.h"
#include "timer0.h"
#include "twislave.h"
 
#define MAX_SENDE_BUFF 100
#define MAX_EMPFANGS_BUFF 100
 
unsigned volatile char SIO_Sollwert = 0;
unsigned volatile char SioTmp = 0;
unsigned volatile char SendeBuffer[MAX_SENDE_BUFF];
unsigned volatile char RxdBuffer[MAX_EMPFANGS_BUFF];
unsigned volatile char NeuerDatensatzEmpfangen = 0;
unsigned volatile char UebertragungAbgeschlossen = 1;
unsigned char GetVersionAnforderung = 0,DebugTextAnforderung = 0,DebugGetAnforderung = 0, KompassAntwort = 0;
unsigned char MeineSlaveAdresse;
unsigned char MotorTest[4] = {0,0,0,0};
unsigned volatile char AnzahlEmpfangsBytes = 0;
unsigned char PcZugriff;
#define FALSE 0
#define TRUE 1
 
struct str_DebugOut DebugOut;
struct str_ExternData ExternData;
struct str_ExternControl ExternControl;
struct str_VersionInfo VersionInfo;
#define TXD_BUFFER_LEN 100
#define RXD_BUFFER_LEN 100
 
volatile uint8_t txd_buffer[TXD_BUFFER_LEN];
volatile uint8_t rxd_buffer_locked = FALSE;
volatile uint8_t rxd_buffer[RXD_BUFFER_LEN];
volatile uint8_t txd_complete = TRUE;
volatile uint8_t ReceivedBytes = 0;
 
uint8_t RequestVerInfo = FALSE;
uint8_t RequestDebugData = FALSE;
uint8_t RequestDebugLabel = FALSE;
uint8_t RequestCompassHeading = FALSE;
 
int Debug_Timer;
uint8_t MySlaveAddr = 0;
 
const unsigned char ANALOG_TEXT[32][16] =
//unsigned char,DebugGetAnforderung = 0,
 
DebugOut_t DebugOut;
ExternData_t ExternData;
ExternControl_t ExternControl;
VersionInfo_t VersionInfo;
 
uint16_t Debug_Timer;
 
const uint8_t ANALOG_LABEL[32][16] =
{
//1234567890123456
"Magnet N ", //0
"Magnet R ",
"Magnet X ", //0
"Magnet Y ",
"Magnet Z ",
"Raw N ",
"Raw R ",
"Raw Z ", //5
"Lage N ",
"Lage R ",
"Xmin ",
"Xmax ",
"Ymin ", //10
"Ymax ",
"Zmin ",
"ZMax ",
"Raw X ",
"Raw Y ",
"Raw Z ", //5
"Attitude Nick ",
"Attitude Roll ",
"XOffset ",
"XRange ",
"YOffset ", //10
"YRange ",
"ZOffset ",
"ZRange ",
"Calstate ",
"Kompass ", //15
"Heading Request ", //15
"User0 ",
"User1 ",
"Analog18 ",
"Analog19 ",
"Analog20 ", //20
"Analog21 ",
"Analog21 ",
"Analog22 ",
"Analog23 ",
"Analog24 ",
120,356 → 129,356
};
 
 
/****************************************************************/
/* Initialization of the USART0 */
/****************************************************************/
void USART0_Init (void)
{
uint8_t sreg = SREG;
 
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++ Sende-Part der Datenübertragung
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
SIGNAL(INT_VEC_TX)
uint16_t ubrr = (uint16_t) ((uint32_t) SYSCLK/(8 * BAUD_RATE) - 1);
 
// disable all interrupts before configuration
cli();
 
// disable RX-Interrupt
UCSR0B &= ~(1 << RXCIE0);
// disable TX-Interrupt
UCSR0B &= ~(1 << TXCIE0);
 
// set direction of RXD0 and TXD0 pins
 
// set RXD0 (PD0) as an input pin
PORTD |= (1 << PORTD0);
DDRD &= ~(1 << DDD0);
// set TXD0 (PD1) as an output pin
PORTD |= (1 << PORTD1);
DDRD |= (1 << DDD1);
 
// USART0 Baud Rate Register
// set clock divider
UBRR0H = (uint8_t)(ubrr >> 8);
UBRR0L = (uint8_t)ubrr;
 
// USART0 Control and Status Register A, B, C
 
// enable double speed operation in
UCSR0A |= (1 << U2X0);
// enable receiver and transmitter in
UCSR0B |= (1 << TXEN0) | (1 << RXEN0);
// set asynchronous mode
UCSR0C &= ~(1 << UMSEL01);
UCSR0C &= ~(1 << UMSEL00);
// no parity
UCSR0C &= ~(1 << UPM01);
UCSR0C &= ~(1 << UPM00);
// 1 stop bit
UCSR0C &= ~(1 << USBS0);
// 8-bit
UCSR0B &= ~(1 << UCSZ02);
UCSR0C |= (1 << UCSZ01);
UCSR0C |= (1 << UCSZ00);
 
// flush receive buffer
while ( UCSR0A & (1<<RXC0) ) UDR0;
 
// enable interrupts at the end
// enable RX-Interrupt
UCSR0B |= (1 << RXCIE0);
// enable TX-Interrupt
UCSR0B |= (1 << TXCIE0);
 
rxd_buffer_locked = FALSE;
txd_complete = TRUE;
 
Debug_Timer = SetDelay(200);
 
 
// restore global interrupt flags
SREG = sreg;
 
VersionInfo.Major = VERSION_MAJOR;
VersionInfo.Minor = VERSION_MINOR;
VersionInfo.PCCompatible = VERSION_COMPATIBLE;
 
// Version beim Start ausgeben (nicht schön, aber geht... )
uart_putchar ('\n');uart_putchar ('C');uart_putchar ('P');uart_putchar (':');
uart_putchar ('V');uart_putchar (0x30 + VERSION_MAJOR);uart_putchar ('.');uart_putchar (0x30 + VERSION_MINOR/10); uart_putchar (0x30 + VERSION_MINOR%10);
uart_putchar ('\n');
}
 
// ---------------------------------------------------------------------------------
void USART0_EnableTXD(void)
{
static unsigned int ptr = 0;
unsigned char tmp_tx;
if(!UebertragungAbgeschlossen)
{
ptr++; // die [0] wurde schon gesendet
tmp_tx = SendeBuffer[ptr];
if((tmp_tx == '\r') || (ptr == MAX_SENDE_BUFF))
{
ptr = 0;
UebertragungAbgeschlossen = 1;
}
UDR = tmp_tx;
}
else ptr = 0;
DDRD |= (1<<DDD1); // set TXD pin as output
UCSR0B |= (1 << TXEN0); // enable TX in USART
}
 
void SendUart(void)
// ---------------------------------------------------------------------------------
void USART0_DisableTXD(void)
{
static unsigned int ptr = 0;
unsigned char tmp_tx;
if(!(USR & 0x40)) return;
if(!UebertragungAbgeschlossen)
{
ptr++; // die [0] wurde schon gesendet
tmp_tx = SendeBuffer[ptr];
if((tmp_tx == '\r') || (ptr == MAX_SENDE_BUFF))
{
ptr = 0;
UebertragungAbgeschlossen = 1;
}
USR |= (1<TXC0);
UDR = tmp_tx;
}
else ptr = 0;
UCSR0B &= ~(1 << TXEN0); // disable TXD in USART
DDRD &= ~(1<<DDD1); // set TXD pin as input
}
 
// --------------------------------------------------------------------------
void Decode64(unsigned char *ptrOut, unsigned char len, unsigned char ptrIn,unsigned char max) // Wohin mit den Daten; Wie lang; Wo im RxdBuffer
/****************************************************************/
/* USART0 transmitter ISR */
/****************************************************************/
ISR(USART_TX_vect)
{
unsigned char a,b,c,d;
unsigned char ptr = 0;
unsigned char x,y,z;
while(len)
{
a = RxdBuffer[ptrIn++] - '=';
b = RxdBuffer[ptrIn++] - '=';
c = RxdBuffer[ptrIn++] - '=';
d = RxdBuffer[ptrIn++] - '=';
if(ptrIn > max - 2) break; // nicht mehr Daten verarbeiten, als empfangen wurden
static uint16_t ptr_txd_buffer = 0;
uint8_t tmp_tx;
if(!txd_complete) // transmission not completed
{
ptr_txd_buffer++; // die [0] wurde schon gesendet
tmp_tx = txd_buffer[ptr_txd_buffer];
// if terminating character or end of txd buffer was reached
if((tmp_tx == '\r') || (ptr_txd_buffer == TXD_BUFFER_LEN))
{
ptr_txd_buffer = 0; // reset txd pointer
txd_complete = 1; // stop transmission
}
UDR0 = tmp_tx; // send current byte will trigger this ISR again
}
// transmission completed
else ptr_txd_buffer = 0;
}
 
x = (a << 2) | (b >> 4);
y = ((b & 0x0f) << 4) | (c >> 2);
z = ((c & 0x03) << 6) | d;
/****************************************************************/
/* USART0 receiver ISR */
/****************************************************************/
ISR(USART_RX_vect)
{
static uint16_t crc;
static uint8_t ptr_rxd_buffer = 0;
uint8_t crc1, crc2;
uint8_t c;
 
if(len--) ptrOut[ptr++] = x; else break;
if(len--) ptrOut[ptr++] = y; else break;
if(len--) ptrOut[ptr++] = z; else break;
}
c = UDR0; // catch the received byte
 
if(rxd_buffer_locked) return; // if rxd buffer is locked immediately return
 
// the rxd buffer is unlocked
if((ptr_rxd_buffer == 0) && (c == '#')) // if rxd buffer is empty and syncronisation character is received
{
rxd_buffer[ptr_rxd_buffer++] = c; // copy 1st byte to buffer
crc = c; // init crc
}
#if 0
else if (ptr_rxd_buffer == 1) // handle address
{
rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer
crc += c; // update crc
}
#endif
else if (ptr_rxd_buffer < RXD_BUFFER_LEN) // collect incomming bytes
{
if(c != '\r') // no termination character
{
rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer
crc += c; // update crc
}
else // termination character was received
{
// the last 2 bytes are no subject for checksum calculation
// they are the checksum itself
crc -= rxd_buffer[ptr_rxd_buffer-2];
crc -= rxd_buffer[ptr_rxd_buffer-1];
// calculate checksum from transmitted data
crc %= 4096;
crc1 = '=' + crc / 64;
crc2 = '=' + crc % 64;
// compare checksum to transmitted checksum bytes
if((crc1 == rxd_buffer[ptr_rxd_buffer-2]) && (crc2 == rxd_buffer[ptr_rxd_buffer-1]))
{ // checksum valid
rxd_buffer_locked = TRUE; // lock the rxd buffer
ReceivedBytes = ptr_rxd_buffer; // store number of received bytes
rxd_buffer[ptr_rxd_buffer] = '\r'; // set termination character
// if 2nd byte is an 'R' enable watchdog that will result in an reset
if(rxd_buffer[2] == 'R') {wdt_enable(WDTO_250MS);} // Reset-Commando
}
else
{ // checksum invalid
rxd_buffer_locked = FALSE; // unlock rxd buffer
}
ptr_rxd_buffer = 0; // reset rxd buffer pointer
}
}
else // rxd buffer overrun
{
ptr_rxd_buffer = 0; // reset rxd buffer
rxd_buffer_locked = FALSE; // unlock rxd buffer
}
}
 
 
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++ Empfangs-Part der Datenübertragung
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
SIGNAL(INT_VEC_RX)
// --------------------------------------------------------------------------
void AddCRC(uint16_t datalen)
{
static unsigned int crc;
static unsigned char crc1,crc2,buf_ptr;
static unsigned char UartState = 0;
unsigned char CrcOkay = 0;
SioTmp = UDR;
if(buf_ptr >= MAX_EMPFANGS_BUFF) UartState = 0;
if(SioTmp == '\r' && UartState == 2)
{
UartState = 0;
crc -= RxdBuffer[buf_ptr-2];
crc -= RxdBuffer[buf_ptr-1];
crc %= 4096;
crc1 = '=' + crc / 64;
crc2 = '=' + crc % 64;
CrcOkay = 0;
if((crc1 == RxdBuffer[buf_ptr-2]) && (crc2 == RxdBuffer[buf_ptr-1])) CrcOkay = 1; else { CrcOkay = 0; };
if(CrcOkay) // Datensatz schon verarbeitet
{
NeuerDatensatzEmpfangen = 1;
AnzahlEmpfangsBytes = buf_ptr;
RxdBuffer[buf_ptr] = '\r';
if((RxdBuffer[2] == 'R')) wdt_enable(WDTO_250MS); // Reset-Commando
// uart_putchar(RxdBuffer[2]);
}
}
else
switch(UartState)
{
case 0:
if(SioTmp == '#' && !NeuerDatensatzEmpfangen) UartState = 1; // Startzeichen und Daten schon verarbeitet
buf_ptr = 0;
RxdBuffer[buf_ptr++] = SioTmp;
crc = SioTmp;
break;
case 1: // Adresse auswerten
UartState++;
RxdBuffer[buf_ptr++] = SioTmp;
crc += SioTmp;
break;
case 2: // Eingangsdaten sammeln
RxdBuffer[buf_ptr] = SioTmp;
if(buf_ptr < MAX_EMPFANGS_BUFF) buf_ptr++;
else UartState = 0;
crc += SioTmp;
break;
default:
UartState = 0;
break;
}
uint16_t tmpCRC = 0, i;
for(i = 0; i < datalen; i++)
{
tmpCRC += txd_buffer[i];
}
tmpCRC %= 4096;
txd_buffer[i++] = '=' + tmpCRC / 64;
txd_buffer[i++] = '=' + tmpCRC % 64;
txd_buffer[i++] = '\r';
txd_complete = FALSE;
UDR0 = txd_buffer[0]; // initiates the transmission (continued in the TXD ISR)
}
 
};
 
 
// --------------------------------------------------------------------------
void AddCRC(unsigned int wieviele)
void SendOutData(uint8_t cmd,uint8_t module, uint8_t *snd, uint8_t len)
{
unsigned int tmpCRC = 0,i;
for(i = 0; i < wieviele;i++)
{
tmpCRC += SendeBuffer[i];
}
tmpCRC %= 4096;
SendeBuffer[i++] = '=' + tmpCRC / 64;
SendeBuffer[i++] = '=' + tmpCRC % 64;
SendeBuffer[i++] = '\r';
UebertragungAbgeschlossen = 0;
UDR = SendeBuffer[0];
uint16_t pt = 0;
uint8_t a,b,c;
uint8_t ptr = 0;
 
txd_buffer[pt++] = '#'; // Start character
txd_buffer[pt++] = module; // Address (a=0; b=1,...)
txd_buffer[pt++] = cmd; // Command
 
while(len)
{
if(len) { a = snd[ptr++]; len--;} else a = 0;
if(len) { b = snd[ptr++]; len--;} else b = 0;
if(len) { c = snd[ptr++]; len--;} else c = 0;
txd_buffer[pt++] = '=' + (a >> 2);
txd_buffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
txd_buffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
txd_buffer[pt++] = '=' + ( c & 0x3f);
}
AddCRC(pt); // add checksum after data block and initates the transmission
}
 
 
// --------------------------------------------------------------------------
void SendOutData(unsigned char cmd,unsigned char modul, unsigned char *snd, unsigned char len)
void Decode64(uint8_t *ptrOut, uint8_t len, uint8_t ptrIn, uint8_t max)
{
unsigned int pt = 0;
unsigned char a,b,c;
unsigned char ptr = 0;
SendeBuffer[pt++] = '#'; // Startzeichen
SendeBuffer[pt++] = modul; // Adresse (a=0; b=1,...)
SendeBuffer[pt++] = cmd; // Commando
uint8_t a,b,c,d;
uint8_t ptr = 0;
uint8_t x,y,z;
while(len)
{
a = rxd_buffer[ptrIn++] - '=';
b = rxd_buffer[ptrIn++] - '=';
c = rxd_buffer[ptrIn++] - '=';
d = rxd_buffer[ptrIn++] - '=';
if(ptrIn > max - 2) break;
 
while(len)
{
if(len) { a = snd[ptr++]; len--;} else a = 0;
if(len) { b = snd[ptr++]; len--;} else b = 0;
if(len) { c = snd[ptr++]; len--;} else c = 0;
SendeBuffer[pt++] = '=' + (a >> 2);
SendeBuffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
SendeBuffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
SendeBuffer[pt++] = '=' + ( c & 0x3f);
}
AddCRC(pt);
x = (a << 2) | (b >> 4);
y = ((b & 0x0f) << 4) | (c >> 2);
z = ((c & 0x03) << 6) | d;
 
if(len--) ptrOut[ptr++] = x; else break;
if(len--) ptrOut[ptr++] = y; else break;
if(len--) ptrOut[ptr++] = z; else break;
}
}
 
 
 
//############################################################################
//Routine für die Serielle Ausgabe
int uart_putchar (char c)
//############################################################################
// --------------------------------------------------------------------------
int16_t uart_putchar (int8_t c)
{
if(!(UCR & (1 << TXEN))) return (0);
if (c == '\n')
uart_putchar('\r');
//Warten solange bis Zeichen gesendet wurde
loop_until_bit_is_set(USR, UDRE);
//Ausgabe des Zeichens
UDR = c;
// if tx is not enabled return immediatly
if(!(UCSR0B & (1 << TXEN0))) return (0);
if (c == '\n') uart_putchar('\r');
// wait until previous character was send
loop_until_bit_is_set(UCSR0A, UDRE0);
// send character
UDR0 = c;
return (0);
}
 
 
// --------------------------------------------------------------------------
void WriteProgramData(unsigned int pos, unsigned char wert)
void USART0_ProcessRxData(void)
{
}
// if data in the rxd buffer are not locked immediately return
if(!rxd_buffer_locked) return;
 
//############################################################################
//INstallation der Seriellen Schnittstelle
void UART_Init (void)
//############################################################################
{
//Enable TXEN im Register UCR TX-Data Enable & RX Enable
uint8_t tmp_char_arr2[2]; // local char buffer
 
UCR=(1 << TXEN) | (1 << RXEN);
// UART Double Speed (U2X)
USR |= (1<<U2X);
// RX-Interrupt Freigabe
switch(rxd_buffer[2])
{
case 'w':// Attitude
Decode64((uint8_t *) &ExternData, sizeof(ExternData), 3, ReceivedBytes);
DebugOut.Analog[15]++;
RequestCompassHeading = TRUE;
break;
 
UCSRB |= (1<<RXCIE); // serieller Empfangsinterrupt
case 'b': // extern control
case 'c': // extern control with debug request
Decode64((uint8_t *) &ExternControl,sizeof(ExternControl), 3,ReceivedBytes);
ExternData.Attitude[0] = ExternControl.Par1;
ExternData.Attitude[1] = ExternControl.Par2;
break;
 
// TX-Interrupt Freigabe
UCSRB |= (1<<TXCIE);
case 'h':// x-1 display columns
PC_Connected = 255;
break;
 
//Teiler wird gesetzt
UBRR= (SYSCLK / (BAUD_RATE * 8L) -1 );
//öffnet einen Kanal für printf (STDOUT)
// fdevopen (uart_putchar, NULL);
Debug_Timer = SetDelay(200);
// Version beim Start ausgeben (nicht schön, aber geht... )
uart_putchar ('\n');uart_putchar ('C');uart_putchar ('P');uart_putchar (':');
uart_putchar ('V');uart_putchar (0x30 + VERSION_HAUPTVERSION);uart_putchar ('.');uart_putchar (0x30 + VERSION_NEBENVERSION/10); uart_putchar (0x30 + VERSION_NEBENVERSION%10);
uart_putchar ('\n');
case 'v': // get version and board release
RequestVerInfo = TRUE;
PC_Connected = 255;
break;
 
case 'a':// Labels of the Analog Debug outputs
Decode64((uint8_t *) &tmp_char_arr2[0], sizeof(tmp_char_arr2), 3, ReceivedBytes);
RequestDebugLabel = tmp_char_arr2[0];
PC_Connected = 255;
break;
 
case 'g':// get debug data
RequestDebugData = TRUE;
PC_Connected = 255;
break;
}
// unlock the rxd buffer after processing
rxd_buffer_locked = FALSE;
}
 
 
void BearbeiteRxDaten(void)
 
//---------------------------------------------------------------------------------------------
void USART0_TransmitTxData(void)
{
if(!NeuerDatensatzEmpfangen) return;
// unsigned int tmp_int_arr1[1];
// unsigned int tmp_int_arr2[2];
// unsigned int tmp_int_arr3[3];
unsigned char tmp_char_arr2[2];
// unsigned char tmp_char_arr3[3];
// unsigned char tmp_char_arr4[4];
//if(!MotorenEin)
PcZugriff = 255;
if(!(UCSR0B & (1 << TXEN0))) return;
 
switch(RxdBuffer[2])
{
case 'w':// Lagewinkel
Decode64((unsigned char *) &ExternData,sizeof(ExternData),3,AnzahlEmpfangsBytes);
DebugOut.Analog[15]++;
KompassAntwort = 1;
break;
case 'c':
case 'b':
Decode64((unsigned char *) &ExternControl,sizeof(ExternControl),3,AnzahlEmpfangsBytes);
ExternData.Winkel[0] = ExternControl.Par1;
ExternData.Winkel[1] = ExternControl.Par2;
break;
case 'v': // Version-Anforderung und Ausbaustufe
GetVersionAnforderung = 1;
PC_Connected = 255;
break;
if(!txd_complete) return;
 
case 'a':// Texte der Analogwerte
Decode64((unsigned char *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,AnzahlEmpfangsBytes);
DebugTextAnforderung = tmp_char_arr2[0];
PC_Connected = 255;
break;
case 'g':// "Get"-Anforderung für Debug-Daten
// Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
PC_Connected = 255;
DebugGetAnforderung = 1;
break;
case 'h':// x-1 Displayzeilen
PC_Connected = 255;
break;
/*
case 'b':
Decode64((unsigned char *) &ExternControl,sizeof(ExternControl),3,AnzahlEmpfangsBytes);
RemoteTasten |= ExternControl.RemoteTasten;
ConfirmFrame = ExternControl.Frame;
break;
case 'c':
Decode64((unsigned char *) &ExternControl,sizeof(ExternControl),3,AnzahlEmpfangsBytes);
RemoteTasten |= ExternControl.RemoteTasten;
ConfirmFrame = ExternControl.Frame;
DebugDataAnforderung = 1;
break;
case 'h':// x-1 Displayzeilen
Decode64((unsigned char *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,AnzahlEmpfangsBytes);
RemoteTasten |= tmp_char_arr2[0];
if(tmp_char_arr2[1] == 255) NurKanalAnforderung = 1; else NurKanalAnforderung = 0; // keine Displaydaten
DebugDisplayAnforderung = 1;
break;
case 't':// Motortest
Decode64((unsigned char *) &MotorTest[0],sizeof(MotorTest),3,AnzahlEmpfangsBytes);
break;
case 'k':// Keys von DubWise
Decode64((unsigned char *) &DubWiseKeys[0],sizeof(DubWiseKeys),3,AnzahlEmpfangsBytes);
ConfirmFrame = DubWiseKeys[3];
break;
case 'q':// "Get"-Anforderung für Settings
// Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
Decode64((unsigned char *) &tmp_char_arr2[0],sizeof(tmp_char_arr2),3,AnzahlEmpfangsBytes);
if(tmp_char_arr2[0] != 0xff)
{
if(tmp_char_arr2[0] > 5) tmp_char_arr2[0] = 5;
ReadParameterSet(tmp_char_arr2[0], (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);
SendOutData('L' + tmp_char_arr2[0] -1,MeineSlaveAdresse,(unsigned char *) &EE_Parameter.Kanalbelegung[0],STRUCT_PARAM_LAENGE);
}
else
SendOutData('L' + GetActiveParamSetNumber()-1,MeineSlaveAdresse,(unsigned char *) &EE_Parameter.Kanalbelegung[0],STRUCT_PARAM_LAENGE);
break;
case 'l':
case 'm':
case 'n':
case 'o':
case 'p': // Parametersatz speichern
Decode64((unsigned char *) &EE_Parameter.Kanalbelegung[0],STRUCT_PARAM_LAENGE,3,AnzahlEmpfangsBytes);
WriteParameterSet(RxdBuffer[2] - 'l' + 1, (unsigned char *) &EE_Parameter.Kanalbelegung[0], STRUCT_PARAM_LAENGE);
eeprom_write_byte(&EEPromArray[EEPROM_ADR_ACTIVE_SET], RxdBuffer[2] - 'l' + 1); // aktiven Datensatz merken
Umschlag180Nick = (long) EE_Parameter.WinkelUmschlagNick * 2500L;
Umschlag180Roll = (long) EE_Parameter.WinkelUmschlagRoll * 2500L;
Piep(GetActiveParamSetNumber());
break;
*/
}
// DebugOut.AnzahlZyklen = Debug_Timer_Intervall;
NeuerDatensatzEmpfangen = 0;
}
if(CheckDelay(Debug_Timer) && txd_complete)
{
SetDebugValues();
SendOutData('D',MySlaveAddr,(uint8_t *) &DebugOut,sizeof(DebugOut));
Debug_Timer = SetDelay(250);
}
 
if(RequestDebugLabel != 255)
{
SendOutData('A',RequestDebugLabel + '0',(uint8_t *) ANALOG_LABEL[RequestDebugLabel],16);
RequestDebugLabel = 255;
}
 
//---------------------------------------------------------------------------------------------
void DatenUebertragung(void)
{
if((CheckDelay(Debug_Timer) && UebertragungAbgeschlossen)) // im Singlestep-Betrieb in jedem Schtitt senden
{
SetDebugValues();
SendOutData('D',MeineSlaveAdresse,(unsigned char *) &DebugOut,sizeof(DebugOut));
Debug_Timer = SetDelay(250); // Sendeintervall
}
if(GetVersionAnforderung && UebertragungAbgeschlossen)
{
SendOutData('V',MeineSlaveAdresse,(unsigned char *) &VersionInfo,sizeof(VersionInfo));
GetVersionAnforderung = 0;
}
if(DebugTextAnforderung != 255) // Texte für die Analogdaten
{
SendOutData('A',DebugTextAnforderung + '0',(unsigned char *) ANALOG_TEXT[DebugTextAnforderung],16);
DebugTextAnforderung = 255;
}
if(DebugGetAnforderung && UebertragungAbgeschlossen) // Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
{
SendOutData('G',MeineSlaveAdresse,(unsigned char *) &ExternControl,sizeof(ExternControl));
DebugGetAnforderung = 0;
}
if(KompassAntwort && UebertragungAbgeschlossen) // Bei Get werden die vom PC einstellbaren Werte vom PC zurückgelesen
{
SendOutData('K',MeineSlaveAdresse,(unsigned char *) &I2C_Heading,sizeof(I2C_Heading));
KompassAntwort = 0;
}
if(RequestVerInfo && txd_complete)
{
SendOutData('V',MySlaveAddr,(uint8_t *) &VersionInfo, sizeof(VersionInfo));
RequestVerInfo = FALSE;
}
 
if(RequestDebugData && txd_complete)
{
SetDebugValues();
SendOutData('G',MySlaveAddr,(uint8_t *) &ExternControl,sizeof(ExternControl));
RequestDebugData = FALSE;
}
 
if(RequestCompassHeading && txd_complete)
{
SendOutData('K',MySlaveAddr,(uint8_t *) &I2C_Heading, sizeof(I2C_Heading));
RequestCompassHeading = FALSE;
}
}
 
/branches/MK3Mag V0.14 Code Redesign Killagreg/uart.h
1,135 → 1,74
#ifndef _UART_H
#define _UART_H
#ifndef _UART_H_
#define _UART_H_
 
extern unsigned volatile char SIO_Sollwert;
extern unsigned volatile char UebertragungAbgeschlossen;
extern unsigned volatile char PC_DebugTimeout;
extern unsigned char MeineSlaveAdresse;
extern int Debug_Timer;
extern void UART_Init (void);
extern int uart_putchar (char c);
extern void boot_program_page (uint32_t page, uint8_t *buf);
extern void SendUart(void);
#include <inttypes.h>
 
void DatenUebertragung(void);
 
struct str_DebugOut
{
unsigned char Digital[2];
unsigned int Analog[32]; // Debugwerte
};
 
struct str_ExternData
{
signed int Winkel[2]; // in 0,1 degree
unsigned char UserParameter[2];
unsigned char CalState;
unsigned char Orientation;
};
extern struct str_ExternData ExternData;
#define NICK 0
#define ROLL 1
 
 
struct str_ExternControl
{
unsigned char Digital[2];
unsigned char RemoteTasten;
signed char Nick;
signed char Roll;
signed char Gier;
unsigned char Gas;
signed char Hight;
unsigned char Par1;
unsigned char Par2;
unsigned char Par3;
};
extern struct str_ExternControl ExternControl;
#define BAUD_RATE 57600
 
struct str_VersionInfo
 
extern uint16_t Debug_Timer;
 
 
void USART0_Init (void);
void USART0_EnableTXD(void);
void USART0_DisableTXD(void);
void USART0_TransmitTxData(void);
void USART0_ProcessRxData(void);
int16_t uart_putchar(int8_t c);
 
 
 
typedef struct
{
unsigned char Hauptversion;
unsigned char Nebenversion;
unsigned char PCKompatibel;
unsigned char Rserved[7];
};
extern struct str_VersionInfo VersionInfo;
uint8_t Digital[2];
uint16_t Analog[32]; // Debugvalues
} DebugOut_t;
 
extern DebugOut_t DebugOut;
 
extern struct str_DebugOut DebugOut;
extern struct str_DebugOut DebugOut;
//Die Baud_Rate der Seriellen Schnittstelle
//#define BAUD_RATE 9600 //Baud Rate für die Serielle Schnittstelle
//#define BAUD_RATE 14400 //Baud Rate für die Serielle Schnittstelle
//#define BAUD_RATE 28800 //Baud Rate für die Serielle Schnittstelle
 
#if X3D_SIO == 1
#define BAUD_RATE 38400 //Baud Rate für die Serielle Schnittstelle
#else
#define BAUD_RATE 57600 //Baud Rate für die Serielle Schnittstelle
#endif
 
//Anpassen der seriellen Schnittstellen Register wenn ein ATMega128 benutzt wird
#if defined (__AVR_ATmega128__)
# define USR UCSR0A
# define UCR UCSR0B
# define UDR UDR0
# define UBRR UBRR0L
# define EICR EICRB
#endif
typedef struct
{
int16_t Attitude[2]; // nock and roll angle in 0.1 deg
uint8_t UserParam[2];
uint8_t CalState;
uint8_t Orientation;
} ExternData_t;
 
#if defined (__AVR_ATmega8__)
# define USR UCSRA
# define UCR UCSRB
# define UBRR UBRRL
# define EICR EICRB
# define INT_VEC_RX SIG_UART_RECV
# define INT_VEC_TX SIG_UART_TRANS
#endif
extern ExternData_t ExternData;
 
#if defined (__AVR_ATmega168__)
# define USR UCSR0A
# define UCR UCSR0B
# define UDR UDR0
# define UBRR UBRR0L
# define EICR EICR0B
# define TXEN TXEN0
# define RXEN RXEN0
# define RXCIE RXCIE0
# define TXCIE TXCIE0
# define U2X U2X0
# define UCSRB UCSR0B
# define UDRE UDRE0
# define INT_VEC_RX SIG_USART_RECV
# define INT_VEC_TX SIG_USART_TRANS
#endif
 
typedef struct
{
uint8_t Digital[2];
uint8_t RemoteButtons;
int8_t Nick;
int8_t Roll;
int8_t Yaw;
uint8_t Gas;
int8_t Height;
uint8_t Par1;
uint8_t Par2;
uint8_t Par3;
} ExternControl_t;
 
#if defined (__AVR_ATmega32__)
# define USR UCSRA
# define UCR UCSRB
# define UBRR UBRRL
# define EICR EICRB
# define INT_VEC_RX SIG_UART_RECV
# define INT_VEC_TX SIG_UART_TRANS
#endif
extern ExternControl_t ExternControl;
 
#if defined (__AVR_ATmega644__)
# define USR UCSR0A
# define UCR UCSR0B
# define UDR UDR0
# define UBRR UBRR0L
# define EICR EICR0B
# define TXEN TXEN0
# define RXEN RXEN0
# define RXCIE RXCIE0
# define TXCIE TXCIE0
# define U2X U2X0
# define UCSRB UCSR0B
# define UDRE UDRE0
# define INT_VEC_RX SIG_USART_RECV
# define INT_VEC_TX SIG_USART_TRANS
#endif
 
typedef struct
{
uint8_t Major;
uint8_t Minor;
uint8_t PCCompatible;
uint8_t Reserved[7];
} VersionInfo_t;
 
#endif //_UART_H
extern VersionInfo_t VersionInfo;
 
 
#endif //_UART_H_