293 lines
6.4 KiB
C
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;
|
|
}
|
|
|