#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include "stm32f1xx.h" // Заголовочный файл STM32F1xx стандартной библиотеки HAL

// Заданные адреса и смещения
#define RCC_base_add      0x40021000
#define APB2_offset       0x18
#define SPI1_base_add     0x40013000
#define GPIOA_base_add    0x40010800
#define GPIO_PIN_5        5

volatile uint32_t *output_reg; // Глобальное объявление

// Инициализация SPI
void initSPI(void) {
    RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; // Включаем тактовый сигнал для SPI1

    // Настройка GPIO для SPI
    GPIOA->CRL &= ~(0xF << (GPIO_PIN_5 * 4)); // Очищаем настройки PA5
    GPIOA->CRL |= 0xB << (GPIO_PIN_5 * 4); // Настраиваем PA5 на режим альтернативной функции push-pull
}

// Отправка данных через SPI
void sendSPI(uint8_t data) {
    SPI1->DR = data; // Передаем данные для отправки
    while (!(SPI1->SR & SPI_SR_TXE)); // Ждем, пока буфер передатчика освободится
    while (SPI1->SR & SPI_SR_BSY); // Ждем, пока завершится передача
}

// Функция для вывода информации на дисплей отладочной платы
void displayInfo(const char* text) {
    for (int i = 0; text[i] != '\0'; i++) {
        sendSPI(text[i]); // Отправляем каждый символ текста по SPI
    }
}

int main(void) {
    volatile uint32_t *clock_reg  = (uint32_t*) (RCC_base_add + APB2_offset);
    output_reg = (uint32_t*) (GPIOA_base_add + GPIO_PIN_5); // Инициализация output_reg

    *clock_reg |= 1 << 2; // Включаем тактовый сигнал для GPIOA

    initSPI(); // Инициализация SPI

    // Инициализация системы
    HAL_Init();
    SystemClock_Config();

    displayInfo("Hello, World!"); // Отображаем текст на дисплее

    while (1) {
        // Можно добавить другие действия или оставить программу работать только с отображением текста
        
    }

    return 0;
}