initial commit

This commit is contained in:
DELL4 2023-03-01 19:41:49 +01:00
commit df732149dd
13 changed files with 636 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.pio
CMakeListsPrivate.txt
cmake-build-*/

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

4
.idea/misc.xml Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/untitled.iml" filepath="$PROJECT_DIR$/.idea/untitled.iml" />
</modules>
</component>
</project>

2
.idea/untitled.iml Normal file
View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

33
CMakeLists.txt Normal file
View File

@ -0,0 +1,33 @@
# !!! WARNING !!! AUTO-GENERATED FILE, PLEASE DO NOT MODIFY IT AND USE
# https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags
#
# If you need to override existing CMake configuration or add extra,
# please create `CMakeListsUser.txt` in the root of project.
# The `CMakeListsUser.txt` will not be overwritten by PlatformIO.
cmake_minimum_required(VERSION 3.13)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER_WORKS 1)
set(CMAKE_CXX_COMPILER_WORKS 1)
project("untitled" C CXX)
include(CMakeListsPrivate.txt)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/CMakeListsUser.txt)
include(CMakeListsUser.txt)
endif()
add_custom_target(
Production ALL
COMMAND platformio -c clion run "$<$<NOT:$<CONFIG:All>>:-e${CMAKE_BUILD_TYPE}>"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
add_custom_target(
Debug ALL
COMMAND platformio -c clion debug "$<$<NOT:$<CONFIG:All>>:-e${CMAKE_BUILD_TYPE}>"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
add_executable(Z_DUMMY_TARGET ${SRC_LIST} todo/main_dma.cpp)

39
include/README Normal file
View File

@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

46
lib/README Normal file
View File

@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

20
platformio.ini Normal file
View File

@ -0,0 +1,20 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:bluepill_f103c8_128k]
platform = ststm32
board = bluepill_f103c8_128k
framework = arduino
debug_tool = stlink
upload_protocol = stlink
build_flags =
-ggdb
-D USBCON
-D USBD_USE_CDC

176
src/main.cpp Normal file
View File

@ -0,0 +1,176 @@
#include <Arduino.h>
#include "stm32f1xx_hal_dma.h"
#define OUTPIN PA8
#define OUTPIN_N PB13
#define HVGENPIN PB9
HardwareTimer *shockTimer;
uint32_t shockPwmChannel;
uint32_t shockPwmChannel_N;
HardwareTimer *hvTimer;
uint32_t hvPwmChannel;
uint32_t frequency = 50;
uint8_t dutyCycle = 50;
uint8_t deadTime = 50;
uint32_t hvFrequency = 250000;
uint8_t hvDutyCycle = 61;
/**
* output = red, green jumper wire
* input = yellow
*
*/
void setup(void) {
pinMode(PA0, INPUT_ANALOG);
pinMode(LED_BUILTIN, OUTPUT);
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
// https://github.com/ahmetonat/STM32F103-ADC-DMA-example/blob/master/Src/stm32f1xx_hal_msp.c
// https://www.stm32duino.com/viewtopic.php?f=41&t=110
// https://controllerstech.com/dma-with-adc-using-registers-in-stm32/
// https://stm32duinoforum.com/forum/viewtopic_f_48_t_4399.html
TIM_TypeDef *shockInstance = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(OUTPIN), PinMap_PWM);
shockPwmChannel = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(OUTPIN), PinMap_PWM));
shockPwmChannel_N = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(OUTPIN_N), PinMap_PWM));
shockTimer = new HardwareTimer(shockInstance);
TIM_TypeDef *hvInstance = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(HVGENPIN), PinMap_PWM);
hvPwmChannel = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(HVGENPIN), PinMap_PWM));
hvTimer = new HardwareTimer(hvInstance);
// hvTimer->getHandle()->Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED3;
hvTimer->setPWM(hvPwmChannel, HVGENPIN, hvFrequency, hvDutyCycle);
Serial.begin(0);
/*shockTimer->pause();
shockTimer->setMode(shockPwmChannel, TIMER_OUTPUT_COMPARE_PWM1, OUTPIN);
shockTimer->setOverflow(5, HERTZ_FORMAT); // Hertz
shockTimer->setCaptureCompare(shockPwmChannel, 50,
PERCENT_COMPARE_FORMAT); // 50% Duty Cycle
shockTimer->resume(); */
shockTimer->setMode(shockPwmChannel_N, TIMER_OUTPUT_COMPARE_PWM1, OUTPIN_N);
shockTimer->setPWM(shockPwmChannel, OUTPIN, frequency, dutyCycle);
TIM1->CCER |= TIM_CCER_CC1NE; // Enable time r1 complementare output (channel 1)
sBreakDeadTimeConfig.BreakState = TIM_BREAK_ENABLE;
sBreakDeadTimeConfig.DeadTime = deadTime;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_LOW;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_1;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE;
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_ENABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_ENABLE;
HAL_TIMEx_ConfigBreakDeadTime(shockTimer->getHandle(), &sBreakDeadTimeConfig);
// LL_TIM_OC_SetDeadTime(TIM1, 50);
// shockInstance->BDTR |= 0xFF;
// with register manipulation, approx 14ns per increment 0 to 128
// (DTG Bits 7:0) -> DGT Bit 2|5 = 00100100 = 560ns
// bitSet(TIMER1_BASE->BDTR, 2);
// bitSet(TIMER1_BASE->BDTR, 5);
// shockTimer->setPWM(shockPwmChannel, OUTPIN_N, frequency, dutyCycle);
// shockTimer->setPWM(shockPwmChannel, OUTPIN_N, frequency, dutyCycle);
// setMode(shockPwmChannel, TIMER_, pin);
/* shockTimer->pause();
// TIM1->CCER |= 0x555; //3ch compl enable. 0x55 = 2ch compl enable. 0x5 = 1ch compl enable. As seen on RM0008 pages 353 & 354, CCxNE and CCxE bits
TIM1->CCER &= ~TIM_CCER_CC1NP; -- polarity low (or |= to high)
TIM1->CCER |= TIM_OCNPOLARITY_HIGH;
TIM1->CCER |= 0;
TIM1->CCER |= 2;
TIM1->CCER |= TIM_CCER_CC1NE;
TIM1->CR1 |= TIM_CR1_CMS_1; // center waveform
shockTimer->resume(); */
}
void setRegister(uint8_t reg, uint32_t val) {
if (reg == 1) {
frequency = val;
} else if (reg == 2) {
dutyCycle = val;
} else if (reg == 3) {
hvFrequency = val;
} else if (reg == 4) {
hvDutyCycle = val;
} else if (reg == 5) {
deadTime = val;
}
if (reg == 1 || reg == 2) {
shockTimer->setOverflow(frequency, HERTZ_FORMAT);
shockTimer->setCaptureCompare(shockPwmChannel, dutyCycle, PERCENT_COMPARE_FORMAT);
} else if (reg == 3 || reg == 4) {
hvTimer->setOverflow(hvFrequency, HERTZ_FORMAT);
hvTimer->setCaptureCompare(hvPwmChannel, hvDutyCycle, PERCENT_COMPARE_FORMAT);
} else if (reg == 5) {
LL_TIM_OC_SetDeadTime(TIM1, deadTime);
}
/* char buffer[256];
sprintf(buffer, "Setting register: %d to %d\n", reg, val);
Serial.print(buffer); */
}
uint32_t getRegister(uint8_t reg) {
if (reg == 1) {
return frequency;
} else if (reg == 2) {
return dutyCycle;
} else if (reg == 3) {
return hvFrequency;
} else if (reg == 4) {
return hvDutyCycle;
} else if (reg == 5) {
return deadTime;
}
return -1;
}
void processSerial() {
uint8_t msgType = Serial.read();
if (msgType == 1) {
// ping
uint8_t ack = 0x69;
Serial.write((uint8_t*) &ack, sizeof(ack));
} else if (msgType == 2) {
// set register
uint8_t reg = Serial.read();
uint32_t buf;
Serial.readBytes((char*) &buf, sizeof(buf));
setRegister(reg, buf);
uint8_t ack = 0x69;
Serial.write((uint8_t*) &ack, sizeof(ack));
} else if (msgType == 3) {
// get register
uint8_t reg = Serial.read();
uint32_t val = getRegister(reg);
// Serial.write((uint8_t*) &val, sizeof(val));
Serial.write((uint8_t*) &val, sizeof(val));
// Serial.write((uint8_t*) &val, sizeof(val));
// uint32_t val = getRegister(reg);
} else {
for (int i = 0; i < 5; i++) {
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
digitalWrite(LED_BUILTIN, LOW);
delay(100);
}
}
}
void loop(void) {
if (Serial.available()) {
processSerial();
}
delay(1);
}

