C-Libs/Soft_SPI.c
2021-07-01 11:55:32 +00:00

293 lines
6.4 KiB
C

/*
* Soft_SPI.c
*
* Created on: Nov 26, 2019
* Author: Adcis
*
* SCK_Pin, MOSI_Pin, MISO_Pin, CS0_Pin and CS1_Pin required to define in project
*
* Software SPI library for use with STM32 MCUs
*/
#include "main.h"
#include "Soft_SPI.h"
#ifdef NXP_LPC
#include "chip.h"
#include <stdbool.h>
#include "debug.h"
#endif
int SOFT_Power(int,int);
void SOFT_SCK(unsigned int); //rizeni SCK pinu
void SOFT_SPI(unsigned int); //rizeni MOSI pinu
void SOFT_SPI_Send(unsigned int); //odeslani zpravy po SPI
int SOFT_SPI_Receive(unsigned int); //prijem zpravy po SPI
void SOFT_CS(unsigned int); //chip select - 0 = DA prevodnik, 1 = AD prevodnik, cokoliv jineho = nezvoleno nic
void SOFT_SPI_CLK(unsigned int); //1 puls _|-|_ na SCK
int SOFT_SPI_ReadWrite(uint32_t, uint8_t, uint8_t, uint32_t*);
int SOFT_Power(int x, int y){
if (y == 0){
return 1;
}
else if (y % 2 == 0){
return SOFT_Power(x, y / 2) * SOFT_Power(x, y / 2);
}
else{
return x * SOFT_Power(x, y / 2) * SOFT_Power(x, y / 2);
}
}
/**
* @brief Controls SCK
*
* @param var = set state of SCK
*
* @retval None
*/
void SOFT_SCK(unsigned int state){
if(state == 1){
#ifdef NXP_LPC
Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, SCLK, true);
#else
GPIOB->BSRR = SCK_Pin;
#endif
}
else{
#ifdef NXP_LPC
Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, SCLK, false);
#else
GPIOB->BRR = SCK_Pin;
#endif
}
}
/**
* @brief Controls MOSI
*
* @param var = set state of MOSI
*
* @retval None
*/
void SOFT_SPI(unsigned int var){
if(var!=0){
#ifdef NXP_LPC
Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, MOSI, true);
#else
GPIOB->BSRR = MOSI_Pin;
#endif
}
else{
#ifdef NXP_LPC
Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, MOSI, false);
#else
GPIOB->BRR = MOSI_Pin;
#endif
}
}
/**
* @brief SPI CS control
*
* @param cs = what cs pin to use
*
* @retval None
*/
void SOFT_CS(unsigned int cs){
if(cs == 0){
#ifdef NXP_LPC
Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, CS, false);
#else
GPIOB->BSRR = CS1_Pin;
GPIOB->BRR = CS0_Pin;
#endif
}
else if(cs == 1){
#ifdef NXP_LPC
Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, CS, true);
#else
GPIOB->BSRR = CS0_Pin;
GPIOB->BRR = CS1_Pin;
#endif
}
else{
#ifdef NXP_LPC
Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, CS, false);
#else
GPIOB->BSRR = CS0_Pin;
GPIOB->BSRR = CS1_Pin;
#endif
}
}
/**
* @brief Sends SPI message
*
* @param value = what byte to send
*
* @retval None
*/
void SOFT_SPI_Send(unsigned int value){
unsigned int valueBin[] = {0,0,0,0,0,0,0,0};
if(value >= 128){
valueBin[0] = 1;
value = value % 128;
}
if(value >= 64){
valueBin[1] = 1;
value = value % 64;
}
if(value >= 32){
valueBin[2] = 1;
value = value % 32;
}
if(value >= 16){
valueBin[3] = 1;
value = value % 16;
}
if(value >= 8){
valueBin[4] = 1;
value = value % 8;
}
if(value >= 4){
valueBin[5] = 1;
value = value % 4;
}
if(value >= 2){
valueBin[6] = 1;
}
valueBin[7] = value % 2;
SOFT_SCK(0);
SOFT_SPI(valueBin[0]);
SOFT_SCK(0);
SOFT_SCK(1);
SOFT_SPI(valueBin[1]);
SOFT_SCK(0);
SOFT_SCK(1);
SOFT_SPI(valueBin[2]);
SOFT_SCK(0);
SOFT_SCK(1);
SOFT_SPI(valueBin[3]);
SOFT_SCK(0);
SOFT_SCK(1);
SOFT_SPI(valueBin[4]);
SOFT_SCK(0);
SOFT_SCK(1);
SOFT_SPI(valueBin[5]);
SOFT_SCK(0);
SOFT_SCK(1);
SOFT_SPI(valueBin[6]);
SOFT_SCK(0);
SOFT_SCK(1);
SOFT_SPI(valueBin[7]);
SOFT_SCK(0);
SOFT_SCK(1);
#ifdef NXP_LPC
Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, MOSI, false);
#else
GPIOB->BRR = MOSI_Pin;
#endif
SOFT_SCK(0);
}
/**
* @brief Recieves SPI message
*
* @param bits = how long will received mesage be
*
* @retval uint16_t
*/
int SOFT_SPI_Receive(unsigned int bits){
uint8_t arr_bts[bits];
uint8_t sumarr[bits];
uint16_t sum;
for(int i=0; i<bits;i++){
SOFT_SCK(1);
#ifdef NXP_LPC
uint8_t MISO_read = Chip_GPIO_GetPinState(LPC_GPIO_PORT, 0, MISO);
#else
uint8_t MISO_read = HAL_GPIO_ReadPin(GPIOB, MISO_Pin);
#endif
if(MISO_read == 1){
arr_bts[i] = 1;
}
else{
arr_bts[i] = 0;
}
#ifndef FAST_SPI
sumarr[i] = arr_bts[i] * power(2 , bits - i - 1);
#endif
SOFT_SCK(0);
}
#ifdef FAST_SPI
for(int i = 0; i < bits; i++){
sumarr[i] = arr_bts[i] * SOFT_Power(2 , bits - i - 1);
}
#endif
//receive string
if(bits==12){
sum = sumarr[0]+sumarr[1]+sumarr[2]+sumarr[3]+sumarr[4]+sumarr[5]+sumarr[6]+sumarr[7]+sumarr[8]+sumarr[9]+sumarr[10]+sumarr[11];
}
else if(bits==16){
sum = sumarr[0]+sumarr[1]+sumarr[2]+sumarr[3]+sumarr[4]+sumarr[5]+sumarr[6]+sumarr[7]+sumarr[8]+sumarr[9]+sumarr[10]+sumarr[11]+sumarr[12]+sumarr[13]+sumarr[14]+sumarr[15];
}
else if(bits==8){
sum = sumarr[0]+sumarr[1]+sumarr[2]+sumarr[3]+sumarr[4]+sumarr[5]+sumarr[6]+sumarr[7];
}
else{
sum = 0;
}
return sum;
}
/**
* @brief SPI clk
*
* @param cycles = how many cycles to make
*
* @retval None
*/
void SOFT_SPI_CLK(unsigned int cycles){
for(int i=0;i<cycles;i++){
SOFT_SCK(1);
for(int j=0;j<1;j++);
SOFT_SCK(0);
}
}
int SOFT_SPI_ReadWrite(uint32_t valueToSend, uint8_t dataLen, uint8_t packets, uint32_t *RxBuffer){
int nOfBits = dataLen * packets;
int valueToSendMaxPackets = 32/dataLen;
uint32_t receiveData = 0;
//uint32_t RxBuffer[packets];
int bitsTransferred = 0;
SOFT_SCK(0);
for(int j = 0; j < packets; j++){
for(int i = 0; i < dataLen; i++){
SOFT_SPI((valueToSend >> (dataLen-i)) & 1);
SOFT_SCK(0);
SOFT_SCK(1);
#ifdef NXP_LPC
uint8_t MISO_read = Chip_GPIO_GetPinState(LPC_GPIO_PORT, 0, MISO);
#else
uint8_t MISO_read = HAL_GPIO_ReadPin(GPIOB, MISO_Pin);
#endif
if(MISO_read == 1){
receiveData |= (1 << (dataLen - i));
}
//else{
// receiveData |= (1 << i);
//}
bitsTransferred++;
}
#ifdef NXP_LPC
Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, MOSI, false);
#else
GPIOB->BRR = MOSI_Pin;
#endif
SOFT_SCK(0);
RxBuffer[j] = receiveData >> 1;
}
return bitsTransferred;
}