gnss.cpp
323 lines
| 7.7 KiB
| text/x-c
|
CppLexer
|
r177 | /* | ||
* gnss.cpp | ||||
* | ||||
* Created on: Dec 29, 2014 | ||||
* Author: aras | ||||
*/ | ||||
|
r209 | #include "gnss.h" | ||
|
r177 | |||
|
r209 | namespace te_gnss{ | ||
|
r177 | |||
|
r209 | /** | ||
* \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) { | ||||
|
r203 | 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); | ||||
} | ||||
|
r177 | |||
|
r203 | |||
|
r209 | /** | ||
* \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() { | ||||
|
r203 | PORTD |= (1<<PK0); | ||
return PORTD & (1<<PK0); | ||||
} | ||||
|
r209 | /** | ||
* \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() { | ||||
|
r203 | PORTD &= ~(1<<PK0); | ||
return (~PORTD) & (1<<PK0); | ||||
} | ||||
|
r209 | /** | ||
* \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){ | ||||
|
r203 | if(not scan_baud_success){ | ||
scan_baud_finish = false; | ||||
scan_baudrate(); | ||||
while(not scan_baud_finish){}// TODO sleep() | ||||
|
r177 | } | ||
|
r203 | if(scan_baud_success){ | ||
write_baud(GNSS_PORT,baud); | ||||
}else{ | ||||
return false; | ||||
} | ||||
return true; | ||||
} | ||||
|
r177 | |||
|
r209 | /** | ||
* \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(){ | ||||
|
r203 | 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; | ||||
} | ||||
|
r177 | } | ||
|
r203 | return false; | ||
} | ||||
|
r177 | |||
|
r209 | /** | ||
* \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){ | ||||
|
r203 | if(scan_baud_success){ | ||
is_raw = raw; | ||||
stk_ptr = 0; | ||||
|
r209 | stack[0] = NULL; | ||
|
r203 | pfunc_pps = &get_pps_data_func; | ||
}else{ | ||||
return false; | ||||
|
r177 | } | ||
|
r203 | return true; | ||
} | ||||
|
r177 | |||
|
r209 | /** | ||
* \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){ | ||||
|
r203 | return true; // TODO all | ||
} | ||||
|
r196 | |||
|
r209 | /** | ||
* \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; | ||||
} | ||||
|
r203 | |||
|
r209 | /** | ||
* \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(); | ||||
|
r177 | } | ||
|
r203 | |||
|
r209 | /** | ||
* \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; | ||||
|
r203 | } | ||
|
r209 | /** | ||
* \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; | ||||
} | ||||
|
r203 | |||
|
r209 | |||
/** | ||||
* \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; | ||||
|
r203 | } | ||
|
r209 | |||
/** | ||||
* \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 | ||||
} | ||||