Blame |
Last modification |
View Log
| RSS feed
/*****************************************************************************
* Copyright (C) 2008 Thomas Kaiser, thomas@ft-fanpage.de *
* Copyright (C) 2009 Peter "woggle" Mack, mac@denich.net *
* Copyright (C) 2011 Christian "Cebra" Brandtner, brandtner@brandtner.net *
* Copyright (C) 2011 Harald Bongartz *
* *
* 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. *
* *
* *
* Credits to: *
* Holger Buss & Ingo Busker from mikrokopter.de for the MK project + SVN *
* http://www.mikrokopter.de *
* Gregor "killagreg" Stobrawa for his version of the MK code *
* Thomas Kaiser "thkais" for the original project. See *
* http://www.ft-fanpage.de/mikrokopter/ *
* http://forum.mikrokopter.de/topic-4061-1.html *
* Claas Anders "CaScAdE" Rathje for providing the font and his C-OSD code *
* http://www.mylifesucks.de/oss/c-osd/ *
* Harald Bongartz "HaraldB" for providing his Ideas and Code for usibility*
*****************************************************************************/
#include "cpu.h"
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdlib.h>
#include <string.h>
#include "lcd.h"
#include "usart.h"
#include "uart1.h"
#include "main.h"
#include "Wi232.h"
#include "timer.h"
#include "eeprom.h"
#if defined HWVERSION1_3W || defined HWVERSION3_9 || defined HWVERSION1_2W
uint8_t Wi232_hardware = 0;
uint8_t InitErr=0;
uint8_t Wi232_Baudrate = 0; //Merkzelle für aktuelle Baudrate
uint8_t New_Baudrate = 0; //Merkzelle für zu setzende Baudrate
uint8_t Old_Baudrate = 0; //Merkzelle für alte Baudrate
void SetUart0_Wi232(uint8_t Baudrate)
{
switch (Baudrate)
{
case Wi232_2400: USART_Init( UART_BAUD_SELECT(2400,F_CPU) ); break; /* erstmal mit 2400 versuchen*/
case Wi232_9600: USART_Init( UART_BAUD_SELECT(9600,F_CPU) ); break; /* erstmal mit 9600 versuchen*/
case Wi232_19200: USART_Init( UART_BAUD_SELECT(19200,F_CPU) ); break; /* erstmal mit 19200 versuchen*/
case Wi232_38400: USART_Init( UART_BAUD_SELECT(38400,F_CPU) ); break; /* erstmal mit 38400 versuchen*/
case Wi232_57600: USART_Init( UART_BAUD_SELECT(57600,F_CPU) ); break; /* erstmal mit 57600 versuchen*/
// case Wi232_115200: USART_Init( UART_BAUD_SELECT(115200,F_CPU) ); break; /* erstmal mit 115200 versuchen*/
// Macro erechnet falschen Wert (9,85 = 9) für 115200 Baud mit 20Mhz Quarz, zu grosse Abweichung
#warning "Baurate prüfen wenn kein 20 Mhz Quarz verwendet wird"
case Wi232_115200: USART_Init( 10 ); break; /* erstmal mit 115200 versuchen*/
}
}
void SetUart1_Wi232(uint8_t Baudrate)
{
switch (Baudrate)
{
case Wi232_2400: uart1_init( UART_BAUD_SELECT(2400,F_CPU) ); break; /* erstmal mit 2400 versuchen*/
case Wi232_9600: uart1_init( UART_BAUD_SELECT(9600,F_CPU) ); break; /* erstmal mit 9600 versuchen*/
case Wi232_19200: uart1_init( UART_BAUD_SELECT(19200,F_CPU) ); break; /* erstmal mit 19200 versuchen*/
case Wi232_38400: uart1_init( UART_BAUD_SELECT(38400,F_CPU) ); break; /* erstmal mit 38400 versuchen*/
case Wi232_57600: uart1_init( UART_BAUD_SELECT(57600,F_CPU) ); break; /* erstmal mit 57600 versuchen*/
// case Wi232_115200: uart1_init( UART_BAUD_SELECT(115200,F_CPU) ); break; /* erstmal mit 115200 versuchen*/
case Wi232_115200: uart1_init( 10 ); break; /* erstmal mit 115200 versuchen*/
}
}
/*************************************************************************
Function: discoverWI232()
Purpose: check if Wi232 available
Returns: Version or 0 = timeout
**************************************************************************/
void discoverWi232(uint8_t Baudrate)
{
int16_t RegisterWi232;
SwitchToWi232(); /* Serielle Kanäle Wi232 mit USB verbinden*/
set_WI232CMD();
_delay_ms(200);
lcd_cls();
SetUart0_Wi232( Baudrate);
// switch (PKT_Baudrate)
// {
// case Wi232_2400: USART_Init( UART_BAUD_SELECT(2400,F_CPU) ); break; /* erstmal mit 2400 versuchen*/
// case Wi232_9600: USART_Init( UART_BAUD_SELECT(9600,F_CPU) ); break; /* erstmal mit 9600 versuchen*/
// case Wi232_19200: USART_Init( UART_BAUD_SELECT(19200,F_CPU) ); break; /* erstmal mit 19200 versuchen*/
// case Wi232_38400: USART_Init( UART_BAUD_SELECT(38400,F_CPU) ); break; /* erstmal mit 38400 versuchen*/
// case Wi232_57600: USART_Init( UART_BAUD_SELECT(57600,F_CPU) ); break; /* erstmal mit 57600 versuchen*/
// case Wi232_115200: USART_Init( UART_BAUD_SELECT(115200,F_CPU) ); break; /* erstmal mit 115200 versuchen*/
// }
lcd_printpns_at (0, 0, PSTR("search Wi.232 Modul"),0);
RegisterWi232 = ReadWi232(regDiscover);
lcd_print_hex_at(18,0,RegisterWi232,0);
if (RegisterWi232 > 0 && RegisterWi232 < 0xFF)
{ Wi232_hardware = 1; // Wi232 mit aktueller Baudrate gefunden
Wi232_Baudrate = PKT_Baudrate;}
if (RegisterWi232 == 0) // nicht gefunden, dann alle Baudraten durchsuchen
{
USART_Init( UART_BAUD_SELECT(2400,F_CPU) ); /* neues Modul mit 2400 suchen*/
lcd_printpns_at (0, 1, PSTR(" with 2400 Baud "),0);
RegisterWi232 = ReadWi232(regDiscover);
lcd_print_hex_at(18,1,RegisterWi232,0);
if (RegisterWi232 > 0 && RegisterWi232 < 0xFF)
{ Wi232_hardware = 2;
Wi232_Baudrate = Wi232_2400; }
if (RegisterWi232 == 0)
{
USART_Init( UART_BAUD_SELECT(9600,F_CPU) ); /* 9600 suchen*/
lcd_printpns_at (0, 2, PSTR(" with 9600 Baud "),0);
RegisterWi232 = ReadWi232(regDiscover);
lcd_print_hex_at(18,2,RegisterWi232,0);
if (RegisterWi232 > 0 && RegisterWi232 < 0xFF)
{ Wi232_hardware = 2;
Wi232_Baudrate = Wi232_9600; }
}
if (RegisterWi232 == 0)
{
USART_Init( UART_BAUD_SELECT(19200,F_CPU) ); /* 19200 suchen*/
lcd_printpns_at (0, 3, PSTR(" with 19200 Baud "),0);
RegisterWi232 = ReadWi232(regDiscover);
lcd_print_hex_at(18,3,RegisterWi232,0);
if (RegisterWi232 > 0 && RegisterWi232 < 0xFF)
{ Wi232_hardware = 2;
Wi232_Baudrate = Wi232_19200; }
}
if (RegisterWi232 == 0)
{
USART_Init( UART_BAUD_SELECT(38400,F_CPU) ); /* 38400 suchen*/
lcd_printpns_at (0, 4, PSTR(" with 38400 Baud"),0);
RegisterWi232 = ReadWi232(regDiscover);
lcd_print_hex_at(18,4,RegisterWi232,0);
if (RegisterWi232 > 0 && RegisterWi232 < 0xFF)
{ Wi232_hardware = 2;
Wi232_Baudrate = Wi232_38400; }
}
if (RegisterWi232 == 0 )
{
USART_Init( UART_BAUD_SELECT(57600,F_CPU) ); /* mit 57600 suchen*/
lcd_printpns_at (0, 5, PSTR(" with 57600 Baud"),0);
RegisterWi232 = ReadWi232(regDiscover);
lcd_print_hex_at(18,5,RegisterWi232,0);
if (RegisterWi232 > 0 && RegisterWi232 < 0xFF)
{ Wi232_hardware = 2;
Wi232_Baudrate = Wi232_57600; }
}
if (RegisterWi232 == 0)
{
USART_Init( UART_BAUD_SELECT(115200,F_CPU) ); /* 115200 suchen*/
lcd_printpns_at (0, 6, PSTR(" with 115200 Baud"),0);
RegisterWi232 = ReadWi232(regDiscover);
lcd_print_hex_at(18,6,RegisterWi232,0);
if (RegisterWi232 > 0 && RegisterWi232 < 0xFF)
{ Wi232_hardware = 2;
Wi232_Baudrate = Wi232_115200; }
}
_delay_ms(2000);
}
if (RegisterWi232 == 0)
{
lcd_cls();
lcd_printpns_at (0, 0, PSTR("no Wi.232 found"),0);
Wi232_hardware = 0;
_delay_ms(2000);
}
if (RegisterWi232 == 0xFF)
{
lcd_cls();
lcd_printpns_at (0, 0, PSTR("Wi.232 Sytaxerror "),0);
set_beep ( 1000, 0x0040, BeepNormal);
_delay_ms(2000);
RegisterWi232 = 0;
}
if (RegisterWi232 > 0 && RegisterWi232 < 0xFF)
{
lcd_cls();
if (Wi232_hardware ==1) // alles ok , Baudrate Wi232 passt
lcd_printpns_at (0, 0, PSTR("Wi.232 found "),0);
if (Wi232_hardware ==2) // Wi232 gefunden, aber falsche Baudrate
{
WiIsSet= false; //wenn hier 2400 gefunden wurde, ist Wi232 nicht initialisiert
lcd_printpns_at (0, 0, PSTR("Wi.232 wrong Baudrate"),0);
if (WriteWi232(regNVDATARATE,PKT_Baudrate)!=0) /* NV-Ram auf PKT-Baudrate setzen*/
{
lcd_printpns_at (0, 1, PSTR("Error set NV-RAM"),0);
set_beep ( 1000, 0x0040, BeepNormal);
_delay_ms(2000);
}
else
{
_delay_ms(1000);
lcd_printpns_at (0, 1, PSTR("NV-RAM is set to "),0);
lcd_printpns_at (0, 2, PSTR("given Baudrate"),0);
_delay_ms(2000);
}
if (WriteWi232(regDATARATE,PKT_Baudrate)!=0) /* Ram auf PKT_Baudrate setzen*/
{
lcd_printpns_at (0, 3, PSTR("Error set RAM "),0);
set_beep ( 1000, 0x0040, BeepNormal);
_delay_ms(2000);
}
else
{
_delay_ms(1000);
lcd_printpns_at (0, 1, PSTR("RAM is set to "),0);
lcd_printpns_at (0, 2, PSTR("given Baudrate"),0);
_delay_ms(2000);
}
SetUart0_Wi232(PKT_Baudrate);
Old_Baudrate = PKT_Baudrate;
}
lcd_cls_line (0,1,21);
lcd_printpns_at (0, 1, PSTR("Version:"),0);
lcd_print_hex_at(9,1,RegisterWi232,0);
}
clr_WI232CMD();
}
/*************************************************************************
Function: InitWI232()
Purpose: set Wi232Register for Mikrokopter
Returns: 0 = ACK, FF = NAK
**************************************************************************/
void InitWi232(uint8_t Baudrate)
{
uint8_t i = 0;
#ifdef HWVERSION3_9
Change_Output(Uart02Wi); // Verbindung zu Wi232 herstellen
#endif
discoverWi232(Old_Baudrate); // Check if Wi232 available
if (Wi232_hardware != 0)
{
lcd_printpns_at (0, 2, PSTR("Init Wi232 wait...."),0);
set_WI232CMD();
_delay_ms(200);
SwitchToWi232(); /* Serielle Kanäle Wi232 mit USB verbinden*/
// USART_Init( UART_BAUD_SELECT(57600,F_CPU) ); /* erstmal mit 57600 versuchen*/
if (WriteWi232(regNETGRP,126)!=0) /*damit Wi232 nix mehr vom Kopter schickt erstmal Networkgroup ins Nirwana setzen */
lcd_printpns_at (i++,4,PSTR("."),0);
// InitErr =12;
// Grund:
//If RF packets are received while the CMD line is active,
//they are still processed and presented to the moduleâs UART for transmission.
// wenn sich ein EEPROM-Wert ändert wird auch das Ram beschrieben damit die Ãnderung sofort wirksam wird
if (WriteWi232(regNVTXCHANNEL,WiTXRXChannel)!=0)
InitErrorWi232(1); /*TX Channel*/
lcd_printpns_at (i++,4,PSTR("."),0);
if (WriteWi232(regTXCHANNEL,WiTXRXChannel)!=0)
InitErrorWi232(2);/*TX Channel*/
lcd_printpns_at (i++,4,PSTR("."),0);
if (WriteWi232(regNVRXCHANNEL,WiTXRXChannel)!=0)
InitErrorWi232(3);/* RX Channel*/
lcd_printpns_at (i++,4,PSTR("."),0);
if (WriteWi232(regRXCHANNEL,WiTXRXChannel)!=0)
InitErrorWi232(4);/* RX Channel*/
lcd_printpns_at (i++,4,PSTR("."),0);
if (WriteWi232(regNVSLPMODE ,Sleep_Awake)!=0)
InitErrorWi232(5);/* Sleepmode*/
lcd_printpns_at (i++,4,PSTR("."),0);
if (WriteWi232(regNVPWRMODE,WbModeP15)!=0)
InitErrorWi232(6);/* Transceiver Mode/Powermode */
lcd_printpns_at (i++,4,PSTR("."),0);
if (WriteWi232(regNVTXTO,WiTXTO)!=0)
InitErrorWi232(7);/* UART Timeout */
lcd_printpns_at (i++,4,PSTR("."),0);
if (WriteWi232(regTXTO,WiTXTO)!=0)
InitErrorWi232(8);/* UART Timeout */
lcd_printpns_at (i++,4,PSTR("."),0);
if (WriteWi232(regNVUARTMTU,WiUartMTU)!=0)
InitErrorWi232(9);/* UART Buffer*/
lcd_printpns_at (i++,4,PSTR("."),0);
if (WriteWi232(regUARTMTU,WiUartMTU)!=0)
InitErrorWi232(10);/* UART Buffer*/
lcd_printpns_at (i++,4,PSTR("."),0);
if (WriteWi232(regNVNETMODE,WiNetworkMode)!=0)
InitErrorWi232(11);/* Networkmode*/
lcd_printpns_at (i++,4,PSTR("."),0);
if (WriteWi232(regNETMODE,WiNetworkMode)!=0)
InitErrorWi232(12);/* Networkmode*/
lcd_printpns_at (i++,4,PSTR("."),0);
if (WriteWi232(regNVUSECRC ,CRC_Enable)!=0)
InitErrorWi232(13);/* CRC*/
lcd_printpns_at (i++,4,PSTR("."),0);
if (WriteWi232(regNVCSMAMODE,CSMA_En)!=0)
InitErrorWi232(14);/* CSMA*/
lcd_printpns_at (i++,4,PSTR("."),0);
if (WriteWi232(regNVNETGRP,WiNetworkGroup)!=0)
InitErrorWi232(15);/* Networkgroup */
lcd_printpns_at (i++,4,PSTR("."),0);
if (WriteWi232(regNETGRP,WiNetworkGroup)!=0)
InitErrorWi232(15);/* Networkgroup */
lcd_printpns_at (i++,4,PSTR("."),0);
if (WriteWi232(regNVDATARATE,New_Baudrate)!=0)
InitErrorWi232(16);/* Baudrate*/
lcd_printpns_at (i++,4,PSTR("."),0);
if (WriteWi232(regDATARATE,New_Baudrate)!=0)
InitErrorWi232(17);/* Baudrate*/
lcd_printpns_at (i++,4,PSTR("."),0);
clr_WI232CMD();
if (InitErr !=0)
{
lcd_printpns_at (0, 2, PSTR("Wi232 InitError "),0);
lcd_print_hex(InitErr,0);
set_beep ( 1000, 0x0040, BeepNormal);
_delay_ms(2000);
}
else
{
lcd_printpns_at (0, 2, PSTR("Wi232 Init ok...."),0);
WriteWiInitFlag(); // Init merken
}
// USART_Init (UART_BAUD_SELECT(PKT_Baudrate,F_CPU));
SetUart0_Wi232(PKT_Baudrate);
Old_Baudrate = PKT_Baudrate;
_delay_ms(2000);
}
}
/*************************************************************************
Function: InitErrorWI232()
Purpose: Show Wi232 Error, Value
Returns:
**************************************************************************/
void InitErrorWi232(uint8_t Error)
{
lcd_printpns_at (0, 3, PSTR("Wi232 InitError "),0);
lcd_print_hex(Error,0);
InitErr=Error;
set_beep ( 500, 0x0040, BeepNormal);
_delay_ms(500);
}
/*************************************************************************
Function: WriteWI232()
Purpose: set Register to Wi232, Register, Value
Returns: 0 = ACK, FF = NAK
ACHTUNG nur für Value <0x80
**************************************************************************/
int16_t WriteWi232(uint8_t Wi232Register, uint8_t RegisterValue)
{
uint8_t timeout=10;
uint8_t tc=0;
unsigned int v;
USART_putc(0xff);
USART_putc(0x02);
USART_putc(Wi232Register);
USART_putc(RegisterValue);
// lcd_print_hex(Wi232Register,0);
// lcd_print_hex(RegisterValue,0);
do
{
v = USART_getc(); /*ACK erwartet*/
_delay_ms(100);
tc ++;
}
while (v==0 && tc!=timeout);
// lcd_print_hex(v,0);
if (v != 0x06)
{
lcd_printpns_at (0, 2, PSTR("Wi.232 NAK"),0);
set_beep ( 1000, 0x0040, BeepNormal);
_delay_ms(2000);
return 0xFF;
}
if (v==0x06)
return 0;
return 0xFF;
}
/*************************************************************************
Function: ReadWI232()
Purpose: send Readcommand to Wi232,
Returns: Registervalue, 0 = timeout 0xFF = Syntaxerror
**************************************************************************/
int16_t ReadWi232(uint16_t Wi232Register)
{
uint8_t timeout=10;
uint8_t tc=0;
unsigned int v;
v = USART_getc(); /*Zeichen löschen*/
USART_putc(0xff);
USART_putc(0x02);
USART_putc(0xfe);
USART_putc(Wi232Register);
_delay_ms(50);
// lcd_printpns_at (0, 2, PSTR("read Wi232"),0);
do
{
v = USART_getc(); /*ACK erwartet*/
_delay_ms(100);
tc ++;
}
while (v==0 && tc!=timeout);
if (tc == timeout)
return 0; /* Timeout*/
if (v != 0x06)
return 0xFF; /* Syntaxerror*/
lcd_print_hex(v,0);
v = USART_getc(); /*Register*/
// lcd_print_hex(v,0);
v = USART_getc(); /*Value*/
// lcd_print_hex(v,0);
return v;
}
/*************************************************************************
Function: EscapeString()
Purpose:
Returns:
Quelle: Radiotronix Wi.232 Manual
**************************************************************************/
int EscapeString(char *src, char src_len, char *dest)
{
// The following function copies and encodes the first
// src_len characters from *src into *dest. This
// encoding is necessary for Wi.232 command formats.
// The resulting string is null terminated. The size
// of this string is the function return value.
// ---------------------------------------------------
uint8_t src_idx, dest_idx;
// Save space for the command header and size bytes
// ------------------------------------------------
dest_idx = 2;
// Loop through source string and copy/encode
// ------------------------------------------
for (src_idx = 0; src_idx < src_len; src_idx++)
{
if (src[src_idx] > 127)
{
dest[dest_idx++] = 0xFE;
}
dest[dest_idx++] = (src[src_idx] & 0x7F);
}
// Add null terminator
// -------------------
dest[dest_idx] = 0;
// Add command header
// ------------------
dest[0] = 0xFF;
dest[1] = dest_idx-2;
// Return escape string size
// -------------------------
return dest_idx;
}
//#if defined HWVERSION1_3W || defined HWVERSION3_9
/*************************************************************************
Function: Wi232USB()
Purpose: Connect Wi232 Programmmode to PKT USB,
Returns:
**************************************************************************/
void Wi232_USB(void)
{
unsigned int c0,c1;
if (Wi232_hardware==1)
{
// USART_Init (UART_BAUD_SELECT(57600,F_CPU));
// uart1_init( UART_BAUD_SELECT(57600,F_CPU) );
// USART_Init (UART_BAUD_SELECT(2400,F_CPU));
// uart1_init( UART_BAUD_SELECT(2400,F_CPU) );
}
if (Wi232_hardware==2)
{
USART_Init (UART_BAUD_SELECT(2400,F_CPU));
uart1_init( UART_BAUD_SELECT(2400,F_CPU) );
}
lcd_cls ();
// SwitchToWi232(); /* Serielle Kanäle Wi232 mit USB verbinden*/
set_WI232CMD();
lcd_printpns_at (0, 0, PSTR("Wi.232 Konfiguration "),0);
lcd_printpns_at (0, 1, PSTR("PC mit USB verbinden"),0);
lcd_printpns_at (0, 2, PSTR("Wi.232"),0);
lcd_printpns_at (0, 3, PSTR("Programm starten"),0);
lcd_printpns_at (17, 7, PSTR("Exit"),0);
c1 = 0;
for(;;)
{
c0 = uart1_getc(); /* from USB*/
if ( c0 & UART_NO_DATA )
{
c1 = USART_getc();
if (c1 == 0)
{}
else
{
// lcd_print_hex(c1,0);
uart1_putc (c1); /*to USB*/;
}
}
else
{
USART_putc(c0 ); /* to Wi232*/
// lcd_print_hex(c0,0);
// _delay_ms(1);
}
if ((get_key_press (1 << KEY_ENTER)))
{
clr_WI232CMD();
// uart1_init( UART_BAUD_SELECT(57600,F_CPU) );
// USART_Init( UART_BAUD_SELECT(57600,F_CPU) );
// SwitchToFC();
return;
}
}
}
/*************************************************************************
Function: Wi232_FC()
Purpose: Connect Wi232 to PKT USB, Transparent
Returns:
**************************************************************************/
void Wi232_FC(void)
{
unsigned int c0,c1;
// USART_Init (UART_BAUD_SELECT(PKT_Baudrate,F_CPU));
// uart1_init( UART_BAUD_SELECT(PKT_Baudrate,F_CPU) );
//TODO: SetUart0_Wi232(PKT_Baudrate);
// SetUart1_Wi232(PKT_Baudrate);
lcd_cls ();
// SwitchToWi232(); /* Serielle Kanäle Wi232 mit USB verbinden*/
lcd_printpns_at (0, 0, PSTR("Wi.232 to FC "),0);
lcd_printpns_at (0, 1, PSTR("PC mit USB verbinden"),0);
lcd_printpns_at (0, 2, PSTR("und Mikrokoptertool"),0);
lcd_printpns_at (0, 3, PSTR("starten"),0);
lcd_printpns_at (17, 7, PSTR("Exit"),0);
c1 = 0;
for(;;)
{
c0 = uart1_getc(); /* from USB*/
if ( c0 & UART_NO_DATA )
{
c1 = USART_getc();
if (c1 == 0)
{}
else
{
// lcd_print_hex(c1,0);
uart1_putc (c1); /*to USB*/;
}
}
else
{
USART_putc(c0 ); /* to Wi232*/
// lcd_print_hex(c0,0);
// _delay_ms(1);
}
if ((get_key_press (1 << KEY_ENTER)))
{
return;
}
}
}
#endif