Skip to content

Commit

Permalink
synchronized SI7021 and GPS processes to run concurrently. Removed ca…
Browse files Browse the repository at this point in the history
…lls to exit critical and replaced them with a task notification in GPS.c. Created GPS uart handler function. Switched to using create binary semaphore.
  • Loading branch information
EasonNYC committed Apr 14, 2017
1 parent 2687c63 commit a92cc40
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 61 deletions.
1 change: 1 addition & 0 deletions include/GPS.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,5 @@ float getAltitudeSealvl(void);
uint8_t getFix(void);
void GPS_ppsHandler(uint32_t cur_msTicks);
uint8_t getGPS(GPS_pub* myGPS); //for public mass consumption
void GPS_uart2Handler(void);
#endif /* GPS_GPS_H_ */
101 changes: 61 additions & 40 deletions src/GPS.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,18 @@
//circular array
static volatile CircArr_InitTypeDef circarr; //first create 1 circular array buffer called msg

extern volatile uint8_t rx2Buff; //uart2 incoming byte buffer

static uint8_t FLAG_OKTOCOPYNAVDATA = 0;
static uint32_t tmp_timestamp = 0;
static uint32_t tmp_PPStimestamp = 0;

static SemaphoreHandle_t mutex_CIRCARR_RW;
static SemaphoreHandle_t mutex_NAVDATA = NULL;

static volatile TaskHandle_t GPS_xTaskHandle = NULL;


extern volatile uint32_t msTicks;

