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

ALT Firmware #206

Open
wants to merge 49 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
9de6bc4
implemented a time signature to clock
scottc11 Oct 24, 2022
9216fff
sequence now waits for the start of a bar before enabling recording
scottc11 Oct 24, 2022
f1f08bd
implemented superclock reset
scottc11 Oct 29, 2022
ca40bde
better seq length handling + record disarm by the bar
scottc11 Oct 29, 2022
deaf9ff
added sequencer progress
scottc11 Nov 2, 2022
7af013e
changed order of seq advance vs. seq handling
scottc11 Nov 3, 2022
319e1eb
reworked toolchain installation instructions
scottc11 Nov 4, 2022
b5da5cd
re-wrote seq progress display, cleaned up associated bugs
scottc11 Nov 27, 2022
7d558b3
closed #188 sequence ratcheting bug
scottc11 Nov 27, 2022
3bcbe2b
#182 better handling of low frequency adc signals for quantization
scottc11 Dec 1, 2022
b44aa3f
#187 removed unused adc queue which was causing system crashes
scottc11 Dec 1, 2022
8147769
#189 sequence octave touch pads (mono only)
scottc11 Dec 3, 2022
5b71ea1
quantizer mode octave recording
scottc11 Dec 5, 2022
38ed5da
readme update
scottc11 Dec 5, 2022
951a6aa
Clear sequence when toggling modes. Closes #192
scottc11 Dec 5, 2022
9ed3a1e
closes #193 , changed default dac note index from 0 to 12 to allow fo…
scottc11 Dec 5, 2022
e86b534
Merge branch 'firmware-update-dec-2022' into time-sig-recording
scottc11 Dec 5, 2022
44dc175
Record overflow now draws sequence to display
scottc11 Dec 6, 2022
f2acf18
added clock step callback, nothing implemented for it yet
scottc11 Dec 6, 2022
3bad2df
handling of pre-recorded events (auto quantization to first step)
scottc11 Feb 2, 2023
b34a3a7
freeze button led stays on when pressed
scottc11 Feb 5, 2023
ce2deaf
LENGTH button now adjusts clock time signature (steps per bar)
scottc11 Feb 6, 2023
7351ffd
closes #201, fixed pitch bend when exiting idle bender position
scottc11 Feb 6, 2023
56d6a4d
closes #195 firmware version check
scottc11 Mar 11, 2023
6fe1a59
created functions and setup flash to store and recall a single channe…
scottc11 Mar 13, 2023
52382a3
refactored remaining channel config values to use new storage schema
scottc11 Mar 13, 2023
c2aebab
closes #185 save channel sequence in flash
scottc11 Mar 13, 2023
441de18
changed total flash size for program memory
scottc11 Mar 13, 2023
5bec171
split channel calibration data and config data into two different sec…
scottc11 Mar 18, 2023
4fcf90f
channel config and calibration data is now completely independant
scottc11 Mar 18, 2023
0e78166
fixed flash validate
scottc11 Mar 18, 2023
f296047
Closes #202, disabled certain menu actions when record is enabled
scottc11 Apr 17, 2023
d585131
closes #198 sequence override snapback on release
scottc11 Apr 17, 2023
a6f6a77
Merge branch 'firmware-update-dec-2022' into time-sig-recording
scottc11 Apr 18, 2023
b1fcdf4
manual fix of merge conflict
scottc11 Apr 18, 2023
c170f3a
removed uneeded class
scottc11 May 10, 2023
0a07795
Revert "closes #198 sequence override snapback on release"
scottc11 May 20, 2023
9eb588c
fixed bug in IC mode so steps get handled more accurately.
scottc11 Jun 4, 2023
089a4de
fixed bug to better set lenght when loading sequence data
scottc11 Jun 4, 2023
c630fb7
Revert "closes #198 sequence override snapback on release"
scottc11 Jun 4, 2023
fbfbf4f
fixed + tweaked 1VO calibration routine, added back ADC external queue
scottc11 Jun 7, 2023
1a1c234
Merge branch 'firmware-update-dec-2022' into time-sig-recording
scottc11 Jun 7, 2023
5866cff
closes #207 , select pad synced to channels now
scottc11 Jun 8, 2023
4c8e113
Merge branch 'firmware-update-dec-2022' into time-sig-recording
scottc11 Jun 8, 2023
249e624
fixed CV input quantization hysteresis
scottc11 Jun 9, 2023
139f2a6
Merge branch 'firmware-update-dec-2022' into time-sig-recording
scottc11 Jun 9, 2023
38cba9b
closes #200 reset seq display after freeze
scottc11 Jun 10, 2023
ce30a84
finished writing the logger queue
scottc11 Jun 12, 2023
956a1f5
handled reset when externally clocked
scottc11 Jun 12, 2023
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
2 changes: 1 addition & 1 deletion .vscode/.cortex-debug.peripherals.state.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[{"node":"FLASH","expanded":true,"format":0,"pinned":false}]
[{"node":"FLASH","expanded":true,"format":0,"pinned":false},{"node":"FLASH.ACR","expanded":true,"format":0},{"node":"FLASH.KEYR","expanded":true,"format":0},{"node":"FLASH.SR","expanded":true,"format":0},{"node":"FLASH.OPTCR","expanded":true,"format":0}]
6 changes: 4 additions & 2 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"name": "Mac",
"compilerPath": "/opt/homebrew/bin/arm-none-eabi-gcc",
"defines": [
"USE_HAL_DRIVER"
"USE_HAL_DRIVER",
"STM32F446xx"
],
"includePath": [
"${workspaceFolder}/API/*",
Expand All @@ -23,12 +24,13 @@
"${workspaceFolder}/Drivers/STM32F4xx_HAL_Driver/*",
"${workspaceFolder}/Drivers/STM32F4xx_HAL_Driver/Inc/*",
"${workspaceFolder}/Drivers/STM32F4xx_HAL_Driver/Src/*",
"${workspaceFolder}/Drivers/CMSIS/Device/ST/STM32F4xx/Include",
"${workspaceFolder}/Drivers/CMSIS/Device/ST/STM32F4xx/Source",
"${workspaceFolder}/middleware/FreeRTOS/Source/*",
"${workspaceFolder}/middleware/FreeRTOS/Source/portable/GCC/ARM_CM4F/*",
"${workspaceFolder}/middleware/FreeRTOS/Source/portable/MemMang/*",
"${workspaceFolder}/middleware/FreeRTOS/Source/CMSIS_RTOS_V2/*",
"${workspaceFolder}/middleware/FreeRTOS/Source/include/*",
"${workspaceFolder}/etl/include/**",
"${workspaceFolder}/ok-drivers/**",
"${workspaceFolder}/System/*",
"${workspaceFolder}/System/Inc/*",
Expand Down
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
"forward_list": "cpp",
"list": "cpp",
"condition_variable": "cpp",
"mutex": "cpp"
"mutex": "cpp",
"ranges": "cpp",
"ranges": "cpp",
"span": "cpp"
}
}
9 changes: 7 additions & 2 deletions API/Inc/Flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,19 @@ class Flash {
HAL_StatusTypeDef erase(uint32_t address);

HAL_StatusTypeDef write(uint32_t address, uint32_t *data, int size);
void write(uint32_t address, uint32_t data);

void copySector(uint32_t sourceSector, uint32_t targetSector, uint32_t size);

void read(uint32_t address, uint32_t *rxBuffer, int size);
uint32_t read_word(void *address);

uint32_t getSector(uint32_t Address);
bool validate(uint32_t *data, int size);

private:
static Mutex _mutex;
HAL_StatusTypeDef unlock(uint32_t sector);
HAL_StatusTypeDef lock();

private:
static Mutex _mutex;
};
22 changes: 18 additions & 4 deletions API/Inc/SuperClock.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
#define PPQN 96
#endif

