ISD4003 SPI problem

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

hello,

now i am having some problems with SPI communication with ISD4003 kit. I am using ATMEGA16A (5.0V for its power supply) as SPI master and ISD4003 (3.3V for its power supply)as SPI slave.

Btw, i have made some routines that will play and stop the ISD, including the initialization for its SPI communication but seems like it doesn't really want to work because the ISD gives no response to the mcu.

I have investigate its wiring several times but i think the device has no problems with that...i have also checked (and modified) the routine code several times and followed ISD4003 datasheet very well but that still doesn't solve the problem....do you know how to solve this problem?

here is the attachmet containing routines that i will use to control the ISD4003 kit :

Attachment(s): 

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

Have you investigated the data stream on the communication pins with a scope? Are your power supply grounds connected and have you verified voltages on the ISD pins? Loose wires on breadboard that look like they are connected but really are not for example.

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

metron9 wrote:
Have you investigated the data stream on the communication pins with a scope? Are your power supply grounds connected and have you verified voltages on the ISD pins? Loose wires on breadboard that look like they are connected but really are not for example.

i don't have an oscilloscope but i have ensured it several times that the cable is connected well (and its path as well) so i think the cable is not the problem for this case....i also have verified the voltage on ISD and there's nothing wrong with that...btw i don't use breadboard for this project but i use actual PCB board for both controller and the ISD instead...

so my suspicion finally goes to the routine that i have uploaded here...perhaps there are some mistake on the code that i don't notice....can you help me out with that? or do anyone here have some experience about using ISD4003?

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

I've used 2 different ISD chips, but not your model. WHY are you running the chips at different Vcc's ? Post a schematic. For such SMALL file sizes, just post them on your thread, downloading strangers files makes some people nervous. In your next reply just post the code and use the code tag button.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

indianajones11 wrote:
I've used 2 different ISD chips, but not your model. WHY are you running the chips at different Vcc's ? Post a schematic. For such SMALL file sizes, just post them on your thread, downloading strangers files makes some people nervous. In your next reply just post the code and use the code tag button.

btw, about the voltage source, i use the same source to power them up, and for regulating the voltage source i use 5v regulator for my atmega16A and 3.3v regulator for my ISD chip.

btw, here is the code :

//*****************************************************************************
//
// File Name	: 'isd400x.c'
// Title		: isd400x function / routine
// Author		: e0ne199
// Version		: 1.1
// Target MCU	: ATMega16
//
//*****************************************************************************

#include "isd400x.h"
#include 
#include 
#include 
#include 



void isdinit()
{
	
	isdddr		|= _BV(mosi)|_BV(sck)|_BV(ss);
	isdport		|= _BV(ss);
	intisd_port |= _BV(intisd);
	SPCR		|= (0<<SPIE)|(1<<DORD)|(1<<MSTR)|(1<<CPOL)|(0<<CPHA)|(0<<SPI2X)|(0<<SPR1)|(1<<SPR0); //691kHz, LSB first
	
	// some configuration for INT1 :)
	cbi(intisd_ddr, intisd_pin);
	sbi(intisd_port, intisd_pin);
	cbi(MCUCR, ISC10);
	cbi(MCUCR, ISC11);
	sbi(GICR, INT1);
	
}

void on_isp()
{
	isdport &=~_BV(ss);
	SPCR  	|=_BV(SPE);
	_delay_ms(50);
}

void off_isp()
{
	_delay_ms(50);
	isdport |=_BV(ss);
	SPCR  	&=~_BV(SPE);
}

void power_up_command()
{
	on_isp();
	SPDR	= 0x00;
	wait_transmit_spi();
	SPDR 	= power_up;
	wait_transmit_spi();
	off_isp();
}

void set_intplay_command()
{
	on_isp();
	SPDR	= isd_lower_address;
	wait_transmit_spi();
	//for isd 4003 and isd4002
	temp    = isd_higher_address | set_play; 
	SPDR 	= temp;
	//for isd4004
	//SPDR	= isd_higher_address;
	//wait_transmit_spi();
	//SPDR	= set_play;
	//--------------------
	wait_transmit_spi();
	off_isp();
}

