sdp-dry-sensor/platform.c

111 lines
2.5 KiB
C

//
// Created by vlad on 17.08.22.
//
#include "platform.h"
#include "config.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
volatile uint8_t timeout_err;
ISR(WDT_OVERFLOW_vect) {
timeout_err = 1;
}
void platform_init() {
// инициализация GPIO
DDRD = INIT_DDRD;
DDRB = INIT_DDRB;
DIDR = 0x03; // отключение цифрового ввода/вывода на входах компаратора
// инициализация юарта
uart_init();
// инициализация таймера 1 (16-ти битный)
// mode=14 (FastPWM, top in ICR1), x64, ICR1=1000000/64=15625
TCCR1B = (1 << WGM13) | (1 << WGM12);
TCCR1A = (1 << WGM11);
// выставляем TOP
ICR1 = (uint16_t)(F_CPU / 64);
// инициализация таймера 0 (8-ми битный)
// x1024, mode7 (fastpwm, top in OCRA)
TCCR0A = (1 << WGM01) | (1 << WGM00);
TCCR0B = (1 << WGM02); // предделитель пока не ставим, таймер без него не работает
OCR0A = 250;
// разрешаем прерывание по переполнению
TIMSK |= (1 << TOV1) | (1 << TOV0);
TCCR1B |= (1 << CS11) | (1 << CS10); // выставляем x64, то есть запускаем таймер
sei();
}
void platform_wdt_start() {
timeout_err = 0;
asm volatile ("wdr");
WDTCSR = (1 << WDIE) | (1 << WDP3) | (1 << WDP0); // 8 sec, interrupt enable
}
void platform_wdt_stop() {
WDTCSR = (1 << WDP3) | (1 << WDP0); // stop
}
void uart_init() {
// U2X=1, baud=9600, error=0.2%, f=1M
UBRRH = 0;
UBRRL = 12;
UCSRA = (1 << U2X);
UCSRB = (1 << TXEN) | (1 << RXEN);
}
void uart_deinit() {
UCSRB = 0; // снимаем RXEN и TXEN
}
void uart_write_char(char c) {
while ((UCSRA & (1 << UDRE)) == 0)
;
UDR = c;
}
void uart_write_str(const char* str) {
while (1) {
char c = *(str++);
if (c == '\0') {
break;
}
uart_write_char(c);
}
}
void uart_write_fstr(PGM_P str) {
while (1) {
char c = pgm_read_byte(str++);
if (c == '\0') {
break;
}
uart_write_char(c);
}
}
char uart_read_char() {
while (!(UCSRA & (1 << RXC))) {
if (timeout_err) {
return -1;
}
}
return UDR;
}
void uart_discard_input() {
while (UCSRA & (1 << RXC)) {
char __attribute__((__unused__)) _tmp = UDR;
}
}