diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..23c7c99 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "External/MockTools"] + path = External/MockTools + url = https://github.com/ToolboxPlane/MockTools.git diff --git a/CMakeLists.txt b/CMakeLists.txt index e7429a3..7ac76aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,2 +1,5 @@ project(AvrHAL) add_library(${PROJECT_NAME} STATIC adc.c i2c.c pwm16bit.c spi.c timer8bit.c uart.c) + +add_subdirectory(External/MockTools) +add_subdirectory(Tests) diff --git a/External/MockTools b/External/MockTools new file mode 160000 index 0000000..7b5afea --- /dev/null +++ b/External/MockTools @@ -0,0 +1 @@ +Subproject commit 7b5afeaa0bdfaa2eb0e70263e4fd5a888fea96ff diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt new file mode 100644 index 0000000..cddbde6 --- /dev/null +++ b/Tests/CMakeLists.txt @@ -0,0 +1,12 @@ +make_test(MODULE_UNDER_TEST ../pwm16bit.c + TEST_DEFINITION pwm16bit.cpp + REQUIRED_HEADERS + ${MockLib_SOURCE_DIR}/../System/avr/io.h) +make_test(MODULE_UNDER_TEST ../timer8bit.c + TEST_DEFINITION timer8bit.cpp + REQUIRED_HEADERS + ${MockLib_SOURCE_DIR}/../System/avr/io.h) +make_test(MODULE_UNDER_TEST ../uart.c + TEST_DEFINITION uart.cpp + REQUIRED_HEADERS + ${MockLib_SOURCE_DIR}/../System/avr/io.h) diff --git a/Tests/pwm16bit.cpp b/Tests/pwm16bit.cpp new file mode 100644 index 0000000..fcaee93 --- /dev/null +++ b/Tests/pwm16bit.cpp @@ -0,0 +1,410 @@ +#include +#include + +extern "C" { +#include +} + +TEST(TEST_NAME, init__timer_1_basic) { + /* + * Initialize timer 1 with no_clock (=0) as clock option and top=0 + */ + pwm_init(1, no_clock, 0); + + EXPECT_EQ((TCCR1A >> 6U) & 0b11U, 2); // COMnA + EXPECT_EQ((TCCR1A >> 4U) & 0b11U, 2); // COMnB + EXPECT_EQ((TCCR1A >> 2U) & 0b11U, 2); // COMnC + EXPECT_EQ((TCCR1A & 0b11U) | ((TCCR1B >> 1U) & 0b1100U), 14); // WGMn + EXPECT_EQ((TCCR1B >> 7U) & 0b1U, 0); // ICNC + EXPECT_EQ((TCCR1B >> 6U) & 0b1U, 0); // ICES + EXPECT_EQ((TCCR1B >> 5U) & 0b1U, 0); // Reserved + EXPECT_EQ(TCCR1B & 0b111U, 0); // Clock Select + EXPECT_EQ((TCCR1C >> 7U) & 0b1, 0); // Force Output Compare A + EXPECT_EQ((TCCR1C >> 6U) & 0b1, 0); // Force Output Compare B + EXPECT_EQ((TCCR1C >> 5U) & 0b1, 0); // Force Output Compare C + EXPECT_EQ(TCNT1, 0); // Timer/Counter + EXPECT_EQ(OCR1A, 0); // Output compare register A + EXPECT_EQ(OCR1B, 0); // Output compare register B + EXPECT_EQ(OCR1C, 0); // Output compare register C + EXPECT_EQ(ICR1, 0); // Input Capture register (i.e. top) + EXPECT_EQ((TIMSK1 >> 5U) & 0b1U, 0); // ICIE + EXPECT_EQ((TIMSK1 >> 3U) & 0b1U, 0); // OICIEnC + EXPECT_EQ((TIMSK1 >> 2U) & 0b1U, 0); // OICIEnB + EXPECT_EQ((TIMSK1 >> 1U) & 0b1U, 0); // OICIEnA + EXPECT_EQ((TIMSK1 >> 0U) & 0b1U, 0); // TOIEn +} + +TEST(TEST_NAME, init__timer_3_basic) { + /* + * Initialize timer 3 with no_clock (=0) as clock option and top=0 + */ + pwm_init(3, no_clock, 0); + + EXPECT_EQ((TCCR3A >> 6U) & 0b11U, 2); // COMnA + EXPECT_EQ((TCCR3A >> 4U) & 0b11U, 2); // COMnB + EXPECT_EQ((TCCR3A >> 2U) & 0b11U, 2); // COMnC + EXPECT_EQ((TCCR3A & 0b11U) | ((TCCR3B >> 1U) & 0b1100U), 14); // WGMn + EXPECT_EQ((TCCR3B >> 7U) & 0b1U, 0); // ICNC + EXPECT_EQ((TCCR3B >> 6U) & 0b1U, 0); // ICES + EXPECT_EQ((TCCR3B >> 5U) & 0b1U, 0); // Reserved + EXPECT_EQ(TCCR3B & 0b111U, 0); // Clock Select + EXPECT_EQ((TCCR3C >> 7U) & 0b1, 0); // Force Output Compare A + EXPECT_EQ((TCCR3C >> 6U) & 0b1, 0); // Force Output Compare B + EXPECT_EQ((TCCR3C >> 5U) & 0b1, 0); // Force Output Compare C + EXPECT_EQ(TCNT3, 0); // Timer/Counter + EXPECT_EQ(OCR3A, 0); // Output compare register A + EXPECT_EQ(OCR3B, 0); // Output compare register B + EXPECT_EQ(OCR3C, 0); // Output compare register C + EXPECT_EQ(ICR3, 0); // Input Capture register (i.e. top) + EXPECT_EQ((TIMSK3 >> 5U) & 0b1U, 0); // ICIE + EXPECT_EQ((TIMSK3 >> 3U) & 0b1U, 0); // OICIEnC + EXPECT_EQ((TIMSK3 >> 2U) & 0b1U, 0); // OICIEnB + EXPECT_EQ((TIMSK3 >> 1U) & 0b1U, 0); // OICIEnA + EXPECT_EQ((TIMSK3 >> 0U) & 0b1U, 0); // TOIEn +} + +TEST(TEST_NAME, init__timer_4_basic) { + /* + * Initialize timer 4 with no_clock (=0) as clock option and top=0 + */ + pwm_init(4, no_clock, 0); + + EXPECT_EQ((TCCR4A >> 6U) & 0b11U, 2); // COMnA + EXPECT_EQ((TCCR4A >> 4U) & 0b11U, 2); // COMnB + EXPECT_EQ((TCCR4A >> 2U) & 0b11U, 2); // COMnC + EXPECT_EQ((TCCR4A & 0b11U) | ((TCCR4B >> 1U) & 0b1100U), 14); // WGMn + EXPECT_EQ((TCCR4B >> 7U) & 0b1U, 0); // ICNC + EXPECT_EQ((TCCR4B >> 6U) & 0b1U, 0); // ICES + EXPECT_EQ((TCCR4B >> 5U) & 0b1U, 0); // Reserved + EXPECT_EQ(TCCR4B & 0b111U, 0); // Clock Select + EXPECT_EQ((TCCR4C >> 7U) & 0b1, 0); // Force Output Compare A + EXPECT_EQ((TCCR4C >> 6U) & 0b1, 0); // Force Output Compare B + EXPECT_EQ((TCCR4C >> 5U) & 0b1, 0); // Force Output Compare C + EXPECT_EQ(TCNT4, 0); // Timer/Counter + EXPECT_EQ(OCR4A, 0); // Output compare register A + EXPECT_EQ(OCR4B, 0); // Output compare register B + EXPECT_EQ(OCR4C, 0); // Output compare register C + EXPECT_EQ(ICR4, 0); // Input Capture register (i.e. top) + EXPECT_EQ((TIMSK4 >> 5U) & 0b1U, 0); // ICIE + EXPECT_EQ((TIMSK4 >> 3U) & 0b1U, 0); // OICIEnC + EXPECT_EQ((TIMSK4 >> 2U) & 0b1U, 0); // OICIEnB + EXPECT_EQ((TIMSK4 >> 1U) & 0b1U, 0); // OICIEnA + EXPECT_EQ((TIMSK4 >> 0U) & 0b1U, 0); // TOIEn +} + +TEST(TEST_NAME, init__timer_5_basic) { + /* + * Initialize timer 5 with no_clock (=0) as clock option and top=0 + */ + pwm_init(5, no_clock, 0); + + EXPECT_EQ((TCCR5A >> 6U) & 0b11U, 2); // COMnA + EXPECT_EQ((TCCR5A >> 4U) & 0b11U, 2); // COMnB + EXPECT_EQ((TCCR5A >> 2U) & 0b11U, 2); // COMnC + EXPECT_EQ((TCCR5A & 0b11U) | ((TCCR5B >> 1U) & 0b1100U), 14); // WGMn + EXPECT_EQ((TCCR5B >> 7U) & 0b1U, 0); // ICNC + EXPECT_EQ((TCCR5B >> 6U) & 0b1U, 0); // ICES + EXPECT_EQ((TCCR5B >> 5U) & 0b1U, 0); // Reserved + EXPECT_EQ(TCCR5B & 0b111U, 0); // Clock Select + EXPECT_EQ((TCCR5C >> 7U) & 0b1, 0); // Force Output Compare A + EXPECT_EQ((TCCR5C >> 6U) & 0b1, 0); // Force Output Compare B + EXPECT_EQ((TCCR5C >> 5U) & 0b1, 0); // Force Output Compare C + EXPECT_EQ(TCNT5, 0); // Timer/Counter + EXPECT_EQ(OCR5A, 0); // Output compare register A + EXPECT_EQ(OCR5B, 0); // Output compare register B + EXPECT_EQ(OCR5C, 0); // Output compare register C + EXPECT_EQ(ICR5, 0); // Input Capture register (i.e. top) + EXPECT_EQ((TIMSK5 >> 5U) & 0b1U, 0); // ICIE + EXPECT_EQ((TIMSK5 >> 3U) & 0b1U, 0); // OICIEnC + EXPECT_EQ((TIMSK5 >> 2U) & 0b1U, 0); // OICIEnB + EXPECT_EQ((TIMSK5 >> 1U) & 0b1U, 0); // OICIEnA + EXPECT_EQ((TIMSK5 >> 0U) & 0b1U, 0); // TOIEn +} + +TEST(TEST_NAME, init__timer_prescaler_1) { + /* + * Initialize timer 1 with prescaler 1 as clock option and top=0 + */ + pwm_init(1, prescaler_1, 0); + + EXPECT_EQ((TCCR1A >> 6U) & 0b11U, 2); // COMnA + EXPECT_EQ((TCCR1A >> 4U) & 0b11U, 2); // COMnB + EXPECT_EQ((TCCR1A >> 2U) & 0b11U, 2); // COMnC + EXPECT_EQ((TCCR1A & 0b11U) | ((TCCR1B >> 1U) & 0b1100U), 14); // WGMn + EXPECT_EQ((TCCR1B >> 7U) & 0b1U, 0); // ICNC + EXPECT_EQ((TCCR1B >> 6U) & 0b1U, 0); // ICES + EXPECT_EQ((TCCR1B >> 5U) & 0b1U, 0); // Reserved + EXPECT_EQ(TCCR1B & 0b111U, 0b001); // Clock Select + EXPECT_EQ((TCCR1C >> 7U) & 0b1, 0); // Force Output Compare A + EXPECT_EQ((TCCR1C >> 6U) & 0b1, 0); // Force Output Compare B + EXPECT_EQ((TCCR1C >> 5U) & 0b1, 0); // Force Output Compare C + EXPECT_EQ(TCNT1, 0); // Timer/Counter + EXPECT_EQ(OCR1A, 0); // Output compare register A + EXPECT_EQ(OCR1B, 0); // Output compare register B + EXPECT_EQ(OCR1C, 0); // Output compare register C + EXPECT_EQ(ICR1, 0); // Input Capture register (i.e. top) + EXPECT_EQ((TIMSK1 >> 5U) & 0b1U, 0); // ICIE + EXPECT_EQ((TIMSK1 >> 3U) & 0b1U, 0); // OICIEnC + EXPECT_EQ((TIMSK1 >> 2U) & 0b1U, 0); // OICIEnB + EXPECT_EQ((TIMSK1 >> 1U) & 0b1U, 0); // OICIEnA + EXPECT_EQ((TIMSK1 >> 0U) & 0b1U, 0); // TOIEn +} + +TEST(TEST_NAME, init__timer_prescaler_8) { + /* + * Initialize timer 1 with prescaler 8 as clock option and top=0 + */ + pwm_init(1, prescaler_8, 0); + + EXPECT_EQ((TCCR1A >> 6U) & 0b11U, 2); // COMnA + EXPECT_EQ((TCCR1A >> 4U) & 0b11U, 2); // COMnB + EXPECT_EQ((TCCR1A >> 2U) & 0b11U, 2); // COMnC + EXPECT_EQ((TCCR1A & 0b11U) | ((TCCR1B >> 1U) & 0b1100U), 14); // WGMn + EXPECT_EQ((TCCR1B >> 7U) & 0b1U, 0); // ICNC + EXPECT_EQ((TCCR1B >> 6U) & 0b1U, 0); // ICES + EXPECT_EQ((TCCR1B >> 5U) & 0b1U, 0); // Reserved + EXPECT_EQ(TCCR1B & 0b111U, 0b010); // Clock Select + EXPECT_EQ((TCCR1C >> 7U) & 0b1, 0); // Force Output Compare A + EXPECT_EQ((TCCR1C >> 6U) & 0b1, 0); // Force Output Compare B + EXPECT_EQ((TCCR1C >> 5U) & 0b1, 0); // Force Output Compare C + EXPECT_EQ(TCNT1, 0); // Timer/Counter + EXPECT_EQ(OCR1A, 0); // Output compare register A + EXPECT_EQ(OCR1B, 0); // Output compare register B + EXPECT_EQ(OCR1C, 0); // Output compare register C + EXPECT_EQ(ICR1, 0); // Input Capture register (i.e. top) + EXPECT_EQ((TIMSK1 >> 5U) & 0b1U, 0); // ICIE + EXPECT_EQ((TIMSK1 >> 3U) & 0b1U, 0); // OICIEnC + EXPECT_EQ((TIMSK1 >> 2U) & 0b1U, 0); // OICIEnB + EXPECT_EQ((TIMSK1 >> 1U) & 0b1U, 0); // OICIEnA + EXPECT_EQ((TIMSK1 >> 0U) & 0b1U, 0); // TOIEn +} + +TEST(TEST_NAME, init__timer_prescaler_64) { + /* + * Initialize timer 1 with prescaler 64 as clock option and top=0 + */ + pwm_init(1, prescaler_64, 0); + + EXPECT_EQ((TCCR1A >> 6U) & 0b11U, 2); // COMnA + EXPECT_EQ((TCCR1A >> 4U) & 0b11U, 2); // COMnB + EXPECT_EQ((TCCR1A >> 2U) & 0b11U, 2); // COMnC + EXPECT_EQ((TCCR1A & 0b11U) | ((TCCR1B >> 1U) & 0b1100U), 14); // WGMn + EXPECT_EQ((TCCR1B >> 7U) & 0b1U, 0); // ICNC + EXPECT_EQ((TCCR1B >> 6U) & 0b1U, 0); // ICES + EXPECT_EQ((TCCR1B >> 5U) & 0b1U, 0); // Reserved + EXPECT_EQ(TCCR1B & 0b111U, 0b011); // Clock Select + EXPECT_EQ((TCCR1C >> 7U) & 0b1, 0); // Force Output Compare A + EXPECT_EQ((TCCR1C >> 6U) & 0b1, 0); // Force Output Compare B + EXPECT_EQ((TCCR1C >> 5U) & 0b1, 0); // Force Output Compare C + EXPECT_EQ(TCNT1, 0); // Timer/Counter + EXPECT_EQ(OCR1A, 0); // Output compare register A + EXPECT_EQ(OCR1B, 0); // Output compare register B + EXPECT_EQ(OCR1C, 0); // Output compare register C + EXPECT_EQ(ICR1, 0); // Input Capture register (i.e. top) + EXPECT_EQ((TIMSK1 >> 5U) & 0b1U, 0); // ICIE + EXPECT_EQ((TIMSK1 >> 3U) & 0b1U, 0); // OICIEnC + EXPECT_EQ((TIMSK1 >> 2U) & 0b1U, 0); // OICIEnB + EXPECT_EQ((TIMSK1 >> 1U) & 0b1U, 0); // OICIEnA + EXPECT_EQ((TIMSK1 >> 0U) & 0b1U, 0); // TOIEn +} + +TEST(TEST_NAME, init__timer_prescaler_256) { + /* + * Initialize timer 1 with prescaler 256 as clock option and top=0 + */ + pwm_init(1, prescaler_256, 0); + + EXPECT_EQ((TCCR1A >> 6U) & 0b11U, 2); // COMnA + EXPECT_EQ((TCCR1A >> 4U) & 0b11U, 2); // COMnB + EXPECT_EQ((TCCR1A >> 2U) & 0b11U, 2); // COMnC + EXPECT_EQ((TCCR1A & 0b11U) | ((TCCR1B >> 1U) & 0b1100U), 14); // WGMn + EXPECT_EQ((TCCR1B >> 7U) & 0b1U, 0); // ICNC + EXPECT_EQ((TCCR1B >> 6U) & 0b1U, 0); // ICES + EXPECT_EQ((TCCR1B >> 5U) & 0b1U, 0); // Reserved + EXPECT_EQ(TCCR1B & 0b111U, 0b100); // Clock Select + EXPECT_EQ((TCCR1C >> 7U) & 0b1, 0); // Force Output Compare A + EXPECT_EQ((TCCR1C >> 6U) & 0b1, 0); // Force Output Compare B + EXPECT_EQ((TCCR1C >> 5U) & 0b1, 0); // Force Output Compare C + EXPECT_EQ(TCNT1, 0); // Timer/Counter + EXPECT_EQ(OCR1A, 0); // Output compare register A + EXPECT_EQ(OCR1B, 0); // Output compare register B + EXPECT_EQ(OCR1C, 0); // Output compare register C + EXPECT_EQ(ICR1, 0); // Input Capture register (i.e. top) + EXPECT_EQ((TIMSK1 >> 5U) & 0b1U, 0); // ICIE + EXPECT_EQ((TIMSK1 >> 3U) & 0b1U, 0); // OICIEnC + EXPECT_EQ((TIMSK1 >> 2U) & 0b1U, 0); // OICIEnB + EXPECT_EQ((TIMSK1 >> 1U) & 0b1U, 0); // OICIEnA + EXPECT_EQ((TIMSK1 >> 0U) & 0b1U, 0); // TOIEn +} +TEST(TEST_NAME, init__timer_prescaler_1024) { + /* + * Initialize timer 1 with prescaler 1024 as clock option and top=0 + */ + pwm_init(1, prescaler_1024, 0); + + EXPECT_EQ((TCCR1A >> 6U) & 0b11U, 2); // COMnA + EXPECT_EQ((TCCR1A >> 4U) & 0b11U, 2); // COMnB + EXPECT_EQ((TCCR1A >> 2U) & 0b11U, 2); // COMnC + EXPECT_EQ((TCCR1A & 0b11U) | ((TCCR1B >> 1U) & 0b1100U), 14); // WGMn + EXPECT_EQ((TCCR1B >> 7U) & 0b1U, 0); // ICNC + EXPECT_EQ((TCCR1B >> 6U) & 0b1U, 0); // ICES + EXPECT_EQ((TCCR1B >> 5U) & 0b1U, 0); // Reserved + EXPECT_EQ(TCCR1B & 0b111U, 0b101); // Clock Select + EXPECT_EQ((TCCR1C >> 7U) & 0b1, 0); // Force Output Compare A + EXPECT_EQ((TCCR1C >> 6U) & 0b1, 0); // Force Output Compare B + EXPECT_EQ((TCCR1C >> 5U) & 0b1, 0); // Force Output Compare C + EXPECT_EQ(TCNT1, 0); // Timer/Counter + EXPECT_EQ(OCR1A, 0); // Output compare register A + EXPECT_EQ(OCR1B, 0); // Output compare register B + EXPECT_EQ(OCR1C, 0); // Output compare register C + EXPECT_EQ(ICR1, 0); // Input Capture register (i.e. top) + EXPECT_EQ((TIMSK1 >> 5U) & 0b1U, 0); // ICIE + EXPECT_EQ((TIMSK1 >> 3U) & 0b1U, 0); // OICIEnC + EXPECT_EQ((TIMSK1 >> 2U) & 0b1U, 0); // OICIEnB + EXPECT_EQ((TIMSK1 >> 1U) & 0b1U, 0); // OICIEnA + EXPECT_EQ((TIMSK1 >> 0U) & 0b1U, 0); // TOIEn +} +TEST(TEST_NAME, init__timer_clock_falling) { + /* + * Initialize timer 1 with external falling as clock option and top=0 + */ + pwm_init(1, external_falling, 0); + + EXPECT_EQ((TCCR1A >> 6U) & 0b11U, 2); // COMnA + EXPECT_EQ((TCCR1A >> 4U) & 0b11U, 2); // COMnB + EXPECT_EQ((TCCR1A >> 2U) & 0b11U, 2); // COMnC + EXPECT_EQ((TCCR1A & 0b11U) | ((TCCR1B >> 1U) & 0b1100U), 14); // WGMn + EXPECT_EQ((TCCR1B >> 7U) & 0b1U, 0); // ICNC + EXPECT_EQ((TCCR1B >> 6U) & 0b1U, 0); // ICES + EXPECT_EQ((TCCR1B >> 5U) & 0b1U, 0); // Reserved + EXPECT_EQ(TCCR1B & 0b111U, 0b110); // Clock Select + EXPECT_EQ((TCCR1C >> 7U) & 0b1, 0); // Force Output Compare A + EXPECT_EQ((TCCR1C >> 6U) & 0b1, 0); // Force Output Compare B + EXPECT_EQ((TCCR1C >> 5U) & 0b1, 0); // Force Output Compare C + EXPECT_EQ(TCNT1, 0); // Timer/Counter + EXPECT_EQ(OCR1A, 0); // Output compare register A + EXPECT_EQ(OCR1B, 0); // Output compare register B + EXPECT_EQ(OCR1C, 0); // Output compare register C + EXPECT_EQ(ICR1, 0); // Input Capture register (i.e. top) + EXPECT_EQ((TIMSK1 >> 5U) & 0b1U, 0); // ICIE + EXPECT_EQ((TIMSK1 >> 3U) & 0b1U, 0); // OICIEnC + EXPECT_EQ((TIMSK1 >> 2U) & 0b1U, 0); // OICIEnB + EXPECT_EQ((TIMSK1 >> 1U) & 0b1U, 0); // OICIEnA + EXPECT_EQ((TIMSK1 >> 0U) & 0b1U, 0); // TOIEn +} +TEST(TEST_NAME, init__timer_clock_rising) { + /* + * Initialize timer 1 with external rising as clock option and top=0 + */ + pwm_init(1, external_rising, 0); + + EXPECT_EQ((TCCR1A >> 6U) & 0b11U, 2); // COMnA + EXPECT_EQ((TCCR1A >> 4U) & 0b11U, 2); // COMnB + EXPECT_EQ((TCCR1A >> 2U) & 0b11U, 2); // COMnC + EXPECT_EQ((TCCR1A & 0b11U) | ((TCCR1B >> 1U) & 0b1100U), 14); // WGMn + EXPECT_EQ((TCCR1B >> 7U) & 0b1U, 0); // ICNC + EXPECT_EQ((TCCR1B >> 6U) & 0b1U, 0); // ICES + EXPECT_EQ((TCCR1B >> 5U) & 0b1U, 0); // Reserved + EXPECT_EQ(TCCR1B & 0b111U, 0b111); // Clock Select + EXPECT_EQ((TCCR1C >> 7U) & 0b1, 0); // Force Output Compare A + EXPECT_EQ((TCCR1C >> 6U) & 0b1, 0); // Force Output Compare B + EXPECT_EQ((TCCR1C >> 5U) & 0b1, 0); // Force Output Compare C + EXPECT_EQ(TCNT1, 0); // Timer/Counter + EXPECT_EQ(OCR1A, 0); // Output compare register A + EXPECT_EQ(OCR1B, 0); // Output compare register B + EXPECT_EQ(OCR1C, 0); // Output compare register C + EXPECT_EQ(ICR1, 0); // Input Capture register (i.e. top) + EXPECT_EQ((TIMSK1 >> 5U) & 0b1U, 0); // ICIE + EXPECT_EQ((TIMSK1 >> 3U) & 0b1U, 0); // OICIEnC + EXPECT_EQ((TIMSK1 >> 2U) & 0b1U, 0); // OICIEnB + EXPECT_EQ((TIMSK1 >> 1U) & 0b1U, 0); // OICIEnA + EXPECT_EQ((TIMSK1 >> 0U) & 0b1U, 0); // TOIEn +} + +TEST(TEST_NAME, init__timer_top_0) { + /* + * Initialize timer 1 with no_clock (=0) as clock option and top=0 + */ + pwm_init(1, no_clock, 0); + + EXPECT_EQ((TCCR1A >> 6U) & 0b11U, 2); // COMnA + EXPECT_EQ((TCCR1A >> 4U) & 0b11U, 2); // COMnB + EXPECT_EQ((TCCR1A >> 2U) & 0b11U, 2); // COMnC + EXPECT_EQ((TCCR1A & 0b11U) | ((TCCR1B >> 1U) & 0b1100U), 14); // WGMn + EXPECT_EQ((TCCR1B >> 7U) & 0b1U, 0); // ICNC + EXPECT_EQ((TCCR1B >> 6U) & 0b1U, 0); // ICES + EXPECT_EQ((TCCR1B >> 5U) & 0b1U, 0); // Reserved + EXPECT_EQ(TCCR1B & 0b111U, 0); // Clock Select + EXPECT_EQ((TCCR1C >> 7U) & 0b1, 0); // Force Output Compare A + EXPECT_EQ((TCCR1C >> 6U) & 0b1, 0); // Force Output Compare B + EXPECT_EQ((TCCR1C >> 5U) & 0b1, 0); // Force Output Compare C + EXPECT_EQ(TCNT1, 0); // Timer/Counter + EXPECT_EQ(OCR1A, 0); // Output compare register A + EXPECT_EQ(OCR1B, 0); // Output compare register B + EXPECT_EQ(OCR1C, 0); // Output compare register C + EXPECT_EQ(ICR1, 0); // Input Capture register (i.e. top) + EXPECT_EQ((TIMSK1 >> 5U) & 0b1U, 0); // ICIE + EXPECT_EQ((TIMSK1 >> 3U) & 0b1U, 0); // OICIEnC + EXPECT_EQ((TIMSK1 >> 2U) & 0b1U, 0); // OICIEnB + EXPECT_EQ((TIMSK1 >> 1U) & 0b1U, 0); // OICIEnA + EXPECT_EQ((TIMSK1 >> 0U) & 0b1U, 0); // TOIEn +} + +TEST(TEST_NAME, init__timer_top_1337) { + /* + * Initialize timer 1 with no_clock (=0) as clock option and top=1337 + */ + pwm_init(1, no_clock, 1337); + + EXPECT_EQ((TCCR1A >> 6U) & 0b11U, 2); // COMnA + EXPECT_EQ((TCCR1A >> 4U) & 0b11U, 2); // COMnB + EXPECT_EQ((TCCR1A >> 2U) & 0b11U, 2); // COMnC + EXPECT_EQ((TCCR1A & 0b11U) | ((TCCR1B >> 1U) & 0b1100U), 14); // WGMn + EXPECT_EQ((TCCR1B >> 7U) & 0b1U, 0); // ICNC + EXPECT_EQ((TCCR1B >> 6U) & 0b1U, 0); // ICES + EXPECT_EQ((TCCR1B >> 5U) & 0b1U, 0); // Reserved + EXPECT_EQ(TCCR1B & 0b111U, 0); // Clock Select + EXPECT_EQ((TCCR1C >> 7U) & 0b1, 0); // Force Output Compare A + EXPECT_EQ((TCCR1C >> 6U) & 0b1, 0); // Force Output Compare B + EXPECT_EQ((TCCR1C >> 5U) & 0b1, 0); // Force Output Compare C + EXPECT_EQ(TCNT1, 0); // Timer/Counter + EXPECT_EQ(OCR1A, 0); // Output compare register A + EXPECT_EQ(OCR1B, 0); // Output compare register B + EXPECT_EQ(OCR1C, 0); // Output compare register C + EXPECT_EQ(ICR1, 1337); // Input Capture register (i.e. top) + EXPECT_EQ((TIMSK1 >> 5U) & 0b1U, 0); // ICIE + EXPECT_EQ((TIMSK1 >> 3U) & 0b1U, 0); // OICIEnC + EXPECT_EQ((TIMSK1 >> 2U) & 0b1U, 0); // OICIEnB + EXPECT_EQ((TIMSK1 >> 1U) & 0b1U, 0); // OICIEnA + EXPECT_EQ((TIMSK1 >> 0U) & 0b1U, 0); // TOIEn +} + +TEST(TEST_NAME, init__timer_top_65535) { + + /* + * Initialize timer 1 with no_clock (=0) as clock option and top=65535 + */ + pwm_init(1, no_clock, 65535); + + EXPECT_EQ((TCCR1A >> 6U) & 0b11U, 2); // COMnA + EXPECT_EQ((TCCR1A >> 4U) & 0b11U, 2); // COMnB + EXPECT_EQ((TCCR1A >> 2U) & 0b11U, 2); // COMnC + EXPECT_EQ((TCCR1A & 0b11U) | ((TCCR1B >> 1U) & 0b1100U), 14); // WGMn + EXPECT_EQ((TCCR1B >> 7U) & 0b1U, 0); // ICNC + EXPECT_EQ((TCCR1B >> 6U) & 0b1U, 0); // ICES + EXPECT_EQ((TCCR1B >> 5U) & 0b1U, 0); // Reserved + EXPECT_EQ(TCCR1B & 0b111U, 0); // Clock Select + EXPECT_EQ((TCCR1C >> 7U) & 0b1, 0); // Force Output Compare A + EXPECT_EQ((TCCR1C >> 6U) & 0b1, 0); // Force Output Compare B + EXPECT_EQ((TCCR1C >> 5U) & 0b1, 0); // Force Output Compare C + EXPECT_EQ(TCNT1, 0); // Timer/Counter + EXPECT_EQ(OCR1A, 0); // Output compare register A + EXPECT_EQ(OCR1B, 0); // Output compare register B + EXPECT_EQ(OCR1C, 0); // Output compare register C + EXPECT_EQ(ICR1, 65535); // Input Capture register (i.e. top) + EXPECT_EQ((TIMSK1 >> 5U) & 0b1U, 0); // ICIE + EXPECT_EQ((TIMSK1 >> 3U) & 0b1U, 0); // OICIEnC + EXPECT_EQ((TIMSK1 >> 2U) & 0b1U, 0); // OICIEnB + EXPECT_EQ((TIMSK1 >> 1U) & 0b1U, 0); // OICIEnA + EXPECT_EQ((TIMSK1 >> 0U) & 0b1U, 0); // TOIEn +} diff --git a/Tests/timer8bit.cpp b/Tests/timer8bit.cpp new file mode 100644 index 0000000..98f885f --- /dev/null +++ b/Tests/timer8bit.cpp @@ -0,0 +1,265 @@ +#include +#include + +extern "C" { +#include +#include +} + +bool callbackCalled = false; +void callback() { + callbackCalled = true; +} + + +TEST(TEST_NAME, init__timer_0_no_clock) { + timer_8bit_init(TIMER_ID_0, no_clock, nullptr); + + EXPECT_EQ((TCCR0A >> 6U) & 0b11U, 0); //COMnA + EXPECT_EQ((TCCR0A >> 4U) & 0b11U, 0); //COMnB + EXPECT_EQ(((TCCR0B >> 1U) & (0b100U)) | (TCCR0A & 0b11U), 0); // WGMn + EXPECT_EQ((TCCR0B >> 7U) & 0b1U, 0); //FOCnA + EXPECT_EQ((TCCR0B >> 7U) & 0b1U, 0); //FOCnB + EXPECT_EQ((TCCR0B & 0b111U), 0); // CS + EXPECT_EQ(TCNT0, 0); + EXPECT_EQ(TIMSK0, 0b00000001); // Interrupts: only OV +} + +TEST(TEST_NAME, init__timer_0_prescaler_1) { + timer_8bit_init(TIMER_ID_0, prescaler_1, nullptr); + + EXPECT_EQ((TCCR0A >> 6U) & 0b11U, 0); //COMnA + EXPECT_EQ((TCCR0A >> 4U) & 0b11U, 0); //COMnB + EXPECT_EQ(((TCCR0B >> 1U) & (0b100U)) | (TCCR0A & 0b11U), 0); // WGMn + EXPECT_EQ((TCCR0B >> 7U) & 0b1U, 0); //FOCnA + EXPECT_EQ((TCCR0B >> 7U) & 0b1U, 0); //FOCnB + EXPECT_EQ((TCCR0B & 0b111U), 1); // CS + EXPECT_EQ(TCNT0, 0); + EXPECT_EQ(TIMSK0, 0b00000001); // Interrupts: only OV +} + +TEST(TEST_NAME, init__timer_0_prescaler_8) { + timer_8bit_init(TIMER_ID_0, prescaler_8, nullptr); + + EXPECT_EQ((TCCR0A >> 6U) & 0b11U, 0); //COMnA + EXPECT_EQ((TCCR0A >> 4U) & 0b11U, 0); //COMnB + EXPECT_EQ(((TCCR0B >> 1U) & (0b100U)) | (TCCR0A & 0b11U), 0); // WGMn + EXPECT_EQ((TCCR0B >> 7U) & 0b1U, 0); //FOCnA + EXPECT_EQ((TCCR0B >> 7U) & 0b1U, 0); //FOCnB + EXPECT_EQ((TCCR0B & 0b111U), 2); // CS + EXPECT_EQ(TCNT0, 0); + EXPECT_EQ(TIMSK0, 0b00000001); // Interrupts: only OV +} + +TEST(TEST_NAME, init__timer_0_prescaler_64) { + timer_8bit_init(TIMER_ID_0, prescaler_64, nullptr); + + EXPECT_EQ((TCCR0A >> 6U) & 0b11U, 0); //COMnA + EXPECT_EQ((TCCR0A >> 4U) & 0b11U, 0); //COMnB + EXPECT_EQ(((TCCR0B >> 1U) & (0b100U)) | (TCCR0A & 0b11U), 0); // WGMn + EXPECT_EQ((TCCR0B >> 7U) & 0b1U, 0); //FOCnA + EXPECT_EQ((TCCR0B >> 7U) & 0b1U, 0); //FOCnB + EXPECT_EQ((TCCR0B & 0b111U), 3); // CS + EXPECT_EQ(TCNT0, 0); + EXPECT_EQ(TIMSK0, 0b00000001); // Interrupts: only OV +} + +TEST(TEST_NAME, init__timer_0_prescaler_256) { + timer_8bit_init(TIMER_ID_0, prescaler_256, nullptr); + + EXPECT_EQ((TCCR0A >> 6U) & 0b11U, 0); //COMnA + EXPECT_EQ((TCCR0A >> 4U) & 0b11U, 0); //COMnB + EXPECT_EQ(((TCCR0B >> 1U) & (0b100U)) | (TCCR0A & 0b11U), 0); // WGMn + EXPECT_EQ((TCCR0B >> 7U) & 0b1U, 0); //FOCnA + EXPECT_EQ((TCCR0B >> 7U) & 0b1U, 0); //FOCnB + EXPECT_EQ((TCCR0B & 0b111U), 4); // CS + EXPECT_EQ(TCNT0, 0); + EXPECT_EQ(TIMSK0, 0b00000001); // Interrupts: only OV +} + +TEST(TEST_NAME, init__timer_0_prescaler_1024) { + timer_8bit_init(TIMER_ID_0, prescaler_1024, nullptr); + + EXPECT_EQ((TCCR0A >> 6U) & 0b11U, 0); //COMnA + EXPECT_EQ((TCCR0A >> 4U) & 0b11U, 0); //COMnB + EXPECT_EQ(((TCCR0B >> 1U) & (0b100U)) | (TCCR0A & 0b11U), 0); // WGMn + EXPECT_EQ((TCCR0B >> 7U) & 0b1U, 0); //FOCnA + EXPECT_EQ((TCCR0B >> 7U) & 0b1U, 0); //FOCnB + EXPECT_EQ((TCCR0B & 0b111U), 5); // CS + EXPECT_EQ(TCNT0, 0); + EXPECT_EQ(TIMSK0, 0b00000001); // Interrupts: only OV +} + +TEST(TEST_NAME, init__timer_0_prescaler_clock_falling) { + timer_8bit_init(TIMER_ID_0, external_falling, nullptr); + + EXPECT_EQ((TCCR0A >> 6U) & 0b11U, 0); //COMnA + EXPECT_EQ((TCCR0A >> 4U) & 0b11U, 0); //COMnB + EXPECT_EQ(((TCCR0B >> 1U) & (0b100U)) | (TCCR0A & 0b11U), 0); // WGMn + EXPECT_EQ((TCCR0B >> 7U) & 0b1U, 0); //FOCnA + EXPECT_EQ((TCCR0B >> 7U) & 0b1U, 0); //FOCnB + EXPECT_EQ((TCCR0B & 0b111U), 6); // CS + EXPECT_EQ(TCNT0, 0); + EXPECT_EQ(TIMSK0, 0b00000001); // Interrupts: only OV +} + +TEST(TEST_NAME, init__timer_0_prescaler_clock_rising) { + timer_8bit_init(TIMER_ID_0, external_rising, nullptr); + + EXPECT_EQ((TCCR0A >> 6U) & 0b11U, 0); //COMnA + EXPECT_EQ((TCCR0A >> 4U) & 0b11U, 0); //COMnB + EXPECT_EQ(((TCCR0B >> 1U) & (0b100U)) | (TCCR0A & 0b11U), 0); // WGMn + EXPECT_EQ((TCCR0B >> 7U) & 0b1U, 0); //FOCnA + EXPECT_EQ((TCCR0B >> 7U) & 0b1U, 0); //FOCnB + EXPECT_EQ((TCCR0B & 0b111U), 7); // CS + EXPECT_EQ(TCNT0, 0); + EXPECT_EQ(TIMSK0, 0b00000001); // Interrupts: only OV +} + +TEST(TEST_NAME, init__timer_0_callback) { + timer_8bit_init(TIMER_ID_0, no_clock, callback); + callbackCalled = false; + TIMER0_OVF_vect(); + EXPECT_TRUE(callbackCalled); +} + +TEST(TEST_NAME, init__timer_2_no_clock) { + timer_8bit_init(TIMER_ID_2, no_clock, nullptr); + + EXPECT_EQ((TCCR2A >> 6U) & 0b11U, 0); //COMnA + EXPECT_EQ((TCCR2A >> 4U) & 0b11U, 0); //COMnB + EXPECT_EQ(((TCCR2B >> 1U) & (0b100U)) | (TCCR2A & 0b11U), 0); // WGMn + EXPECT_EQ((TCCR2B >> 7U) & 0b1U, 0); //FOCnA + EXPECT_EQ((TCCR2B >> 7U) & 0b1U, 0); //FOCnB + EXPECT_EQ((TCCR2B & 0b111U), 0); // CS + EXPECT_EQ(TCNT2, 0); + EXPECT_EQ(TIMSK2, 0b00000001); // Interrupts: only OV +} + +TEST(TEST_NAME, init__timer_2_prescaler_1) { + timer_8bit_init(TIMER_ID_2, prescaler_1, nullptr); + + EXPECT_EQ((TCCR2A >> 6U) & 0b11U, 0); //COMnA + EXPECT_EQ((TCCR2A >> 4U) & 0b11U, 0); //COMnB + EXPECT_EQ(((TCCR2B >> 1U) & (0b100U)) | (TCCR2A & 0b11U), 0); // WGMn + EXPECT_EQ((TCCR2B >> 7U) & 0b1U, 0); //FOCnA + EXPECT_EQ((TCCR2B >> 7U) & 0b1U, 0); //FOCnB + EXPECT_EQ((TCCR2B & 0b111U), 1); // CS + EXPECT_EQ(TCNT2, 0); + EXPECT_EQ(TIMSK2, 0b00000001); // Interrupts: only OV +} + +TEST(TEST_NAME, init__timer_2_prescaler_8) { + timer_8bit_init(TIMER_ID_2, prescaler_8, nullptr); + + EXPECT_EQ((TCCR2A >> 6U) & 0b11U, 0); //COMnA + EXPECT_EQ((TCCR2A >> 4U) & 0b11U, 0); //COMnB + EXPECT_EQ(((TCCR2B >> 1U) & (0b100U)) | (TCCR2A & 0b11U), 0); // WGMn + EXPECT_EQ((TCCR2B >> 7U) & 0b1U, 0); //FOCnA + EXPECT_EQ((TCCR2B >> 7U) & 0b1U, 0); //FOCnB + EXPECT_EQ((TCCR2B & 0b111U), 2); // CS + EXPECT_EQ(TCNT2, 0); + EXPECT_EQ(TIMSK2, 0b00000001); // Interrupts: only OV +} + +TEST(TEST_NAME, init__timer_2_prescaler_32) { + timer_8bit_init(TIMER_ID_2, prescaler_32, nullptr); + + EXPECT_EQ((TCCR2A >> 6U) & 0b11U, 0); //COMnA + EXPECT_EQ((TCCR2A >> 4U) & 0b11U, 0); //COMnB + EXPECT_EQ(((TCCR2B >> 1U) & (0b100U)) | (TCCR2A & 0b11U), 0); // WGMn + EXPECT_EQ((TCCR2B >> 7U) & 0b1U, 0); //FOCnA + EXPECT_EQ((TCCR2B >> 7U) & 0b1U, 0); //FOCnB + EXPECT_EQ((TCCR2B & 0b111U), 3); // CS + EXPECT_EQ(TCNT2, 0); + EXPECT_EQ(TIMSK2, 0b00000001); // Interrupts: only OV +} + +TEST(TEST_NAME, init__timer_2_prescaler_64) { + timer_8bit_init(TIMER_ID_2, prescaler_64, nullptr); + + EXPECT_EQ((TCCR2A >> 6U) & 0b11U, 0); //COMnA + EXPECT_EQ((TCCR2A >> 4U) & 0b11U, 0); //COMnB + EXPECT_EQ(((TCCR2B >> 1U) & (0b100U)) | (TCCR2A & 0b11U), 0); // WGMn + EXPECT_EQ((TCCR2B >> 7U) & 0b1U, 0); //FOCnA + EXPECT_EQ((TCCR2B >> 7U) & 0b1U, 0); //FOCnB + EXPECT_EQ((TCCR2B & 0b111U), 4); // CS + EXPECT_EQ(TCNT2, 0); + EXPECT_EQ(TIMSK2, 0b00000001); // Interrupts: only OV +} + +TEST(TEST_NAME, init__timer_2_prescaler_128) { + timer_8bit_init(TIMER_ID_2, prescaler_128, nullptr); + + EXPECT_EQ((TCCR2A >> 6U) & 0b11U, 0); //COMnA + EXPECT_EQ((TCCR2A >> 4U) & 0b11U, 0); //COMnB + EXPECT_EQ(((TCCR2B >> 1U) & (0b100U)) | (TCCR2A & 0b11U), 0); // WGMn + EXPECT_EQ((TCCR2B >> 7U) & 0b1U, 0); //FOCnA + EXPECT_EQ((TCCR2B >> 7U) & 0b1U, 0); //FOCnB + EXPECT_EQ((TCCR2B & 0b111U), 5); // CS + EXPECT_EQ(TCNT2, 0); + EXPECT_EQ(TIMSK2, 0b00000001); // Interrupts: only OV +} + +TEST(TEST_NAME, init__timer_2_prescaler_256) { + timer_8bit_init(TIMER_ID_2, prescaler_256, nullptr); + + EXPECT_EQ((TCCR2A >> 6U) & 0b11U, 0); //COMnA + EXPECT_EQ((TCCR2A >> 4U) & 0b11U, 0); //COMnB + EXPECT_EQ(((TCCR2B >> 1U) & (0b100U)) | (TCCR2A & 0b11U), 0); // WGMn + EXPECT_EQ((TCCR2B >> 7U) & 0b1U, 0); //FOCnA + EXPECT_EQ((TCCR2B >> 7U) & 0b1U, 0); //FOCnB + EXPECT_EQ((TCCR2B & 0b111U), 6); // CS + EXPECT_EQ(TCNT2, 0); + EXPECT_EQ(TIMSK2, 0b00000001); // Interrupts: only OV +} + +TEST(TEST_NAME, init__timer_2_prescaler_1024) { + timer_8bit_init(TIMER_ID_2, prescaler_1024, nullptr); + + EXPECT_EQ((TCCR2A >> 6U) & 0b11U, 0); //COMnA + EXPECT_EQ((TCCR2A >> 4U) & 0b11U, 0); //COMnB + EXPECT_EQ(((TCCR2B >> 1U) & (0b100U)) | (TCCR2A & 0b11U), 0); // WGMn + EXPECT_EQ((TCCR2B >> 7U) & 0b1U, 0); //FOCnA + EXPECT_EQ((TCCR2B >> 7U) & 0b1U, 0); //FOCnB + EXPECT_EQ((TCCR2B & 0b111U), 7); // CS + EXPECT_EQ(TCNT2, 0); + EXPECT_EQ(TIMSK2, 0b00000001); // Interrupts: only OV +} + +TEST(TEST_NAME, init__timer_2_callback) { + timer_8bit_init(TIMER_ID_2, no_clock, callback); + callbackCalled = false; + TIMER2_OVF_vect(); + EXPECT_TRUE(callbackCalled); +} + +TEST(TEST_NAME, get__timer_0_0) { + TCNT0 = 0; + EXPECT_EQ(timer_8bit_get_count(TIMER_ID_0), 0); +} + +TEST(TEST_NAME, get__timer_0_17) { + TCNT0 = 17; + EXPECT_EQ(timer_8bit_get_count(TIMER_ID_0), 17); +} + +TEST(TEST_NAME, get__timer_0_255) { + TCNT0 = 255; + EXPECT_EQ(timer_8bit_get_count(TIMER_ID_0), 255); +} + +TEST(TEST_NAME, get__timer_2_0) { + TCNT2 = 0; + EXPECT_EQ(timer_8bit_get_count(TIMER_ID_2), 0); +} + +TEST(TEST_NAME, get__timer_2_17) { + TCNT2 = 17; + EXPECT_EQ(timer_8bit_get_count(TIMER_ID_2), 17); +} + +TEST(TEST_NAME, get__timer_2_255) { + TCNT2 = 255; + EXPECT_EQ(timer_8bit_get_count(TIMER_ID_2), 255); +} diff --git a/Tests/uart.cpp b/Tests/uart.cpp new file mode 100644 index 0000000..941b39f --- /dev/null +++ b/Tests/uart.cpp @@ -0,0 +1,10 @@ +#include +#include + +extern "C" { +#include +} + +TEST(TEST_NAME, test) { + +} diff --git a/pwm16bit.h b/pwm16bit.h index d3df92b..900dad6 100644 --- a/pwm16bit.h +++ b/pwm16bit.h @@ -26,7 +26,25 @@ typedef enum { } pwm_clock_option_t; /** - * Initialize, enable and start the pwm + * @brief Initialize, enable and start the pwm + * + * For the initialization the following register settings are used (for the corresponding timer id): + * * Timer/Counter Control Register A: + * * Waveform Generation: Fast PWM with ICRn as top (mode 14), see Table 17.2 + * * Compare Output mode: non inverting mode (mode 2), see Table 17.4 + * * Timer/Counter Control Register B: + * * Input Capture Noise Canceller: disabled, as no input is captured + * * Input Capture Edge Select: disabled, as no input is captured + * * Waveform Generation: see TCCA + * * Clock Select: according to parameter pwm_clock_option + * * Timer/Counter Control Register C: + * * Force Output compare: disabled as PWM is active + * * Timer/Counter: initialized to 0 + * * Output Compare Registers: initialized to 0 + * * Input Capture Registers: defines the top in PWM mode, set to parameter "top" + * * Timer/Counter Interrupt Mask Register: All interrupt disabled + * * Timer/Counter Interrupt Flag Registers: not applicable as interrupts are disabled + * * @param timer_id the number of the timer, should be in {1,3,4,5} * @param pwm_clock_option a value of pwm_clock_option_t to select the prescaler * @param top the maximum value of the counter, should be in [1,65535] @@ -34,21 +52,30 @@ typedef enum { void pwm_init(uint8_t timer_id, pwm_clock_option_t pwm_clock_option, uint16_t top); /** - * Set the pwm1 output a to specifiy duty cycle (relative to top) + * @brief Set the PWM output a (OCnA) to specific duty cycle (relative to top) + * + * To set the duty cycle the parameter "val" is written to the respective Output Compare Register A + * * @param timer_id the number of the timer, should be in {1,3,4,5} * @param val the compare value, the duty cycle is given by val/top */ void pwm_set_out_a(uint8_t timer_id, uint16_t val); /** - * Set the pwm1 output b to specifiy duty cycle (relative to top) + * @brief Set the PWM output b (OCnB) to specific duty cycle (relative to top) + * + * To set the duty cycle the parameter "val" is written to the respective Output Compare Register B + * * @param timer_id the number of the timer, should be in {1,3,4,5} * @param val the compare value, the duty cycle is given by val/top */ void pwm_set_out_b(uint8_t timer_id, uint16_t val); /** - * Set the pwm1 output c to specifiy duty cycle (relative to top) + * @brief Set the PWM output c (OCnC) to specific duty cycle (relative to top) + * + * To set the duty cycle the parameter "val" is written to the respective Output Compare Register C + * * @param timer_id the number of the timer, should be in {1,3,4,5} * @param val the compare value, the duty cycle is given by val/top */ diff --git a/timer8bit.c b/timer8bit.c index a7191b9..c98d094 100644 --- a/timer8bit.c +++ b/timer8bit.c @@ -62,10 +62,10 @@ ISR(TIMER2_OVF_vect) { void timer_8bit_init(timer_8bit_id_t num, timer_8bit_clock_option_t timer_clock_option, timer_8bit_callback_t callback) { instances[num].callback = callback; - *instances[num].tccra = 0b00000000u; // Output compare disconnected, normal mode + *instances[num].tccra = 0b00000000U; // Output compare disconnected, normal mode *instances[num].tccrb = - 0b00000000u | prescaler_bits[num][timer_clock_option]; // No force override, normal mode, prescaler - *instances[num].timsk = 0b00000001u; // Overflow interrupt enabled + 0b00000000U | prescaler_bits[num][timer_clock_option]; // No force override, normal mode, prescaler + *instances[num].timsk = 0b00000001U; // Overflow interrupt enabled *instances[num].tcnt = 0; // Set the counter to 0 } diff --git a/timer8bit.h b/timer8bit.h index 1de9060..4ff98a5 100644 --- a/timer8bit.h +++ b/timer8bit.h @@ -47,7 +47,19 @@ typedef enum { TIMER_ID_0 = 0, TIMER_ID_2 = 1 } timer_8bit_id_t; /** - * Initialize, enable and start the timer. + * @brief Initialize, enable and start the timer. + * + * For the initialization the following register settings are used (for the corresponding timer id): + * * Timer/Counter Control Register A: + * * Compare Match Output A/B: Disconnected (0) + * * Waveform Generation: Normal (0) + * * Timer/Counter Control Register B: + * * Force Output Compare A/B: disabled + * * Waveform Generation: See TCCA + * * Clock select depending on parameter "timer_clock_option" + * * Timer/Counter: initialized to 0 + * * Timer/Counter Interrupt Mask Register: Overflow interrupt (bit 0) enabled + * * @param num id of the timer * @param timer_clock_option the prescaler * @param callback a functor that gets called on every overflow @@ -55,7 +67,10 @@ typedef enum { TIMER_ID_0 = 0, TIMER_ID_2 = 1 } timer_8bit_id_t; void timer_8bit_init(timer_8bit_id_t num, timer_8bit_clock_option_t timer_clock_option, timer_8bit_callback_t callback); /** - * Read the current value of the timer + * @brief Read the current value of the timer + * + * Returns the value of the Timer/Counter Register + * * @param num id of the timer * @return a value in [0, 255] representing the value of the timer */