void set_play_command()
{
	on_isp();
	SPDR	= 0x00;
	wait_transmit_spi();
	//for isd 4003 and isd4002
	SPDR 	= play;
	//for isd 4004
	//SPDR	= isd_higher_address;
	//wait_transmit_spi();
	//SPDR	= play;
	//----------------------
	wait_transmit_spi();
	off_isp();	
}

void powerup_mode()
{
	power_up_command();
	_delay_ms(50);
}

void play_mode()
{   
	powerup_mode();
	set_intplay_command();
	set_play_command();
}

void stop_command()
{
	on_isp();
	SPDR	= 0x00;
	wait_transmit_spi();
	SPDR	= stop;
	wait_transmit_spi();
	off_isp();
}

void wait_transmit_spi()
{
	while(!(SPSR & (1<<SPIF)));
	
}

void check_eom_play()
{
	ledport	|=_BV(led);
	loop_until_bit_is_clear(intisd_pin,intisd);
	_delay_ms(50);
	loop_until_bit_is_clear(intisd_pin,intisd);
	ledport &=~_BV(led);
}

and the header :

//*****************************************************************************
//
// File Name	: 'isd400x.h'
// Title		: isd400x interface I/O
// Version		: 1.2
// Target MCU	: ATMega16A
//
//*****************************************************************************

#include 
#include 


#define intisd		3
#define intisd_port PORTD
#define intisd_pin  PIND
#define intisd_ddr  DDRD


#define mosi		5
#define sck			7
#define ss			4
#define isdport		PORTB
#define isdpin		PINB
#define isdddr		DDRB

#define led			5
#define ledport		PORTD
#define	ledpin		PIND
#define	ledddr		DDRD
//===========================================
// d15 --> C4 = Run , 1 --> run, 0 --> stop
// d14 --> C3 = Play/record , 1--> play, 0 --> record
// d13 --> C2 = Power UP, 1 --> Pwr UP, 0 --> Pwr Down
// d12 --> C1 = IAB (ignore address bit), 1 --> ignore, 0--> use A0-A10
// d11 --> C0 = Message Cueing, 1 --> enable, 0 --> disable
// d10-d0 --> A10-A0 = address
//Command power UP, reader after TPud
#define power_up 		0b00100000
//playback from address
#define set_play 		0b11100000
//playback from current address(until EOM/OVF)
#define play			0b11110000
//initial MC from address
#define set_mc			0b11101000
//perform MC
#define mc				0b11111000
//stop operation
#define stop 			0b00110000
//stop operation and going to power down
#define stop_powerdown	0b00010000
//read interrupt status bit
#define rint			0b00110000	

volatile uint8_t isd_lower_address,isd_higher_address;
volatile uint8_t temp;

//lower address = A7-A0
//higher address = A11-A8


void isdinit(void);
void on_isp(void);
void off_isp(void);
void power_up_command(void);
void set_intplay_command(void);
void set_play_command(void);
void powerup_mode(void);
void play_mode(void);
void stop_command(void);
void wait_transmit_spi(void);
void cek_eom_play(void);

and you can see the schematic on my attachment below.

thx for the help :D

Attachment(s): 

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

I can't open your schematic, and I can't tell what application it's from. Try it as a pdf or some other common format. Or even BETTER, just show it as an openly viewable post ( gif, pdf... ) ...no downloading required is ALWAYS best !

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

indianajones11 wrote:
I can't open your schematic, and I can't tell what application it's from. Try it as a pdf or some other common format. Or even BETTER, just show it as an openly viewable post ( gif, pdf... ) ...no downloading required is ALWAYS best !

honestly i don't know how to make the schematics viewed directly without downloading them first, i am terribly sorry :(

but i can ensure that the file doesn't contain any malicious things or something that can possibly break your system :)

ok, i have converted the schematics become jpg files, you can download it again now :)

again, thx for the help :D

Attachment(s): 

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

Type some text in the comment box.
Then click on "PREVIEW" instead of "SUBMIT".
A new box will pop up.
You can then Browse to the JPG file and Attach it.

Then Submit the post.

The JPG will now be part of your post.

JC

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

