coonecting atlemga16 in slave mode problem

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi all
i m trying to connect the atmel in slave mode. i hav a program dat runs on it for both slave reciver and transmitter.. i m trying to connect it to the lego mindstorm using the i2c interface. i am able to do the slave reciver mode but i m not able to do the salve transmitter mode..

the problem i face is this.. wen i start the devices it transmit for once and than the data line goes blank to transmiit again i hav to restart the atmel.. i m using CRO to see the wave forms... wat i find is wen i try to write to atmel the adrres sent from the device is 00100000.. it works right in wat ever mode i send it but wen i try to read from atmel it send the addres 00100001 and atmel stops responding and i coonote see any wave form onthe CRO its goes to staright line.

wat could b the problem???/

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You forgot to ferkle the findlap in line 32.

There can be many reasons why the code is failing. Please read Help, My "..." Doesn't Work! Then, when you post code, you can make it easier to read by highlighting the code and then pressing the Code button on the submit page.

Your code
   will then
      look 
   like
THIS!

(assuming you put indents in your code)

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i m facing this problem i m using lego mindstorm and the code works fine .. my atmel is slave

but wen i chnage the firm ware from standard to java ones .. the data lines on CRO goes to staright line.. i m not able to get the reason..
the code on my lego sends three things one is adress of atmel , than it sends some register and than it sends the buffer to recive the value.. can it b the problem of register value..
cause atmel need only the adrres and buffer to recive data

the code on atmel is here i copied it from a site of lego mindstorm..

/****************************************************************************
* Target:          ATmega8
* Title:           I2C communication between LEGO MINDSTORMS NXT and
*                  ATMEL ATMEGA8 Microcontrollerheader for i2c slave on ATMEGA8.
* Description:     Demo test, reads a bit from a slavedevice and print it on
*                  the NXT display.
*
* Authors:         Nimal Kailasanathan
* Copyright:       GPL
*
*
*****************************************************************************/

#include "NXCDefs.h"

//Variable
#define SENSOR_PORT S3

//ATmega8 COMMAND SET
unsigned char i2c_write[]={0x20};               //0x10 is the slave address of ATmega16, shifted to give 0x020; xxx is the data to be written
unsigned char i2c_data[1];                     // we only expect one byte to be read back

sub twi_atmega() //I2C-connetion, also called TWI, between ATmega8 and NXT
{

char result;
unsigned char bytes_ready;

SetSensorType(SENSOR_PORT, IN_TYPE_LOWSPEED);   //Set the sensor type, which is the predefined I2C digital sensor type constant. The port is specified using a variable;
SetSensorMode(SENSOR_PORT, IN_MODE_RAW);       //Set the sensor mode, which is the predefined sensor raw mode constant. Meaning: raw value from 0 to 1023
ResetSensor(SENSOR_PORT);                      //Reset the value of the sensor


//CHEKS THE CONFIG STATUS

/*I2CStatus in a loop to check the status of the port. If I2CStatus
returns a status code of 0 and a count of bytes available in the read buffer,
the system is ready for use I2CRead to copy the data from the read buffer
into a buffer */


if( LowspeedStatus(SENSOR_PORT, bytes_ready) != NO_ERR) {
ClearScreen();
while(true) {
NumOut(0,50,I2CStatus(SENSOR_PORT, bytes_ready));
TextOut(0,LCD_LINE2,"cfg_err");
            }
}

// Wait for the transaction to complete
while(LowspeedStatus(SENSOR_PORT, bytes_ready)==STAT_COMM_PENDING);


//Read sensor data from ATmega8
while (true) {
TextOut(0,20,"test:");

// Write our data to the ATmega16, and say we expect one byte back
result = LowspeedWrite(SENSOR_PORT, 2, i2c_write);
if( result != NO_ERR) {
while(true) {
NumOut(0,LCD_LINE1,result);
TextOut(0,LCD_LINE2,"write_err2");
            }
}

// Wait for the transaction to complete
while(LowspeedStatus(SENSOR_PORT, bytes_ready)==STAT_COMM_PENDING);

//Read the result back from the buffer
result = LowspeedRead(SENSOR_PORT, 2, i2c_data);
if( result != NO_ERR) {
while(true) {
NumOut(0,LCD_LINE1,result);
TextOut(0,LCD_LINE2,"read_err");

            }

}

//Print out the i2c_data buffer
 NumOut(0,LCD_LINE3,i2c_data[0]);

// Wait for the transaction to complete
while(LowspeedStatus(SENSOR_PORT, bytes_ready)==STAT_COMM_PENDING);



}
    }
