83 lines
2.6 KiB
C++
83 lines
2.6 KiB
C++
/*
|
|
Speeduino - Simple engine management for the Arduino Mega 2560 platform
|
|
Copyright (C) Josh Stewart
|
|
A full copy of the license may be found in the projects root directory
|
|
*/
|
|
|
|
|
|
/*
|
|
Returns how much free dynamic memory exists (between heap and stack)
|
|
This function is one big MISRA violation. MISRA advisories forbid directly poking at memory addresses, however there is no other way of determining heap size on embedded systems.
|
|
*/
|
|
#include <avr/pgmspace.h>
|
|
#include "globals.h"
|
|
#include "utils.h"
|
|
#include "decoders.h"
|
|
|
|
uint16_t freeRam ()
|
|
{
|
|
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
|
extern int __heap_start, *__brkval;
|
|
uint16_t v;
|
|
|
|
return (uint16_t) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
|
|
|
|
#elif defined(CORE_TEENSY)
|
|
uint32_t stackTop;
|
|
uint32_t heapTop;
|
|
|
|
// current position of the stack.
|
|
stackTop = (uint32_t) &stackTop;
|
|
|
|
// current position of heap.
|
|
void* hTop = malloc(1);
|
|
heapTop = (uint32_t) hTop;
|
|
free(hTop);
|
|
|
|
// The difference is the free, available ram.
|
|
return (uint16_t)stackTop - heapTop;
|
|
#elif defined(CORE_STM32)
|
|
char top = 't';
|
|
return &top - reinterpret_cast<char*>(sbrk(0));
|
|
|
|
#endif
|
|
}
|
|
|
|
//This function performs a translation between the pin list that appears in TS and the actual pin numbers
|
|
//For the digital IO, this will simply return the same number as the rawPin value as those are mapped directly.
|
|
//For analog pins, it will translate them into the currect internal pin number
|
|
byte pinTranslate(byte rawPin)
|
|
{
|
|
byte outputPin = rawPin;
|
|
if(rawPin > BOARD_DIGITAL_GPIO_PINS) { outputPin = A8 + (outputPin - BOARD_DIGITAL_GPIO_PINS - 1); }
|
|
|
|
return outputPin;
|
|
}
|
|
|
|
|
|
void setResetControlPinState()
|
|
{
|
|
BIT_CLEAR(currentStatus.status3, BIT_STATUS3_RESET_PREVENT);
|
|
|
|
/* Setup reset control initial state */
|
|
switch (resetControl)
|
|
{
|
|
case RESET_CONTROL_PREVENT_WHEN_RUNNING:
|
|
/* Set the reset control pin LOW and change it to HIGH later when we get sync. */
|
|
digitalWrite(pinResetControl, LOW);
|
|
BIT_CLEAR(currentStatus.status3, BIT_STATUS3_RESET_PREVENT);
|
|
break;
|
|
case RESET_CONTROL_PREVENT_ALWAYS:
|
|
/* Set the reset control pin HIGH and never touch it again. */
|
|
digitalWrite(pinResetControl, HIGH);
|
|
BIT_SET(currentStatus.status3, BIT_STATUS3_RESET_PREVENT);
|
|
break;
|
|
case RESET_CONTROL_SERIAL_COMMAND:
|
|
/* Set the reset control pin HIGH. There currently isn't any practical difference
|
|
between this and PREVENT_ALWAYS but it doesn't hurt anything to have them separate. */
|
|
digitalWrite(pinResetControl, HIGH);
|
|
BIT_CLEAR(currentStatus.status3, BIT_STATUS3_RESET_PREVENT);
|
|
break;
|
|
}
|
|
}
|