#define PPQN_ERROR (PPQN - (PPQN / 6))
#define PPQN_8th (PPQN / 2)
#define PPQN_16th (PPQN / 4)

#ifndef EXT_CLOCK_INPUT
#define EXT_CLOCK_INPUT PA_3
Expand All @@ -29,15 +30,19 @@ class SuperClock {
public:

int pulse; // the current PPQN
uint8_t step; // current step. Will never exceed value of stepsPerBar
uint16_t ticksPerStep; // how many TIM2 ticks per one step / quarter note
uint16_t ticksPerPulse; // how many TIM2 ticks for one PPQN
uint8_t stepsPerBar; // value represents the number of quarter notes per bar (ie. 3/4, 4/4, 5/4, 6/4, 7/4)
bool externalInputMode;

Callback<void()> tickCallback; // this callback gets executed at a frequency equal to tim1_freq
Callback<void()> input_capture_callback; // this callback gets executed every on the rising edge of external input
Callback<void()> barResetCallback; // executes when clock.step exceeds the set time signature (ie. one bar)
Callback<void()> input_capture_callback; // this callback gets executed on the rising edge of an external input signal
Callback<void(uint8_t pulse)> ppqnCallback; // this callback gets executed at a rate equal to input capture / PPQN. It passes the current tick values as arguments
Callback<void(uint16_t step)> stepCallback; // executes every step
Callback<void(uint8_t pulse)> resetCallback;
Callback<void()> overflowCallback; // callback executes when all when a full step completes
Callback<void()> overflowCallback; // callback executes when a full step completes

/**
* TODO: initial inputCapture value should be the product of TIM1 and TIM2 prescaler values combined with 120 BPM
Expand All @@ -48,12 +53,17 @@ class SuperClock {
instance = this;
ticksPerStep = 11129;
ticksPerPulse = ticksPerStep / PPQN;
stepsPerBar = 4;
};

void init();
void initTIM2(uint16_t prescaler, uint32_t period);
void initTIM4(uint16_t prescaler, uint16_t period);

void start();
void reset();
void setStepsPerBar(int steps);
void handleStep();

void setPulseFrequency(uint32_t ticks);
uint16_t convertADCReadToTicks(uint16_t min, uint16_t max, uint16_t value);
Expand All @@ -63,8 +73,12 @@ class SuperClock {
// Callback Setters
void attachInputCaptureCallback(Callback<void()> func);
void attachPPQNCallback(Callback<void(uint8_t pulse)> func);
void attachStepCallback(Callback<void(uint16_t step)> func) {
stepCallback = func;
}
void attachResetCallback(Callback<void(uint8_t pulse)> func);

void attachBarResetCallback(Callback<void()> func);

// Low Level HAL interupt handlers
void handleInputCaptureCallback();
void handleOverflowCallback();
Expand Down
21 changes: 16 additions & 5 deletions API/Inc/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@
#define OK_UART_TX (PinName) PC_10
#endif

#define MAX_MESSAGE_LENGTH 50

typedef union
{
bool boolValue;
int intValue;
char *charValue;
} QueueMessage;

void logger_queue_message(char const *message);
void logger_queue_message(int num);
void logger_queue_message_ISR(char const *message);
void logger_queue_message_ISR(int num);
void task_logger(void *params);

void logger_init();

void logger_log(char const *str);
Expand Down Expand Up @@ -46,8 +61,4 @@ void logger_log_arr(T arr[], int length)
void logger_log_system_config();

void logger_log_task_watermark(void);
void logger_log_task_watermark(TaskHandle_t task_handle);

void logger_queue_message(uint16_t message);

void TASK_logger(void *params);
void logger_log_task_watermark(TaskHandle_t task_handle);
75 changes: 68 additions & 7 deletions API/Src/Flash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,16 @@ HAL_StatusTypeDef Flash::erase(uint32_t address)
return status;
}

/**
* @brief Write to flash memory
* @note flash memory can only be written to by changing its value from a 1 to a 0.
* Once a bit in the flash memory is set to 0, it cannot be changed back to 1 without erasing the entire sector.
*
* @param address flash memory address you wish to write to
* @param data pointer to an array containing the data you want to store in flash
* @param size size of data array
* @return HAL_StatusTypeDef
*/
HAL_StatusTypeDef Flash::write(uint32_t address, uint32_t *data, int size)
{
HAL_StatusTypeDef status;
Expand Down Expand Up @@ -111,7 +121,7 @@ HAL_StatusTypeDef Flash::write(uint32_t address, uint32_t *data, int size)
flashError = HAL_FLASH_GetError();
} else {
size--;
address += 4;
address += 4; // 1 "word" == 4 bytes
data++;
}
}
Expand All @@ -123,8 +133,40 @@ HAL_StatusTypeDef Flash::write(uint32_t address, uint32_t *data, int size)
return status;
}