task main()
{
twi_atmega();
}

thanx..
Hitesh

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The code you posted is for the MindStorms processor, not the ATmega8. Sorry, I have no knowledge of the Mindstorm, and it is unlikely that anyone else looking at this forum does, either.

I recommend you find a forum dedicated to the Mindstorm and repost your code there.

While you're at it, you might want to post the following indented code as it is far more readable than what you posted:

/****************************************************************************
* Target:          ATmega8
* Title:           I2C communication between LEGO MINDSTORMS NXT and
*                  ATMEL ATMEGA8 Microcontrollerheader for i2c slave on ATMEGA8.
* Description:     Demo test, reads a bit from a slavedevice and print it on
*                  the NXT display.
*
* Authors:         Nimal Kailasanathan
* Copyright:       GPL
*
*
*****************************************************************************/

#include "NXCDefs.h"

//Variable
#define SENSOR_PORT S3

//ATmega8 COMMAND SET
unsigned char i2c_write[]={0x20};	//0x10 is the slave address of ATmega16, shifted to give 0x020; xxx is the data to be written
unsigned char i2c_data[1];			// we only expect one byte to be read back

sub twi_atmega() //I2C-connetion, also called TWI, between ATmega8 and NXT
{
	char result;
	unsigned char bytes_ready;

	// Set the sensor type, which is the predefined I2C digital sensor
	// type constant. The port is specified using a variable;
	SetSensorType(SENSOR_PORT, IN_TYPE_LOWSPEED);

	// Set the sensor mode, which is the predefined sensor raw mode 
	// constant. Meaning: raw value from 0 to 1023
	SetSensorMode(SENSOR_PORT, IN_MODE_RAW);
	
	//Reset the value of the sensor
	ResetSensor(SENSOR_PORT);

	//CHEKS THE CONFIG STATUS

	// I2CStatus in a loop to check the status of the port. If I2CStatus
	// returns a status code of 0 and a count of bytes available in the 
	// read buffer, the system is ready for use I2CRead to copy the data
	// from the read buffer into a buffer

	if( LowspeedStatus(SENSOR_PORT, bytes_ready) != NO_ERR) {
		ClearScreen();
		while(true) {
			NumOut(0,50,I2CStatus(SENSOR_PORT, bytes_ready));
			TextOut(0,LCD_LINE2,"cfg_err");
		}
	}

	// Wait for the transaction to complete
	while(LowspeedStatus(SENSOR_PORT, bytes_ready)==STAT_COMM_PENDING);


	//Read sensor data from ATmega8
	while (true) {
		TextOut(0,20,"test:");

		// Write our data to the ATmega16, and say we expect one byte back
		result = LowspeedWrite(SENSOR_PORT, 2, i2c_write);
		if( result != NO_ERR) {
			while(true) {
				NumOut(0,LCD_LINE1,result);
				TextOut(0,LCD_LINE2,"write_err2");
			}
		}

		// Wait for the transaction to complete
		while (LowspeedStatus(SENSOR_PORT, bytes_ready)==STAT_COMM_PENDING);

		//Read the result back from the buffer
		result = LowspeedRead(SENSOR_PORT, 2, i2c_data);
		if( result != NO_ERR) {
			while(true) {
				NumOut(0,LCD_LINE1,result);
				TextOut(0,LCD_LINE2,"read_err");
			}
		}

		//Print out the i2c_data buffer
		NumOut(0,LCD_LINE3,i2c_data[0]);

		// Wait for the transaction to complete
		while (LowspeedStatus(SENSOR_PORT, bytes_ready)==STAT_COMM_PENDING);
	}
}

