diff --git a/obc/CMakeLists.txt b/obc/CMakeLists.txt index 1352aaa56..ce223e365 100644 --- a/obc/CMakeLists.txt +++ b/obc/CMakeLists.txt @@ -1,10 +1,5 @@ cmake_minimum_required(VERSION 3.15) -if(APPLE) - find_library(COREFOUNDATION CoreFoundation) - find_library(IOKIT IOKit) -endif() - # Set default values for firmware build options include(${CMAKE_SOURCE_DIR}/cmake/obc_build_options.cmake) @@ -74,8 +69,9 @@ elseif(${CMAKE_BUILD_TYPE} MATCHES Examples) target_include_directories (${OUT_FILE_NAME} PRIVATE examples/test_app_cc1120_spi) elseif(${EXAMPLE_TYPE} MATCHES RS) add_executable(${OUT_FILE_NAME} examples/test_app_rs/main.c) - - # ADD MORE EXAMPLES ABOVE THIS COMMENT + elseif(${EXAMPLE_TYPE} MATCHES CC1120_TEMP) + add_executable(${OUT_FILE_NAME} examples/test_app_cc1120_temp/main.c) + # ADD MORE EXAMPLES ABOVE THIS COMMENT else () message (FATAL_ERROR "Invalid example type: ${EXAMPLE_TYPE} ") endif() diff --git a/obc/app/drivers/cc1120/cc1120.c b/obc/app/drivers/cc1120/cc1120.c index 0273eaf95..cceb15191 100644 --- a/obc/app/drivers/cc1120/cc1120.c +++ b/obc/app/drivers/cc1120/cc1120.c @@ -3,6 +3,7 @@ #include "cc1120_mcu.h" #include "obc_logging.h" #include "obc_board_config.h" +#include "obc_adc.h" #define READ_BIT 1 << 7 #define BURST_BIT 1 << 6 @@ -474,3 +475,75 @@ obc_error_code_t cc1120Rng(uint8_t *randomValue) { (*randomValue) ^= receivedData; return OBC_ERR_CODE_SUCCESS; } + +/** + * @brief Read temperature from the CC1120 + * + * This function reads the analog voltage from GPIO1 (via ADC) and converts + * it to temperature in Celsius. + * + * @param temperature - Pointer to float where temperature will be stored + * @return obc_error_code_t - OBC_ERR_CODE_SUCCESS or error code + */ +obc_error_code_t cc1120ReadTemp(float *temperature) { + uint8_t temp_val; + obc_error_code_t errCode; + + if (temperature == NULL) { + return OBC_ERR_CODE_INVALID_ARG; + } + + // idle state + RETURN_IF_ERROR_CODE(cc1120StrobeSpi(CC1120_STROBE_SIDLE)); + vTaskDelay(pdMS_TO_TICKS(1)); + + // change GPIO1 to output analog voltage + temp_val = 0x80U; + RETURN_IF_ERROR_CODE(cc1120WriteSpi(CC1120_REGS_IOCFG1, &temp_val, 1)); + + // enable analog test output + temp_val = 0x2AU; + RETURN_IF_ERROR_CODE(cc1120WriteExtAddrSpi(CC1120_REGS_EXT_ATEST, &temp_val, 1)); + + // set to temperature mode + temp_val = 0x0CU; + RETURN_IF_ERROR_CODE(cc1120WriteExtAddrSpi(CC1120_REGS_EXT_ATEST_MODE, &temp_val, 1)); + + // set bias current for analog circuits + temp_val = 0x07U; + RETURN_IF_ERROR_CODE(cc1120WriteExtAddrSpi(CC1120_REGS_EXT_GBIAS1, &temp_val, 1)); + + // wait for analog signal to stabilize + vTaskDelay(pdMS_TO_TICKS(2)); + + float voltage_sum = 0.0f; + uint16_t adcReading = 0; + + for (int i = 0; i < 16; i++) { + RETURN_IF_ERROR_CODE(adcGetSingleData(ADC_MODULE_1, ADC_CHANNEL_1, ADC_GROUP_1, &adcReading, pdMS_TO_TICKS(10))); + voltage_sum += (adcReading * 3.0f) / 4095.0f; // TODO: verify 3.0V is your actual ADC reference + } + + float avg_voltage = voltage_sum / 16.0f; + + // T = 25 + (V_measured - V_at_25C) / temp_coefficient + // Values from SWRA415D Table 2 for VDD = 3.0V + *temperature = 25.0f + (avg_voltage - 0.79478f) / 0.0026733f; + + // restore GPIO1 to HighZ (matches your cc1120SettingsStd init value) + temp_val = 0x30U; + RETURN_IF_ERROR_CODE(cc1120WriteSpi(CC1120_REGS_IOCFG1, &temp_val, 1)); + + // restore ATEST registers to defaults (0x00) + temp_val = 0x00U; + RETURN_IF_ERROR_CODE(cc1120WriteExtAddrSpi(CC1120_REGS_EXT_ATEST, &temp_val, 1)); + RETURN_IF_ERROR_CODE(cc1120WriteExtAddrSpi(CC1120_REGS_EXT_ATEST_MODE, &temp_val, 1)); + + // restore GBIAS1 to default (0x00) + RETURN_IF_ERROR_CODE(cc1120WriteExtAddrSpi(CC1120_REGS_EXT_GBIAS1, &temp_val, 1)); + + // return to FSTXON state (matches end of cc1120Init) + RETURN_IF_ERROR_CODE(cc1120StrobeSpi(CC1120_STROBE_SFSTXON)); + + return OBC_ERR_CODE_SUCCESS; +} \ No newline at end of file diff --git a/obc/app/drivers/cc1120/cc1120.h b/obc/app/drivers/cc1120/cc1120.h index 87f77b45e..2f63364c0 100644 --- a/obc/app/drivers/cc1120/cc1120.h +++ b/obc/app/drivers/cc1120/cc1120.h @@ -180,3 +180,14 @@ obc_error_code_t cc1120Init(void); * @return obc_error_code_t - Whether or not the register read was successful */ obc_error_code_t cc1120Rng(uint8_t *randomValue); + +/** + * @brief Read temperature from the CC1120 + * + * This function reads the analog voltage from GPIO1 (via ADC) and converts + * it to temperature in Celsius. + * + * @param temperature - Pointer to float where temperature will be stored + * @return obc_error_code_t - OBC_ERR_CODE_SUCCESS or error code + */ +obc_error_code_t cc1120ReadTemp(float *temperature); diff --git a/obc/app/drivers/cc1120/cc1120_defs.h b/obc/app/drivers/cc1120/cc1120_defs.h index 002893726..01d66df29 100644 --- a/obc/app/drivers/cc1120/cc1120_defs.h +++ b/obc/app/drivers/cc1120/cc1120_defs.h @@ -226,6 +226,8 @@ #define CC1120_REGS_EXT_SPACE_END 0xD9U +#define CC1120_STATE_IDLE 0x01 + /* Standard register space defaults */ #define CC1120_DEFAULTS_IOCFG3 0x06U #define CC1120_DEFAULTS_IOCFG2 0x07U diff --git a/obc/app/modules/health_collector/health_collector.c b/obc/app/modules/health_collector/health_collector.c index 90f938dba..23f13c7bd 100644 --- a/obc/app/modules/health_collector/health_collector.c +++ b/obc/app/modules/health_collector/health_collector.c @@ -10,6 +10,9 @@ #include #include +#include "cc1120.h" +#include "cc1120_defs.h" + #define HEALTH_COLLECTION_PERIOD_MS 60000UL static obc_error_code_t collectObcLm75bdTemp(void); @@ -29,11 +32,20 @@ static obc_error_code_t collectObcLm75bdTemp(void) { obc_error_code_t errCode; float temp = 0.0f; + float temp1 = 0.0f; + + uint8_t partnum; + RETURN_IF_ERROR_CODE(cc1120ReadExtAddrSpi(CC1120_REGS_EXT_PARTNUMBER, &partnum, 1)); + RETURN_IF_ERROR_CODE(readTempLM75BD(LM75BD_OBC_I2C_ADDR, &temp)); + RETURN_IF_ERROR_CODE(cc1120ReadTemp(&temp1)); + telemetry_data_t obcTempVal = {.obcTemp = temp, .id = TELEM_OBC_TEMP, .timestamp = getCurrentUnixTime()}; + telemetry_data_t cc1120TempVal = {.cc1120Temp = temp1, .id = TELEM_CC1120_TEMP, .timestamp = getCurrentUnixTime()}; RETURN_IF_ERROR_CODE(addTelemetryData(&obcTempVal)); + RETURN_IF_ERROR_CODE(addTelemetryData(&cc1120TempVal)); return OBC_ERR_CODE_SUCCESS; } diff --git a/obc/examples/test_app_cc1120_temp/main.c b/obc/examples/test_app_cc1120_temp/main.c new file mode 100755 index 000000000..e0c91f610 --- /dev/null +++ b/obc/examples/test_app_cc1120_temp/main.c @@ -0,0 +1,72 @@ +#include "obc_logging.h" +#include "obc_sci_io.h" +#include "obc_spi_io.h" +#include "obc_print.h" +#include "cc1120.h" + +#include "FreeRTOS.h" +#include "os_task.h" +#include "os_portable.h" + +#include +#include +#include +#include +#include + +static TaskHandle_t testTaskHandle = NULL; +static StaticTask_t testTaskBuffer; +static StackType_t testTaskStack[1024U]; + +void initTestTask(void); +static void vTestTask(void* pvParameters); + +void initTestTask(void) { + ASSERT((testTaskStack != NULL) && (&testTaskBuffer != NULL)); + if (testTaskHandle == NULL) { + testTaskHandle = xTaskCreateStatic(vTestTask, "test task", 1024U, NULL, 1U, testTaskStack, &testTaskBuffer); + } +} + +static void vTestTask(void* pvParameters) { + float temperature; + obc_error_code_t err; + + // Initialize CC1120 + err = cc1120Init(); + if (err != OBC_ERR_CODE_SUCCESS) { + sciPrintf("cc1120Init failed\r\n"); + return; + } + + // Read temperature every 5 seconds + while (1) { + err = cc1120ReadTemp(&temperature); + if (err == OBC_ERR_CODE_SUCCESS) { + sciPrintf("CC1120 temperature: %.2f C\r\n", temperature); + } else { + sciPrintf("Failed to read temperature\r\n"); + } + vTaskDelay(pdMS_TO_TICKS(5000)); + } +} + +int main(void) { + gioInit(); + sciInit(); + spiInit(); + adcInit(); + initSciPrint(); + + // Initialize logger + // initLogger(); + // logSetLevel(LOG_DEBUG); + + // Initialize bus mutexes + initSciMutex(); + initSpiMutex(); + + initTestTask(); + + vTaskStartScheduler(); +} \ No newline at end of file