1) That ISD can't take 5V, so you'll have problems there. You either have to work out a voltage interface ( resistors between the 2 chips ) or just make the m16 same voltage as ISD ( quickest & easiest thing to do ) . Your reply to my voltage question was no answer as to why you complicate your design running at different voltages...without a GOOD reason .

2)My problem with the file was I couldn't open it, not wouldn't download it. Now I can open it though, so good job.

You're setting INT1 interrupt, but not providing an ISR for it. Comment out any ISR code out for now until it's working w/o any of that.

CPOL has to be 0, NOT '1'. 50 ms delays aren't needed/shown for this ISD, I'd take them out. Why are you enabling/disabling SPE ( But I doubt it will cause problems... ) ?

Show the code as it's used in main(), too ( not just the functions ).
I'll finish checking the code in the meantime.

PS: Your binary #defines are making me cross-eyed trying to count positions, etc... !! Your ISD cmd functions are wrong. You need to pass the 11 bit address into the cmd and then merge address with the control bits for whatever cmd being used and only then send the LSB, then MSB.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

indianajones11 wrote:
1) That ISD can't take 5V, so you'll have problems there. You either have to work out a voltage interface ( resistors between the 2 chips ) or just make the m16 same voltage as ISD ( quickest & easiest thing to do ) . Your reply to my voltage question was no answer as to why you complicate your design running at different voltages...without a GOOD reason .

2)My problem with the file was I couldn't open it, not wouldn't download it. Now I can open it though, so good job.

You're setting INT1 interrupt, but not providing an ISR for it. Comment out any ISR code out for now until it's working w/o any of that.

CPOL has to be 0, NOT '1'. 50 ms delays aren't needed/shown for this ISD, I'd take them out. Why are you enabling/disabling SPE ( But I doubt it will cause problems... ) ?

Show the code as it's used in main(), too ( not just the functions ).
I'll finish checking the code in the meantime.

PS: Your binary #defines are making me cross-eyed trying to count positions, etc... !! Your ISD cmd functions are wrong. You need to pass the 11 bit address into the cmd and then merge address with the control bits for whatever cmd being used and only then send the LSB, then MSB.

i thought i said it before :

Quote:
btw, about the voltage source, i use the same source to power them up, and for regulating the voltage source i use 5v regulator for my atmega16A and 3.3v regulator for my ISD chip.

i use 3.3 volt regulator to power my ISD :)

btw, i read an example code made for PIC mcus that the ISD uses SPI communication mode 2, but i don't know the details about why that mode is used...

about this :

void set_intplay_command()
{
   on_isp();
   SPDR   = isd_lower_address; // <-A7-A0
   wait_transmit_spi();
   //for isd 4003 and isd4002

   //A11-A8 | command
   temp   = isd_higher_address | set_play; 

   SPDR    = temp;
   //for isd4004
   //SPDR   = isd_higher_address;
   //wait_transmit_spi();
   //SPDR   = set_play;
   //--------------------
   wait_transmit_spi();
   off_isp();
}

void set_play_command()
{
   on_isp();
   SPDR   = 0x00;
   wait_transmit_spi();
   //for isd 4003 and isd4002
   SPDR    = play;
   //for isd 4004
   //SPDR   = isd_higher_address;
   //wait_transmit_spi();
   //SPDR   = play;
   //----------------------
   wait_transmit_spi();
   off_isp();   
}

and this :

#define power_up       0b00100000
//playback from address
#define set_play       0b11100000
//playback from current address(until EOM/OVF)
#define play         0b11110000
//initial MC from address
#define set_mc         0b11101000
//perform MC
#define mc            0b11111000
//stop operation
#define stop          0b00110000
//stop operation and going to power down
#define stop_powerdown   0b00010000
//read interrupt status bit
#define rint         0b00110000   
 

do you have a better way to make those code work?

here is the main code, i hope this will help :)

/*
 * NONGGEZ.c
 *
 * Created : 5/26/2012 6:33:19 PM
 * Author  : e0ne199
 * purpose : -
 */ 


#include 

#include "global.h"
#include 
#include "lcd.h"
#include 
#include "isd400x.h"
#include 
#include "rprintf.h"
#include "encoder.h"



