File: spi.c

package info (click to toggle)
limesuite 23.11.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 17,228 kB
  • sloc: cpp: 157,511; ansic: 6,852; python: 197; sh: 56; xml: 21; makefile: 19
file content (126 lines) | stat: -rw-r--r-- 3,021 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "spi.h"
#include "LMS7002_REGx51.h"

void Delay()
{
    TR0 = 0; //stop timer 0
    TH0 = 0xFF;
    TL0 = 0xF0;
    TF0 = 0; //clear overflow
    TR0 = 1; //start timer
    while( !TF0 ); //wait for timer overflow
}

void SPI_transferVariable(unsigned short value)
{								  
	uint8_t spiIter;
	for(spiIter = 16; spiIter>0; spiIter--) //MSB First
	{
		ucSCLK=0;	//set Clock low
		ucSDIN = value & 0x8000; //if current bit is 1 set Output High
		value <<= 1; //shift mask to right
		ucSCLK=1; 	//set Clock high
	}
	ucSCLK=0;	//set Clock low
}

void SPI_transferVariable_slow(unsigned short value)
{
	uint8_t spiIter;
	for(spiIter = 16; spiIter>0; spiIter--) //MSB First
	{
		ucSCLK=0;	//set Clock low
        Delay();
		ucSDIN = value & 0x8000; //if current bit is 1 set Output High
        Delay();
		value <<= 1; //shift mask to right
		ucSCLK=1; 	//set Clock high
        Delay();
	}
	ucSCLK=0;	//set Clock low
}

void SPI_write(const unsigned short spiAddrReg, const unsigned short spiDataReg)
{
	ucSCLK=0;
	ucSEN=0;
	//write addr
	SPI_transferVariable(spiAddrReg | 0x8000); //set write bit
	//write data
	SPI_transferVariable(spiDataReg);
	ucSEN=1;
	ucSDIN=1;
}

void SPI_write_slow(const unsigned short spiAddrReg, const unsigned short spiDataReg)
{
	ucSCLK=0;
	ucSEN=0;
	//write addr
	SPI_transferVariable_slow(spiAddrReg | 0x8000); //set write bit
	//write data
	SPI_transferVariable_slow(spiDataReg);
	ucSEN=1;
	ucSDIN=1;
}

unsigned short SPI_read_slow (const unsigned short spiAddrReg)
{
	uint8_t spiIter;	
	uint16_t spiDataReg = 0;
	ucSCLK=0;
	ucSEN=0;
	//write addr
	SPI_transferVariable_slow(spiAddrReg & ~0x8000);	//clear write bit
	ucSDIN=1;
	//read data
	for(spiIter = 16; spiIter>0; spiIter--) //MSB First
	{
		ucSCLK=1; 	//set Clock high
        Delay();
		spiDataReg <<= 1;
		if (ucSDOUT)
			spiDataReg |= 1;
		ucSCLK=0;	//set Clock low
        Delay();
	}
	ucSEN=1;
	ucSDIN=1;
	return spiDataReg;
}

unsigned short SPI_read (const unsigned short spiAddrReg)
{
	uint8_t spiIter;
	uint16_t spiDataReg = 0;
	ucSCLK=0;
	ucSEN=0;
	//write addr
	SPI_transferVariable(spiAddrReg & ~0x8000);	//clear write bit
	ucSDIN=1;
	//read data
	for(spiIter = 16; spiIter>0; spiIter--) //MSB First
	{
		ucSCLK=1; 	//set Clock high
		spiDataReg <<= 1;
		if (ucSDOUT)
			spiDataReg |= 1;
		ucSCLK=0;	//set Clock low
	}
	ucSEN=1;
	ucSDIN=1;
	return spiDataReg;
}

void Modify_SPI_Reg_bits(const uint16_t SPI_reg_addr, const uint8_t bits, const uint16_t new_bits_data)
{
	uint16_t spiDataReg = SPI_read(SPI_reg_addr); //read current SPI reg data
	const uint16_t spiMask = (~(~0 << ((bits>>4)-(bits&0xF)+1))) << (bits&0xF); // creates bit mask
	spiDataReg = (spiDataReg & (~spiMask)) | ((new_bits_data << (bits&0xF)) & spiMask) ;//clear bits
	SPI_write(SPI_reg_addr, spiDataReg); //write modified data back to SPI reg
}

uint16_t Get_SPI_Reg_bits(const uint16_t SPI_reg_addr, const uint8_t bits)
{
	return (SPI_read(SPI_reg_addr) & (~(~0<<((bits>>4)+1)))) >> (bits&0xF); //shift bits to LSB
}