void Flash::write(uint32_t address, uint32_t data)
{
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, (uint64_t)data);
}

/**
* @brief Copy contents of a sector in flash into another sector in flash. Requires no buffer
* as it copies word by word
*
* @param sourceSector sector you wish to copy
* @param targetSector sector you wish to store the copy in
* @param size how much of the source you want to copy
*/
void Flash::copySector(uint32_t sourceSector, uint32_t targetSector, uint32_t size)
{
// Step 1: clear Sector 6
this->erase(targetSector);

// Step 2: copy all data from Sector 7 into Sector 6
this->unlock(sourceSector);
uint32_t read_address = sourceSector;
uint32_t write_address = targetSector;
while (read_address < (sourceSector + size))
{
uint32_t word = this->read_word((void *)read_address);
this->write(write_address, word);
read_address += 4;
write_address += 4;
}
this->lock();
}

/**
* @brief Read data starting at defined address
* @brief Read data starting at defined address and load it into a buffer
*
* @param address Address to begin reading from
* @param rxBuffer The buffer to read data into. Must be of type uint32_t
Expand All @@ -141,6 +183,17 @@ void Flash::read(uint32_t address, uint32_t *rxBuffer, int size)
}
}

/**
* @brief read a single 32-bit word at a specific memory address and return it
*
* @param address
* @return uint32_t
*/
uint32_t Flash::read_word(void *address)
{
return *(uint32_t *)address;
}