task main()
{
	twi_atmega();
} 

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sry for the code i hav wriiten actaully i just copied paste it an ddidnt read wich code i hav put here

#include 
#include 
#include  
#include "atmega_compat.h"

#define MAX_BUF_LEN 21
#define TWSR_STATUS_MASK   0xF8
#define TWCR_CMD_MASK      0x0F


#define TW_ST_SLA_ACK           0xA8
#define TW_ST_ARB_LOST_SLA_ACK  0xB0
#define TW_ST_DATA_ACK          0xB8
#define TW_ST_DATA_NACK         0xC0
#define TW_ST_LAST_DATA         0xC8
/* TWI states, slave receiver */
#define TW_SR_SLA_ACK           0x60
#define TW_SR_ARB_LOST_SLA_ACK  0x68
#define TW_SR_GCALL_ACK         0x70
#define TW_SR_ARB_LOST_GCALL_ACK 0x78
#define TW_SR_DATA_ACK          0x80
#define TW_SR_DATA_NACK         0x88
#define TW_SR_GCALL_DATA_ACK    0x90
#define TW_SR_GCALL_DATA_NACK   0x98
#define TW_SR_STOP              0xA0
/* Misc */
#define TW_NO_INFO              0xF8
#define TW_BUS_ERROR            0x00


volatile static uint8_t slave_state=0; 		// 1 = receive, 2 = transmit, 0 = ready (all data recieved or sent
											// slave receiver buffer (we expect \0 terminated strings in there):
volatile static uint8_t slave_rec_buf[MAX_BUF_LEN+1];
volatile static uint8_t slave_rec_buf_pos=0; 

// slave_tx_buf is a \0 terminated buffer
volatile static uint8_t slave_tx_buf[MAX_BUF_LEN+1];
volatile static uint8_t slave_tx_buf_pos=0; 


void i2c_init(uint8_t devadr, uint8_t gencall)
{
   uint8_t i;
   // init the TWI as a slave receiver or transmitter. Transmit
   // or receive depends on the direction bit received from the master
   // (the bit after the address). Zero in the direction bit means write
   // = transmit from master = we receive.
   //
   // enable TWI (two wire interface)
   // You will have to call sei() in the main program to use this.

   slave_state=0;
   slave_rec_buf_pos=0;
   slave_tx_buf_pos=0;
   for(i=0;i<=MAX_BUF_LEN;i++){
      slave_tx_buf[i]='\0';
   }
        // enable TWI interrupt and slave address ACK
   outp((BV(TWINT)|BV(TWEA)|BV(TWEN)|BV(TWIE)),TWCR);
   // set local device address for the slave, must be done after setting of TWCR
   devadr=devadr<<1;
   outp(((devadr & 0xFE) | (gencall ?1:0)),TWAR );
   // The Address Match unit checks if received address bytes match 
   // the seven-bit address in the TWI Address Register (TWAR). If 
   // the TWI General Call Recognition Enable (TWGCE) bit in the TWAR 
   // is written to one. If the TWGCE is set, the TWI will respond to 
   // the general call address (0x00).

        // When the address is received from the master it is followed by
        // a 0 to indicate that the slave should receive or 1 to indicate
        // that it should transmit.
	

}

// get the data received from master.
// It has to be a null char terminated string
// It reads whatever is in i2c_outbuf
uint8_t i2c_get_received_data(char *i2c_outbuf)
{
	
   if (slave_state !=1 && slave_rec_buf_pos >0 && slave_rec_buf[slave_rec_buf_pos-1]=='\0'){
      slave_rec_buf[MAX_BUF_LEN]='\0';
      strncpy(i2c_outbuf,(char *) slave_rec_buf,MAX_BUF_LEN);
      // clear buffer
      slave_rec_buf_pos=0;
      return(1);
   }else{
      // no data available
      return(0);
   }
}

