|
|
/*
|
|
|
* gnss.cpp
|
|
|
*
|
|
|
* Created on: Dec 29, 2014
|
|
|
* Author: aras
|
|
|
*/
|
|
|
|
|
|
#include "gnss.h"
|
|
|
|
|
|
namespace te_gnss{
|
|
|
|
|
|
/**
|
|
|
* \fn configure
|
|
|
* \brief Realiza la configuracion inicial antes de operar.
|
|
|
* Establece el baudrate del operacion. Primero autodetecta el baudrate del
|
|
|
* receptor y luego la cambia ala deseada.
|
|
|
* Tambien activa las trmas NMEA deseadas.
|
|
|
* \param gcs estructura de configuracion del receptor gnss
|
|
|
* \return "true" si se ha configurado correctamente.
|
|
|
* \see gnss_config_struct
|
|
|
*/
|
|
|
bool configure(gnss_config_struct &gcs) {
|
|
|
bool r;
|
|
|
r = activate();
|
|
|
r = r && set_baudrate(gcs.baudrate);
|
|
|
r = r && set_position(gcs.lat,gcs.lon);
|
|
|
return r && activate_nmea_frames(gcs.nmea_mask);
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* \fn activate
|
|
|
* \brief Le da energia de fuente al receptor GNSS a traves de un regulador
|
|
|
* con pin de "enable".
|
|
|
* \return '0', si falla. Diferente de '0' ("true") si se ha configurado
|
|
|
* correctamente.
|
|
|
* \see deactivate
|
|
|
*/
|
|
|
bool activate() {
|
|
|
PORTD |= (1<<PK0);
|
|
|
return PORTD & (1<<PK0);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* \fn deactivate
|
|
|
* \brief Le quita energia de fuente al receptor GNSS a traves de un regulador
|
|
|
* con pin de "enable".
|
|
|
* \return '0', si falla. Diferente de '0' ("true") si se ha configurado
|
|
|
* correctamente.
|
|
|
* \see activate
|
|
|
*/
|
|
|
bool deactivate() {
|
|
|
PORTD &= ~(1<<PK0);
|
|
|
return (~PORTD) & (1<<PK0);
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* \fn set_baudrate
|
|
|
* \brief Autodetecta el baudrate del receptor y luego la cambia al deseado.
|
|
|
* \param baud El baudrate en 16 bits
|
|
|
* \return "true" si se ha configurado correctamente.
|
|
|
*/
|
|
|
bool set_baudrate(uint16_t baud){
|
|
|
if(not scan_baud_success){
|
|
|
scan_baud_finish = false;
|
|
|
scan_baudrate();
|
|
|
while(not scan_baud_finish){}// TODO sleep()
|
|
|
}
|
|
|
if(scan_baud_success){
|
|
|
write_baud(GNSS_PORT,baud);
|
|
|
}else{
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* \fn wait_to_be_locked
|
|
|
* \brief Bloquea el flujo del programa hasta que el receptor GNSS se haya
|
|
|
* "enganchado" (sincronizado con satelites) correctamente.
|
|
|
* \return "true" si se ha enganchado correctamente. "false" luego de
|
|
|
* "LOCK_IDX_MAX" intentos o si no se ha configurado el baudrate
|
|
|
* \see LOCK_IDX_MAX
|
|
|
* \see scan_lock_func
|
|
|
*/
|
|
|
bool wait_to_be_locked(){
|
|
|
scan_lock_finish = false;
|
|
|
scan_lock_success = false;
|
|
|
if(scan_baud_success){
|
|
|
lock_idx = 0;
|
|
|
push(pfunc_pps);
|
|
|
pfunc_pps = &scan_lock_func;
|
|
|
while(! scan_lock_finish){}// TODO sleep()
|
|
|
if(scan_lock_success){
|
|
|
PORTL != (1<<PL7);
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* \fn get_pps_data
|
|
|
* \brief Inicia la recoleccion de data del receptor GNSS
|
|
|
* \param raw "true", si se va a enviar al mbebido las tramas tal cual.
|
|
|
* "flase", si se va a enviar las tramas procesadas (informacion relevante,
|
|
|
* recomendable para operacion normal)
|
|
|
* \return "true", si inicia corecctamente. "false" si no se ha configurado
|
|
|
* el baudrate
|
|
|
* \see get_pps_data_func
|
|
|
* \see set_baudrate
|
|
|
*/
|
|
|
bool get_pps_data(bool raw){
|
|
|
if(scan_baud_success){
|
|
|
is_raw = raw;
|
|
|
stk_ptr = 0;
|
|
|
stack[0] = NULL;
|
|
|
pfunc_pps = &get_pps_data_func;
|
|
|
}else{
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* \fn set_position
|
|
|
* \brief Configura la posicion actual en el receptor GNSS. Para receptores
|
|
|
* nuevos, estos han sido probados en el hemiferio norte muy lejos de la
|
|
|
* ubicacion donde sera puesto. En este caso el algoritmo de acercamiento
|
|
|
* progresivo que usan los receptores GNSS puede tomar varios minutos en
|
|
|
* hallar la posicion correcta (decenas de minutos). Por ello es recomendable
|
|
|
* configurarles, por lo menos una posicion cercana a su ubicacion final.
|
|
|
* Esto puede ser critico si se instala en el campo.
|
|
|
* Los numeros decimales que representan a la latitud y longitud son de punto
|
|
|
* fijo de la libreria "fixpoint.h" adjunta al codigo fuente.
|
|
|
* \param lat Latitud de la posicion.
|
|
|
* \param lon Longitud de la posicion.
|
|
|
* \return "true", si configura la posicion corecctamente. "false" si no se ha
|
|
|
* configurado.
|
|
|
*/
|
|
|
bool set_position(fix32 lat, fix32 lon){
|
|
|
return true; // TODO all
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* \fn get_pps_data
|
|
|
* \brief Inicia la recoleccion de data del receptor GNSS
|
|
|
* \param raw "true", si se va a enviar al mbebido las tramas tal cual.
|
|
|
* "flase", si se va a enviar las tramas procesadas (informacion relevante,
|
|
|
* recomendable para operacion normal)
|
|
|
* \return "true", si inicia corecctamente. "false" si no se ha configurado
|
|
|
* el baudrate
|
|
|
* \see get_pps_data_func
|
|
|
* \see set_baudrate
|
|
|
*/
|
|
|
bool activate_nmea_frames(uint16_t pars_mask){
|
|
|
#ifndef MICROCONTROLLER
|
|
|
initialize(pars_mask, synt_mask);
|
|
|
#else
|
|
|
nmea::initialize(pars_mask);
|
|
|
#endif
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* \fn ISR_pps
|
|
|
* \brief Interrupcion hardware. Se ejecuta cada vez que el receptor GNSS
|
|
|
* genera un pulso por segundo.
|
|
|
* Esta solo ejecuta una funcion, cualquiera que sea a la que apunta el
|
|
|
* puntero a funcion "pfunc_pps"
|
|
|
* \see pfunc_pps
|
|
|
*/
|
|
|
void ISR_pps(){
|
|
|
pfunc_pps();
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* \fn push
|
|
|
* \brief Almacena en una pila la funcion apuntada por "pfunc"
|
|
|
* \param pfunc funcion que sera almacenada en pila
|
|
|
* \see pop
|
|
|
*/
|
|
|
void push(void (*pfunc)()){
|
|
|
if(stk_ptr >= 5) return;
|
|
|
stack[stk_ptr++]=pfunc;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* \fn pop
|
|
|
* \brief Recupera de la pila la primera funcion y la devuelve en "pfunc"
|
|
|
* \param pfunc apuntara a la funcion recuperada de la pila.
|
|
|
* \see push
|
|
|
*/
|
|
|
void pop(void (*pfunc)()){
|
|
|
if(stk_ptr == 0) return;
|
|
|
pfunc = stack[--stk_ptr];
|
|
|
stack[stk_ptr]=NULL;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* \fn scan_baudrate
|
|
|
* \brief Inicia la funcion de escaneo en el puerto uart conectado al GNSS,
|
|
|
* con la finalidad de determinar que baudrate esta configurado
|
|
|
* \see scan_baudrate_func
|
|
|
*/
|
|
|
void scan_baudrate(){
|
|
|
baud_idx = 0;
|
|
|
write_baud(GNSS_PORT,BAUDRATE(baud_idx));
|
|
|
push(pfunc_pps);
|
|
|
pfunc_pps = &scan_baud_func;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* \fn scan_baudrate_func
|
|
|
* \brief Escanea el puerto uart conectado al GNSS, con la finalidad de
|
|
|
* determinar que baudrate esta configurado.
|
|
|
* \see scan_baudrate
|
|
|
*/
|
|
|
void scan_baud_func(){
|
|
|
if(is_gnss_frame_valid()){
|
|
|
pop(pfunc_pps);
|
|
|
scan_baud_finish = true;
|
|
|
scan_baud_success = true;
|
|
|
}else{
|
|
|
baud_idx++;
|
|
|
if(baud_idx < BAUD_IDX_MAX){
|
|
|
write_baud(GNSS_PORT,BAUDRATE(baud_idx));
|
|
|
}else{
|
|
|
pop(pfunc_pps);
|
|
|
scan_baud_finish = true;
|
|
|
scan_baud_success = false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* \fn scan_lock_func
|
|
|
* \brief Escanea las tramas generadas por el receptor GNSS, con la finalidad de
|
|
|
* determinar si esta enganchado o no.
|
|
|
* \see wait_to_be_locked
|
|
|
*/
|
|
|
void scan_lock_func(){
|
|
|
if(is_locked()){
|
|
|
pop(pfunc_pps);
|
|
|
scan_lock_finish = true;
|
|
|
scan_lock_success = true;
|
|
|
}else{
|
|
|
lock_idx++;
|
|
|
if(lock_idx >= LOCK_IDX_MAX){
|
|
|
pop(pfunc_pps);
|
|
|
scan_lock_finish = true;
|
|
|
scan_lock_success = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* \fn get_pps_data_func
|
|
|
* \brief lee y procesa las tramas generadas por el receptor GNSS
|
|
|
* \see get_pps_data
|
|
|
*/
|
|
|
void get_pps_data_func(){
|
|
|
char* fr = readline(GNSS_PORT);
|
|
|
if(!is_raw){
|
|
|
process_frame(fr);
|
|
|
}else{
|
|
|
writeline(RBP_PORT,fr);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* \fn is_gnss_frame_valid
|
|
|
* \brief Si todos los caracteres de la trama leida son imprimibles, entonces
|
|
|
* la trama sera considerada valida.
|
|
|
* Se utiliza para determinar si el baudrate es correcto, ya que de no serlo,
|
|
|
* habran caracteres no imprimibles por la desincronizacion.
|
|
|
* \return "true" si la trama es valida; "false" de lo contrario.
|
|
|
*/
|
|
|
bool is_gnss_frame_valid(){
|
|
|
uint8_t idx;
|
|
|
char* fr = readline(GNSS_PORT);
|
|
|
uint8_t sz = strlen(fr);
|
|
|
for(idx=0;idx<sz;idx++){
|
|
|
if(!isprint(fr[idx]))
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* \fn is_locked
|
|
|
* \brief Lee las tramas NMEA y busca en ellas la informacion referente a el
|
|
|
* enganche del receptor a los satelites.
|
|
|
* \return "true" si esta enganchado; "false" de lo contrario.
|
|
|
*/
|
|
|
bool is_locked() {
|
|
|
char* fr = readline(GNSS_PORT);
|
|
|
if(strstr(fr,",A,")){
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* \fn process_frame
|
|
|
* \brief Procesa la cadena de tramas en fr. Para lo cual usa el parser de la
|
|
|
* librteria libnmea++
|
|
|
* \param fr
|
|
|
*/
|
|
|
void process_frame(const char* fr){
|
|
|
|
|
|
}
|
|
|
// TODO
|
|
|
|
|
|
}
|
|
|
|