int tmp, temp_;
u08 a=0;


inline void init()
{
	lcdInitHW();
	isdinit();
	encoderInit();
}

void voice_play(volatile uint8_t _low, volatile uint8_t _high)
{   
	isd_lower_address=_low;
	isd_higher_address=_high;
	play_mode();
	cek_eom_play();
	stop_command();
	
}

int main(void)
{
		
		voice_play(5,0);
		
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

indianajones11 wrote:
1) That ISD can't take 5V, so you'll have problems there. You either have to work out a voltage interface ( resistors between the 2 chips ) or just make the m16 same voltage as ISD ( quickest & easiest thing to do ) . Your reply to my voltage question was no answer as to why you complicate your design running at different voltages...without a GOOD reason .

2)My problem with the file was I couldn't open it, not wouldn't download it. Now I can open it though, so good job.

You're setting INT1 interrupt, but not providing an ISR for it. Comment out any ISR code out for now until it's working w/o any of that.

CPOL has to be 0, NOT '1'. 50 ms delays aren't needed/shown for this ISD, I'd take them out. Why are you enabling/disabling SPE ( But I doubt it will cause problems... ) ?

Show the code as it's used in main(), too ( not just the functions ).
I'll finish checking the code in the meantime.

PS: Your binary #defines are making me cross-eyed trying to count positions, etc... !! Your ISD cmd functions are wrong. You need to pass the 11 bit address into the cmd and then merge address with the control bits for whatever cmd being used and only then send the LSB, then MSB.

i thought i said it before :

Quote:
btw, about the voltage source, i use the same source to power them up, and for regulating the voltage source i use 5v regulator for my atmega16A and 3.3v regulator for my ISD chip.

i use 3.3 volt regulator to make my ISD work :)

btw, i read an example code made for PIC mcus that the ISD uses SPI communication mode 2, but i don't know the details about why that mode is used...

about this :

void set_intplay_command()
{
   on_isp();
   SPDR   = isd_lower_address; // <-A7-A0
   wait_transmit_spi();
   //for isd 4003 and isd4002

   //A11-A8 | command
   temp   = isd_higher_address | set_play; 

   SPDR    = temp;
   //for isd4004
   //SPDR   = isd_higher_address;
   //wait_transmit_spi();
   //SPDR   = set_play;
   //--------------------
   wait_transmit_spi();
   off_isp();
}

void set_play_command()
{
   on_isp();
   SPDR   = 0x00;
   wait_transmit_spi();
   //for isd 4003 and isd4002
   SPDR    = play;
   //for isd 4004
   //SPDR   = isd_higher_address;
   //wait_transmit_spi();
   //SPDR   = play;
   //----------------------
   wait_transmit_spi();
   off_isp();   
}

and this :

#define power_up       0b00100000
//playback from address
#define set_play       0b11100000
//playback from current address(until EOM/OVF)
#define play         0b11110000
//initial MC from address
#define set_mc         0b11101000
//perform MC
#define mc            0b11111000
//stop operation
#define stop          0b00110000
//stop operation and going to power down
#define stop_powerdown   0b00010000
//read interrupt status bit
#define rint         0b00110000   
 

do you have a better way to make those codes work?

here is the main code, i hope this will help :)

/*
 * NONGGEZ.c
 *
 * Created : 5/26/2012 6:33:19 PM
 * Author  : e0ne199
 * purpose : -
 */ 


#include 

#include "global.h"
#include 
#include "lcd.h"
#include 
#include "isd400x.h"
#include 
#include "rprintf.h"
#include "encoder.h"



int tmp, temp_;
u08 a=0;


inline void init()
{
	lcdInitHW();
	isdinit();
	encoderInit();
}

void voice_play(volatile uint8_t _low, volatile uint8_t _high)
{   
	isd_lower_address=_low;
	isd_higher_address=_high;
	play_mode();
	cek_eom_play();
	stop_command();
	
}

