##// END OF EJS Templates
Versión inicial de los bloques de comunicación para el módulo de procesamiento.
Versión inicial de los bloques de comunicación para el módulo de procesamiento.

File last commit:

r209:210
r219:220
Show More
gnss.cpp
323 lines | 7.7 KiB | text/x-c | CppLexer
/*
* 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
}