diff --git a/Apps/FlightSoftware/PrimaryFlightController/FlightMCU/.cproject b/Apps/FlightSoftware/PrimaryFlightController/FlightMCU/.cproject
index fb30581d6..fca10f49c 100644
--- a/Apps/FlightSoftware/PrimaryFlightController/FlightMCU/.cproject
+++ b/Apps/FlightSoftware/PrimaryFlightController/FlightMCU/.cproject
@@ -18,8 +18,8 @@
-
-
+
+
@@ -27,19 +27,19 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -48,26 +48,26 @@
-
-
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
@@ -113,22 +113,22 @@
-
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
+
@@ -277,4 +277,5 @@
+
diff --git a/Apps/FlightSoftware/PrimaryFlightController/FlightMCU/Include/FswPacket.hpp b/Apps/FlightSoftware/PrimaryFlightController/FlightMCU/Include/FswPacket.hpp
index 4df0a2e8f..269f8f198 100644
--- a/Apps/FlightSoftware/PrimaryFlightController/FlightMCU/Include/FswPacket.hpp
+++ b/Apps/FlightSoftware/PrimaryFlightController/FlightMCU/Include/FswPacket.hpp
@@ -84,12 +84,13 @@ struct FswFileHeader {
uint8_t totalBlocks;
uint8_t blockNumber; // This is 1-indexed, 0-index is optional and contains file-specific metadata
FileLength_t length; // This is the size of the following data **not including this header**
-};
+} __attribute__((packed));
struct FswFileMetadata { // Block 0 of files
uint16_t callbackId;
uint32_t timestamp;
-};
+} __attribute__((packed));
+
struct FswFile {
struct FswFileHeader header;
diff --git a/Apps/FlightSoftware/PrimaryFlightController/FlightMCU/Include/Version.h b/Apps/FlightSoftware/PrimaryFlightController/FlightMCU/Include/Version.h
index 2af266191..c113dfad7 100644
--- a/Apps/FlightSoftware/PrimaryFlightController/FlightMCU/Include/Version.h
+++ b/Apps/FlightSoftware/PrimaryFlightController/FlightMCU/Include/Version.h
@@ -10,7 +10,7 @@
*****************************************************************************/
static const unsigned VERSION_MAJOR = 8; // Version: ++ when drafting a new Release Candidate (for a new upload opportunity)
-static const unsigned VERSION_MINOR = 0; // Subversion: ++ when a new major feature has been added / made to work
+static const unsigned VERSION_MINOR = 1; // Subversion: ++ when a new major feature has been added / made to work
static const unsigned VERSION_REVISION = 0; // Patch: ++ when you make a change and want to reflect that.
#endif // _VERSION_H_
diff --git a/Apps/FlightSoftware/Watchdog/.cproject b/Apps/FlightSoftware/Watchdog/.cproject
index 7b1df5eff..cc0091e6e 100644
--- a/Apps/FlightSoftware/Watchdog/.cproject
+++ b/Apps/FlightSoftware/Watchdog/.cproject
@@ -281,8 +281,8 @@
-
+
@@ -359,6 +359,116 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Apps/FlightSoftware/Watchdog/.gitignore b/Apps/FlightSoftware/Watchdog/.gitignore
index 637ca8fab..ab997e9da 100644
--- a/Apps/FlightSoftware/Watchdog/.gitignore
+++ b/Apps/FlightSoftware/Watchdog/.gitignore
@@ -8,3 +8,4 @@ doc/
/Debug__opt_for_speed__4/
/Debug_with_flag/
/Debug_Radio_Flashing/
+/Debug_Radio_Herc_Flashing/
diff --git a/Apps/FlightSoftware/Watchdog/include/flags.h b/Apps/FlightSoftware/Watchdog/include/flags.h
index 6669b76f0..bac7377fe 100644
--- a/Apps/FlightSoftware/Watchdog/include/flags.h
+++ b/Apps/FlightSoftware/Watchdog/include/flags.h
@@ -81,13 +81,13 @@ extern "C"
#define DEFAULT_PWM_LIMIT 9999 // deprecated
#define DEFAULT_HEATER_SETPOINT 3325 // deprecated
#define DEFAULT_HEATER_WINDOW 60 // deprecated
-// 3670 is the -5 deg C thermistor voltage ADC reading - heater transitions to ON when T ADC < this value:
-#define DEFAULT_HEATER_ON_VAL 2781
-// 3670 is the 0 deg C thermistor voltage ADC reading - heater transitions to OFF when T ADC > this value:
-#define DEFAULT_HEATER_OFF_VAL 2291
+// 2540 is the 0 deg C thermistor voltage ADC reading - heater transitions to ON when T ADC < this value:
+#define DEFAULT_HEATER_ON_VAL 2540
+// 2042 is the 10 deg C thermistor voltage ADC reading - heater transitions to OFF when T ADC > this value:
+#define DEFAULT_HEATER_OFF_VAL 2040
#define DEFAULT_HEATING_CONTROL_ENABLED TRUE
#define DEFAULT_HEATER_DUTY_CYCLE_PERIOD 10000
-#define DEFAULT_HEATER_DUTY_CYCLE 8500
+#define DEFAULT_HEATER_DUTY_CYCLE 9998
#define GENERIC_BIT_INDEX_TO_TYPE_MASK(type, index) (((type)1) << ((type)(index)))
#define GENERIC_BIT_INDEX_TO_UINT8_MASK(index) GENERIC_BIT_INDEX_TO_TYPE_MASK(uint8_t, index)
diff --git a/Apps/FlightSoftware/Watchdog/src/stateMachine/RoverStateEnteringService.cpp b/Apps/FlightSoftware/Watchdog/src/stateMachine/RoverStateEnteringService.cpp
index d772c7e10..aac50955a 100644
--- a/Apps/FlightSoftware/Watchdog/src/stateMachine/RoverStateEnteringService.cpp
+++ b/Apps/FlightSoftware/Watchdog/src/stateMachine/RoverStateEnteringService.cpp
@@ -2,6 +2,7 @@
#include
+#include "comms/debug_comms.h"
#include "drivers/bsp.h"
namespace iris
@@ -43,6 +44,9 @@ namespace iris
{
*(theContext.m_persistentInMission) = false;
+ DPRINTF("Defaulting MONITOR_HERCULES to OFF in SERVICE.");
+ theContext.m_watchdogOpts &= ~WDOPT_MONITOR_HERCULES; // don't monitor Hercules for aliveness by default in service
+
// Enable the falling edge interrupt for WD_INT (should be done after unlocking LOCKLPM5 per slau367p section 12.3.2)
enableWdIntFallingEdgeInterrupt();
diff --git a/Apps/FlightSoftware/Watchdog/src/stateMachine/RoverStateInit.cpp b/Apps/FlightSoftware/Watchdog/src/stateMachine/RoverStateInit.cpp
index e19bb8db3..4b6e935b8 100644
--- a/Apps/FlightSoftware/Watchdog/src/stateMachine/RoverStateInit.cpp
+++ b/Apps/FlightSoftware/Watchdog/src/stateMachine/RoverStateInit.cpp
@@ -95,6 +95,13 @@ namespace iris
DebugComms__tryPrintfToLanderNonblocking("[WARNING] WD SW is in Radio-Programming Mode. This should be changed before flight.\n");
#endif
+#ifdef HERC_PROGRAMMING_MODE
+ // [CWC-03/13/2023] Warn that this is the WRONG version of the SW for Flight and should only be used for hercules programming.
+ // Essentially this is a special version of the SW that disable hercules monitioring by default in mission (instead of enables) so
+ // hercules can be programmed. In flight, though, we want Hercules monitoring to be on by default.
+ DebugComms__tryPrintfToLanderNonblocking("[WARNING] WD SW is in Hercules-Programming Mode. This should be changed before flight.\n");
+#endif
+
/* set up watchdog */
watchdog_init(&(theContext.m_watchdogFlags),
Time__getPointerToCentisecondCount(),
diff --git a/Apps/FlightSoftware/Watchdog/src/stateMachine/RoverStateMission.cpp b/Apps/FlightSoftware/Watchdog/src/stateMachine/RoverStateMission.cpp
index 47a424ccd..00eecd1fe 100644
--- a/Apps/FlightSoftware/Watchdog/src/stateMachine/RoverStateMission.cpp
+++ b/Apps/FlightSoftware/Watchdog/src/stateMachine/RoverStateMission.cpp
@@ -212,6 +212,17 @@ namespace iris
disableHeater();
}
+#ifdef HERC_PROGRAMMING_MODE
+ // [CWC-03/13/2023] Warn that this is the WRONG version of the SW for Flight and should only be used for hercules programming.
+ // Essentially this is a special version of the SW that disable hercules monitioring by default in mission (instead of enables) so
+ // hercules can be programmed. In flight, though, we want Hercules monitoring to be on by default.
+ DPRINTF("Defaulting MONITOR_HERCULES to OFF in MISSION for programming.");
+ theContext.m_watchdogOpts &= ~WDOPT_MONITOR_HERCULES;
+#else
+ DPRINTF("Defaulting MONITOR_HERCULES to ON in MISSION.");
+ theContext.m_watchdogOpts |= WDOPT_MONITOR_HERCULES; // default to monitoring Hercules for aliveness
+#endif
+
return getState();
}
diff --git a/Apps/FlightSoftware/Watchdog/src/watchdog.c b/Apps/FlightSoftware/Watchdog/src/watchdog.c
index fb4a0106a..3b333a0a3 100644
--- a/Apps/FlightSoftware/Watchdog/src/watchdog.c
+++ b/Apps/FlightSoftware/Watchdog/src/watchdog.c
@@ -169,6 +169,14 @@ int watchdog_monitor(HerculesComms__State *hState,
DEBUG_LOG_NULL_CHECK_RETURN(writeIOExpander, "Parameter is NULL", -1);
DEBUG_LOG_NULL_CHECK_RETURN(details, "Parameter is NULL", -1);
+ // Quick and dirty parameters for tuning Hercules Monitoring:
+ // How many consequtive kicks has hercules missed since being reset:
+ static uint8_t herc_conseq_missed_kicks_since_reset = 0;
+ // How many consequtive missed kicks until a reset (testing has shown it has to be at least 2):
+ // -- setting this too low won't give Hercules time to reboot after a crash and reset before
+ // being reset again...
+ static const uint8_t HERC_CONSEQ_MISSED_KICK_THRESHOLD = 3;
+
/* temporarily disable interrupts */
__disable_interrupt();
@@ -206,6 +214,7 @@ int watchdog_monitor(HerculesComms__State *hState,
*watchdogFlags ^= WDFLAG_UNRESET_HERCULES;
*writeIOExpander = TRUE;
SET_RABI_IN_UINT(details->m_resetActionBits, RABI__HERCULES_UNRESET);
+ DPRINTF("Unreset Hercules.");
}
/* unreset motor 1 */
@@ -276,29 +285,42 @@ int watchdog_monitor(HerculesComms__State *hState,
if (*watchdogFlags & WDFLAG_HERCULES_KICK)
{
*watchdogFlags ^= WDFLAG_HERCULES_KICK;
+ herc_conseq_missed_kicks_since_reset = 0;
+ // Let Ground know Hercules is still alive
+ // (if Hercules was rebooted while our comms were only over Wifi,
+ // we wouldn't know when it would be good to send SWITCH TO WIFI MODE).
+ DPRINTF("Hercules Alive.");
}
else
{
if (*watchdogOpts & WDOPT_MONITOR_HERCULES)
{
- // reset the hercules
- setHerculesReset();
-
- SET_RABI_IN_UINT(details->m_resetActionBits, RABI__HERCULES_WATCHDOG_RESET);
-
- // Set the flag so that the next time this function triggers, the Hercules will be un-reset
- *watchdogFlags |= WDFLAG_UNRESET_HERCULES;
-
- // if the issue was due to a comms breakdown, reset the comms state
- if (NULL != hState)
- {
- HerculesComms__Status hcStatus = HerculesComms__resetState(hState);
-
- //!< @todo Replace with returning watchdog error code once that is implemented.
- DEBUG_ASSERT_EQUAL(HERCULES_COMMS__STATUS__SUCCESS, hcStatus);
+ // Only inc. counter if Herc is being monitored.
+ herc_conseq_missed_kicks_since_reset += 1;
+ DPRINTF("Hercules Unresponsive.");
+ // Only reset if counter too big:
+ if(herc_conseq_missed_kicks_since_reset >= HERC_CONSEQ_MISSED_KICK_THRESHOLD){
+ // reset the hercules
+ DPRINTF("No Hercules Kick. Resetting Hercules . . .");
+ herc_conseq_missed_kicks_since_reset = 0;
+ setHerculesReset();
+
+ // queue up hercules unreset
+ *watchdogFlags |= WDFLAG_UNRESET_HERCULES;
+ SET_RABI_IN_UINT(details->m_resetActionBits, RABI__HERCULES_WATCHDOG_RESET);
+
+ // if the issue was due to a comms breakdown, reset the comms state
+ if (NULL != hState)
+ {
+ DPRINTF("\t Resetting Hercules Comms . . .");
+ HerculesComms__Status hcStatus = HerculesComms__resetState(hState);
+
+ //!< @todo Replace with returning watchdog error code once that is implemented.
+ DEBUG_ASSERT_EQUAL(HERCULES_COMMS__STATUS__SUCCESS, hcStatus);
+ }
+
+ *writeIOExpander = TRUE;
}
-
- *writeIOExpander = TRUE;
}
else
{
diff --git a/Apps/FlightSoftware/fprime/CubeRover/Camera/Camera.cpp b/Apps/FlightSoftware/fprime/CubeRover/Camera/Camera.cpp
index 64cec923a..5aabec4fc 100644
--- a/Apps/FlightSoftware/fprime/CubeRover/Camera/Camera.cpp
+++ b/Apps/FlightSoftware/fprime/CubeRover/Camera/Camera.cpp
@@ -71,7 +71,7 @@ namespace CubeRover {
{
m_numComponentImgsReq++;
tlmWrite_Cam_ComponentImagesRequested(m_numComponentImgsReq);
- triggerImageCapture(CameraNum, CallbackId);
+ takeImage(CameraNum, CallbackId);
}
// ----------------------------------------------------------------------
@@ -98,7 +98,7 @@ namespace CubeRover {
{
m_numGroundImgsReq++;
tlmWrite_Cam_CommandImagesRequested(m_numGroundImgsReq);
- triggerImageCapture(camera_num, callback_id);
+ takeImage(camera_num, callback_id);
this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
}
@@ -199,66 +199,149 @@ namespace CubeRover {
this->cmdResponse_out(opCode,cmdSeq,Fw::COMMAND_OK);
}
- void CameraComponentImpl::downsampleLine() {
- for(uint32_t x = 0; x < IMAGE_WIDTH/DOWNSAMPLING; x++) {
- m_imageLineBuffer[x] = m_imageLineBuffer[x*DOWNSAMPLING];
- }
- }
-
- void CameraComponentImpl::selectCamera(int cameraSelect) {
- // ASSERT camera == 0 or 1
- gioSetBit(linPORT, 1, cameraSelect & 0x01);
-
- // add small delays to make sure camera is selection is done
- for(int delay=0; delay<500; delay++) asm(" NOP");
- }
-
- // TODO: Implement dual queue image capture to allow for two threads to downlink an
- // image at once (ie navigation and science photo)
- void CameraComponentImpl::triggerImageCapture(uint8_t camera, uint16_t callbackId) {
- uint16_t spiTxCmd = 0xFF;
- spiDAT1_t fpgaDataConfig;
-
- S25fl512l::MemAlloc alloc;
- alloc.startAddress = 0; // Uhhh. Should use S25fl512l alloc method
- alloc.reservedSize = 0;
-
- fpgaDataConfig.CS_HOLD = false;
- fpgaDataConfig.DFSEL = SPI_FMT_0;
- fpgaDataConfig.WDEL = false;
- fpgaDataConfig.CSNR = 0;
-
- selectCamera(static_cast(camera));
-
- gioSetBit(spiPORT1, 0, 0); // set CS LOW
- spiTransmitData(spiREG1, &fpgaDataConfig, 1, &spiTxCmd); // send data
- gioSetBit(spiPORT1, 0, 1); // set CS HIGH
-
- tlmWrite_Cam_LatestCallbackId(callbackId);
- while(gioGetBit(gioPORTB, 1)); // Wait until image capture complete FIXME: This could loop forever :(
- uint32_t createTime = static_cast(getTime().get_time_ms());
-
- // TODO: Operator should be able to specify DOWNSAMPLING (but for testing smaller images are faster
- for(int i = 0; i < IMAGE_HEIGHT; i+=DOWNSAMPLING) {
-#ifdef __USE_DUMMY_IMAGE__
- getLineDummyImage(i, m_imageLineBuffer);
+ // ----------------------------------------------------------------------
+ // User Methods
+ // ----------------------------------------------------------------------
+
+ // TAKE IMAGE
+ void CameraComponentImpl::takeImage(uint8_t camera, uint16_t callbackId)
+ {
+ // Set the camera and callback IDs
+ m_cameraSelect = camera;
+ m_lastCallbackId = callbackId;
+ tlmWrite_Cam_LatestCallbackId(callbackId);
+
+#ifdef DUMMY_IMG_GRID
+ // Create and send Dummy Image
+ generateDummyImage();
#else
- m_fpgaFlash.readDataFromFlash(&alloc, 0, m_imageLineBuffer, sizeof(m_imageLineBuffer));
- alloc.startAddress = 6 * PAGE_SIZE * i; // jump to next available block
+ // Take Real Image!
+
+ // set bit to control camera
+ gioSetBit(linPORT, 1, m_cameraSelect & 0x01);
+
+ eraseFpgaFlash();
+
+ // add small delays to make sure camera is selection is done
+ for(int delay=0; delay<500; delay++) asm(" NOP");
+
+ uint32_t createTime = static_cast(getTime().get_time_ms());
+
+ // capture image
+ triggerImageCapture();
+ while(gioGetBit(gioPORTB, 1));
+
+ // send image from flash
+ sendImgFromFlash(createTime);
#endif
- downsampleLine();
- downlinkImage(m_imageLineBuffer, sizeof(m_imageLineBuffer), callbackId, createTime);
- }
- m_imagesSent++;
- tlmWrite_Cam_ImagesSent(m_imagesSent);
- }
-
- void CameraComponentImpl::downlinkImage(uint8_t *image, int size, uint16_t callbackId, uint32_t createTime) {
- Fw::Buffer fwBuffer(0, 0, reinterpret_cast(image), size);
- downlinkImage_out(0, callbackId, createTime, fwBuffer);
- m_bytesSent += static_cast(size);
- tlmWrite_Cam_BytesSent(m_bytesSent);
+ }
+
+
+ // CREATE AND SEND DUMMY IMAGE
+ void CameraComponentImpl::generateDummyImage(void)
+ {
+ int grid_x_spacing = DUMMY_IMAGE_WIDTH / DUMMY_IMG_GRID_n;
+ int grid_y_spacing = DUMMY_IMAGE_HEIGHT / DUMMY_IMG_GRID_n;
+
+#ifdef VIA_FLASH
+ // Prep Flash before writing each line
+ S25fl512l::MemAlloc alloc;
+ alloc.startAddress = 0;
+ alloc.reservedSize = sizeof(m_imageLineBuffer);
+
+ eraseFpgaFlash();
+#endif
+
+ uint32_t createTime = static_cast(getTime().get_time_ms());
+
+ for (int y = 0; y < DUMMY_IMAGE_HEIGHT; y++) {
+ for (int x = 0; x < DUMMY_IMAGE_WIDTH; x++) {
+ // if camera == 0 then all black, else black and white grid, in theory...
+ m_imageLineBuffer[x] = 255 * (((x / grid_x_spacing) + (y / grid_y_spacing)) % 2);
+ // Make it a gradient in both x and y for debugging:
+ if(m_imageLineBuffer[x] == 0x00){
+ m_imageLineBuffer[x] += 255 * x / DUMMY_IMAGE_WIDTH / 3;
+ m_imageLineBuffer[x] += 255 * y / DUMMY_IMAGE_HEIGHT / 3;
+ } else {
+ m_imageLineBuffer[x] -= 255 * x / DUMMY_IMAGE_WIDTH / 3;
+ m_imageLineBuffer[x] -= 255 * y / DUMMY_IMAGE_HEIGHT / 3;
+ }
+ }
+#ifdef VIA_FLASH
+ // write each line to flash
+ m_fpgaFlash.writeDataToFlash(&alloc, 0, m_imageLineBuffer, sizeof(m_imageLineBuffer));
+ alloc.startAddress += PAGE_SIZE * 6;
+ }
+ // then send from flash
+ sendImgFromFlash(createTime);
+#else
+ // send each line as it is created
+ downlinkImage(m_imageLineBuffer, sizeof(m_imageLineBuffer), m_lastCallbackId, createTime);
+ }
+#endif
+
+ // Finished sending Dummy Image
+ m_imagesSent++;
+ tlmWrite_Cam_ImagesSent(m_imagesSent);
+ }
+
+
+// TRIGGER IMAGE CAPTURE ON CAMERA
+void CameraComponentImpl::triggerImageCapture()
+{
+ uint16_t spiTxCmd = 0xFF;
+ spiDAT1_t g_fpgaDataConfig;
+
+ g_fpgaDataConfig.CS_HOLD = false;
+ g_fpgaDataConfig.DFSEL = SPI_FMT_0;
+ g_fpgaDataConfig.WDEL = false;
+ g_fpgaDataConfig.CSNR = 0;
+
+ gioSetBit(spiPORT1, 0, 0); // set CS LOW
+
+ // send data
+ spiTransmitData(spiREG1, &g_fpgaDataConfig, 1, &spiTxCmd);
+
+ gioSetBit(spiPORT1, 0, 1); // set CS HIGH
+}
+
+
+ // ERASE FLASH
+ void CameraComponentImpl::eraseFpgaFlash(void){
+ for(int i=0; i< 40; i++){
+ m_fpgaFlash.sectorErase(i);
}
-
+ }
+
+
+ // SEND IMAGE FROM FLASH
+ void CameraComponentImpl::sendImgFromFlash(uint32_t createTime)
+ {
+ S25fl512l::MemAlloc alloc;
+ alloc.startAddress = 0;
+ alloc.reservedSize = 0;
+
+ for(int i=0;i(image), size);
+ downlinkImage_out(0, callbackId, createTime, fwBuffer);
+ m_bytesSent += static_cast(size);
+ tlmWrite_Cam_BytesSent(m_bytesSent);
+ }
+
+
} // end namespace CubeRover
diff --git a/Apps/FlightSoftware/fprime/CubeRover/Camera/Camera.hpp b/Apps/FlightSoftware/fprime/CubeRover/Camera/Camera.hpp
index 47ba3c951..387bea163 100644
--- a/Apps/FlightSoftware/fprime/CubeRover/Camera/Camera.hpp
+++ b/Apps/FlightSoftware/fprime/CubeRover/Camera/Camera.hpp
@@ -1,6 +1,6 @@
// ======================================================================
// \title CameraComponentImpl.hpp
-// \author justin
+// \author Raewyn
// \brief hpp file for Camera component implementation class
//
// \copyright
@@ -17,12 +17,23 @@
#include "S25fl512l.hpp"
+// --- SYSTEM IMAGE PARAMS ---
#define IMAGE_WIDTH 2592
#define IMAGE_HEIGHT 1944
-#define DOWNSAMPLING 2
-#define DOWNSAMPLED_IMG_WIDTH (IMAGE_WIDTH / DOWNSAMPLING)
-#define DOWNSAMPLE_IMG_HEIGHT (IMAGE_HEIGHT / DOWNSAMPLING)
+// --- DUMMY IMAGE PARAMS ---
+
+//#define DUMMY_IMG_GRID // Dummy image is grid of NxN squares
+#define DUMMY_IMG_GRID_n 5 // Dummy image is grid of NxN squares
+#define VIA_FLASH // Read & Write dummy image w/ FPGA Flash
+
+#define DUMMY_IMAGE_WIDTH IMAGE_WIDTH
+#define DUMMY_IMAGE_HEIGHT IMAGE_HEIGHT
+
+// RAD TODO - isn't downsampling a user-defined parameter?
+//#define DOWNSAMPLING 1
+//#define DOWNSAMPLED_IMG_WIDTH (IMAGE_WIDTH / DOWNSAMPLING)
+//#define DOWNSAMPLE_IMG_HEIGHT (IMAGE_HEIGHT / DOWNSAMPLING)
namespace CubeRover {
@@ -181,20 +192,25 @@ namespace CubeRover {
);
- // User methods
-
- void downsampleLine();
- void selectCamera(int camera);
- void triggerImageCapture(uint8_t camera, uint16_t callbackId);
- void downlinkImage(uint8_t *image, int size, uint16_t callbackId, uint32_t createTime);
-
- S25fl512l m_fpgaFlash;
- uint8_t m_imageLineBuffer[IMAGE_WIDTH];
- U32 m_numComponentImgsReq;
- U32 m_numGroundImgsReq;
- U32 m_imagesSent;
- U32 m_bytesSent;
+ // ----------------------------------------------------------------------
+ // User Methods
+ // ----------------------------------------------------------------------
+ void takeImage(uint8_t camera, uint16_t callbackId);
+ void generateDummyImage(void);
+ void triggerImageCapture(void);
+ void eraseFpgaFlash(void);
+ void sendImgFromFlash(uint32_t createTime);
+ void downlinkImage(uint8_t *image, int size, uint16_t callbackId, uint32_t createTime);
+
+ S25fl512l m_fpgaFlash;
+ uint8_t m_imageLineBuffer[IMAGE_WIDTH];
+ U32 m_numComponentImgsReq;
+ U32 m_numGroundImgsReq;
+ U32 m_imagesSent;
+ U32 m_bytesSent;
+ uint16_t m_lastCallbackId;
+ uint8_t m_cameraSelect;
};
} // end namespace CubeRover
diff --git a/Apps/FlightSoftware/fprime/CubeRover/Camera/CameraComponentAi.xml b/Apps/FlightSoftware/fprime/CubeRover/Camera/CameraComponentAi.xml
index ef1058ec3..b4f05d040 100644
--- a/Apps/FlightSoftware/fprime/CubeRover/Camera/CameraComponentAi.xml
+++ b/Apps/FlightSoftware/fprime/CubeRover/Camera/CameraComponentAi.xml
@@ -1,5 +1,6 @@
CubeRover/CubeRoverPorts/FileDownlink/FileDownlinkPortAi.xml
+ Fw/Time/TimePortAi.xml
CubeRover/CubeRoverPorts/CameraTakePicture/CameraTakePicturePortAi.xml
Manages the CubeRover cameras
diff --git a/Apps/FlightSoftware/fprime/CubeRover/GroundInterface/GroundInterface.cpp b/Apps/FlightSoftware/fprime/CubeRover/GroundInterface/GroundInterface.cpp
index 51edcc581..654348748 100644
--- a/Apps/FlightSoftware/fprime/CubeRover/GroundInterface/GroundInterface.cpp
+++ b/Apps/FlightSoftware/fprime/CubeRover/GroundInterface/GroundInterface.cpp
@@ -11,9 +11,12 @@
// ======================================================================
#include
+#include // ! TODO: FIXME Hacky patch connection to steal NM data
#include "Fw/Types/BasicTypes.hpp"
#include
+extern CubeRover::NetworkManagerComponentImpl networkManager; // ! TODO: FIXME Hacky patch connection to steal NM data
+
namespace CubeRover
{
@@ -172,6 +175,7 @@ namespace CubeRover
{
struct FswPacket::FswFile *obj = reinterpret_cast(downlinkBuffer);
obj->header.magic = FSW_FILE_MAGIC;
+ obj->header.hashedId = hashedId;
obj->header.totalBlocks = 1;
obj->header.blockNumber = 1;
obj->header.length = static_cast(dataSize);
@@ -179,6 +183,14 @@ namespace CubeRover
downlinkFileMetadata(hashedId, 1, static_cast(callbackId), static_cast(createTime));
downlinkBufferWrite(downlinkBuffer, static_cast(singleFileObjectSize), DownlinkFile);
m_appBytesDownlinked += singleFileObjectSize;
+ // ! TODO: FIXME
+ // !Forcibly halt the idle thread until Wf121TxTask sends the packet (tx count goes up):
+ // ! (do this to avoid maxing out the radio Tx queue):
+ flushTlmDownlinkBuffer(); // FLUSH BUFFER TO GET PACKET OUT
+ int startUdpTxCount = networkManager.m_pRadioDriver->m_networkInterface.m_protectedRadioStatus.getUdpTxPacketCount();
+ while(startUdpTxCount == networkManager.m_pRadioDriver->m_networkInterface.m_protectedRadioStatus.getUdpTxPacketCount() && networkManager.m_pRadioDriver->m_networkInterface.udpTxQueueRoom() < 1){
+ vTaskDelay(10 / portTICK_PERIOD_MS); // Check back in 10ms
+ }
}
else
{ // Send file fragments
@@ -207,6 +219,13 @@ namespace CubeRover
log_DIAGNOSTIC_GI_DownlinkedItem(m_downlinkSeq, DownlinkFile);
downlink(downlinkBuffer, datagramLength);
data += blockLength;
+ // ! TODO: FIXME
+ // !Forcibly halt the idle thread until Wf121TxTask sends the packet (tx count goes up):
+ // ! (do this to avoid maxing out the radio Tx queue):
+ int startUdpTxCount = networkManager.m_pRadioDriver->m_networkInterface.m_protectedRadioStatus.getUdpTxPacketCount();
+ while(startUdpTxCount == networkManager.m_pRadioDriver->m_networkInterface.m_protectedRadioStatus.getUdpTxPacketCount() && networkManager.m_pRadioDriver->m_networkInterface.udpTxQueueRoom() < 1){
+ vTaskDelay(10 / portTICK_PERIOD_MS); // Check back in 10ms
+ }
}
else
{ // Final Fragment is written to the member buffer to downlink with other objects
diff --git a/Apps/FlightSoftware/fprime/CubeRover/GroundInterface/GroundInterface.hpp b/Apps/FlightSoftware/fprime/CubeRover/GroundInterface/GroundInterface.hpp
index 955ee0ec8..bb4d31758 100644
--- a/Apps/FlightSoftware/fprime/CubeRover/GroundInterface/GroundInterface.hpp
+++ b/Apps/FlightSoftware/fprime/CubeRover/GroundInterface/GroundInterface.hpp
@@ -14,6 +14,7 @@
#define GroundInterface_HPP
#include "CubeRover/GroundInterface/GroundInterfaceComponentAc.hpp"
+#include "CubeRover/NetworkManager/NetworkManager.hpp" // ! TODO: FIXME Hacky patch connection to steal NM data
#include
namespace CubeRover {
diff --git a/Apps/FlightSoftware/fprime/CubeRover/NetworkManager/NetworkManager.cpp b/Apps/FlightSoftware/fprime/CubeRover/NetworkManager/NetworkManager.cpp
index 7b479f7e1..14f4104fb 100644
--- a/Apps/FlightSoftware/fprime/CubeRover/NetworkManager/NetworkManager.cpp
+++ b/Apps/FlightSoftware/fprime/CubeRover/NetworkManager/NetworkManager.cpp
@@ -27,6 +27,7 @@
#include
#include
#include
+#include
extern CubeRover::WatchDogInterfaceComponentImpl watchDogInterface;
@@ -178,11 +179,29 @@ namespace CubeRover
const NATIVE_INT_TYPE portNum,
Fw::Buffer &fwBuffer)
{
+ if(portNum == 1 && m_pRadioDriver->m_networkInterface.udpTxQueueRoom() <= 2){
+ // Don't let WDI send anything if we're currently swamped
+ return;
+ }
+
+ static Os::Mutex sloppyResourceProtectionMutex; // quick and dirty. keeps multiple tasks from doing this at once (i.e. GI and WDI)
+ sloppyResourceProtectionMutex.lock();
// Grab the data from the FW Buffer:
uint8_t *buffer = reinterpret_cast(fwBuffer.getdata());
+ if(
+ (fwBuffer.getsize() >= 8 && (memcmp(buffer, "DEBUGRTT", 8) == 0))
+ || (fwBuffer.getsize() >= 8 && (memcmp(buffer, "DEBUGRDL", 8) == 0))
+ ){
+ // Don't let RTT or RDL messages be sent over wifi (too many of them):
+ sloppyResourceProtectionMutex.unLock();
+ return;
+ }
+
+
// Copy it into the outbound payload:
m_udpPayloadWorkingBuffer.copyIn(fwBuffer.getsize(), buffer);
+ sloppyResourceProtectionMutex.unLock(); // unlock before potentially getting stuck in Queue wait.
// Queue up the Payload for downlink:
m_pRadioDriver->m_networkInterface.sendUdpPayload(&m_udpPayloadWorkingBuffer);
diff --git a/Apps/FlightSoftware/fprime/CubeRover/NetworkManager/NetworkManager.hpp b/Apps/FlightSoftware/fprime/CubeRover/NetworkManager/NetworkManager.hpp
index 03ade2059..c91940d3f 100644
--- a/Apps/FlightSoftware/fprime/CubeRover/NetworkManager/NetworkManager.hpp
+++ b/Apps/FlightSoftware/fprime/CubeRover/NetworkManager/NetworkManager.hpp
@@ -224,11 +224,12 @@ namespace CubeRover
);
// User defined methods, members, and structs
-
+public:
// Pointer to the RadioDriver being used (we add this level of indirection
// and don't just use `CORE_RADIO_DRIVER` in case we want to change what's
// used in the future):
Wf121::RadioDriver *m_pRadioDriver;
+PRIVATE:
// Single common working buffer used for handling RX'd or TX'ing UDP Payloads:
// (NOT for long term storage of data / passing data out of NetworkManager):
Wf121::UdpPayload m_udpPayloadWorkingBuffer;
diff --git a/Apps/FlightSoftware/fprime/CubeRover/Top/CubeRoverTopologyAppAi.xml b/Apps/FlightSoftware/fprime/CubeRover/Top/CubeRoverTopologyAppAi.xml
index b87fa6cb2..783276539 100644
--- a/Apps/FlightSoftware/fprime/CubeRover/Top/CubeRoverTopologyAppAi.xml
+++ b/Apps/FlightSoftware/fprime/CubeRover/Top/CubeRoverTopologyAppAi.xml
@@ -212,6 +212,11 @@
+
+
+
+
+