int main(void)
{
		
		voice_play(5,0);
		
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OP wrote:
i thought i said it before :

Quote:
btw, about the voltage source, i use the same source to power them up, and for regulating the voltage source i use 5v regulator for my atmega16A and 3.3v regulator for my ISD chip.

YOU are the one who doesn't get it. The ISD can ONLY TAKE 3.3V max and the MCU is sending 5V on SPI pins ( Good way to damage it over time ) ...!
Quote:
do you have a better way to make those codes work?
It has 2 "play" cmds and only 1 of them needs to send an address, so I was wrong about that and the way you do it is ok. You should still be passing the address to whatever functions need it, though because that's where such info "belongs" in the code.

You're doing too much with voice_play, calling too many other functions, ESPECIALLY when the code needs to be debugged. You should only have functions that logically go in there. The others can be called just before voice_play.

I can't tell if ANA- pin goes to ground or not. Is the mic input single or differential ? Double check and make sure the record input circuit's right.

Quote:
btw, i read an example code made for PIC mcus that the ISD uses SPI communication mode 2, but i don't know the details about why that mode is used...

Other ISDs may be mode 2, but not this one ! When the SS pin goes low, I'd think the SPI is expecting the unit to be enabled already...you should enable it in the init() for now just in case. I'm not sure about the way you do that .

To debug you should send powerup cmd, and use SET_REC cmd and read back A0-A10 bits to verify that SPI between the chips is working...nothing else until that test passes. It should be good after that.

You can't end MCU main() like that...it doesn't have an OS to return to. Put a

while(1);

as your last line.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

Last Edited: Sun. Jul 22, 2012 - 11:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
YOU are the one who doesn't get it. The ISD can ONLY TAKE 3.3V max and the MCU is sending 5V on SPI pins ( Good way to damage it over time ) ...!

i'm sorry i didn't get what you meant before..

hmmm i have never think if voltage difference between those two can make the SPI communication fail to work...ok i will try to use ATMega16L instead..thx for the advice :)

Quote:
I can't tell if ANA- pin goes to ground or not. Is the mic input single or differential ? Double check and make sure the record input circuit's right.

the ISD that i'm using now is actually a module from a manufacturer so i believe that the circuit is working well, but i will check it :)

Quote:
To debug you should send powerup cmd, and use SET_REC cmd and read back A0-A10 bits to verify that SPI between the chips is working...nothing else until that test passes. It should be good after that.

do you mean record it and play it back ?
ok i will try this too :)

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

Quote:
do you mean record it and play it back ?
I meant get the 2 bytes from MISO, and confirm that the 11 addr. bits are the same as what you sent when doing SET_REC cmd. Then you'd know that the SPI is correct between the chips.

Ok, having a commercial module helps alot ! How are you connecting the mic, single or diff. ?

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

Quote:
I meant get the 2 bytes from MISO, and confirm that the 11 addr. bits are the same as what you sent when doing SET_REC cmd. Then you'd know that the SPI is correct between the chips.

do i just use usual SPI receive from micro to read those bytes after sending the command?

Quote:
Ok, having a commercial module helps alot ! How are you connecting the mic, single or diff. ?

i think i use single instead of diff one :)

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

On the pin voltages:

I think the communication pins are rated at 5VDC as I remember reading the datasheet. The output pins you read from the device are the only other pins connected so as long as your micro pins are set to input that is not a problem although you are close to the 2.5VDC threshold when the device is high at 3.3VDC baring any voltage drops that should be fine as well.

There was something about resistors as well to drop the current if 5VDC was used, perhaps read the datasheet again on voltages as that was my first thought as well.

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

metron9 wrote:
On the pin voltages:

I think the communication pins are rated at 5VDC as I remember reading the datasheet. The output pins you read from the device are the only other pins connected so as long as your micro pins are set to input that is not a problem although you are close to the 2.5VDC threshold when the device is high at 3.3VDC baring any voltage drops that should be fine as well.

There was something about resistors as well to drop the current if 5VDC was used, perhaps read the datasheet again on voltages as that was my first thought as well.

yup that's right :)

however the device is still failed to start, i don't know what to do anymore since i have followed every instruction here :(

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

Quote:
do i just use usual SPI receive from micro to read those bytes after sending the command?
To read SPI, after you send each byte and wait for it to end in while loop, then just do :

