NEO-6M GPS Module Receiving Poor Data
Hello board. I am attempting to implement an STM32F0 to receive data from a GPS module, a NEO-6M in this case, and then transmit it to an external LoRa module.
I am attempting to implement this by initializing a ring buffer and inserting information one character at a time via a UART global interrupt (code below).
To keep the ISR short, I set a flag and disable the ISR at the end of the call to allow the main function to process the data.
I then store the newly stored element in the ring buffer to a different "packet_buffer" in order to allow me to check if the NMEA sentence is correct, which I check for utilizing the minmea library from GitHub.
Here is the issue: Utilizing the current program, I'm--at best--able to get one correct transmission out to an external UART logger (which I'm using to debug the program). In most cases, however, I'm simply getting a "Bad Data" message, which tells me that the data I'm receiving into the buffer isn't high quality, or even passable at that.
The GPS module is getting a lock, so I'm at a bit of a mental-block as to what could be going on software-wise.
Thank you in advance.
#include "main.h"
#include "ChangeClockTo48Mhz.h"
#include "string.h"
#include "minmea.h"
#include "Ring_Buffer.h"
#define BUFFERSIZE 120
volatile uint8_t packet_buffer[BUFFERSIZE] = "\0";
volatile int Packet_Flag;
volatile int packet_index;
volatile int Buffer_Flag;
volatile uint8_t temp_hold;
char *newline;
//Pre-Defined Size of 256 in Header
ring_buffer rbuffer;
void TransmitChar(USART_TypeDef* USARTx, uint8_t ch);
void TransmitString(USART_TypeDef* USARTx, uint8_t * str);
void put_in_buffer(uint8_t entry);
int get_from_que(uint8_t *entry);
void Send_To_LoRa(USART_TypeDef* USARTx);
void SetupRegs(void);
int main(void)
{
HAL_Init();
ChangeInternalClockTo48MHZ();
SetupRegs();
NVIC_EnableIRQ(USART1_IRQn);
while (1)
{
if(Packet_Flag)
{
temp_hold = rbuffer_get(&rbuffer);
packet_buffer[packet_index++] = temp_hold;
if(packet_index >= BUFFERSIZE)
{
Buffer_Flag = 1;
packet_index = 0;
}
if(minmea_check(packet_buffer, true))
{
Send_To_LoRa(USART1);
packet_index = 0;
memset(packet_buffer, 0, strlen(packet_buffer));
}
else
{
TransmitString(USART1, "Bad Data\n");
packet_index = 0;
memset(packet_buffer, 0, strlen(packet_buffer));
}
Packet_Flag = 0;
__enable_irq();
}
}
}
void USART1_IRQHandler(void)
{
if(USART1->ISR & (USART_ISR_ORE | USART_ISR_PE))
{
USART1->ICR |= USART_ICR_ORECF;
}
if ((USART1->ISR & USART_ISR_RXNE))
{
// put_in_buffer(USART1->RDR);
rbuffer_put(&rbuffer, USART1->RDR);
Packet_Flag = 1;
__disable_irq();
}
}
void TransmitChar(USART_TypeDef* USARTx, uint8_t ch){
while(!(USARTx->ISR & USART_ISR_TXE));
USART1->TDR = ch;
}
void TransmitString(USART_TypeDef* USARTx, uint8_t* str){
while(*str != 0)
{
TransmitChar(USARTx, *str);
str++;
}
}
void Send_To_LoRa(USART_TypeDef* USARTx){
uint8_t AT_SEND_CMD[125] = "AT+SEND=1,100,";
//ERROR WITH 2nd Argument String
strcat(AT_SEND_CMD, packet_buffer);
TransmitString(USARTx, (uint8_t*) AT_SEND_CMD );
//TransmitString(USARTx, (uint8_t*) packet_buffer);
}
void SetupRegs(void){
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
//Mode Register
GPIOA->MODER &= ~(GPIO_MODER_MODER9_0 | GPIO_MODER_MODER10_0);
GPIOA->MODER |= (GPIO_MODER_MODER9_1 | GPIO_MODER_MODER10_1);
//Speed Register
GPIOA->OSPEEDR &= (GPIO_OSPEEDR_OSPEEDR9 | GPIO_OSPEEDR_OSPEEDR10);
//PUPDR Register (Pulled High)
GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPDR9 | GPIO_PUPDR_PUPDR10);
GPIOA->PUPDR |= (GPIO_PUPDR_PUPDR9_0 | GPIO_PUPDR_PUPDR10_0);
//Type Register
GPIOA->OTYPER &= ~(GPIO_OTYPER_OT_9 | GPIO_OTYPER_OT_10);
//Set the Alternate Functions
GPIOA->AFR[1] &= ~(GPIO_AFRH_AFRH1 | GPIO_AFRH_AFRH2);
GPIOA->AFR[1] |= (1 << 4) | (1 << 8);
//Enable USART1
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
//Baud Rate and Oversampling
USART1->BRR = 0x1388;
USART1->CR1 &= ~USART_CR1_OVER8;
USART1->CR3 &= ~USART_CR3_ONEBIT;
//Setting Word Length
USART1->CR1 &= ~(USART_CR1_M);
//Disable Parity Bit
USART1->CR1 &= ~USART_CR1_PCE;
//Stop Bit
USART1->CR2 &= ~USART_CR2_STOP;
//Enable Transmission
USART1->CR1 |= USART_CR1_TE;
//Enable Receiving Interrupt
USART1->CR1 |= USART_CR1_RXNEIE;
USART1->CR1 |= USART_CR1_RE;
//Enable USART
USART1->CR1 |= USART_CR1_UE;
}
Here is the ring buffer header + src files
/*
* Ring_Buffer.c
*
* Created on: Sep 2, 2024
*
*/
#include "Ring_Buffer.h"
#include <stdint.h>
void rbuffer_initialize(ring_buffer *rbuffer){
rbuffer->read_index = 0;
rbuffer->write_index = 0;
}
void rbuffer_put(ring_buffer *rbuffer, uint8_t entry){
rbuffer->buffer[rbuffer->write_index++] = entry;
}
uint8_t rbuffer_get(ring_buffer *rbuffer)
{
return rbuffer->buffer[rbuffer->read_index++];
}///Ring_Buffer.h
#ifndef RING_BUFFER_H_
#define RING_BUFFER_H_
#include <stdint.h>
typedef struct
{
uint8_t buffer[256];
volatile uint8_t write_index;
volatile uint8_t read_index;
}ring_buffer;
void rbuffer_initialize(ring_buffer *rbuffer);
void rbuffer_put(ring_buffer *rbuffer, uint8_t entry);
uint8_t rbuffer_get(ring_buffer *rbuffer);
#endif /*RING_BUFFER_H_ */