/**
* @brief Check if data read from flash has been cleared / not written too by testing contents of buffer
*
Expand All @@ -150,11 +203,19 @@ void Flash::read(uint32_t address, uint32_t *rxBuffer, int size)
*/
bool Flash::validate(uint32_t *data, int size)
{
size = size > 65000 ? 65000 : size; // protect
uint32_t validator = 0;
for (int i = 0; i < size; i++)
validator += (uint16_t)data[i]; // uint16 for overflow
return validator == size * 0xFFFF ? true : false;
bool dataIsClear = false;
for (int i = 0; i < size; i++) {
if (data[i] == 0xFFFFFFFF)
{
dataIsClear = true;
}
else
{
dataIsClear = false;
break;
}
}
return dataIsClear;
}

/**
Expand Down
57 changes: 48 additions & 9 deletions API/Src/SuperClock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,26 @@ void SuperClock::start()
error_handler(status);
}

void SuperClock::reset()
{
__HAL_TIM_SetCounter(&htim2, 0); // not certain this has to happen, just assuming
__HAL_TIM_SetCounter(&htim4, 0);
if (!externalInputMode) { // special for timing!
this->pulse = 0;
}
this->step = 0;
}

void SuperClock::setStepsPerBar(int steps) {
if (steps < 3) {
return;
} else if (steps > 7) {
return;
} else {
stepsPerBar = steps;
}
}

/**
* @brief initialize TIM2 as a slave to TIM1
* @param prescaler setting to 1 should be best
Expand Down Expand Up @@ -141,10 +161,10 @@ void SuperClock::setPulseFrequency(uint32_t ticks)
*/
void SuperClock::handleInputCaptureCallback()
{
// almost always, there will need to be at least 1 pulse not yet executed prior to an input capture,
// so you must execute all remaining until
if (pulse < PPQN)
// almost always, there will need to be at least 1 pulse not yet executed prior to an input capture, so you must execute all remaining until
if (pulse < PPQN - 1)
{
handleStep();
if (resetCallback)
{
resetCallback(pulse);
Expand Down Expand Up @@ -185,26 +205,41 @@ void SuperClock::handleOverflowCallback()
{
if (ppqnCallback)
ppqnCallback(pulse); // when clock inits, this ensures the 0ith pulse will get handled

// by checking this first, you have the chance to reset any sequences prior to executing their 0ith pulse
// if (pulse == 0) {
// if (resetCallback)
// resetCallback();
// }
if (pulse == 0) {
if (stepCallback)
stepCallback(step);
}

if (pulse < PPQN - 1) {
pulse++;
} else {
if (externalInputMode)
{
__HAL_TIM_DISABLE(&htim4); // halt TIM4
// external input will reset pulse to 0 and resume TIM4 in input capture callback
__HAL_TIM_DISABLE(&htim4); // halt TIM4
handleStep();
} else {
pulse = 0;
handleStep();
}
}
}

void SuperClock::handleStep() {
if (step < stepsPerBar - 1)
{
step++;
}
else
{
step = 0;
if (barResetCallback)
barResetCallback();
}
}

void SuperClock::attachInputCaptureCallback(Callback<void()> func)
{
input_capture_callback = func;
Expand All @@ -220,6 +255,10 @@ void SuperClock::attachResetCallback(Callback<void(uint8_t pulse)> func)
resetCallback = func;
}

void SuperClock::attachBarResetCallback(Callback<void()> func) {
barResetCallback = func;
}

void SuperClock::RouteOverflowCallback(TIM_HandleTypeDef *htim)
{
if (htim == &htim4)
Expand Down
Loading