#include "SPI_peripherals.h"

void HAL_SPI_peripehrals_Init(SPI_HandleTypeDef *SPI, uint16_t SPI_NUM)
{

    if(SPI_NUM == 1)
    {
        __SPI1_CLK_ENABLE();  // Povolení hodin CLK pro port SPI1

        GPIO_InitTypeDef GPIO_SPI1;

        //Nastavení pinů SPI1 - pouze pro vysílání dat
        GPIO_SPI1.Pin = SPI1_MOSI|SPI1_SCK;
        GPIO_SPI1.Mode = GPIO_MODE_AF_PP;
        GPIO_SPI1.Pull = GPIO_PULLUP;
        GPIO_SPI1.Speed = GPIO_SPEED_HIGH;
        GPIO_SPI1.Alternate = GPIO_AF5_SPI1;
        HAL_GPIO_Init(SPI1_PORT,&GPIO_SPI1);

        SPI->Instance = SPI1; // SPI1
        SPI->Init.Mode = SPI_MODE_MASTER;
        SPI->Init.Direction = SPI_DIRECTION_2LINES;
        SPI->Init.DataSize = SPI_DATASIZE_16BIT; // 16 bitový mod SPI
        SPI->Init.CLKPolarity = SPI_POLARITY_LOW;
        SPI->Init.CLKPhase = SPI_PHASE_1EDGE;
        SPI->Init.NSS = SPI_NSS_SOFT;
        SPI->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
        SPI->Init.FirstBit = SPI_FIRSTBIT_MSB;
        SPI->Init.TIMode = SPI_TIMODE_DISABLED;
        SPI->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
        SPI->Init.CRCPolynomial = 10;

    }
    else if(SPI_NUM == 2)
    {
        __SPI2_CLK_ENABLE();  // Povolení hodin CLK pro port SPI2

        GPIO_InitTypeDef GPIO_SPI2;

        //Nastavení pinů SPI1 - pouze pro příjem dat - MISO
        GPIO_SPI2.Pin = SPI2_MISO;
        GPIO_SPI2.Mode = GPIO_MODE_AF_PP;
        GPIO_SPI2.Pull = GPIO_PULLUP;
        GPIO_SPI2.Speed = GPIO_SPEED_HIGH;
        GPIO_SPI2.Alternate = GPIO_AF5_SPI2;
        HAL_GPIO_Init(SPI2_PORT_C,&GPIO_SPI2);

        //Nastavení pinů SPI1 - pouze pro příjem dat - SCK
        GPIO_SPI2.Pin = SPI2_SCK;
        GPIO_SPI2.Mode = GPIO_MODE_AF_PP;
        GPIO_SPI2.Pull = GPIO_PULLUP;
        GPIO_SPI2.Speed = GPIO_SPEED_HIGH;
        GPIO_SPI2.Alternate = GPIO_AF5_SPI2;
        HAL_GPIO_Init(SPI2_PORT_B,&GPIO_SPI2);

        SPI->Instance = SPI2;
        SPI->Init.Mode = SPI_MODE_MASTER;
        SPI->Init.Direction = SPI_DIRECTION_2LINES;
        SPI->Init.DataSize = SPI_DATASIZE_16BIT; // 16 bitový mod SPI
        SPI->Init.CLKPolarity = SPI_POLARITY_LOW;
        SPI->Init.CLKPhase = SPI_PHASE_1EDGE;
        SPI->Init.NSS = SPI_NSS_SOFT;
        SPI->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
        SPI->Init.FirstBit = SPI_FIRSTBIT_MSB;
        SPI->Init.TIMode = SPI_TIMODE_DISABLED;
        SPI->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
        SPI->Init.CRCPolynomial = 10;

    }
    else if(SPI_NUM == 3)
    {
        __SPI3_CLK_ENABLE();  // Povolení hodin CLK pro port SPI3

        GPIO_InitTypeDef GPIO_SPI3;

        //Nastavení pinů SPI3 - pouze pro vysílání dat - SCK
        GPIO_SPI3.Pin = SPI3_SCK;
        GPIO_SPI3.Mode = GPIO_MODE_AF_PP;
        GPIO_SPI3.Pull = GPIO_PULLUP;
        GPIO_SPI3.Speed = GPIO_SPEED_HIGH;
        GPIO_SPI3.Alternate = GPIO_AF7_SPI3;
        HAL_GPIO_Init(SPI3_PORT_B,&GPIO_SPI3);

        //Nastavení pinů SPI3 - pouze pro vysílání dat - MISO
        GPIO_SPI3.Pin = SPI3_MOSI;
        GPIO_SPI3.Mode = GPIO_MODE_AF_PP;
        GPIO_SPI3.Pull = GPIO_PULLUP;
        GPIO_SPI3.Speed = GPIO_SPEED_HIGH;
        GPIO_SPI3.Alternate = GPIO_AF6_SPI3;
        HAL_GPIO_Init(SPI3_PORT_C,&GPIO_SPI3);

        SPI->Instance = SPI3;
        SPI->Init.Mode = SPI_MODE_MASTER;
        SPI->Init.Direction = SPI_DIRECTION_2LINES;
        SPI->Init.DataSize = SPI_DATASIZE_16BIT; // 16 bitový mod SPI
        SPI->Init.CLKPolarity = SPI_POLARITY_LOW;
        SPI->Init.CLKPhase = SPI_PHASE_1EDGE;
        SPI->Init.NSS = SPI_NSS_SOFT;
        SPI->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
        SPI->Init.FirstBit = SPI_FIRSTBIT_MSB;
        SPI->Init.TIMode = SPI_TIMODE_DISABLED;
        SPI->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
        SPI->Init.CRCPolynomial = 10;

    }

    HAL_SPI_Init(SPI);
    __HAL_SPI_ENABLE(SPI); // Povolení periférie

}


uint16_t spi_send_data (SPI_HandleTypeDef *SPI, uint16_t data)
{
    while ((SPI->Instance->SR & SPI_FLAG_TXE) == 0); // Čeká dokud nejsou všechna data odeslána
    SPI->Instance->DR = data;
    while ((SPI->Instance->SR & SPI_FLAG_RXNE) == 0); // Čeká dokud nejsou všechna data přijata
    return (SPI->Instance->DR); // Navrácení přijatých dat
}








