mongoose/examples/renesas/ek-ra6m4-make-baremetal-builtin/hal.h
2024-01-27 17:06:28 +00:00

128 lines
3.2 KiB
C

// Copyright (c) 2024 Cesanta Software Limited
// All rights reserved
//
// MCU and ek-ra6m4 eval board datasheets:
// https://www.renesas.com/us/en/document/man/ra6m4-group-user-s-manual-hardware
// https://www.renesas.com/us/en/document/man/ek-ra6m5-v1-users-manual
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "bsp_exceptions.h"
#include "R7FA6M4AF.h"
extern void hal_init(void);
#define LED1 PIN('E', 15)
#define LED2 PIN('E', 4)
#define LED3 PIN('E', 0)
#define UART_DEBUG R_SCI0
#define UART_TX PIN('G', 13)
#define UART_RX PIN('G', 12)
#define BIT(x) (1UL << (x))
#define CLRSET(reg, clear, set) ((reg) = ((reg) & ~(clear)) | (set))
#define PIN(port, num) ((((port) - 'A') << 8) | (num))
#define PIN_NUM(pin) (pin & 255)
#define PIN_PORT(pin) (pin >> 8)
// No-op HAL API implementation for a device with GPIO and UART
#define rng_read() 0
#define rng_init()
#define uart_read_ready(uart) 0
#define GENERATE_MAC_ADDRESS() \
{ 2, 3, 4, 5, 6, 7 }
// Clock
#define SYS_FREQUENCY 2000000
static inline void clock_init(void) {
SCB->CPACR = (uint32_t) 15U << 20;
}
// GPIO
#define GPIO(N) ((R_PORT0_Type *) (R_PORT0_BASE + 0x20 * (N)))
enum { GPIO_MODE_INPUT, GPIO_MODE_OUTPUT, GPIO_MODE_AF };
static inline void gpio_init(uint16_t pin, uint8_t mode, uint8_t af) {
R_PORT0_Type *gpio = GPIO(PIN_PORT(pin));
if (mode == GPIO_MODE_OUTPUT) {
gpio->PCNTR1 |= BIT(PIN_NUM(pin));
} else if (mode == GPIO_MODE_INPUT) {
gpio->PCNTR1 &= ~BIT(PIN_NUM(pin));
} else {
(void) af;
}
}
static inline void gpio_output(uint16_t pin) {
gpio_init(pin, GPIO_MODE_OUTPUT, 0);
}
static inline void gpio_input(uint16_t pin) {
gpio_init(pin, GPIO_MODE_INPUT, 0);
}
static inline bool gpio_read(uint16_t pin) {
R_PORT0_Type *gpio = GPIO(PIN_PORT(pin));
return gpio->PCNTR2 & BIT(PIN_NUM(pin)) ? true : false;
}
static inline void gpio_write(uint16_t pin, bool val) {
R_PORT0_Type *gpio = GPIO(PIN_PORT(pin));
gpio->PCNTR3 = BIT(PIN_NUM(pin)) << (val ? 0 : 16U);
}
static inline void gpio_toggle(uint16_t pin) {
gpio_write(pin, !gpio_read(pin));
}
// UART
static inline void uart_init(R_SCI0_Type *uart, unsigned baud) {
gpio_output(UART_TX);
gpio_input(UART_RX);
(void) uart, (void) baud;
}
static inline void uart_write_byte(void *uart, uint8_t byte) {
uint16_t pin = UART_TX;
uint32_t baud = 9600;
uint32_t interval = SYS_FREQUENCY / baud; // Time to send 1 bit
uint8_t bits[] = {
0, // Start bit
(byte >> 0) & 1U,
(byte >> 1) & 1U,
(byte >> 2) & 1U,
(byte >> 3) & 1U,
(byte >> 4) & 1U,
(byte >> 5) & 1U,
(byte >> 6) & 1U,
(byte >> 7) & 1U,
1, // Stop bit
};
uint32_t t = SysTick->VAL; // Current timer value
for (uint8_t i = 0; i < 10; i++) {
gpio_write(pin, bits[i]);
if (t <= interval) {
while (SysTick->VAL <= t) (void) 0;
t = SysTick->LOAD + 1 - interval;
while (SysTick->VAL > t) (void) 0;
} else {
t -= interval;
while (SysTick->VAL > t) (void) 0;
}
}
(void) uart;
}
static inline void uart_write_buf(void *uart, char *buf, size_t len) {
while (len-- > 0) uart_write_byte(uart, *(uint8_t *) buf++);
}
// Ethernet
static inline void ethernet_init(void) {
}