11
test/README Normal file
View File

@ -0,0 +1,11 @@
This directory is intended for PlatformIO Test Runner and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html

280
todo/main_dma.cpp Normal file
View File

@ -0,0 +1,280 @@
#include <Arduino.h>
#include "stm32f1xx_ll_dma.h"
#include "stm32f1xx_hal_dma.h"
#include "math.h"
#define OUTPIN PA8
#define OUTPIN_N PB13
#define HVGENPIN PB9
#define M_PI 3.141526535
HardwareTimer *shockTimer;
uint32_t shockPwmChannel;
uint32_t shockPwmChannel_N;
HardwareTimer *hvTimer;
uint32_t hvPwmChannel;
uint32_t frequency = 50;
uint8_t dutyCycle = 50;
uint8_t deadTime = 50;
bool readyToSend = false;
uint32_t hvFrequency = 250000;
uint8_t hvDutyCycle = 61;
/**
* output = red, green jumper wire
* input = yellow
*
*
*
*/
__attribute__((aligned(4))) volatile uint16_t dmaBuf[] = { /*100, 150, 127, 100*/ 1, 1, 200, 200, 1, 1, 100, 100};
size_t dmaBuf_len = sizeof(dmaBuf) / sizeof(dmaBuf[0]);
void setup(void) {
pinMode(PA0, INPUT_ANALOG);
pinMode(LED_BUILTIN, OUTPUT);
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
// https://github.com/ahmetonat/STM32F103-ADC-DMA-example/blob/master/Src/stm32f1xx_hal_msp.c
// https://www.stm32duino.com/viewtopic.php?f=41&t=110
// https://controllerstech.com/dma-with-adc-using-registers-in-stm32/
// https://stm32duinoforum.com/forum/viewtopic_f_48_t_4399.html
// DMA:
// https://controllerstech.com/pwm-with-dma-in-stm32/ -- good
// https://deepbluembedded.com/stm32-change-pwm-duty-cycle-with-dma-for-sine-wave-generation/
// https://electronics.stackexchange.com/questions/652738/stm32-pwm-and-output-compare
// https://community.st.com/s/question/0D53W000007zeyoSAA/pwm-output-synchronization-problem
// LL_TIM_OC_SetDeadTime
TIM_TypeDef *shockInstance = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(OUTPIN), PinMap_PWM);
shockPwmChannel = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(OUTPIN), PinMap_PWM));
shockPwmChannel_N = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(OUTPIN_N), PinMap_PWM));
shockTimer = new HardwareTimer(shockInstance);
/* TIM_TypeDef *hvInstance = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(HVGENPIN), PinMap_PWM);
hvPwmChannel = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(HVGENPIN), PinMap_PWM));
hvTimer = new HardwareTimer(hvInstance); */
// hvTimer->handle
// _timerObj.handle.Init
// hvTimer->getHandle()->Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED3;
Serial.begin(0);
for (size_t i = 0; i < dmaBuf_len; i++) {
// dmaBuf[i] = sin(2 * M_PI * i / dmaBuf_len);
}
/*shockTimer->pause();
shockTimer->setMode(shockPwmChannel, TIMER_OUTPUT_COMPARE_PWM1, OUTPIN);
shockTimer->setOverflow(5, HERTZ_FORMAT); // Hertz
shockTimer->setCaptureCompare(shockPwmChannel, 50,
PERCENT_COMPARE_FORMAT); // 50% Duty Cycle
shockTimer->resume(); */
shockTimer->setMode(shockPwmChannel_N, TIMER_OUTPUT_COMPARE_PWM1, OUTPIN_N);
shockTimer->setPWM(shockPwmChannel, OUTPIN, frequency, dutyCycle);
TIM1->CCER |= TIM_CCER_CC1NE;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_ENABLE;
sBreakDeadTimeConfig.DeadTime = deadTime;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_LOW;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_1;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE;
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_ENABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_ENABLE;
HAL_TIMEx_ConfigBreakDeadTime(shockTimer->getHandle(), &sBreakDeadTimeConfig);
// LL_TIM_OC_SetDeadTime(TIM1, 50);
// shockInstance->BDTR |= 0xFF;
//Inserts Dead Time approx 14ns per increment 0 to 128
//(DTG Bits 7:0)
//DGT Bit 2&5 = 00100100 = 560ns
// bitSet(TIMER1_BASE->BDTR,2);
// bitSet(TIMER1_BASE->BDTR,5);
//shockTimer->setPWM(shockPwmChannel, OUTPIN_N, frequency, dutyCycle);
// shockTimer->setPWM(shockPwmChannel, OUTPIN_N, frequency, dutyCycle);
// setMode(shockPwmChannel, TIMER_, pin);
// hvTimer->setPWM(hvPwmChannel, HVGENPIN, hvFrequency, hvDutyCycle);
// delay(3000);
/* shockTimer->pause();
// TIM1->CCER |= 0x555; //3ch compl enable. 0x55 = 2ch compl enable. 0x5 = 1ch compl enable. As seen on RM0008 pages 353 & 354, CCxNE and CCxE bits
TIM1->CCER &= ~TIM_CCER_CC1NP; -- polarity low (or |= to high)
TIM1->CCER |= TIM_OCNPOLARITY_HIGH;
TIM1->CCER |= 0;
TIM1->CCER |= 2;
TIM1->CCER |= TIM_CCER_CC1NE;
TIM1->CR1 |= TIM_CR1_CMS_1; // center waveform
// shockTimer->setPWM(shockPwmChannel, OUTPIN, frequency, dutyCycle);
shockTimer->resume(); */
// auto timerMax = (__HAL_TIM_GET_AUTORELOAD(&(shockTimer->getHandle())) + 1);
/* for (uint8_t i = 0; i < 200; i++) {
angle = ASR*(float)i;
IV[i] = (uint16_t) rint(100 + 99*sinf(angle*(PI/180)));
} */
DMA_HandleTypeDef hdma_tim2_ch1;
hdma_tim2_ch1.Instance = DMA1_Channel5; // Table 78
hdma_tim2_ch1.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tim2_ch1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tim2_ch1.Init.MemInc = DMA_MINC_ENABLE;
// on an STM32F407 Tim1 is 16bit so DMA transfer needs to be half word, eg Tim2 is 32bit so use word
hdma_tim2_ch1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_tim2_ch1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_tim2_ch1.Init.Mode = DMA_CIRCULAR;
hdma_tim2_ch1.Init.Priority = DMA_PRIORITY_HIGH;
// HAL_TIM_PWM_DeInit(shockTimer->getHandle());
if (HAL_DMA_Init(&hdma_tim2_ch1) != HAL_OK) {
// Error_Handler();
for (int i = 0; i < 5; i++) {
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
digitalWrite(LED_BUILTIN, LOW);
delay(100);
}
}
// __HAL_RCC_DMA1_CLK_ENABLE();
// __HAL_LINKDMA(shockTimer->getHandle(), hdma[TIM_DMA_ID_CC1], hdma_tim2_ch1); // TIM_DMA_ID_CC1 -> shockPwmChannel ???
__HAL_LINKDMA(shockTimer->getHandle(), hdma[TIM_DMA_ID_CC4], hdma_tim2_ch1); // TIM_DMA_ID_CC1 -> shockPwmChannel ???
__HAL_LINKDMA(shockTimer->getHandle(), hdma[TIM_DMA_ID_TRIGGER], hdma_tim2_ch1);
// page 358 Mastering STM32
// If anyone else is forced by their pinout to use one of the complementary PWM outputs (e.g. CH3N)
// then be sure to change the call to HAL_TIM_PWM_Start_DMA() for HAL_TIMEx_PWMN_Start_DMA()
// HAL_TIM_PWM_Start_DMA(shockTimer->getHandle(), TIM_CHANNEL_1, (uint32_t*) &dmaBuf, dmaBuf_len);
HAL_TIM_PWM_Start_DMA(shockTimer->getHandle(), TIM_CHANNEL_1, (uint32_t*) &dmaBuf[0], dmaBuf_len);
/* LL_DMA_InitTypeDef DMA_InitStruct;
DMA_InitStruct.Channel = LL_DMA_CHANNEL_4;
DMA_InitStruct.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
DMA_InitStruct.MemoryOrM2MDstAddress = (uint32_t)DMA_RX_Buffer;
DMA_InitStruct.NbData = DMA_RX_BUFFER_SIZE;
DMA_InitStruct.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT;
DMA_InitStruct.PeriphOrM2MSrcAddress = (uint32_t)&TIM1->DR;
LL_DMA_Init(DMA1, LL_DMA_STREAM_5, &DMA_InitStruct); */
analogReadResolution(12);
}
void setShockFrequency(uint32_t freq) {
}
void setRegister(uint8_t reg, uint32_t val) {
if (reg == 1) {
frequency = val;
} else if (reg == 2) {
dutyCycle = val;
} else if (reg == 3) {
hvFrequency = val;
} else if (reg == 4) {
hvDutyCycle = val;
} else if (reg == 5) {
deadTime = val;
}
if (reg == 1 || reg == 2) {
shockTimer->setOverflow(frequency, HERTZ_FORMAT);
shockTimer->setCaptureCompare(shockPwmChannel, dutyCycle, PERCENT_COMPARE_FORMAT);
} else if (reg == 3 || reg == 4) {
hvTimer->setOverflow(hvFrequency, HERTZ_FORMAT);
hvTimer->setCaptureCompare(hvPwmChannel, hvDutyCycle, PERCENT_COMPARE_FORMAT);
} else if (reg == 5) {
LL_TIM_OC_SetDeadTime(TIM1, deadTime);
}
/* char buffer[256];
sprintf(buffer, "Setting register: %d to %d\n", reg, val);
Serial.print(buffer); */
}
uint32_t getRegister(uint8_t reg) {
if (reg == 1) {
return frequency;
} else if (reg == 2) {
return dutyCycle;
} else if (reg == 3) {
return hvFrequency;
} else if (reg == 4) {
return hvDutyCycle;
} else if (reg == 5) {
return deadTime;
}
}
void processSerial() {
uint8_t msgType = Serial.read();
if (msgType == 1) {
// ping
uint8_t ack = 0x69;
Serial.write((uint8_t*) &ack, sizeof(ack));
} else if (msgType == 2) {
// set register
uint8_t reg = Serial.read();
uint32_t buf;
Serial.readBytes((char*) &buf, sizeof(buf));
setRegister(reg, buf);
uint8_t ack = 0x69;
Serial.write((uint8_t*) &ack, sizeof(ack));
} else if (msgType == 3) {
// get register
uint8_t reg = Serial.read();
uint32_t val = getRegister(reg);
// Serial.write((uint8_t*) &val, sizeof(val));
Serial.write((uint8_t*) &val, sizeof(val));
// Serial.write((uint8_t*) &val, sizeof(val));
// uint32_t val = getRegister(reg);
} else {
for (int i = 0; i < 5; i++) {
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
digitalWrite(LED_BUILTIN, LOW);
delay(100);
}
}
}
void sendMsg(uint8_t type) {
}
void loop(void) {
if (Serial.available()) {
processSerial();
}
uint16_t v = (uint16_t) analogRead(PA0);
// Serial.write((uint8_t*) &v, sizeof(v));
/* Serial.print(v);
Serial.println(); */
delay(1);
}