...after first SPI while()
temp1 = SPDR; // temp1 is uint8_t global var. to get LSB MISO.

...after second while()
temp2 = SPDR; // Same for MSB MISO.

That's the idea, but you'll have to do some shift/masking tricks to get A0 - A10 bits.

Post your current code. You have to give DETAILS about what doesn't now work in the code. Is the MCU now running at 3V, then won't have to worry about such things ? Vihigh for 5V AVRs is usually 0.6*Vcc = 3V...why complicate your life doing things close to the edge when it's not needed ?!

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

indianajones11 wrote:
Quote:
do i just use usual SPI receive from micro to read those bytes after sending the command?
To read SPI, after you send each byte and wait for it to end in while loop, then just do :

...after first SPI while()
temp1 = SPDR; // temp1 is uint8_t global var. to get LSB MISO.

...after second while()
temp2 = SPDR; // Same for MSB MISO.

That's the idea, but you'll have to do some shift/masking tricks to get A0 - A10 bits.

Post your current code. You have to give DETAILS about what doesn't now work in the code. Is the MCU now running at 3V, then won't have to worry about such things ? Vihigh for 5V AVRs is usually 0.6*Vcc = 3V...why complicate your life doing things close to the edge when it's not needed ?!

here are my current codes :

//*****************************************************************************
//
// File Name	: 'isd400x.c'
// Title		: isd400x function / routine
// Author		: e0ne199
// Version		: 1.1
// Target MCU	: ATMega16
//
//*****************************************************************************

#include "isd400x.h"
#include 
#include 
#include 
#include 


void isdinit()
{
	
	isdddr		|= _BV(mosi)|_BV(sck)|_BV(ss);
	isdport		|= _BV(ss);
	intisd_port |= _BV(intisd);
	SPCR		|= (1<<DORD)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(0<<SPI2X)|(0<<SPR1)|(1<<SPR0); //691kHz, LSB first

}

void on_isp()
{
	isdport &=~_BV(ss);
	SPCR  	|=_BV(SPE);
	_delay_ms(50);
}

void off_isp()
{
	_delay_ms(50);
	isdport |=_BV(ss);
	SPCR  	&=~_BV(SPE);
}

void power_up_command()
{
	on_isp();
	SPDR	= 0x00;
	wait_transmit_spi();
	SPDR 	= power_up;
	wait_transmit_spi();
	off_isp();
}

void set_intplay_command()
{
	on_isp();
	SPDR	= isd_lower_address;
	wait_transmit_spi();
	//for isd 4003 and isd4002
	temp    = isd_higher_address | set_play; 
	SPDR 	= temp;
	//for isd4004
	//SPDR	= isd_higher_address;
	//wait_transmit_spi();
	//SPDR	= set_play;
	//--------------------
	wait_transmit_spi();
	off_isp();
}

void set_play_command()
{
	on_isp();
	SPDR	= 0x00;
	wait_transmit_spi();
	//for isd 4003 and isd4002
	SPDR 	= play;
	//for isd 4004
	//SPDR	= isd_higher_address;
	//wait_transmit_spi();
	//SPDR	= play;
	//----------------------
	wait_transmit_spi();
	off_isp();	
}

void powerup_mode()
{
	power_up_command();
	_delay_ms(50);
}

void play_mode()
{   
	powerup_mode();
	set_intplay_command();
	set_play_command();
}

void stop_command()
{
	on_isp();
	SPDR	= 0x00;
	wait_transmit_spi();
	SPDR	= stop;
	wait_transmit_spi();
	off_isp();
}

void wait_transmit_spi()
{
	while(!(SPSR & (1<<SPIF)));
	
}

void cek_eom_play()
{
	
	//loop_until_bit_is_clear(GIFR,INTF1);
	//_delay_ms(50);
	//loop_until_bit_is_clear(GIFR,INTF1);
	
}

//*****************************************************************************
//
// File Name	: 'isd400x.h'
// Title		: isd400x interface I/O
// Version		: 1.2
// Target MCU	: ATMega16A
//
//*****************************************************************************

#include 
#include 






#define intisd		3
#define intisd_port PORTD
#define intisd_pin  PIND
#define intisd_ddr  DDRD


