Good day to all.
Can somebody please put me through on how to write an SPI-BITBANG for a slave device. I have been having Problem sending data from my slave device(Attiny44)to the master device(Attiny4313).I had earlier implemented the USI in Attiny.everything worked fine.i was able to send data from the master to the slave and at the same time send data from slave to the master.However,this Arrangement did not work for my application in the long run.I have a temperature sensor connected to the slave device using I2C.The USI in the attiny uses specific PINs for its Operation,one of such Pins is the CLOCK PIN.This Clock Pin is the same Pin use by the I2C.The Operation of my circuit is such that the slave device reads the temperature from the sensor using the I2C and then sends the temperature value to the master using the USI.But because of the conflict between the USI Clock Signal and the I2C Clock Signal,the communication between the master and the slave is no longer possible.Because of this conflict i have no other Option but to settle for the SPI-BITBANGING.However I am having Problem with my SPI-BITBANG CODE.The code for the Master device appears to be okay.I checked the data transfered by the master with oscilloscope it was correct, however when i checked the data transfered by the slave device with the oscilloscope,i did not see anything.My assumption is that i am not clocking the slave device correctly.I would be very grateful if somebody could put me through on how to rectify this error.once again thank you for the guide and support.Best regards.
The Pins connection arrangement below was not suitable for my application when I used Usi/Spi features in Attiny.
ATTINY4313(MASTER) ATTINY44(SLAVE)
DO(data-out)-------------------------------------------->DI(data-in)
DI(data-in)<--------------------------------------------DO(data-out)
USCK(clock-pin)------------------------------------------>USCK(clock-pin) //This clock Pin is the same Clock pin(SCK) used for I2C.
Below are my codes for the Master and Slave respectively.
MASTER CODE-ATTINY4313
#include <avr/io.h>
#include <avr/delay.h>
#define OUT_REG PORTB // port output register.
#define IN_REG PINB // port input register.
#define DIR_REG DDRB // port direction register.
#define CLOCK_PIN PINB1 //clock I/O pin.
#define DATAIN_PIN PINB3 //data input pin.
#define DATAOUT_PIN PINB4 //data output pin.
void SetClock()
{
PORTB |= (1 << PINB1); //Set clock HIGH
}
void ClearClock()
{
PORTB &= ~(1 << PINB1); //Set Clock LOW
}
void SetData()
{
PORTB |= (1 << PINB4); //Set Data HIGH
}
void ClearData()
{
PORTB &= ~(1 << PINB4); //Set Data LOW
}
void Spi_Master_Init()
{
DIR_REG |= (1<<DATAOUT_PIN) | (1<<CLOCK_PIN); // set up SCK/MOSI as output Pins
DIR_REG &= ~(1<<DATAIN_PIN); // Data-In (MISO) AS input
OUT_REG &=~(1<<DATAOUT_PIN) | ~(1<<CLOCK_PIN); //Set DATAOUT_PIN and CLOCK_PIN LOW
}
unsigned char Transmitt_Receive(unsigned char val)
{
unsigned char cnt, miso;
for (cnt = 8, miso = 0; cnt--; val <<= 1) {
_delay_us(5);
if (val & 0x80)
SetData();
else
ClearData();
miso <<= 1;
_delay_us(1);
SetClock();
_delay_us(1);
if(IN_REG & (1<<DATAIN_PIN))
miso |= 1;
ClearClock();
}
return miso;
}
int main(void)
{
DDRD =0xFF;
PORTD=0x00;
Spi_Master_Init();
while(1)
{
PORTD=Transmitt_Receive(3);
}
}
SLAVE CODE-ATTINY44
#include <avr/io.h>
#include <util/delay.h>
#define OUT_REG PORTA // port output register.
#define IN_REG PINA // port input register.
#define DIR_REG DDRA //port direction register.
#define CLOCK_PIN PINA1 //clock input pin.
#define DATAIN_PIN PINA0 // data input pin.
#define DATAOUT_PIN PINA7 // data output pin.
unsigned char Transmit_Receive(unsigned char data);
void SetData()
{
PORTA |= (1 << PINA7); //Set Data HIGH
}
void ClearData()
{
PORTA &= ~(1 << PINA7); Set Data LOW
}
unsigned char Spi_Slave_Init() //Initialise Slave Device
{
DIR_REG |= (1<<DATAOUT_PIN); // Set up MISO as output Pins
DIR_REG &= ~(1<<DATAIN_PIN) | ~(1<<CLOCK_PIN); // Clock-Pin and Datain as input
OUT_REG |= (1<<CLOCK_PIN); //Pull-Up
}
int main(void)
{
Spi_Slave_Init();
while(1)
{
Transmit_Receive(40);
}
}
unsigned char Transmit_Receive(unsigned char data)
{
unsigned char Value;
unsigned char Result;
while(1)
{
if ((IN_REG & (1<<CLOCK_PIN))==0)
{
if (data & 0x80)
{
SetData();
}
else
{
ClearData();
}
data <<=1;
}
else
{
Value = ((IN_REG >> DATAIN_PIN) & 0x01);
Result= (Result << 1) | Value ;
}
}
return Result;
}