diff --git a/module01/ex03/Makefile b/module01/ex03/Makefile new file mode 100644 index 0000000..2e40cba --- /dev/null +++ b/module01/ex03/Makefile @@ -0,0 +1 @@ +include ../../Makefile \ No newline at end of file diff --git a/module01/ex03/main.c b/module01/ex03/main.c new file mode 100644 index 0000000..77d3636 --- /dev/null +++ b/module01/ex03/main.c @@ -0,0 +1,94 @@ +#include + +// stringify +#define STRINGIFY_HELPER(x) #x +#define STRINGIFY(x) STRINGIFY_HELPER(x) + +// concatenate +#define CONCAT_HELPER(x, y) x ## y +#define CONCAT(x, y) CONCAT_HELPER(x, y) + +// get argument +#define ARG_1(v1, v2) v1 +#define ARG_2(v1, v2) v2 +#define GET_PORT(args) ARG_1 args +#define GET_BIT(args) ARG_2 args + +// actions on registers +#define SET(register, bit) register |= 1 << bit +#define CLEAR(register, bit) register &= ~(1 << bit) +#define TEST(register, bit) register & 1 << bit +#define TOGGLE(register, bit) register ^= 1 << bit + +// actions on elements +#define SET_ELEM(elem) SET(CONCAT(PORT, GET_PORT(elem)), GET_BIT(elem)) +#define CLEAR_ELEM(elem) CLEAR(CONCAT(PORT, GET_PORT(elem)), GET_BIT(elem)) +#define TEST_ELEM(elem) TEST(CONCAT(PORT, GET_PORT(elem)), GET_BIT(elem)) +#define TOGGLE_ELEM(elem) TOGGLE(CONCAT(PORT, GET_PORT(elem)), GET_BIT(elem)) +#define MODE_OUTPUT(elem) SET(CONCAT(DDR, GET_PORT(elem)), GET_BIT(elem)) +#define MODE_INPUT(elem) CLEAR(CONCAT(DDR, GET_PORT(elem)), GET_BIT(elem)) +#define TOGGLE_PIN(elem) SET(CONCAT(PIN, GET_PORT(elem)), GET_BIT(elem)) +#define TEST_PIN(elem) (TEST(CONCAT(PIN, GET_PORT(elem)), GET_BIT(elem))) +#define IS_PIN_SET(elem) (TEST_PIN(elem) == 0) +#define IS_PIN_CLEAR(elem) (TEST_PIN(elem) == 1) + +// bits +#define D1 0 +#define D2 1 +#define D3 2 +#define D4 4 +#define SW1 2 +#define SW2 4 + +// elements (port, bit) +#define LED1 (B, D1) +#define LED2 (B, D2) +#define LED3 (B, D3) +#define LED4 (B, D4) +#define BUTTON1 (D, SW1) +#define BUTTON2 (D, SW2) + +// TIME +#define PRESCALE_VALUE 1024 +#if (PRESCALE_VALUE == 1) + #define PRESCALE_SET (1 << CS10) +#elif (PRESCALE_VALUE == 8) + #define PRESCALE_SET (1 << CS11) +#elif (PRESCALE_VALUE == 64) + #define PRESCALE_SET (1 << CS10) | (1 << CS11) +#elif (PRESCALE_VALUE == 256) + #define PRESCALE_SET (1 << CS12) +#elif (PRESCALE_VALUE == 1024) + #define PRESCALE_SET (1 << CS10) | (1 << CS12) +#endif +#define TIME_MS(ms) (((F_CPU / PRESCALE_VALUE) * ms) / 1000) +#define PERIOD 1000 +#define DUTY_CYCLE 10 + +// END MACROS + + +int main() { + MODE_OUTPUT(LED2); + + // Table 16-4 : set timer in Fast PWM (Pulse With Modulation) mode with TOP = ICR1 (Mode 14) + SET(TCCR1A, WGM11); + SET(TCCR1B, WGM12); + SET(TCCR1B, WGM13); + + // Table 16-2 : non-inverting mode, the LED will be ON for DUTY_CYCLE% of the time (CLEAR OC1A on compare match, SET OC1A at BOTTOM) + SET(TCCR1A, COM1A1); + + // Table 16-4 : set the period (compare TOP value) + ICR1 = TIME_MS(PERIOD); + + // 16.9.3 : set the duty cycle to DUTY_CYCLE% of the time -> OC1A (alternate function of PORTB1, aka LED2) is cleared when TCNT1 (the counter value) equals OCR1A + OCR1A = TIME_MS(DUTY_CYCLE); + + // start the timer with the prescaler + TCCR1B |= (PRESCALE_SET); + + while(1) { + continue; + } +} \ No newline at end of file