feat(ex03): it works hehe

This commit is contained in:
Maix0 2026-04-15 16:02:30 +02:00
parent d70042cf93
commit a87568e5f7
11 changed files with 291 additions and 0 deletions

21
ex03/src/main.c Normal file
View file

@ -0,0 +1,21 @@
#include <avr/interrupt.h>
#include <avr/io.h>
#include "mystd.h"
#include "timer.h"
#include "uart.h"
#include "utils.h"
int main(void) {
uart_init();
// enable the S_REG
SREG |= _BV(SREG_I);
while (true) {
}
}
// UART_RX COMPLETE
void __attribute__((signal)) __vector_18(void) {
uart_tx(UDR0);
}

38
ex03/src/timer.c Normal file
View file

@ -0,0 +1,38 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#include "mystd.h"
#include "utils.h"
#define PRESCALER 256
#define TIMER_FREQ (F_CPU / PRESCALER)
// at a high level:
// Set the OC1B (PB2) pin as output
// set the TIMER1 mode to COMPARE (CTC)
// say to compare against OC1A
// set the value to be compated at X count
// say the presacler for the timer is 512
//
// all these information are on page ~140
void timer1_init(void) {
// Set PB1 (OC1A) as output
DDRB |= _BV(PB1);
// CTC mode (WGM12 = 1)
TCCR1B |= _BV(WGM12);
// Toggle OC1B on compare match (COM1B0 = 1)
// TCCR1A |= _BV(COM1A0);
// Set compare values
OCR1A = TIMER_FREQ / 2;
// Start timer with prescaler 256 (CS12)
TCCR1B |= _BV(CS12);
// set OCR1A interrupt
TIMSK1 = _BV(1);
sei();
}

49
ex03/src/uart.c Normal file
View file

@ -0,0 +1,49 @@
#include "uart.h"
#include <avr/io.h>
#include "mystd.h"
#include "utils.h"
#define BAUD_RATE 115200
#define UBRR_VALUE ((F_CPU / (8UL * BAUD_RATE)) - 1)
// uart is 115200 baud rate, 8 bits per word, no parrity and 1 stop bit
// 115200 8N1
void uart_init(void) {
// Set baud rate
UBRR0H = (uint8_t)(UBRR_VALUE >> 8);
UBRR0L = (uint8_t)(UBRR_VALUE);
UCSR0A |= _BV(U2X0);
// Enable transmitter
UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0);
// Set frame format: 8 data bits, no parity, 1 stop bit
UCSR0C = _BV(UCSZ01) | _BV(UCSZ00);
// Set TX (PD1) as output
DDRD |= _BV(PD1);
}
void uart_tx(char data) {
// wait for transmit buffer to be empty
while (!(UCSR0A & _BV(UDRE0)))
;
// load data into transmit register
UDR0 = data;
}
char uart_rx(void) {
while (!(UCSR0A & _BV(RXC0)))
;
return UDR0;
}
void uart_sendstring(const char* str) {
if (!str)
return;
while (*str) {
uart_tx(*str);
str++;
}
}

19
ex03/src/utils.c Normal file
View file

@ -0,0 +1,19 @@
#include "utils.h"
// this just burns cycles.
// the volatile is important, it means that the cpu can't optimize any
// read/writes for the value
static inline void spin_loop(volatile uint16_t counts) {
while (counts)
counts--;
}
void delay_ms(uint16_t ms) {
while (ms) {
// this value was taken using a delay of 500ms, and just recording the led
// blinking. it seems to be high enough such that each loop of delay_loop
// takes 1ms :D
spin_loop((F_CPU) / 5000);
ms--;
}
}