diff --git a/.vscode/settings.json b/.vscode/settings.json index af4ab8e..01550e4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,9 @@ "files.associations": { "io.h": "c", "delay.h": "c", - "interrupt.h": "c" + "interrupt.h": "c", + "timer.h": "c", + "usart.h": "c", + "utils.h": "c" } } diff --git a/module02/ex00/bitmanip.h b/module02/ex00/bitmanip.h index 5e36761..4df44d1 100644 --- a/module02/ex00/bitmanip.h +++ b/module02/ex00/bitmanip.h @@ -14,8 +14,14 @@ #define ARG_2(v1, v2) v2 #define GET_PORT(args) ARG_1 args #define GET_BIT(args) ARG_2 args +// // version with "LED1 B, D1" without parenthesis +// #define ARG_1(v1, ...) v1 +// #define ARG_2(v1, v2, ...) v2 +// #define GET_PORT(...) ARG_1(__VA_ARGS__) +// #define GET_BIT(...) ARG_2(__VA_ARGS__) // Actions on elements +// #define SET_ELEM(...) SET(CONCAT(PORT, GET_PORT(__VA_ARGS__)), GET_BIT(__VA_ARGS__)) // version for "LED1 B, D1" without parenthesis #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)) diff --git a/module02/ex00/main.c b/module02/ex00/main.c index 8cddfff..4185c9a 100644 --- a/module02/ex00/main.c +++ b/module02/ex00/main.c @@ -2,63 +2,8 @@ #include #include -// mathematics -#define DIV_ROUND_CLOSEST(n, d) ((((n) < 0) == ((d) < 0)) ? (((n) + (d)/2)/(d)) : (((n) - (d)/2)/(d))) - -// 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 -// // version with "LED1 B, D1" without parenthesis -// #define ARG_1(v1, ...) v1 -// #define ARG_2(v1, v2, ...) v2 -// #define GET_PORT(...) ARG_1(__VA_ARGS__) -// #define GET_BIT(...) ARG_2(__VA_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 SET_ELEM(...) SET(CONCAT(PORT, GET_PORT(__VA_ARGS__)), GET_BIT(__VA_ARGS__)) // version for "LED1 B, D1" without parenthesis -#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 LED1 (B, D1) -#define LED2 (B, D2) -#define LED3 (B, D3) -#define LED4 (B, D4) -#define BUTTON1 (D, SW1) -#define BUTTON2 (D, SW2) +#include "utils.h" +#include "bitmanip.h" // USART // Table 20-1 : Baud Rate Calculation @@ -104,7 +49,7 @@ void uart_tx(char c) { UDR0 = (unsigned char) c; // 20.11.1 : Put data into buffer, UDRn – USART I/O Data Register (read and write) } -// write Z on serial port, at a !Hz frequency +// write Z on serial port, at a 1Hz frequency // `screen /dev/ttyUSB0 115200` int main() { uart_init(); diff --git a/module02/ex00/timer.h b/module02/ex00/timer.h deleted file mode 100644 index 3cb618e..0000000 --- a/module02/ex00/timer.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef TIMER_H -#define TIMER_H - -#define PRESCALE_VALUE 1024 // can be 1, 8, 64, 256, 1024 -// table 16-5 : prescale sets -#define PRESCALE_SET(value) \ - ((value) == 1 ? (0< #include -// mathematics -#define DIV_ROUND_CLOSEST(n, d) ((((n) < 0) == ((d) < 0)) ? (((n) + (d)/2)/(d)) : (((n) - (d)/2)/(d))) // https://stackoverflow.com/a/18067292 -// 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 -// // version with "LED1 B, D1" without parenthesis -// #define ARG_1(v1, ...) v1 -// #define ARG_2(v1, v2, ...) v2 -// #define GET_PORT(...) ARG_1(__VA_ARGS__) -// #define GET_BIT(...) ARG_2(__VA_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 SET_ELEM(...) SET(CONCAT(PORT, GET_PORT(__VA_ARGS__)), GET_BIT(__VA_ARGS__)) // version for "LED1 B, D1" without parenthesis -#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 LED1 (B, D1) -#define LED2 (B, D2) -#define LED3 (B, D3) -#define LED4 (B, D4) -#define BUTTON1 (D, SW1) -#define BUTTON2 (D, SW2) - -// USART -// Table 20-1 : Baud Rate Calculation -#define USART_BAUDRATE 115200 -#define BAUD_PRESCALER (DIV_ROUND_CLOSEST(F_CPU, (16 * USART_BAUDRATE)) - 1) -// Table 20-8 : Mode Selection (USART Mode SELect) -#define ASYNCHRONOUS (0<> 8); // 20.11.5 : UBRRnL and UBRRnH – USART Baud Rate Registers - UBRR0L = (unsigned char) BAUD_PRESCALER; + UBRR0H = (unsigned char) (BAUD_PRESCALER(USART_BAUDRATE) >> 8); // 20.11.5 : UBRRnL and UBRRnH – USART Baud Rate Registers + UBRR0L = (unsigned char) BAUD_PRESCALER(USART_BAUDRATE); UCSR0C |= ASYNCHRONOUS | PARITY_DISABLED | STOP_ONE_BIT | DATA_EIGHT_BIT; // 20.11.4 : set Frame Format @@ -142,10 +46,11 @@ int main() { TCCR1A |= CTC_TOP_OCR1A_IN_TCCR1A; // Table 16-4 : set timer in CTC (Clear Time on Compare) mode TCCR1B |= CTC_TOP_OCR1A_IN_TCCR1B; - sei(); // enable global interrupts (https://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html#gaad5ebd34cb344c26ac87594f79b06b73) + SREG |= ENABLE_GLOBAL_INTERRUPT; // 7.3.1 : Status Register, bit 7 : I – Global Interrupt Enable + TIMSK1 |= INTERRUPT_ENABLE_CHANNEL_A; // 16.11.8 : enables the Timer1 Compare Match A interrupt, this makes the MCU react when OCR1A == TCNT1 by calling TIMER1_COMPA_vect - OCR1A = TIME_MS(PERIOD); // Table 16-4 : set CTC compare value on channel A, the counter is cleared to zero when the counter value (TCNT1) matches the OCR1A register + OCR1A = TIME_MS(PERIOD, PRESCALE_VALUE); // Table 16-4 : set CTC compare value on channel A, the counter is cleared to zero when the counter value (TCNT1) matches the OCR1A register TCCR1B |= (PRESCALE_SET(PRESCALE_VALUE)); // 16.4 : set timer according to prescale value, in register TCCR1B, table 16-5 : prescale sets diff --git a/module02/ex01/timer.h b/module02/ex01/timer.h new file mode 100644 index 0000000..2493232 --- /dev/null +++ b/module02/ex01/timer.h @@ -0,0 +1,27 @@ +#ifndef TIMER_H +#define TIMER_H + +// table 16-5 : prescale sets +#define PRESCALE_SET(value) \ + ((value) == 1 ? (0< #include -// mathematics -#define DIV_ROUND_CLOSEST(n, d) ((((n) < 0) == ((d) < 0)) ? (((n) + (d)/2)/(d)) : (((n) - (d)/2)/(d))) // https://stackoverflow.com/a/18067292 - -// 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 -// // version with "LED1 B, D1" without parenthesis -// #define ARG_1(v1, ...) v1 -// #define ARG_2(v1, v2, ...) v2 -// #define GET_PORT(...) ARG_1(__VA_ARGS__) -// #define GET_BIT(...) ARG_2(__VA_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 SET_ELEM(...) SET(CONCAT(PORT, GET_PORT(__VA_ARGS__)), GET_BIT(__VA_ARGS__)) // version for "LED1 B, D1" without parenthesis -#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 LED1 (B, D1) -#define LED2 (B, D2) -#define LED3 (B, D3) -#define LED4 (B, D4) -#define BUTTON1 (D, SW1) -#define BUTTON2 (D, SW2) +#include "utils.h" +#include "bitmanip.h" +#include "usart.h" // USART -// Table 20-1 : Baud Rate Calculation -#define USART_BAUDRATE 115200 -#define BAUD_PRESCALER (DIV_ROUND_CLOSEST(F_CPU, (16 * USART_BAUDRATE)) - 1) -// Table 20-8 : Mode Selection (USART Mode SELect) -#define ASYNCHRONOUS (0<> 8); // 20.11.5 : UBRRnL and UBRRnH – USART Baud Rate Registers - UBRR0L = (unsigned char) BAUD_PRESCALER; + UBRR0H = (unsigned char) (BAUD_PRESCALER(USART_BAUDRATE) >> 8); // 20.11.5 : UBRRnL and UBRRnH – USART Baud Rate Registers + UBRR0L = (unsigned char) BAUD_PRESCALER(USART_BAUDRATE); UCSR0C |= ASYNCHRONOUS | PARITY_DISABLED | STOP_ONE_BIT | DATA_EIGHT_BIT; // 20.11.4 : set Frame Format diff --git a/module02/ex02/timer.h b/module02/ex02/timer.h new file mode 100644 index 0000000..2493232 --- /dev/null +++ b/module02/ex02/timer.h @@ -0,0 +1,27 @@ +#ifndef TIMER_H +#define TIMER_H + +// table 16-5 : prescale sets +#define PRESCALE_SET(value) \ + ((value) == 1 ? (0< #include // https://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html -// mathematics -#define DIV_ROUND_CLOSEST(n, d) ((((n) < 0) == ((d) < 0)) ? (((n) + (d)/2)/(d)) : (((n) - (d)/2)/(d))) // https://stackoverflow.com/a/18067292 - -// 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 -// // version with "LED1 B, D1" without parenthesis -// #define ARG_1(v1, ...) v1 -// #define ARG_2(v1, v2, ...) v2 -// #define GET_PORT(...) ARG_1(__VA_ARGS__) -// #define GET_BIT(...) ARG_2(__VA_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 SET_ELEM(...) SET(CONCAT(PORT, GET_PORT(__VA_ARGS__)), GET_BIT(__VA_ARGS__)) // version for "LED1 B, D1" without parenthesis -#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 LED1 (B, D1) -#define LED2 (B, D2) -#define LED3 (B, D3) -#define LED4 (B, D4) -#define BUTTON1 (D, SW1) -#define BUTTON2 (D, SW2) +#include "utils.h" +#include "bitmanip.h" +#include "timer.h" +#include "usart.h" +#include "interrupt.h" // USART -// Table 20-1 : Baud Rate Calculation #define USART_BAUDRATE 115200 -#define BAUD_PRESCALER (DIV_ROUND_CLOSEST(F_CPU, (16 * USART_BAUDRATE)) - 1) -// Table 20-8 : Mode Selection (USART Mode SELect) -#define ASYNCHRONOUS (0<= 'A' && (ch) <= 'Z') || ((ch) >= 'a' && (ch) <= 'z') ? ((ch) ^ (1 << 5)) : (ch)) // END MACROS void uart_init() { - UBRR0H = (unsigned char) (BAUD_PRESCALER >> 8); // 20.11.5 : UBRRnL and UBRRnH – USART Baud Rate Registers - UBRR0L = (unsigned char) BAUD_PRESCALER; + UBRR0H = (unsigned char) (BAUD_PRESCALER(USART_BAUDRATE) >> 8); // 20.11.5 : UBRRnL and UBRRnH – USART Baud Rate Registers + UBRR0L = (unsigned char) BAUD_PRESCALER(USART_BAUDRATE); UCSR0C |= ASYNCHRONOUS | PARITY_DISABLED | STOP_ONE_BIT | DATA_EIGHT_BIT; // 20.11.4 : set Frame Format @@ -141,8 +38,8 @@ void uart_tx(char c) { ISR(USART_RX_vect) { // Table 12-7 : we select the code for USART Receive // char received_char = uart_rx(); - char received_char = UDR0; // Read received character - uart_tx(SWITCH_CASE(received_char)); // Toggle case and send back + char received_char = UDR0; // Read received character + uart_tx(SWITCH_CASE(received_char)); // Toggle case and send back } // send back caracters received on serial port with case toggling, using interupt and empty infinite loop @@ -150,7 +47,7 @@ ISR(USART_RX_vect) { // Table 12-7 : we select the code for USART int main() { uart_init(); - sei(); // enable global interrupts + SREG |= ENABLE_GLOBAL_INTERRUPT; // 7.3.1 : Status Register, bit 7 : I – Global Interrupt Enable while(1); } diff --git a/module02/ex03/timer.h b/module02/ex03/timer.h new file mode 100644 index 0000000..2493232 --- /dev/null +++ b/module02/ex03/timer.h @@ -0,0 +1,27 @@ +#ifndef TIMER_H +#define TIMER_H + +// table 16-5 : prescale sets +#define PRESCALE_SET(value) \ + ((value) == 1 ? (0<= 'A' && (ch) <= 'Z') || ((ch) >= 'a' && (ch) <= 'z') ? ((ch) ^ (1 << 5)) : (ch)) + +#endif // UTILS_H \ No newline at end of file diff --git a/module02/ex04/bitmanip.h b/module02/ex04/bitmanip.h new file mode 100644 index 0000000..4df44d1 --- /dev/null +++ b/module02/ex04/bitmanip.h @@ -0,0 +1,53 @@ +#ifndef BITMANIP_H +#define BITMANIP_H + +#include "utils.h" + +// Bit operations 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))) + +// Get arguments from tuple-like definitions +#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 +// // version with "LED1 B, D1" without parenthesis +// #define ARG_1(v1, ...) v1 +// #define ARG_2(v1, v2, ...) v2 +// #define GET_PORT(...) ARG_1(__VA_ARGS__) +// #define GET_BIT(...) ARG_2(__VA_ARGS__) + +// Actions on elements +// #define SET_ELEM(...) SET(CONCAT(PORT, GET_PORT(__VA_ARGS__)), GET_BIT(__VA_ARGS__)) // version for "LED1 B, D1" without parenthesis +#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) + +// Bit definitions +#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) + +#endif // BITMANIP_H \ No newline at end of file diff --git a/module02/ex04/interrupt.h b/module02/ex04/interrupt.h new file mode 100644 index 0000000..dccc1c5 --- /dev/null +++ b/module02/ex04/interrupt.h @@ -0,0 +1,8 @@ +#ifndef INTERRUPT_H +#define INTERRUPT_H + +// 7.3.1 : SREG – AVR Status Register +#define ENABLE_GLOBAL_INTERRUPT (1<<7) +#define DISABLE_GLOBAL_INTERRUPT (0<<7) + +#endif // INTERRUPT_H \ No newline at end of file diff --git a/module02/ex04/main.c b/module02/ex04/main.c index 0207079..41b68c1 100644 --- a/module02/ex04/main.c +++ b/module02/ex04/main.c @@ -2,127 +2,23 @@ #include #include // https://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html -// mathematics -#define DIV_ROUND_CLOSEST(n, d) ((((n) < 0) == ((d) < 0)) ? (((n) + (d)/2)/(d)) : (((n) - (d)/2)/(d))) // https://stackoverflow.com/a/18067292 - -// text -#define SWITCH_CASE(ch) (((ch) >= 'A' && (ch) <= 'Z') || ((ch) >= 'a' && (ch) <= 'z') ? ((ch) ^ (1 << 5)) : (ch)) - -// 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 -// // version with "LED1 B, D1" without parenthesis -// #define ARG_1(v1, ...) v1 -// #define ARG_2(v1, v2, ...) v2 -// #define GET_PORT(...) ARG_1(__VA_ARGS__) -// #define GET_BIT(...) ARG_2(__VA_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 SET_ELEM(...) SET(CONCAT(PORT, GET_PORT(__VA_ARGS__)), GET_BIT(__VA_ARGS__)) // version for "LED1 B, D1" without parenthesis -#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 LED1 (B, D1) -#define LED2 (B, D2) -#define LED3 (B, D3) -#define LED4 (B, D4) -#define BUTTON1 (D, SW1) -#define BUTTON2 (D, SW2) +#include "utils.h" +#include "bitmanip.h" +#include "timer.h" +#include "usart.h" +#include "interrupt.h" // USART -// Table 20-1 : Baud Rate Calculation -#define USART_BAUDRATE 115200 -#define BAUD_PRESCALER (DIV_ROUND_CLOSEST(F_CPU, (16 * USART_BAUDRATE)) - 1) -// Table 20-8 : Mode Selection (USART Mode SELect) -#define ASYNCHRONOUS (0<> 8); // 20.11.5 : UBRRnL and UBRRnH – USART Baud Rate Registers - UBRR0L = (unsigned char) BAUD_PRESCALER; + UBRR0H = (unsigned char) (BAUD_PRESCALER(USART_BAUDRATE) >> 8); // 20.11.5 : UBRRnL and UBRRnH – USART Baud Rate Registers + UBRR0L = (unsigned char) BAUD_PRESCALER(USART_BAUDRATE); UCSR0C |= ASYNCHRONOUS | PARITY_DISABLED | STOP_ONE_BIT | DATA_EIGHT_BIT; // 20.11.4 : set Frame Format @@ -151,12 +47,12 @@ ISR(USART_RX_vect) { // Table 12-7 : we select the code for USART } } -// send back caracters received on serial port with case toggling, using interupt and empty infinite loop +// ask for username and password // `screen /dev/ttyUSB0 115200` int main() { uart_init(); - sei(); // enable global interrupts + SREG |= ENABLE_GLOBAL_INTERRUPT; // 7.3.1 : Status Register, bit 7 : I – Global Interrupt Enable while(1); } diff --git a/module02/ex04/timer.h b/module02/ex04/timer.h new file mode 100644 index 0000000..2493232 --- /dev/null +++ b/module02/ex04/timer.h @@ -0,0 +1,27 @@ +#ifndef TIMER_H +#define TIMER_H + +// table 16-5 : prescale sets +#define PRESCALE_SET(value) \ + ((value) == 1 ? (0<= 'A' && (ch) <= 'Z') || ((ch) >= 'a' && (ch) <= 'z') ? ((ch) ^ (1 << 5)) : (ch)) + +#endif // UTILS_H \ No newline at end of file