#define mosi		5
#define sck			7
#define ss			4
#define isdport		PORTB
#define isdpin		PINB
#define isdddr		DDRB

#define led			5
#define ledport		PORTD
#define	ledpin		PIND
#define	ledddr		DDRD
//===========================================
// d15 --> C4 = Run , 1 --> run, 0 --> stop
// d14 --> C3 = Play/record , 1--> play, 0 --> record
// d13 --> C2 = Power UP, 1 --> Pwr UP, 0 --> Pwr Down
// d12 --> C1 = IAB (ignore address bit), 1 --> ignore, 0--> use A0-A10
// d11 --> C0 = Message Cueing, 1 --> enable, 0 --> disable
// d10-d0 --> A10-A0 = address
//Command power UP, reader after TPud
#define power_up 		0b00100000
//playback from address
#define set_play 		0b11100000
//playback from current address(until EOM/OVF)
#define play			0b11110000
//initial MC from address
#define set_mc			0b11101000
//perform MC
#define mc				0b11111000
//stop operation
#define stop 			0b00110000
//stop operation and going to power down
#define stop_powerdown	0b00010000
//read interrupt status bit
#define rint			0b00110000	

volatile uint8_t isd_lower_address,isd_higher_address;
volatile uint8_t temp;

//lower address = A7-A0
//higher address = A11-A8


void isdinit(void);
void on_isp(void);
void off_isp(void);
void power_up_command(void);
void set_intplay_command(void);
void set_play_command(void);
void powerup_mode(void);
void play_mode(void);
void stop_command(void);
void wait_transmit_spi(void);
void cek_eom_play(void);

/*
 * NONGGEZ.c
 *
 * Created : 5/26/2012 6:33:19 PM
 * Author  : e0ne199
 * purpose : -
 */ 


#include 

#include "global.h"
#include 
#include "lcd.h"
#include 
#include "isd400x.h"
#include 
#include "rprintf.h"
#include "encoder.h"





inline void init()
{
	isdinit();
	
}

void voice_play(volatile uint8_t _low, volatile uint8_t _high)
{   
	isd_lower_address=_low;
	isd_higher_address=_high;
	play_mode();
	cek_eom_play();
	stop_command();
	
}

int main(void)
{
		init();
		
		voice_play(5,0);
		
		while(1);
			
}

after reading ISD4003 datasheet, i see that the device (its SPI pin) is still able to receive SPI communication from microcontrollers that use 5V as their power supply...

...or is the way to initialize the SPI communcation correct?

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

Quote:
...or is the way to initialize the SPI communcation correct?
Like I said, people do SPE bit in the spi_init(), when working the /SS pin it doesn't need the 50 ms delay...so take it out. You use both play cmds in your play(), and I doubt that's ok, you should use one or the other. It might as well be the set_play, for now, for the debug step I talked about before.

Make your /SS codes as macros and then won't have to worry about function call overhead.

  #define   SS_CLR   isdport &= ~_BV(ss) // Do same for SS_SET.

// Spi writes look like this:

  uint8_t   spi_write( uint8_t  data ){

    SPDR = data;
    while( !( SPSR & ( 1<< SPIF )) ); 

    return SPDR; // return MISO value ONLY if function used in an assignment statement.

}


// spi read():

  #define   SPI_RD()      spi_write( 0xFF ) // This is a dummy value just for reading from an spi device.


  main(){

// This just shows a GENERAL example for using it.

  SS_CLR;
  spi_write( byte1 ); // Using a SET_XXXX cmd.

  temp1 = SPI_RD(); // Get returned addr. bits...
  spi_write( byte2 );

  temp2 = SPI_RD(); //... in these 2 vars to confirm/debug.
  SS_SET;

Do you have any other SPI chips that are DIP package and low pin count that can be used in a breadboard ? If you do, list them. The problem seems to be either your SPI code, ISD cmd sequences and/or hardware wiring between the 2 chips.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

ALso, you do a play function without record step and that makes no sense. :wink: Replace that by record and then do the MISO debug step I gave you. Once you KNOW the comms works, continue to trying play code.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1