typedef union revint {
Expand Down Expand Up @@ -67,15 +72,6 @@ typedef struct NAVstruct { //payload of 59 bytes
uint32_t mcu_timestamp;
uint32_t pps_timestamp;
} NAVstruct;

/*todo: make byte aligned and try casting to struct without id
typedef union GPS {
uint8_t raw[NAVLEN];
NAVstruct current;
} GPS;
static GPS NAVdata, tmpNAVdata; //can access NAVdata.current.latitude etc.
*/

NAVstruct NAVdata, tmpNAVdata;//use for now


Expand All @@ -89,13 +85,16 @@ static GPSmsg gpsmsg;


//GPS State Machine
typedef enum {GETSTART, GETSTART2, GETLENGTH, GETPAYLOAD, GETCHECKSUM, GETTRAILER, VALIDATE} GPS_STATE;
typedef enum {GETSTART, GETSTART2, GETLENGTH, GETPAYLOAD, GETCHECKSUM, GETTRAILER} GPS_STATE;
static GPS_STATE state = GETSTART;

//todo: wait on fix. wait on pps up. init time conversion between micro and sat
void GPS_init(void) {

mutex_NAVDATA = xSemaphoreCreateMutex();
mutex_CIRCARR_RW = xSemaphoreCreateMutex();
mutex_CIRCARR_RW = xSemaphoreCreateBinary();

GPS_xTaskHandle = xTaskGetHandle("GPSTask");

initCircArray(&circarr,MAXPAYLOADLEN);//store incoming bytes
}
Expand Down Expand Up @@ -140,35 +139,46 @@ switch(IDBYTE){

uint8_t GPS_available(void) {
uint8_t b = 0;
taskENTER_CRITICAL();
b = buf_available(&circarr);
taskEXIT_CRITICAL();
return b;
}

//current callback function which puts an incoming uart byte into the GPS buffer.
//Puts an incoming uart byte into the GPS buffer. Called in GPS_uart2Callback
void GPS_putByte(uint8_t rxbyte){
buf_putbyte(&circarr,rxbyte);
}

//returns the next byte from the GPS buffer
uint8_t GPS_getByte(void){
uint8_t b = 0;
taskENTER_CRITICAL();
buf_getbyte(&circarr,&b);
taskEXIT_CRITICAL();
buf_getbyte(&circarr,&b);
return b;
}


//Main GPS State Machine processes incoming USART1 bytes into valid GPS Nav messages
//Main GPS State Machine
void processGPS(void){

//ok to timeout till next time
if(FLAG_OKTOCOPYNAVDATA){
if ( xSemaphoreTake( mutex_NAVDATA, (BaseType_t)10)== pdTRUE){
NAVdata = tmpNAVdata;
FLAG_OKTOCOPYNAVDATA = 0;
xSemaphoreGive(mutex_NAVDATA);
}
}


//**BLOCK!**
const TickType_t xMaxBlockTime = portMAX_DELAY;
uint32_t notifier = ulTaskNotifyTake( pdTRUE, xMaxBlockTime );
//**UNBLOCK**

switch(state){
case GETSTART:
//wait for 2 bytes over usart //split this up
if(GPS_available()){

//save timestamp
if(GPS_available()){
//wait for 1 byte
tmp_timestamp = msTicks;
uint8_t received1 = GPS_getByte();

Expand All @@ -177,15 +187,14 @@ void processGPS(void){
}
else
{
//(keep state the same)
GPSstatus.s1_error++;
break;
}

}
break;
case GETSTART2:

//wait for 1 byte
if(GPS_available()){
uint8_t received2 = GPS_getByte();
if(received2 == START2){
Expand All @@ -207,12 +216,11 @@ void processGPS(void){
uint16_t len = highbyte | lowbyte;
gpsmsg.payload_length = len;

if(gpsmsg.payload_length > MAXPAYLOADLEN) { //catch early
if(gpsmsg.payload_length > MAXPAYLOADLEN) {
GPSstatus.payload_length_error++;
state = GETSTART;
break;
}
else {
} else {
gpsmsg.calculated_checksum = 0; //init to 0
state = GETPAYLOAD;
}
Expand All @@ -222,7 +230,7 @@ void processGPS(void){
//wait for payload_length-1 bytes;
if(GPS_available() > (gpsmsg.payload_length-1)){
for(uint16_t i = 0;i < gpsmsg.payload_length;i++){
uint8_t incomingbyte = GPS_getByte(); //take 1 byte from GPS buffer
uint8_t incomingbyte = GPS_getByte();
gpsmsg.payload[i] = incomingbyte;
gpsmsg.calculated_checksum ^= incomingbyte;
}
Expand Down Expand Up @@ -254,33 +262,36 @@ void processGPS(void){
state = GETSTART;
break;
}
state = VALIDATE;
break;//while

//validate CRC here then process the data
if(gpsmsg.calculated_checksum == gpsmsg.received_checksum) {
GPSstatus.payloadOK++;
HandlePayload(gpsmsg.payload,gpsmsg.payload_length); //process data
}
else {
GPSstatus.chksum_error++;
}
state = GETSTART;
}
break;//case
break;
}
/*
case VALIDATE:
//todo: timestamp/offset
//validate checksum
if(gpsmsg.calculated_checksum == gpsmsg.received_checksum) {
GPSstatus.payloadOK++;
//handle message
HandlePayload(gpsmsg.payload,gpsmsg.payload_length);
HandlePayload(gpsmsg.payload,gpsmsg.payload_length); //handle message
}
else {
GPSstatus.chksum_error++;
}
state = GETSTART;
break;
}
*/


//non-blocking (1Hz copy)
if(FLAG_OKTOCOPYNAVDATA){
if ( xSemaphoreTake( mutex_NAVDATA, (BaseType_t)10)== pdTRUE){
NAVdata = tmpNAVdata;
FLAG_OKTOCOPYNAVDATA = 0;
xSemaphoreGive(mutex_NAVDATA);}
}

}//end GPSprocess

Expand Down Expand Up @@ -370,5 +381,15 @@ uint8_t getGPS(GPS_pub* myGPS){
return 1;
}

//runs when a GPS related byte comes in via uart2. Called in rxcompleteISR in main.c
void GPS_uart2Handler(void){
GPSstatus.chars_recvd++;
GPS_putByte(rx2Buff); //put byte in circular array

BaseType_t xHigherPriorityTaskWoken = pdFALSE;
vTaskNotifyGiveFromISR( GPS_xTaskHandle, &xHigherPriorityTaskWoken );//unblock GPS process thread

portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}


7 changes: 4 additions & 3 deletions src/freertos.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,12 @@ void MX_FREERTOS_Init(void) {
//GPS Sensor
osThreadDef(GPSTask, GPSProcessTask, osPriorityNormal, 0, 128); //
GPSTaskHandle = osThreadCreate(osThread(GPSTask), NULL);
GPS_init();

//SI7021 Rel Humidity and Temperature Sensor
osThreadDef(SI7021Task, SI7021ProcessTask, osPriorityNormal, 0, 128);
//SI7021TaskHandle = osThreadCreate(osThread(SI7021Task), NULL);
//SI7021_init();
SI7021TaskHandle = osThreadCreate(osThread(SI7021Task), NULL);
SI7021_init();

//GEIGER counter
osThreadDef(GEIGERTask, GEIGERProcessTask, osPriorityNormal, 0, 128);
Expand Down Expand Up @@ -161,7 +162,7 @@ void StartDefaultTask(void const * argument)
HAL_GPIO_TogglePin(GPIOD,LD6_Pin);

getGPS(&myGPSPUB);
//getSI7021(&mySIPUB);
getSI7021(&mySIPUB);
getGEIGER(&myGEIGERPUB);
osDelay(1200);

Expand Down
29 changes: 11 additions & 18 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,12 @@ int main(void)

/* USER CODE BEGIN 2 */

HAL_UART_Receive_DMA(&huart2, &rx2Buff, 1);//only call once before starting main freeRTOS threads
HAL_TIM_Base_Start_IT(&htim9);
//HAL_
HAL_UART_Receive_DMA(&huart2, &rx2Buff, 1);//for DMA only call once before starting threads
HAL_TIM_Base_Start_IT(&htim9); //1sec timer for geiger CPS/CPM calcs
//HAL_I2C_Master_Receive_DMA(&hi2c1, 0x40, &i2c1rxBuff, 1);

//init periphs
GPS_init();
//GEIG_init(), SI7021_init() called in freertos.c
//inits


/* USER CODE END 2 */

Expand Down Expand Up @@ -213,19 +211,16 @@ void SystemClock_Config(void)

//all incoming uart messages go thru this handler after data arrives
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
//printf("[data arrived]\n");

if(huart->Instance == USART2){
//dataArrived = 1;
//xQueueSendToBackFromISR(queue_GPS,&rx2Buff,NULL);
GPSstatus.chars_recvd++;
GPS_putByte(rx2Buff);

GPS_uart2Handler();
}

else if(huart->Instance == USART3) { //for GEIGER COUNTER (alternate transmission port)
else if(huart->Instance == USART3) { //for GEIGER COUNTER (alternate transmission port option)

if(rx2Buff == 0x0 || rx2Buff == 0x1)
GEIG_incClick(); //no mutex because a few extra clicks in cps readings are acceptable
GEIG_incClick();
}
}

Expand Down Expand Up @@ -265,10 +260,8 @@ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
GEIG_incClick();
}
else if (GPIO_Pin == EXT10_GPS_1PPS_Pin){ //GPS RECEIVER
//notgeigdatarec++;
GPS_ppsHandler(msTicks);
}

}


Expand All @@ -295,10 +288,10 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

}
/* USER CODE BEGIN Callback 1 */
if (htim->Instance == TIM9) { //1Hz Geiger timer
if (htim->Instance == TIM9) { //1Hz Geiger timer
ticks++;
//process CPS,CPM, reset click count
GEIG_tmrHandler();

GEIG_tmrHandler();//process CPS,CPM, reset click count

}

Expand Down

0 comments on commit a92cc40

Please sign in to comment.