Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Completed onboarding challenge #101

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*.a
*.la
*.lo
_deps

# Shared objects (inc. Windows DLLs)
*.dll
Expand Down Expand Up @@ -50,10 +51,12 @@ modules.order
Module.symvers
Mkfile.old
dkms.conf
.cache

# IDE files
.vscode/
.idea/
.DS_Store

.venv/
venv/
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ elseif(CMAKE_BUILD_TYPE MATCHES FW)
sys/i2c/i2c_io.c
sys/logging/logging.c
services/controller/controller.c

lm75bd/lm75bd.c
services/thermal_mgr/thermal_mgr.c
)
Expand Down
69 changes: 44 additions & 25 deletions lm75bd/lm75bd.c
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
#include "lm75bd.h"
#include "i2c_io.h"
#include "console.h"
#include "errors.h"
#include "i2c_io.h"
#include "logging.h"

#include <math.h>
#include <stdint.h>
#include <string.h>
#include <math.h>

/* LM75BD Registers (p.8) */
#define LM75BD_REG_CONF 0x01U /* Configuration Register (R/W) */
#define LM75BD_REG_CONF 0x01U /* Configuration Register (R/W) */

error_code_t lm75bdInit(lm75bd_config_t *config) {
error_code_t errCode;

if (config == NULL) return ERR_CODE_INVALID_ARG;
if (config == NULL)
return ERR_CODE_INVALID_ARG;

RETURN_IF_ERROR_CODE(writeConfigLM75BD(config->devAddr, config->osFaultQueueSize, config->osPolarity,
config->osOperationMode, config->devOperationMode));
RETURN_IF_ERROR_CODE(writeConfigLM75BD(
config->devAddr, config->osFaultQueueSize, config->osPolarity,
config->osOperationMode, config->devOperationMode));

// Assume that the overtemperature and hysteresis thresholds are already set
// Hysteresis: 75 degrees Celsius
Expand All @@ -26,14 +29,29 @@ error_code_t lm75bdInit(lm75bd_config_t *config) {
}

error_code_t readTempLM75BD(uint8_t devAddr, float *temp) {
/* Implement this driver function */

// check if temp is allocated
if (!temp)
return ERR_CODE_NULL_ARG;

Shrey-Varma marked this conversation as resolved.
Show resolved Hide resolved
// set pointer register to temperature
uint8_t buf[1] = {LM75BD_OBC_TEMP_REG};
error_code_t errCode;
RETURN_IF_ERROR_CODE(i2cSendTo(devAddr, buf, 1));
// read data from sensor
uint8_t tempBytes[2] = {0};
RETURN_IF_ERROR_CODE(i2cReceiveFrom(devAddr, tempBytes, 2));

// convert bytes to temperature
int16_t combined = ((tempBytes[0] << 8) | tempBytes[1]);
combined = combined >> 5;
*temp = combined * 0.125;
return ERR_CODE_SUCCESS;
}

#define CONF_WRITE_BUFF_SIZE 2U
error_code_t writeConfigLM75BD(uint8_t devAddr, uint8_t osFaultQueueSize, uint8_t osPolarity,
uint8_t osOperationMode, uint8_t devOperationMode) {
error_code_t writeConfigLM75BD(uint8_t devAddr, uint8_t osFaultQueueSize,
uint8_t osPolarity, uint8_t osOperationMode,
uint8_t devOperationMode) {
error_code_t errCode;

// Stores the register address and data to be written
Expand All @@ -45,20 +63,20 @@ error_code_t writeConfigLM75BD(uint8_t devAddr, uint8_t osFaultQueueSize, uint8_

uint8_t osFaltQueueRegData = 0;
switch (osFaultQueueSize) {
case 1:
osFaltQueueRegData = 0;
break;
case 2:
osFaltQueueRegData = 1;
break;
case 4:
osFaltQueueRegData = 2;
break;
case 6:
osFaltQueueRegData = 3;
break;
default:
return ERR_CODE_INVALID_ARG;
case 1:
osFaltQueueRegData = 0;
break;
case 2:
osFaltQueueRegData = 1;
break;
case 4:
osFaltQueueRegData = 2;
break;
case 6:
osFaltQueueRegData = 3;
break;
default:
return ERR_CODE_INVALID_ARG;
}

buff[1] |= (osFaltQueueRegData << 3);
Expand All @@ -67,7 +85,8 @@ error_code_t writeConfigLM75BD(uint8_t devAddr, uint8_t osFaultQueueSize, uint8_
buff[1] |= devOperationMode;

errCode = i2cSendTo(LM75BD_OBC_I2C_ADDR, buff, CONF_WRITE_BUFF_SIZE);
if (errCode != ERR_CODE_SUCCESS) return errCode;
if (errCode != ERR_CODE_SUCCESS)
return errCode;

return ERR_CODE_SUCCESS;
}
24 changes: 16 additions & 8 deletions lm75bd/lm75bd.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <stdint.h>

/* LM75BD I2C Device Address */
#define LM75BD_OBC_I2C_ADDR /* Define the address here */
#define LM75BD_OBC_I2C_ADDR 0x4F /* Define the address here */

/* LM75BD Configuration Values */
#define LM75BD_DEV_OP_MODE_NORMAL 0x00U
Expand All @@ -17,6 +17,8 @@
#define LM75BD_OS_OP_MODE_COMP 0x00U
#define LM75BD_OS_OP_MODE_INT 0x01U

#define LM75BD_OBC_TEMP_REG 0x00

// Default temperature thresholds
#define LM75BD_DEFAULT_OT_THRESH 80.0f
#define LM75BD_DEFAULT_HYST_THRESH 75.0f
Expand All @@ -25,11 +27,14 @@
* @struct Configuration struct for LM75BD,118 temperature sensor
*
* @param devAddr I2C address of the LM75BD
* @param osFaultQueueSize Number of consecutive OS faults until OS output is activated (1, 2, 4, or 6)
* @param osFaultQueueSize Number of consecutive OS faults until OS output is
* activated (1, 2, 4, or 6)
* @param osPolarity OS output polarity, 0 = active low, 1 = active high
* @param osOperationMode OS output operation mode, 0 = comparator, 1 = interrupt
* @param osOperationMode OS output operation mode, 0 = comparator, 1 =
* interrupt
* @param devOperationMode Device operation mode, 0 = normal, 1 = shutdown
* @param overTempThreshold Overtemperature shutdown threshold, in degrees Celsius
* @param overTempThreshold Overtemperature shutdown threshold, in degrees
* Celsius
* @param hysteresisThreshold Hysteresis threshold, in degrees Celsius
*/
typedef struct {
Expand Down Expand Up @@ -66,14 +71,17 @@ error_code_t readTempLM75BD(uint8_t devAddr, float *temp);
* @brief Write to the configuration register from the LM75BD
*
* @param devAddr I2C address of the LM75BD
* @param osFaultQueueSize Number of consecutive OS faults until OS output is activated (1, 2, 4, or 6)
* @param osFaultQueueSize Number of consecutive OS faults until OS output is
* activated (1, 2, 4, or 6)
* @param osPolarity OS output polarity, 0 = active low, 1 = active high
* @param osOperationMode OS output operation mode, 0 = comparator, 1 = interrupt
* @param osOperationMode OS output operation mode, 0 = comparator, 1 =
* interrupt
* @param devOperationMode Device operation mode, 0 = normal, 1 = shutdown
* @return ERR_CODE_SUCCESS if successful, error code otherwise
*/
error_code_t writeConfigLM75BD(uint8_t devAddr, uint8_t osFaultQueueSize, uint8_t osPolarity,
uint8_t osOperationMode, uint8_t devOperationMode);
error_code_t writeConfigLM75BD(uint8_t devAddr, uint8_t osFaultQueueSize,
uint8_t osPolarity, uint8_t osOperationMode,
uint8_t devOperationMode);

/**
* @brief Handle an OS interrupt from the LM75BD
Expand Down
69 changes: 51 additions & 18 deletions services/thermal_mgr/thermal_mgr.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
#include "thermal_mgr.h"
#include "console.h"
#include "errors.h"
#include "lm75bd.h"
#include "console.h"
#include "logging.h"
#include "os_portmacro.h"
#include "os_projdefs.h"

#include <FreeRTOS.h>
#include <os_task.h>
#include <os_queue.h>
#include <os_task.h>

#include <stdint.h>
#include <string.h>

#define THERMAL_MGR_STACK_SIZE 256U
Expand All @@ -20,41 +24,70 @@ static StackType_t thermalMgrTaskStack[THERMAL_MGR_STACK_SIZE];

static QueueHandle_t thermalMgrQueueHandle;
static StaticQueue_t thermalMgrQueueBuffer;
static uint8_t thermalMgrQueueStorageArea[THERMAL_MGR_QUEUE_LENGTH * THERMAL_MGR_QUEUE_ITEM_SIZE];
static uint8_t thermalMgrQueueStorageArea[THERMAL_MGR_QUEUE_LENGTH *
THERMAL_MGR_QUEUE_ITEM_SIZE];

static void thermalMgr(void *pvParameters);

void initThermalSystemManager(lm75bd_config_t *config) {
memset(&thermalMgrTaskBuffer, 0, sizeof(thermalMgrTaskBuffer));
memset(thermalMgrTaskStack, 0, sizeof(thermalMgrTaskStack));
thermalMgrTaskHandle = xTaskCreateStatic(
thermalMgr, "thermalMgr", THERMAL_MGR_STACK_SIZE,
config, 1, thermalMgrTaskStack, &thermalMgrTaskBuffer);

thermalMgrTaskHandle =
xTaskCreateStatic(thermalMgr, "thermalMgr", THERMAL_MGR_STACK_SIZE,
config, 1, thermalMgrTaskStack, &thermalMgrTaskBuffer);

memset(&thermalMgrQueueBuffer, 0, sizeof(thermalMgrQueueBuffer));
memset(thermalMgrQueueStorageArea, 0, sizeof(thermalMgrQueueStorageArea));

thermalMgrQueueHandle = xQueueCreateStatic(
THERMAL_MGR_QUEUE_LENGTH, THERMAL_MGR_QUEUE_ITEM_SIZE,
thermalMgrQueueStorageArea, &thermalMgrQueueBuffer);

thermalMgrQueueHandle =
xQueueCreateStatic(THERMAL_MGR_QUEUE_LENGTH, THERMAL_MGR_QUEUE_ITEM_SIZE,
thermalMgrQueueStorageArea, &thermalMgrQueueBuffer);
}

error_code_t thermalMgrSendEvent(thermal_mgr_event_t *event) {
/* Send an event to the thermal manager queue */

Shrey-Varma marked this conversation as resolved.
Show resolved Hide resolved
return ERR_CODE_SUCCESS;
Shrey-Varma marked this conversation as resolved.
Show resolved Hide resolved
if (!event)
return ERR_CODE_NULL_ARG;
if (xQueueSend(thermalMgrQueueHandle, event, (TickType_t)0) == pdTRUE)
return ERR_CODE_SUCCESS;
else
return ERR_CODE_QUEUE_FULL;
}

void osHandlerLM75BD(void) {
/* Implement this function */
void osHandlerLM75BD(void) { /* Implement this function */
thermal_mgr_event_t event;
event.type = THERNAL_MGR_EVENT_CHECK_OS;
thermalMgrSendEvent(&event);
}

static void thermalMgr(void *pvParameters) {
/* Implement this task */
lm75bd_config_t details = *(lm75bd_config_t *)pvParameters;
while (1) {

thermal_mgr_event_t event;
if (xQueueReceive(thermalMgrQueueHandle, &event, (TickType_t)10) ==
pdTRUE) {
if (event.type == THERMAL_MGR_EVENT_MEASURE_TEMP_CMD ||
event.type == THERNAL_MGR_EVENT_CHECK_OS) {
float val;
error_code_t errCode = readTempLM75BD(details.devAddr, &val);
if (errCode != ERR_CODE_SUCCESS) {
LOG_ERROR_CODE(errCode);
// ensure that if CHECK_OS event was sent, that the temperature gets
// if it failed the first time attempt to CHECK_OS again
if (event.type == THERNAL_MGR_EVENT_CHECK_OS)
thermalMgrSendEvent(&event);
Shrey-Varma marked this conversation as resolved.
Show resolved Hide resolved
continue;
}
if (event.type == THERNAL_MGR_EVENT_CHECK_OS) {
if (val > details.hysteresisThresholdCelsius)
overTemperatureDetected();
else
safeOperatingConditions();
}
addTemperatureTelemetry(val);
Shrey-Varma marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
}

Expand All @@ -66,6 +99,6 @@ void overTemperatureDetected(void) {
printConsole("Over temperature detected!\n");
}

void safeOperatingConditions(void) {
void safeOperatingConditions(void) {
printConsole("Returned to safe operating conditions!\n");
}
4 changes: 2 additions & 2 deletions services/thermal_mgr/thermal_mgr.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#pragma once

#include "lm75bd.h"
#include "errors.h"
#include "lm75bd.h"

typedef enum {
THERMAL_MGR_EVENT_MEASURE_TEMP_CMD,

THERNAL_MGR_EVENT_CHECK_OS,
} thermal_mgr_event_type_t;

typedef struct {
Expand Down
29 changes: 15 additions & 14 deletions sys/errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,22 @@
/* Define new error codes here if needed */

typedef enum {
/* Common Errors 0 - 99 */
ERR_CODE_SUCCESS = 0,
ERR_CODE_UNKNOWN = 1,
ERR_CODE_INVALID_ARG = 2,
ERR_CODE_INVALID_STATE = 3,
/* Common Errors 0 - 99 */
ERR_CODE_SUCCESS = 0,
ERR_CODE_UNKNOWN = 1,
ERR_CODE_INVALID_ARG = 2,
ERR_CODE_INVALID_STATE = 3,
ERR_CODE_NULL_ARG = 4,

/* FreeRTOS errors */
ERR_CODE_MUTEX_TIMEOUT = 100,
ERR_CODE_QUEUE_FULL = 101,
ERR_CODE_INVALID_QUEUE_MSG = 102,
/* FreeRTOS errors */
ERR_CODE_MUTEX_TIMEOUT = 100,
ERR_CODE_QUEUE_FULL = 101,
ERR_CODE_INVALID_QUEUE_MSG = 102,

/* Driver errors */
ERR_CODE_I2C_TRANSFER_TIMEOUT = 200,
/* Driver errors */
ERR_CODE_I2C_TRANSFER_TIMEOUT = 200,

/* Logging errors */
ERR_CODE_BUFF_TOO_SMALL = 300,
ERR_CODE_LOG_MSG_SILENCED = 301,
/* Logging errors */
ERR_CODE_BUFF_TOO_SMALL = 300,
ERR_CODE_LOG_MSG_SILENCED = 301,
} error_code_t;
Loading