// send a zero terminated data string. The send will be done
// when the master wants us to do so. I.e it may not be send at all.
// you have to have a high level handshake protocol with the master
// if you want to be sure that all data was sent.
uint8_t i2c_send_data(char *i2c_data)

{

	
   while(slave_state==2); // we are still transmitting data. wait here.
   strncpy((char *) slave_tx_buf, i2c_data, MAX_BUF_LEN);
   slave_tx_buf[MAX_BUF_LEN]='\0';
   slave_tx_buf_pos=0;
   return(0);
}


// I2C (TWI) interrupt service routine
ISR (TWI_vect)           
{

		
        // read status bits
        uint8_t status = inp(TWSR) & TWSR_STATUS_MASK;
        switch(status)
        {

   // ---- Slave Receiver
   //
   // 0x60: own SLA+W has been received, ACK has been returned
   case TW_SR_SLA_ACK: 
   // 0x68: own SLA+W has been received, ACK has been returned
   case TW_SR_ARB_LOST_SLA_ACK:
   // 0x70: General call address has been received, ACK has been returned
   case TW_SR_GCALL_ACK:   
   // 0x78:     GCA+W has been received, ACK has been returned
   case TW_SR_ARB_LOST_GCALL_ACK:      
      // we are being addressed as slave for 
      // writing (data will be received from master)
      // set state
      slave_state = 1; 
      // prepare buffer
      slave_rec_buf_pos = 0;
      // receive data byte and return ACK
      outp((inp(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA),TWCR);
      break;
   // 0x80: data byte has been received, ACK has been returned
   case TW_SR_DATA_ACK:      
   // 0x90: data byte has been received, ACK has been returned
   case TW_SR_GCALL_DATA_ACK:   
      // get received data byte
      if (slave_rec_buf_pos>= MAX_BUF_LEN){
         // too much data
         slave_rec_buf[MAX_BUF_LEN]='\0';
         slave_rec_buf_pos=MAX_BUF_LEN+1;
         slave_state = 0;
         // return NACK
         outb(TWCR, (inp(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
      }else{
         slave_rec_buf[slave_rec_buf_pos] = inp(TWDR);
         slave_rec_buf_pos++;
         // return ACK
         outp((inp(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA),TWCR);
		 //PORTD=slave_rec_buf[slave_rec_buf_pos-1];
      }
      break;
   // 0x88: data byte has been received, NACK has been returned
   case TW_SR_DATA_NACK:      
   // 0x98: data byte has been received, NACK has been returned
   case TW_SR_GCALL_DATA_NACK:   
      // receive data byte and return NACK
                outp((inp(TWCR)&TWCR_CMD_MASK)|BV(TWINT),TWCR);
      slave_state = 0;
      break;
   // 0xA0: STOP or REPEATED START has been received while addressed as slave
   case TW_SR_STOP:
      // switch to SR mode with SLA ACK
      outp((inp(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA),TWCR);
      // i2c receive is complete
      // set state
      slave_state = 0;
      break;

   // ---- Slave Transmitter
   //
   // 0xA8: own SLA+R has been received, ACK has been returned
   case TW_ST_SLA_ACK:
   // 0xB0: GCA+R has been received, ACK has been returned
   case TW_ST_ARB_LOST_SLA_ACK:
      // we are being addressed as slave for 
      // reading (data must be transmitted back to master)
      // set state
      slave_state = 2;
      slave_tx_buf_pos=0;
      // reset data index
      // fall-through to transmit first data byte
   // 0xB8: data byte has been transmitted, ACK has been received
   case TW_ST_DATA_ACK:            
      // the master has to know how many bytes it should read
      // the last byte must get a nack from the master.
      if (slave_tx_buf_pos < MAX_BUF_LEN && slave_tx_buf[slave_tx_buf_pos]){
         // we have data, transmit data byte
         outp(slave_tx_buf[slave_tx_buf_pos],TWDR);
         slave_tx_buf_pos++;
         // expect ACK to data byte
         outp((inp(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA),TWCR);
      }else{
         outp(0,TWDR);
         // expect NACK to data byte
         outp((inp(TWCR)&TWCR_CMD_MASK)|BV(TWINT),TWCR);
         slave_tx_buf_pos=0;
         slave_state = 0;
      }
      break;
   // 0xC0: data byte has been transmitted, NACK has been received
   case TW_ST_DATA_NACK:
   // 0xC8: Last data byte in TWDR has been transmitted (TWEA =  0 ); ACK has been received
   case TW_ST_LAST_DATA:
      // all done
      // switch to open slave
      outp((inp(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA),TWCR);
      slave_tx_buf_pos=0;
      // set state
      slave_state = 0;
      break;

   // ---- Misc

   // Status 0xF8 indicates that no relevant information is available
   // because the TWINT Flag is not set. This occurs between other
   // states, and when the TWI is not involved in a serial transfer.
   case TW_NO_INFO:
      // do nothing
      break;
   // Status 0x00 indicates that a bus error has occurred during a
   // Two-wire Serial Bus trans-fer. A bus error occurs when a START
   // or STOP condition occurs at an illegal position in the format
   // frame. Examples of such illegal positions are during the serial
   // transfer of an address byte, a data byte, or an acknowledge
   // bit. When a bus error occurs, TWINT is set. To recover from a
   // bus error, the TWSTO Flag must set and TWINT must be cleared
   // by writing a logic one to it. This causes the TWI to enter the
   // not addressed Slave mode and to clear the TWSTO Flag (no other
   // bits in TWCR are affected). The SDA and SCL lines are released,
   // and no STOP condition is transmitted.
   case TW_BUS_ERROR:
      // reset internal hardware by falling to the default case
   default:
      // we should actually only come here if we forgott
      // something in the above list. That should normally
      // not be the case. Still we just act 
      //
      // reset internal hardware 
      outp((BV(TWINT)|BV(TWEA)|BV(TWEN)|BV(TWIE)),TWCR);
      // set state
      slave_rec_buf_pos=0;
      slave_tx_buf_pos=0;
      slave_state = 0;
      break;
   }
}



int main(void)

{
    
   char sensor_data,rec_data;
   unsigned char i;
   DDRD=0xff;
		DDRA=0x00;
		PORTD = 0x00;
     
   // I2C, also called TWI, init
   i2c_init(0x10,0x00); // 0x10 is the slave adr for ATmega8 microcontroller, and 0x00 is the general call adr
   
   sei(); //enable interrupt
   
//Demo test, sending 0x78 via I2C 
while(1)      
 {
   
   
   i= PINA;
   sensor_data=i;
  
   i2c_send_data(&sensor_data);   
    PORTD=sensor_data;
 	}

}


and the header file compat.h


#ifndef AVR_COMPAT_H
#define AVR_COMPAT_H


#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif

#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

#ifndef inb
#define inb(sfr) _SFR_BYTE(sfr) 
#endif

#ifndef outb
#define outb(sfr, val) (_SFR_BYTE(sfr) = (val))
#endif

#ifndef inw
#define inw(sfr) _SFR_WORD(sfr)
#endif

#ifndef outw
#define outw(sfr, val) ( _SFR_WORD(sfr) = (val)) 
#endif

#ifndef outp
#define outp(val, sfr) outb(sfr, val) 
#endif

#ifndef inp
#define inp(sfr) inb(sfr) 
#endif

#ifndef BV
#define BV(bit) _BV(bit)
#endif


#endif //AVR_COMPAT_H

hope u i get som help this time.. n u might b able to help me