PDA

View Full Version : Winbond ISD1700 Voice Recorder



RFEFX
- 12th August 2008, 03:28
Ok, I am trying to figure out this very simple procedure. I have a 16F876A interfaced via SPI to ISD17120 voice recorder chip. just to make this simple and get an idea i want to record 5 one second messages to the device. then I want to play those 5 messages randomly. if you look at the design guide follow the SPI command interface and these commands SET_PLAY SET_REC SET_ERASE. I am not fully understanding how to address the individual messages. if someone can give me some kind of clue as what to send to the ISD device that would be great. I have searched the forums please dont send me links to other projects involving different ISD devices unless its the 1700 series and pertains to my exact request.

design guide www.gmdii.com/files/ISD1700_Design_Guide.pdf

RussMartin
- 28th August 2008, 06:23
The simplest way would be to randomize a number to get a value between 1 and 5, then invoke the ISD1700 device's FWD command that number of times. You can't hit a dead end because the memory is circular.

RFEFX
- 26th January 2009, 00:23
Good lord... does anyone have any code to use SPI with the ISD1700 Series Devices. I wasted an entire saturday trial and erroring this thing.

Just please give me a simple command set to record a message and then play it back..

ANYONE !!!!

rookie11
- 26th January 2009, 03:18
Would second that, just ordered 1 and would be nice to have some sample code to test it out.

mister_e
- 26th January 2009, 22:56
Ship me one, and I'll do it.

ivirscar
- 1st February 2009, 18:55
Gentlemen... I'm almost there, gimme a few days :)

ivirscar
- 1st February 2009, 23:59
Ship me one, and I'll do it.



Me too! ;)


Or... You can try it yourself :D


Most of this code was written for me by Jerson and I reconfigured to "fit my needs". The following will give you an idea on how to make the ISD1700 series jump and also telling them how high to jump AND how loud... :)



SCLK var portc.0
MOSI var portc.1
MISO var portc.2
SS var portc.3

' This array contains data to be sent to the ISD
' and on return it contains data reveived from ISD
ISD_Data var byte[8]
SR0 var ISD_Data[0]
SR1 var ISD_Data[1]

isCmdErr var SR0.0
isINT var SR0.4
isReady var SR1.0

Reg var byte
Cnt var byte
bSPI var byte ' the byte being transferred on SPI

ADCON1 = %00000111 'Sets all A/D conversion to Digital input/output.
TRISA = %111111 ' All A Ports input
TRISC = %00000100 ' MISO is input
TRISB = %00000000
SS = 1
SCLK = 1
MOSI = 0



' Initialize the ISD
' ------------------------------------------------------------------------------------
gosub PowerUp
pause 10
gosub WR_APC2 ' In my application, this sets the volume and config bits.
'You can use it as well if you desire.
pause 10
gosub ClrInt

'This is the Set_Play command
SetPlay:
isCmdErr = 1
while isCmdErr
ss = 0
bSPI = $80
gosub SPI
ISD_Data[0]=bSPI

bSPI = $00
gosub SPI
ISD_Data[1]=bSPI

bSPI = $10 ' Start Address low byte. (First packet of memory after effects)(Use your begin low address here)
gosub SPI
ISD_Data[2]=bSPI

bSPI = $00 ' Start Address high byte (Use your begin high address here)
gosub SPI
ISD_Data[3]=bSPI

bSPI = $00 ' end address low byte (Use your end address here)
gosub SPI
ISD_Data[4]=bSPI

bSPI = $00 ' end address mid byte(Use your end address here)
gosub SPI
ISD_Data[5]=bSPI

bSPI = $00 ' end address high byte / Note end address is 24 bits long. (Use your end address here)
gosub SPI
ISD_Data[6]=bSPI

bSPI = $00
gosub SPI
ISD_Data[7]=bSPI
ss = 1
wend
return

PowerUp:
isCmdErr = 1
while isCmdErr
SS=0
bSPI=$01
gosub SPI
ISD_Data[0] = bSPI
bSPI=$00
gosub SPI
ISD_Data[1] = bSPI
SS=1
wend
return


'This is the command I use to set the volume as stated above. I have the factory defaults tagged in brackets for reference...

WR_APC2:
isCmdErr = 1
while isCmdErr
ss = 0
bSPI = $65
gosub SPI
ISD_Data[0]=bSPI

bSPI = %01000011
gosub SPI
ISD_Data[1]=bSPI 'Factory default
'high byte 'low byte
bSPI = %00000100 '(0100) (01000000)
gosub SPI
ISD_Data[2]=bSPI
ss=1
wend
return

' transact a byte with SPI interface
' You should come here after setting SS=0 for this to work
SPI:
for Cnt=0 to 7
MOSI=bSPI.0 ' shift MOSI from LSB

SCLK = 0 ' clock the MOSI data
if MISO then ' read the MOSI data
@ bsf status,c
else
@ bcf status,c
endif
@ rrf _bSPI ' shift MISO into MSB
SCLK = 1

next
return


' clear Interrupt and EOM bits
ClrInt:
isCmdErr = 1
while isCmdErr
SS=0
bSPI=$04
gosub SPI
ISD_Data[0] = bSPI
bSPI=$00
gosub SPI
ISD_Data[1] = bSPI
SS=1
wend
return

' read status of Chip
ReadStatus:
SS=0
bSPI=$05
gosub SPI
ISD_Data[0]=bSPI
bSPI=$00
gosub SPI
ISD_Data[1] = bSPI
bSPI=$00
gosub SPI
ISD_Data[2] = bSPI
SS=1
return


Brenon

milestag
- 4th February 2009, 15:46
I haven't tested the code yet (but thanks VERY much for posting it!!).

But I noticed one thing...

You have SR0 and SR1 as the first 2 bytes returned. The datasheet shows that the first TWO bytes returned are SR0 for every SPI command (as SR0 is 2 bytes long). So SR1 should actually be the THIRD byte returned?

SR0 var ISD_Data[0]
SR0b var ISD_Data[1] 'or whatever you want to name it
SR1 var ISD_Data[2]

Or am I missing something? I don't think this would cause a problem in your examples as you are not checking the isReady bit.

ivirscar
- 4th February 2009, 16:38
Good point... Your right, I'm not checking the ready bit, I'm simply playing a sound file at a given time (on a scanning light) and if the time approaches again before it finishes playing, the chip automatically "ignores" the next command sent UNTIL it is ready for a new command (on the next return of the light...)

But for future reference and expandability of my product, I will experiment a little on the SR0 / SR1 and correct so my code can see a ready bit in the future...


Thanks for pointing that out!


Brenon

Jerson
- 4th February 2009, 16:53
I haven't tested the code yet (but thanks VERY much for posting it!!).

But I noticed one thing...

You have SR0 and SR1 as the first 2 bytes returned. The datasheet shows that the first TWO bytes returned are SR0 for every SPI command (as SR0 is 2 bytes long). So SR1 should actually be the THIRD byte returned?

SR0 var ISD_Data[0]
SR0b var ISD_Data[1] 'or whatever you want to name it
SR1 var ISD_Data[2]

Or am I missing something?

No you are not. My mistake :D

Unfortunately I do not have the hardware to have noticed it and so I missed that.

milestag
- 5th February 2009, 21:03
I'm working on a modified version of the code, and hope to test it this weekend. I'll be driving the ISD1700 with a PIC16F684 and will post the final (working) code here. So far I am just checking all the commands against the datasheets.

I do have a couple observations.

The SetPlay command should only send SEVEN bytes. The END address is contained within TWO bytes (12 bits). That THIRD address byte (last byte sent) should be set to "0x00" as it is not supported in existing hardware. Same case for SetRecord.

I finally figured out your use of "While CmdError." Had me stumped for a while, then it clicked. That's pretty clever. Though it looks like in some cases it will be better to check the "RDY" status (depending on which command you are sending).

Also I did not realize that you can shift data into a byte using "status, c" carry bit in assembly. That is a very cool trick, indeed! Pretty much all of the other SPI examples I've found for PicBasic just used the Shiftout command which does not allow reading the Status bits.

For anyone interested, the original ISD1700 development kit made by Windbond (which cost me $270 from Digikey last year) does NOT support batch recording of sounds. You have to set the Start and End address manually and record one sound at a time. Very tedious and not usable other than basic function tests. However... there is a NEW ISD1700 development kit made by Nuvoton and it DOES support batch programming of wav files. So it can function as a decent production programmer. Unfortunately it's going to cost me another $270 - ouch. I called tech support at Nuvoton and they confirmed the new software is NOT compatible with the original Winbond development hardware.

You should also be aware that the Quadravox QV400D programmer never added support for the ISD1700 series. I still use it for programming ISD2560 chips, but they are starting to get expensive and much harder to find.

mister_e
- 5th February 2009, 21:33
:eek: so someone would have to make himself friend with Winbond and suggest them an universal Gang device programmer :D

Not sure this worth it, look at current storage device pricing and add a higher level Microcontroller to it... NO way you're going to be over the Price of any single Winbond IC... not to mention you can update any part of your firmware and sound using a simple bootloading process.

Roman Black sounds almost the same as most Winbond solution and it's free, MP3 codec ICs are cheap, DsPIC are also cheaper... food for thought.

Normnet
- 5th February 2009, 23:47
Not sure this worth it, look at current storage device pricing and add a higher level Microcontroller to it... NO way you're going to be over the Price of any single Winbond IC... not to mention you can update any part of your firmware and sound using a simple bootloading process.

Requires porting of basic code but take a look at PIC iPod wav player. (http://www.picbasic.org/forum/showthread.php?t=10662)

Mono CD quality (16bit 44k) for the price of an SD card and holder,
a PIC18F4520, a few resistors for an R2 ladder, an audio amp and a speaker.

Or stereo 8bit 44k if preferred.
Up to 2 Gig's or 512 wav files.


Norm

milestag
- 6th February 2009, 00:45
:eek: so someone would have to make himself friend with Winbond and suggest them an universal Gang device programmer :D

Yes, Winbond (Nuvoton?) does/did offer a production gang programmer. 12 chips at once I believe. But cost is around $2000

ivirscar
- 7th February 2009, 17:16
Jerson done a FANTASTIC job while not having any hardware to test with!! :) These ISD chips are difficult to work with at a glance anyways...

I done more changing to the code I'm using by adding the 3rd byte to the status register and "singling out" the 2nd bit to check the status of the PLAY mode. With this bit, I can control the amplifier, which sound to play and when and so on...

More than adequate for the application I have :D

milestag
- 8th February 2009, 05:39
This works so far to play back 4 sounds repeatedly. The volume setting via apc2 works also. Next I plan to get rid of the PAUSE delays and monitor status to determine when each sound finished playing.



'DEMO PLAYER FOR ISD1700
'Code Version: 01
'Words Used = 354
'Revision Date: 8 Feb 2009
'PicBasic Pro Compiler version 2.50b
'Processor=PIC16F684 (WDT=ON, MCLR=INPUT, OSC=INTOSC)

'Modified from code posted by Jerson and Brenon

'Memory Reference:
'ISD17XX First Address = 0x010
'ISD1730 Max Address = 0x0FF
'ISD1760 Max Address = 0x1EF
'ISD1790 Max Address = 0x2DF

DEFINE OSC 8
'************************************************* ************
'************************************************* ************
'******************** DEFINE VARIABLES ***********************
'************************************************* ************
'************************************************* ************
temp_bit VAR BIT

temp VAR BYTE
spi_cnt var byte ' counter for SPI transfer
bSPI var byte ' the byte being transferred on SPI

s_addr VAR WORD ' Start Address
e_addr VAR WORD ' End Address

ISD_Data var byte[7] ' This array contains data to/from ISD

SR0a var ISD_Data[0]
SR0b var ISD_Data[1]
SR1 var ISD_Data[2] ' only valid after ReadStatus

isCmdErr var SR0a.0 ' 1=previous command failed/ignored
isFull var SR0a.1 ' 1=memory full
isPU var SR0a.2 ' 1=ISD powered up
isEOM VAR SR0a.3 ' 1=EOM detected (clear by CLR_INT command)
isINT var SR0a.4 ' 1=current operation completed (clear by CLR_INT command)

isReady var SR1.0 ' 1=Ready to receive SPI command (only valid after ReadStatus)
' Some SPI commands can still be sent when isReady=0

'************************************************* ************
'************************************************* ************
'******************** PIN ASSIGNMENTS ************************
'************************************************* ************
'************************************************* ************
Symbol sensor = PORTA.0 '
Symbol miso = PORTA.3 'ISD1760 SPI MISO
Symbol led1 = PORTC.1 '
Symbol led2 = PORTC.2 '
Symbol ss = PORTC.3 'ISD1760 SLAVE SELECT
Symbol sclk = PORTC.4 'ISD1760 SPI CLOCK
Symbol mosi = PORTC.5 'ISD1760 SPI MOSI

'************************************************* ************
'************************************************* ************
'******************** INITIALIZATION *************************
'************************************************* ************
'************************************************* ************
initialize:
CLEAR
OSCCON = %01111000
CMCON0 = 7 'turn off comparators
ANSEL = 0

PR2 = 35 'PWM Period (40K=49, 56K=35) (35 to 55)
CCPR1L = 15 'PWM Duty Cycle (1 to 15)
T2CON = 4 'Timer2 = ON; Prescale = 1:1
CCP1CON = 0 'PWM module off
OPTION_REG = %11111111 'Turn off PortA weak pull-ups

TRISA = %111111 'set PortA directions
WPUA = %000000 'enable weak pull-ups PortA
IOCA = %000000 'disable PORTA.0 Int On Change

TRISC = %000000 'set PortC directions

PORTA = %000000
PORTC = %000000 '

HIGH ss 'start with Slave Select HIGH
HIGH sclk 'start with SPI Clock HIGH
LOW MOSI 'start with MOSI LOW

INPUT sensor
LOW led1
LOW led2


start: 'Initialize the ISD
GoSub isd_pu
PAUSE 50 '50 mS Power Up Delay (per datasheet)
GoSub isd_wr_apc 'set volume and config bits
PAUSE 10
GoSub isd_clr_int 'clear interrupt and EOM
'************************************************* ************
'************************************************* ************
'********************* MAIN PROGRAM **************************
'************************************************* ************
'************************************************* ************
main_loop: '(MAIN PROGRAM LOOP)

PAUSE 2000

s_addr = $010
e_addr = $02b
GOSUB isd_set_play

PAUSE 2500

GOSUB isd_stop

PAUSE 2000

s_addr = $02c
e_addr = $048
GOSUB isd_set_play

PAUSE 2500

GOSUB isd_stop

PAUSE 2000

s_addr = $049
e_addr = $07c
GOSUB isd_set_play

PAUSE 4800

GOSUB isd_stop

PAUSE 2000

s_addr = $07d
e_addr = $093
GOSUB isd_set_play

PAUSE 2000

GOSUB isd_stop

GoTo main_loop


'************************************************* ************
'************************************************* ************
'********************** SUBROUTINES **************************
'************************************************* ************
'************************************************* ************
isd_pu:
LOW ss

bSPI=$01 'Power Up Command
GoSub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI=$00
GoSub isd_spi
ISD_Data[1] = bSPI 'SR0b

HIGH ss

RETURN

'--------------------------------------------------------------------------
isd_wait_ready:
GOSUB isd_rd_status
IF isReady = 0 THEN isd_wait_ready
RETURN

'--------------------------------------------------------------------------
isd_set_play:
LOW ss

bSPI = $80 'Set Play Command (7 bytes)
GoSub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI = $00
GoSub isd_spi
ISD_Data[1] = bSPI 'SR0b

bSPI = s_addr.LowByte ' Start Address low byte.
GoSub isd_spi
ISD_Data[2] = bSPI 'SR0a

bSPI = s_addr.HighByte ' Start Address high byte
GoSub isd_spi
ISD_Data[3] = bSPI 'SR0b

bSPI = e_addr.LowByte ' End Address low byte
GoSub isd_spi
ISD_Data[4] = bSPI 'SR0a

bSPI = e_addr.HighByte ' End Address high byte
GoSub isd_spi
ISD_Data[5] = bSPI 'SR0b

bSPI = $00 ' Reserved Address - set to "0"
GoSub isd_spi
ISD_Data[6] = bSPI 'SR0a

HIGH ss

RETURN

'--------------------------------------------------------------------------
isd_wr_apc: 'Write to APC Register using bits D2:D0 to set Volume
LOW ss

bSPI = $65 'Write APC2
GoSub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI = %01000011 'Volume set by D2:D0 (000=Max)
'Output set by D7 (0=Aud, 1=Aux)
GoSub isd_spi
ISD_Data[1] = bSPI 'SR0b

bSPI = %00000100 'PWM Speaker Output D8 (0=Enable, 1=Disable)

GoSub isd_spi
ISD_Data[2] = bSPI 'SR0a

HIGH ss

RETURN

'--------------------------------------------------------------------------
isd_spi: ' shift SPI data out and into SPI byte
FOR spi_cnt = 0 to 7 '
MOSI = bSPI.0 ' shift LSB of byte onto MOSI line
LOW SCLK ' clock MISO data out to uC (Falling Edge)
temp_bit = miso '
HIGH SCLK ' clock MOSI into ISD1700 (Rising Edge)
bSPI = bSPI >> 1 ' shift SPI byte Right
bSPI.7 = temp_bit
NEXT spi_cnt

RETURN

'--------------------------------------------------------------------------
isd_clr_int: ' CLEAR INTERRUPT AND EOM BITS
LOW SS

bSPI=$04 'Clear Interrupt Command
gosub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI=$00
gosub isd_spi
ISD_Data[1] = bSPI 'SR0b

HIGH SS

RETURN

'--------------------------------------------------------------------------
isd_stop: ' Stop Immediately
LOW ss

bSPI=$02 'Stop Command
gosub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI=$00
gosub isd_spi
ISD_Data[1] = bSPI 'SR0b

HIGH ss

RETURN

'--------------------------------------------------------------------------
isd_pd: ' Stop Immediately
LOW ss

bSPI=$07 'Power Down Command
gosub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI=$00
gosub isd_spi
ISD_Data[1] = bSPI 'SR0b

HIGH ss

RETURN

'--------------------------------------------------------------------------
isd_rd_status: 'read status of ISD1700
LOW ss

bSPI=$05 'Read Status Command
gosub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI=$00
gosub isd_spi
ISD_Data[1] = bSPI 'SR0b

bSPI=$00
gosub isd_spi
ISD_Data[2] = bSPI 'SR1

HIGH ss

RETURN

'************************************************* ************
'************************************************* ************


End

milestag
- 8th February 2009, 19:05
I did some further testing. Seems the best way to determine when a sound has finished playing is to monitor the INT status bit. Just remember to clear the INT before each SET_PLAY.

The PLAY bit will not work as it does not get cleared until you change to another mode (i.e. RECORD).

The READY bit will not tell when the sound is completed playing, rather it tells you that the chip is ready to receive another SPI command (which can happen before the sound is complete when using SETPLAY).

I couldn't find how to edit the previous post, so here are the changed parts:
(obviously your start/end addresses will be different)




mainloop:

PAUSE 1000

s_addr = $049
e_addr = $07c
GOSUB isd_set_play

GOSUB isd_wait_int
GoSub isd_clr_int

PAUSE 1000

s_addr = $07d
e_addr = $093
GOSUB isd_set_play

GOSUB isd_wait_int
GoSub isd_clr_int

GoTo main_loop

'--------------------------------------------------------------------------
isd_wait_int:
GOSUB isd_rd_status
IF isINT = 0 THEN isd_wait_int
RETURN

ivirscar
- 8th February 2009, 19:49
I did some further testing. Seems the best way to determine when a sound has finished playing is to monitor the INT status bit. Just remember to clear the INT before each SET_PLAY...

So monitoring the Int bit - reads 0 when the file is playing and sets to 1 when completed... I have completed the program for this chip in my application! :D : INSERT BOUNCY HERE:


I'd REALLY like to thank Jerson for the initial beginning of this coding and to thank Jim for the clarifications needed to succeedingly write the final piece to operate my products.


Brenon

txniteowl
- 23rd March 2009, 03:22
I'm working on a modified version of the code, and hope to test it this weekend. I'll be driving the ISD1700 with a PIC16F684 and will post the final (working) code here. So far I am just checking all the commands against the datasheets.

I do have a couple observations.

The SetPlay command should only send SEVEN bytes. The END address is contained within TWO bytes (12 bits). That THIRD address byte (last byte sent) should be set to "0x00" as it is not supported in existing hardware. Same case for SetRecord.

I finally figured out your use of "While CmdError." Had me stumped for a while, then it clicked. That's pretty clever. Though it looks like in some cases it will be better to check the "RDY" status (depending on which command you are sending).

Also I did not realize that you can shift data into a byte using "status, c" carry bit in assembly. That is a very cool trick, indeed! Pretty much all of the other SPI examples I've found for PicBasic just used the Shiftout command which does not allow reading the Status bits.

For anyone interested, the original ISD1700 development kit made by Windbond (which cost me $270 from Digikey last year) does NOT support batch recording of sounds. You have to set the Start and End address manually and record one sound at a time. Very tedious and not usable other than basic function tests. However... there is a NEW ISD1700 development kit made by Nuvoton and it DOES support batch programming of wav files. So it can function as a decent production programmer. Unfortunately it's going to cost me another $270 - ouch. I called tech support at Nuvoton and they confirmed the new software is NOT compatible with the original Winbond development hardware.

You should also be aware that the Quadravox QV400D programmer never added support for the ISD1700 series. I still use it for programming ISD2560 chips, but they are starting to get expensive and much harder to find.

--------
I found a Development Board for $70 from Elusions Co.

Dennis

RFEFX
- 16th June 2009, 02:14
Thanks everyone (including Jerson) for the code for these ISD devices. However we only have half of the issue resolved.

According to the code only "set_play" was included. How you gonna play something if it is not recorded?

What i am getting at is... in my original post.....

Show me a simple code to Record 5 messages using set_rec and play any of them back using Set_play... i.e. for the ISD17120

Thanks again.

Ioannis
- 16th June 2009, 08:14
Trying to understand how these devices work, I could not found a way to play e.g. the third message out of 10. How is the messages indexed? I mean if you record 10 messages, how can you know the position of each and how to play them?

Are these devices confussing or am I too dumb to get it? Doh...

Ioannis

RFEFX
- 16th June 2009, 19:26
Are these devices confussing or am I too dumb to get it? Doh...

dude... these are very difficult devices... if you were to take the previous version the 2500 series... they were addressed very easily through and address bus. this SPI interface is a real headache.

my OLED is far simpler to write code for than these chips.

don't worry man this is exactly why i posted this thread.

milestag
- 17th June 2009, 18:59
Hang in there - it's not that bad. It's just that the ISD1700 has a TON of features and options so it's overwhelming to sort out the datasheets and find what you need.

As soon as I am able, I will post some more code examples (PicBasic Pro and Liberty BASIC). I have all the record and playback functions working fine using SetPlay and SetRecord. The PIC firmware (PBPro) translates serial commands from the PC (Liberty BASIC Windows app) and controls the ISD1700 for record, play, erase, etc.

Note: I use DEBUGIN so no UART or level shifter is required for the PC to PIC serial connection.

As far as addressing, for SetRecord and SetPlay you must know the Start and End address of each sound. To make addressing easier, I just divided the ISD memory into predefined "blocks" of 1,2 or 4 seconds. This way I always know the Start address of each sound, and I use the EOM function so I don't need to know the exact length of the sound during playback (it stops automatically when it hits the EOM marker even in SetPlay). So I can replace (re-record) any sound as long as the new sound fits within the block.

Tip: When you are using SetRecord, you must specify the Start and End address. But you can send a STOP command before the End address is reached and the ISD will place an EOM marker at that spot. If you enable the EOM function, playback will stop at the EOM regardless of the End address - even when you use SetPlay!! This is very cool, and it's what allowed me to use the pre-defined memory map without knowing the exact length of the sounds.

It's not the most efficient use of available memory, but it's simple and the software/firmware does not have to calculate length of each wav file and write locations to a table. The table is pre-defined. It works well for my application (Laser Tag) as I just need to trigger a few short sound effects, and my customers want to be able to replace the stock sound effects with their own custom sounds.

Jim

Ioannis
- 17th June 2009, 20:12
Oh boy! Its worst than I thought!

What stupid memory administration these chips have!

I hoped that there was an auto mark method for the start and stop. Well for the stop there is the EOM but what about the 3rd message for example? How can the PIC know where it resides?

Stupid.

Ioannis

milestag
- 17th June 2009, 21:41
If you don't want to use direct addressing, then you can still operate in "pushbutton mode" with fast-forward to each message (same as ISD2560). This can be done with actual 'buttons', microcontroller I/O, or through SPI interface commands simulating tape recorder style operation.

For my application, it is better to use the SPI and 'memory map' scheme. I need the fast response and instant triggering of sounds. But the ISD1700 is VERY flexible so you can still do it the 'old school' way.

I do not have any code for controlling via pushbutton mode, so you would have to read up the datasheets on that. There is some documentation on migrating from ISD2560 to ISD1700 from Winbond (Nuvoton) that should help.

Also they have a tech support email and phone. I used the phone tech support to solve some issues I ran into last year.

There is always a learning curve with a device that has so much flexibility...

Also you may want to check out the Cowlacious website, they have an ISD1700 recorder/player that may be more similar to what you are looking for.

RFEFX
- 18th June 2009, 03:24
Thanks everyone for helping me understand this device and the steps to get it coded. i have been playing with it all day recording messages and playing them back.

Thanks Jerson, Brenon and Jim for simplifying and breaking it down so that i may understand it line by line. my problem i was using the SHIFTOUT commands in PBP and i was not working properly. i now know how much memory space i need for the 20, 1 to 4 second sounds that i will be using.

Cheers to all of you... today is a good day.

- Gary

Jerson
- 18th June 2009, 05:57
Hi Gary

Good to know you have figured it out. You have yourself to thank for the patience and dedication to figure it out.

Regards

Ioannis
- 18th June 2009, 07:44
Thanks Jim for the tips. OK, I will try a bit more without beeing prejudiced.

Gary: If you areallowed can you post the working code?

Thanks,

Ioannis

RFEFX
- 18th June 2009, 23:06
hey Ioannis,
here is my code that I have working. I am using my own RFEFX board which includes an RF. If you have any questions please don't hesitate to ask. after i cleaned up some of Jim's code, as I have a different platform, the lights kinda just went off in my head and it all became real easy. For Video Click Here (http://www.gmdii.com/Projects/ISD17XX.mp4) (9MB File takes a min to load)



'************************************************* ***************
'* Name : ISD17XX.BAS
'* Authors : Jerson,Brenon,Jim,Gary
'************************************************* ***************

define OSC 20

Time1 var word 'these variables used for the Erase flash
Time2 var byte 'LEDS when the device is erased
'used in Label - FlashLED:
time1 = 5000
time2 = 50

'******************** DEFINE VARIABLES ***********************

temp_bit VAR BIT

temp VAR BYTE
spi_cnt var byte ' counter for SPI transfer
bSPI var byte ' the byte being transferred on SPI

s_addr VAR WORD ' Start Address
e_addr VAR WORD ' End Address

ISD_Data var byte[7] ' This array contains data to/from ISD

SR0a var ISD_Data[0]
SR0b var ISD_Data[1]
SR1 var ISD_Data[2] ' only valid after ReadStatus

isCmdErr var SR0a.0 ' 1=previous command failed/ignored
isFull var SR0a.1 ' 1=memory full
isPU var SR0a.2 ' 1=ISD powered up
isEOM VAR SR0a.3 ' 1=EOM detected (clear by CLR_INT command)
isINT var SR0a.4 ' 1=current operation completed (clear by CLR_INT command)

isReady var SR1.0 ' 1=Ready to receive SPI command (only valid after ReadStatus)
' Some SPI commands can still be sent when isReady=0


'******************** PIN ASSIGNMENTS ************************

Symbol miso = PORTC.5 'ISD1760 SPI MISO
Symbol LED1 = PORTA.5 '
Symbol LED2 = PORTA.0 '
Symbol ss = PORTC.7 'ISD1760 SLAVE SELECT
Symbol sclk = PORTC.4 'ISD1760 SPI CLOCK
Symbol mosi = PORTC.6 'ISD1760 SPI MOSI

'******************** INITIALIZATION *************************
initialize:

' Im using a PIC 16F876A with an external 20 MHZ clock
' there is really little setup.


HIGH ss 'start with Slave Select HIGH
HIGH sclk 'start with SPI Clock HIGH
LOW MOSI 'start with MOSI LOW

LOW LED1
LOW led2


start: 'Initialize the ISD
GoSub isd_pu
PAUSE 50 '50 mS Power Up Delay (per datasheet)

'I removed the APC because it doesn't work on my Audio Board

PAUSE 10
GoSub isd_clr_int 'clear interrupt and EOM

gosub erase 'this will erase the ISD chip whenever
'I reprogram my PIC



'********************* MAIN PROGRAM **************************

main_loop: '(MAIN PROGRAM LOOP)

PAUSE 2000

RecordLoop: 'Here is my board waiting for me to
if portc.3 = 1 then Record 'push the record button
goto recordLoop

Record:

high led1 'a record LED

if portc.3 = 1 then record 'it will not continue until i
'release the button

s_addr = $010 'a 1 second clip takes approx 16 rows of
e_addr = $01f 'memory space $010-$01F = 16

GOSUB isd_set_rec 'this Set_rec identical to set_play
'was added so i could record a message


PAUSE 2000

GOSUB isd_stop ' an immediate stop to stop recording

low led1 ' turn record LED off


Playloop: 'the same button then becomes a play button
'pause 2000
if portc.3 = 1 then play
goto playloop

Play:
high led2 'a different LED for play

if portc.3 = 1 then play 'wont play until button is released

s_addr = $010 'playing back from the same 16 rows
e_addr = $01f

GOSUB isd_set_play

PAUSE 2000

GOSUB isd_stop

low led2

Eraseloop:
'pause 2000
if portc.3 = 1 then play 'in this loop you can either play the sound
if portc.5 = 1 then erase 'again or erase it and record another one
goto Eraseloop 'two different buttons are used

Erase: 'this is the erase subroutine which is also
if portc.5 = 1 then erase 'called at the beginning of this program
s_addr = $010 'this is not a Gang erase so the Start and
e_addr = $01f 'End address must be present or you will get
GOSUB isd_set_erase 'a command error

gosub flashLED 'when i erase the chip a series of LEDS
'are flased to indicate an erase.
pause 1000

goto recordloop 'after an erase it goes back to record loop



'********************** SUBROUTINES **************************
isd_pu:
LOW ss

bSPI=$01 'Power Up Command
GoSub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI=$00
GoSub isd_spi
ISD_Data[1] = bSPI 'SR0b

HIGH ss

RETURN

'--------------------------------------------------------------------------
isd_wait_ready:
GOSUB isd_rd_status
IF isReady = 0 THEN isd_wait_ready
RETURN

'--------------------------------------------------------------------------
isd_set_play:
LOW ss

bSPI = $80 'Set Play Command (7 bytes)
GoSub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI = $00
GoSub isd_spi
ISD_Data[1] = bSPI 'SR0b

bSPI = s_addr.LowByte ' Start Address low byte.
GoSub isd_spi
ISD_Data[2] = bSPI 'SR0a

bSPI = s_addr.HighByte ' Start Address high byte
GoSub isd_spi
ISD_Data[3] = bSPI 'SR0b

bSPI = e_addr.LowByte ' End Address low byte
GoSub isd_spi
ISD_Data[4] = bSPI 'SR0a

bSPI = e_addr.HighByte ' End Address high byte
GoSub isd_spi
ISD_Data[5] = bSPI 'SR0b

bSPI = $00 ' Reserved Address - set to "0"
GoSub isd_spi
ISD_Data[6] = bSPI 'SR0a

HIGH ss

RETURN

'--------------------------------------------------------------------------
isd_Set_Erase:
LOW ss

bSPI = $82 'Set Erase Command (7 bytes)
GoSub isd_spi
ISD_Data[0] = bSPI SR0a

bSPI = $00
GoSub isd_spi
ISD_Data[1] = bSPI 'SR0b

bSPI = s_addr.LowByte 'Start Address low byte.
GoSub isd_spi
ISD_Data[2] = bSPI 'SR0a

bSPI = s_addr.HighByte 'Start Address high byte
GoSub isd_spi
ISD_Data[3] = bSPI 'SR0b

bSPI = e_addr.LowByte 'End Address low byte
GoSub isd_spi
ISD_Data[4] = bSPI 'SR0a

bSPI = e_addr.HighByte 'End Address high byte
GoSub isd_spi
ISD_Data[5] = bSPI 'SR0b

bSPI = $00 'Reserved Address - set to "0"
GoSub isd_spi
ISD_Data[6] = bSPI 'SR0a

HIGH ss

RETURN

'--------------------------------------------------------------------------
isd_set_rec:
LOW ss

bSPI = $81 'Set Record Command (7 bytes)
GoSub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI = $00
GoSub isd_spi
ISD_Data[1] = bSPI 'SR0b

bSPI = s_addr.LowByte 'Start Address low byte.
GoSub isd_spi
ISD_Data[2] = bSPI 'SR0a

bSPI = s_addr.HighByte 'Start Address high byte
GoSub isd_spi
ISD_Data[3] = bSPI 'SR0b

bSPI = e_addr.LowByte 'End Address low byte
GoSub isd_spi
ISD_Data[4] = bSPI 'SR0a

bSPI = e_addr.HighByte 'End Address high byte
GoSub isd_spi
ISD_Data[5] = bSPI 'SR0b

bSPI = $00 'Reserved Address - set to "0"
GoSub isd_spi
ISD_Data[6] = bSPI 'SR0a

HIGH ss

RETURN

'--------------------------------------------------------------------------
isd_spi: ' shift SPI data out and into SPI byte
FOR spi_cnt = 0 to 7 '
MOSI = bSPI.0 ' shift LSB of byte onto MOSI line
LOW SCLK ' clock MISO data out to uC (Falling Edge)
temp_bit = miso '
HIGH SCLK ' clock MOSI into ISD1700 (Rising Edge)
bSPI = bSPI >> 1 ' shift SPI byte Right
bSPI.7 = temp_bit
NEXT spi_cnt

RETURN

'--------------------------------------------------------------------------
isd_clr_int: ' CLEAR INTERRUPT AND EOM BITS
LOW SS

bSPI=$04 'Clear Interrupt Command
gosub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI=$00
gosub isd_spi
ISD_Data[1] = bSPI 'SR0b

HIGH SS

RETURN

'--------------------------------------------------------------------------
isd_stop: ' Stop Immediately
LOW ss

bSPI=$02 'Stop Command
gosub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI=$00
gosub isd_spi
ISD_Data[1] = bSPI 'SR0b

HIGH ss

RETURN

'--------------------------------------------------------------------------
isd_rd_status: 'read status of ISD1700
LOW ss '

bSPI=$05 'Read Status Command
gosub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI=$00
gosub isd_spi
ISD_Data[1] = bSPI 'SR0b

bSPI=$00
gosub isd_spi
ISD_Data[2] = bSPI 'SR1

HIGH ss

RETURN

'*********** Erase Indicators ********************************
FlashLED:
pulsout porta.5,time1
pause time2
pulsout porta.3,time1
pause time2
pulsout porta.2,time1
pause time2
pulsout porta.1,time1
pause time2
pulsout porta.0,time1
pause time2
low porta.0
return

End

Ioannis
- 19th June 2009, 06:55
Hi Gary.

Thanks a lot for your sample code.

Nice work with the pcb's too!

Your video was downloaded in less than 9 sec, for the records.

Also your introduction to the site is quite impressive. Waiting to see the rest! Did you do this your own?

Ioannis

RFEFX
- 19th June 2009, 17:34
Hey Ioannis,
Thanks a lot for your feedback. I do understand Flash websites, but in all honesty, it took

me 5 hours modifying that flash intro template to my liking. i couldnt imagine coding the

entire thing from scratch. Although "If there is a will. There is a way."

The website will be based on the same flash template arcitecture and i cant imagine how long

that is going to take me to modify.

But yeah, thanks for the feed back and I hope you like the site when its available...

- Gary

Ioannis
- 20th June 2009, 10:42
Hi Gary.

1. Do you have any newer design guide for the ISD17xx than the revision 0/2006?

2. What do you use for the site you built? Is this template included?

Ioannis

RFEFX
- 20th June 2009, 17:09
The ISD17XXX series is a fairly old device so there have been no changes to it. therefore I

believe the design guide would not change. the design guides are somewhat difficult to get.

I had to tell Winbond that my company (the one I was working for at the time) that we were

going to use about 500,000 devices a year.... so they quickly sent over their design guide.

As far as the flash template modification, I use MXStudio 2004 (photo Attached) and I just

downloaded a free Flash intro template and modified it to my liking.

- Gary

Ioannis
- 21st June 2009, 14:33
500.000! Wow!

Hope I do sell 5.000 pcs only!

Thanks for the infos, very much.

Ioannis

Starfix
- 22nd September 2009, 10:46
Hello all,
first, I want to thank you. With your help I was able to quickly understand ISD1700 functionnality (really bad datasheet !!).

I made a system that can speak numerous messages: Not full messages are recorded, but words.
Then I compose my message, sending play for words one after other.

My question is: How to copy memory from one ISD to another ? Is there a digital way via SPI commands ? I don't want to record my voice on each ISD !!!

milestag
- 23rd September 2009, 11:55
You have 2 choices.

1. Buy the evaluation kit (programmer) that Nuvoton makes. The new design supports "batch" programming. The old version from Winbond does not, so make sure it's the new one made by Nuvoton.

2. Build your own custom programmer. I did this for my laser tag system by embedding the "recorder" functions in my PIC firmware. SO I also wrote a simple Windows application (in Liberty Basic) that plays wav files and sends commands to the PIC telling it to START or STOP recording. It also sends address commands.

To make it easier, I set up a memory map of pre-defined addresses for the ISD1700. Then I just make sure that the wav files are not longer than each memory location. Since the wav files will usually be shorter than the memory slot, I send a STOP command after the PC plays the wav file. The ISD1700 will insert a EOM marker. When the ISD plays the file it will stop playback at the EOM (the EOM feature must be enabled).

Jim

ams0178
- 12th March 2010, 04:30
Hi Guys,

I started a project using the PIC16F887 and a WINBOND ISD1700 Chip. I've been struggling to get the SPI communications working.

In googling and searching through forums I came across this post.

In reading through your posts and some of the code you have posted, it appears that you guys "bit banged" the ISD commands. Have any of you used the specific hardware on your PICs? Do you know if this is possible?

I've used the PIC16F887 before with assembly so it's not that big of a deal to try and read your code, but I was wondering if any of you did any work in C? This is my first project using MPLAB and the HI-Tech C compiler.

Thanks, Alan

Ioannis
- 12th March 2010, 07:19
Hmm, then you are at wrong forum. This is about PicBasic Pro compiler. Not the C compiler of any company.

Ioannis

ams0178
- 13th March 2010, 01:40
Ioannis,

I'm not a fan of those who stray off topic and don't pay attention to forum etiquette. More of my concern was whether or not any of you were able to use your PICs and the actual SPI hardware in them. Or did all of you "bit bang" to communicate?

Thanks, Alan

Ioannis
- 13th March 2010, 12:48
The best code so far is at post #30 by RFEFX.

It uses SPI.

Ioannis

milestag
- 14th March 2010, 06:09
Yes, bit-banged.

The ISD1700 chips are tempermental to say the least. I have it working fine in my project, but there are some undocumented problems with this chip. Overall the documentation is inconsistent/poor and difficult to find current versions. I found out after a year of using this chip that I had the outdated datasheets.

Also, the development systems were redesigned when it moved from Winbond to Nuvoton. And the Winbond hardware does not work with Nuvoton software, so if you were unlucky to buy the early ones, you get to buy it all over again (or you just design your own). I like this chip, but Nuvoton does not help with the problems.

As for SPI, I have worked with the ISD1700 and another SPI device connected to the same PIC micro. Each device uses the complete opposite SPI communications format. The logic levels are inverted and the MSB/LSB is reversed on each device. I don't know which way is "standard" for SPI. So you may want to try changing MSB/LSB data and try inverting various signals (clock, data, chip select).

Otherwise the code examples in previous posts on this thread should be a good head start.

RussMartin
- 15th March 2010, 01:31
The ISD1700 chips are tempermental to say the least. I have it working fine in my project, but there are some undocumented problems with this chip. Overall the documentation is inconsistent/poor and difficult to find current versions. I found out after a year of using this chip that I had the outdated datasheets.

They are indeed temperamental. The timing information in the data sheets may be off by as much as 25%, and this is different from one device model to the next.

I've been working with one for the past 2 weeks . . .

ams0178
- 17th March 2010, 06:21
Hello All,

I've made some progress. At least the MISO pin is "singing" with 1's and 0's. But I can't seem to get the chip to record or play. I'm using the LED off of pin 2 as an indicator. I even put a test probe and monitored the pin 2 just in case the LED was put in backwards.

I also started monitoring pins for more "foolproof" software rather than guessing at delays. One of the things I realized that after sending the record command, 0x51 (bit 4 set for LED) and 0x00 (data byte), the interrupt bit in SR0 never gets set. And according to the datasheet I believe it's suppose to get set after executing that command. I also tried sending the stop command right after the record command, thinking that maybe the interrupt bit is set after the record command is stopped, and this still doesn't result in the interrupt bit being set.

I just want to make sure I'm using the latest datasheet. Is revision 1.1 from May 2007 the latest?

Thanks, Alan

RFEFX
- 17th March 2010, 06:36
Hey ams,
you stated in a previous post something about using C programming. are you even using Picbasic Pro for your pic project or you trying to do this in C?

what is the size of your ISD device you stated its a 1700 but no size specified. this is important as you need to know the start and end addresses of the messages you are trying to record.

If you haven't seen my post #30 i definitely recommend the Cowlacious Designs ISD board. http://www.cowlacious.com/AudioProd.htm

-RFEFX

RFEFX
- 17th March 2010, 06:53
On my very first post i linked the Design guide.

the design guide is different from the datasheet as it gives you vital ISP codes and timing information.

Make sure you are referring to the design guide and not the data sheet.

Unless Nuvaton changed this....

but then again, my project is working... (no offense)

if you are using Picbasic you mind posting some of your code so that some of us may analyze it? I'm sure Jerson can dissect it in his sleep (again no offense)

ams0178
- 17th March 2010, 06:53
RFEFX,

Yes I'm using C to program. I figured this post was as much about interfacing with the ISD17000 and using that hardware, that it was okay to post my question(s) as long as I leave the actual programming out of it. If it's not, just let me know.

Yes, I've been using your Post 30 as a guide for the SPI interface. Thanks for your work. It's been a great start and will definitely help.

I'm working with a custom PCB I built. I'm still on rev 1, so we'll see how good of a PCB designer I am :)

I'm also using the 17240 chip. I'm only using the generic record and play commands at this point. Would their be a reason I can't do this?

Alan

ams0178
- 17th March 2010, 06:56
RFEFX,

I'm actually using a later version of the design guide. If you or anyone for that matter wants a later version, send me a PM with your email and I can email you the PDF.

Alan

Ioannis
- 17th March 2010, 08:11
I have version 1.31, Nov. 6, 2008.

Ioannis

ams0178
- 21st March 2010, 08:00
Hey Guys,

I'm getting close but I'm not quite there. I have the audio chip recording and playing because the LED is constant during recording and blinks during playing. But unfortunately I'm not getting anything out of the speaker except a small hum. I've documented my setup of what I'm doing below. I'm a little bit unfamiliar with audio signals so its certainly possible that I might be doing something wrong.

I'm using the audio in pin which has a 0.1uF cap on it as recommended in the datasheet. Once powered up in SPI mode, the ISD17000 should assumes that the audio input is from this pin and not the microphone, (If I read the design guide correctly). I'm trying to put a simple audio output signal from my PC tower into this pin. I cut off the end of a wire that has an audio jack on the one end. There was a red wire and a white wire inside that I stripped down to the wire. I tested the output audio signals with an oscilloscope and they're between +/- 1 Volt. I didn't think it mattered which wire I soldered to the audio input pin on my board because as far as I know audio is just a differential signal, right? But currently the white wire is soldered to the input pin. And I tied the red wire to ground. I even monitored the input signals here as I recorded them and saw the input on the oscilloscope. But when I go to play back the recording, the speaker just hums as if there was only a very faint sound.

Does anybody know what I'm doing wrong? Any suggestions for troubleshooting? I'm not sure what to check next.

Thanks, Alan

ams0178
- 21st March 2010, 09:33
Well I actually figured out 2 things. 1) The analog input is not a factory default. Bit 6 of the APC register should be cleared to use the analog input. 2) If you enable the visual LED aid during recording or playing and do a read status command without the LED bit enabled, the LED will stop even if it continues to read or write. Learned that lesson in about 5 hours earlier today. :)

Alan

Ioannis
- 21st March 2010, 21:46
Have a look at this:

http://www.4dsystems.com.au/prod.php?id=73

Almost unlimited messages!

Ioannis

RussMartin
- 21st March 2010, 22:07
I have version 1.31, Nov. 6, 2008.

Mine is Rev. 0, October 2006.

RFEFX
- 22nd March 2010, 01:17
Yeah Ioannis,
i saw that audio module a while back .. i will be ordering one soon and posting my project here... i do have several Oled displays from them as well... they make very well designed products and i do recommend them.

- RFEFX

Ioannis
- 22nd March 2010, 09:18
I will be looking forward in reading your review of the product.

Please do post your results on this.

Ioannis

derbende
- 20th February 2011, 16:19
thank you very much for the nice code.

I have tested your code and it is working proerly. I can play and erase the voices by using ISD_ERASE and ISD_PLAY function. However I couldn't record any voices. I am very glad if you can help me. I can nor record any voices in defined addresses. how can I do it?




This works so far to play back 4 sounds repeatedly. The volume setting via apc2 works also. Next I plan to get rid of the PAUSE delays and monitor status to determine when each sound finished playing.



'DEMO PLAYER FOR ISD1700
'Code Version: 01
'Words Used = 354
'Revision Date: 8 Feb 2009
'PicBasic Pro Compiler version 2.50b
'Processor=PIC16F684 (WDT=ON, MCLR=INPUT, OSC=INTOSC)

'Modified from code posted by Jerson and Brenon

'Memory Reference:
'ISD17XX First Address = 0x010
'ISD1730 Max Address = 0x0FF
'ISD1760 Max Address = 0x1EF
'ISD1790 Max Address = 0x2DF

DEFINE OSC 8
'************************************************* ************
'************************************************* ************
'******************** DEFINE VARIABLES ***********************
'************************************************* ************
'************************************************* ************
temp_bit VAR BIT

temp VAR BYTE
spi_cnt var byte ' counter for SPI transfer
bSPI var byte ' the byte being transferred on SPI

s_addr VAR WORD ' Start Address
e_addr VAR WORD ' End Address

ISD_Data var byte[7] ' This array contains data to/from ISD

SR0a var ISD_Data[0]
SR0b var ISD_Data[1]
SR1 var ISD_Data[2] ' only valid after ReadStatus

isCmdErr var SR0a.0 ' 1=previous command failed/ignored
isFull var SR0a.1 ' 1=memory full
isPU var SR0a.2 ' 1=ISD powered up
isEOM VAR SR0a.3 ' 1=EOM detected (clear by CLR_INT command)
isINT var SR0a.4 ' 1=current operation completed (clear by CLR_INT command)

isReady var SR1.0 ' 1=Ready to receive SPI command (only valid after ReadStatus)
' Some SPI commands can still be sent when isReady=0

'************************************************* ************
'************************************************* ************
'******************** PIN ASSIGNMENTS ************************
'************************************************* ************
'************************************************* ************
Symbol sensor = PORTA.0 '
Symbol miso = PORTA.3 'ISD1760 SPI MISO
Symbol led1 = PORTC.1 '
Symbol led2 = PORTC.2 '
Symbol ss = PORTC.3 'ISD1760 SLAVE SELECT
Symbol sclk = PORTC.4 'ISD1760 SPI CLOCK
Symbol mosi = PORTC.5 'ISD1760 SPI MOSI

'************************************************* ************
'************************************************* ************
'******************** INITIALIZATION *************************
'************************************************* ************
'************************************************* ************
initialize:
CLEAR
OSCCON = %01111000
CMCON0 = 7 'turn off comparators
ANSEL = 0

PR2 = 35 'PWM Period (40K=49, 56K=35) (35 to 55)
CCPR1L = 15 'PWM Duty Cycle (1 to 15)
T2CON = 4 'Timer2 = ON; Prescale = 1:1
CCP1CON = 0 'PWM module off
OPTION_REG = %11111111 'Turn off PortA weak pull-ups

TRISA = %111111 'set PortA directions
WPUA = %000000 'enable weak pull-ups PortA
IOCA = %000000 'disable PORTA.0 Int On Change

TRISC = %000000 'set PortC directions

PORTA = %000000
PORTC = %000000 '

HIGH ss 'start with Slave Select HIGH
HIGH sclk 'start with SPI Clock HIGH
LOW MOSI 'start with MOSI LOW

INPUT sensor
LOW led1
LOW led2


start: 'Initialize the ISD
GoSub isd_pu
PAUSE 50 '50 mS Power Up Delay (per datasheet)
GoSub isd_wr_apc 'set volume and config bits
PAUSE 10
GoSub isd_clr_int 'clear interrupt and EOM
'************************************************* ************
'************************************************* ************
'********************* MAIN PROGRAM **************************
'************************************************* ************
'************************************************* ************
main_loop: '(MAIN PROGRAM LOOP)

PAUSE 2000

s_addr = $010
e_addr = $02b
GOSUB isd_set_play

PAUSE 2500

GOSUB isd_stop

PAUSE 2000

s_addr = $02c
e_addr = $048
GOSUB isd_set_play

PAUSE 2500

GOSUB isd_stop

PAUSE 2000

s_addr = $049
e_addr = $07c
GOSUB isd_set_play

PAUSE 4800

GOSUB isd_stop

PAUSE 2000

s_addr = $07d
e_addr = $093
GOSUB isd_set_play

PAUSE 2000

GOSUB isd_stop

GoTo main_loop


'************************************************* ************
'************************************************* ************
'********************** SUBROUTINES **************************
'************************************************* ************
'************************************************* ************
isd_pu:
LOW ss

bSPI=$01 'Power Up Command
GoSub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI=$00
GoSub isd_spi
ISD_Data[1] = bSPI 'SR0b

HIGH ss

RETURN

'--------------------------------------------------------------------------
isd_wait_ready:
GOSUB isd_rd_status
IF isReady = 0 THEN isd_wait_ready
RETURN

'--------------------------------------------------------------------------
isd_set_play:
LOW ss

bSPI = $80 'Set Play Command (7 bytes)
GoSub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI = $00
GoSub isd_spi
ISD_Data[1] = bSPI 'SR0b

bSPI = s_addr.LowByte ' Start Address low byte.
GoSub isd_spi
ISD_Data[2] = bSPI 'SR0a

bSPI = s_addr.HighByte ' Start Address high byte
GoSub isd_spi
ISD_Data[3] = bSPI 'SR0b

bSPI = e_addr.LowByte ' End Address low byte
GoSub isd_spi
ISD_Data[4] = bSPI 'SR0a

bSPI = e_addr.HighByte ' End Address high byte
GoSub isd_spi
ISD_Data[5] = bSPI 'SR0b

bSPI = $00 ' Reserved Address - set to "0"
GoSub isd_spi
ISD_Data[6] = bSPI 'SR0a

HIGH ss

RETURN

'--------------------------------------------------------------------------
isd_wr_apc: 'Write to APC Register using bits D2:D0 to set Volume
LOW ss

bSPI = $65 'Write APC2
GoSub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI = %01000011 'Volume set by D2:D0 (000=Max)
'Output set by D7 (0=Aud, 1=Aux)
GoSub isd_spi
ISD_Data[1] = bSPI 'SR0b

bSPI = %00000100 'PWM Speaker Output D8 (0=Enable, 1=Disable)

GoSub isd_spi
ISD_Data[2] = bSPI 'SR0a

HIGH ss

RETURN

'--------------------------------------------------------------------------
isd_spi: ' shift SPI data out and into SPI byte
FOR spi_cnt = 0 to 7 '
MOSI = bSPI.0 ' shift LSB of byte onto MOSI line
LOW SCLK ' clock MISO data out to uC (Falling Edge)
temp_bit = miso '
HIGH SCLK ' clock MOSI into ISD1700 (Rising Edge)
bSPI = bSPI >> 1 ' shift SPI byte Right
bSPI.7 = temp_bit
NEXT spi_cnt

RETURN

'--------------------------------------------------------------------------
isd_clr_int: ' CLEAR INTERRUPT AND EOM BITS
LOW SS

bSPI=$04 'Clear Interrupt Command
gosub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI=$00
gosub isd_spi
ISD_Data[1] = bSPI 'SR0b

HIGH SS

RETURN

'--------------------------------------------------------------------------
isd_stop: ' Stop Immediately
LOW ss

bSPI=$02 'Stop Command
gosub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI=$00
gosub isd_spi
ISD_Data[1] = bSPI 'SR0b

HIGH ss

RETURN

'--------------------------------------------------------------------------
isd_pd: ' Stop Immediately
LOW ss

bSPI=$07 'Power Down Command
gosub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI=$00
gosub isd_spi
ISD_Data[1] = bSPI 'SR0b

HIGH ss

RETURN

'--------------------------------------------------------------------------
isd_rd_status: 'read status of ISD1700
LOW ss

bSPI=$05 'Read Status Command
gosub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI=$00
gosub isd_spi
ISD_Data[1] = bSPI 'SR0b

bSPI=$00
gosub isd_spi
ISD_Data[2] = bSPI 'SR1

HIGH ss

RETURN

'************************************************* ************
'************************************************* ************


End

spolk10
- 18th March 2011, 12:35
Hey Guys,

I'm getting close but I'm not quite there. I have the audio chip recording and playing because the LED is constant during recording and blinks during playing. But unfortunately I'm not getting anything out of the speaker except a small hum. I've documented my setup of what I'm doing below. I'm a little bit unfamiliar with audio signals so its certainly possible that I might be doing something wrong.

I'm using the audio in pin which has a 0.1uF cap on it as recommended in the datasheet. Once powered up in SPI mode, the ISD17000 should assumes that the audio input is from this pin and not the microphone, (If I read the design guide correctly). I'm trying to put a simple audio output signal from my PC tower into this pin. I cut off the end of a wire that has an audio jack on the one end. There was a red wire and a white wire inside that I stripped down to the wire. I tested the output audio signals with an oscilloscope and they're between +/- 1 Volt. I didn't think it mattered which wire I soldered to the audio input pin on my board because as far as I know audio is just a differential signal, right? But currently the white wire is soldered to the input pin. And I tied the red wire to ground. I even monitored the input signals here as I recorded them and saw the input on the oscilloscope. But when I go to play back the recording, the speaker just hums as if there was only a very faint sound.

Does anybody know what I'm doing wrong? Any suggestions for troubleshooting? I'm not sure what to check next.

Thanks, Alan

Alan,
I am having the same problem. What did you do to fix this?
Scott

dnabdala
- 25th May 2013, 17:40
I implemented hardware SPI using a PIC 16F877A and an ISD1740. I do it with ASM, but you can translate it to PICBasic if needed.

I'm posting it here because is the most extensive thread in the subject I could found, and I haven't found information about how to do it by hardware anywhere. I haven't finish yet, but I will probably forget to post it here late, so here goes what I've done so far.

As PIC SPI is Msb -> Lsb and ISD1700 is Lsb -> Msb, everything is inverted.


ISD commands:

;ISD led active on all the commands, for debugging, set bit 3 to 0 to disable ISD led flashing

CONSTANT SND_CMD_PU = b'10001000'
CONSTANT SND_CMD_SET_PLAY = b'00001001'
CONSTANT SND_CMD_SET_REC = b'10001001'
CONSTANT SND_CMD_PD = b'11101000'
CONSTANT SND_CMD_CLR_INT = b'00101000'
CONSTANT SND_CMD_WR_APC2 = b'10101110'
CONSTANT SND_CMD_WR_NVCFG = b'01101010'
CONSTANT SND_CMD_RD_STATUS = b'10101000'

;PIC ISD ports and pins

CONSTANT SND_PUERTO_ES = PORTC
CONSTANT SND_CONTROL_ES = TRISC
CONSTANT SND_PIN_E = .4
CONSTANT SND_PIN_S = .5
CONSTANT SND_PUERTO_CLK = PORTC
CONSTANT SND_CONTROL_CLK = TRISC
CONSTANT SND_PIN_CLK = .3
CONSTANT SND_PUERTO_SS = PORTA
CONSTANT SND_CONTROL_SS = TRISA
CONSTANT SND_PIN_SS = .5


;SPI configuration and activation

;PORTS config
banksel SND_CONTROL_ES
BCF SND_CONTROL_ES,SND_PIN_S
BSF SND_CONTROL_ES,SND_PIN_E
banksel SND_CONTROL_CLK
BCF SND_CONTROL_CLK,SND_PIN_CLK
banksel SND_PUERTO_ES
BCF SND_PUERTO_ES,SND_PIN_S
banksel SND_PUERTO_CLK
BSF SND_PUERTO_CLK,SND_PIN_CLK
;SPI config
banksel PIE1
BSF PIE1,SSPIE ;enable interrupt
banksel SSPSTAT
MOVLW b'00000000'
MOVWF SSPSTAT
;SSPM3:0 = 0001 = Fosc/16
banksel SSPCON
MOVLW b'00110001'
MOVWF SSPCON
;use SS to signal command start/stop
banksel SND_CONTROL_SS
BCF SND_CONTROL_SS,SND_PIN_SS
banksel SND_PUERTO_SS
BSF SND_PUERTO_SS,SND_PIN_SS

;SPI usage if not using interrupts

;active waiting for SPI transmission to end
snd_debug_esperar
banksel SSPSTAT
BTFSS SSPSTAT,BF
GOTO snd_debug_esperar
BCF SSPSTAT,BF
RETURN

;SPI without interrupts, to verify it works
snd_debug
;it has to be already configured, I'm ignoring ISD response
banksel SND_PUERTO_SS
BCF SND_PUERTO_SS,SND_PIN_SS ;start command
banksel SSPBUF
MOVLW SND_CMD_PU ;first byte
MOVWF SSPBUF
CALL snd_debug_esperar
banksel SSPBUF
MOVFW SSPBUF
CLRW
MOVWF SSPBUF
call snd_debug_esperar
banksel SND_PUERTO_SS
BSF SND_PUERTO_SS,SND_PIN_SS
;enviar un SET_PLAY
pagesel snd_debug
banksel SND_PUERTO_SS
BCF SND_PUERTO_SS,SND_PIN_SS
MOVLW SND_CMD_SET_PLAY
banksel SSPBUF
MOVWF SSPBUF
CALL snd_debug_esperar
banksel SSPBUF
MOVFW SSPBUF
CLRW
MOVWF SSPBUF
call snd_debug_esperar
banksel SSPBUF
MOVFW SSPBUF
MOVLW b'0000100' ; 0x10 inverted
MOVWF SSPBUF
call snd_debug_esperar
banksel SSPBUF
MOVFW SSPBUF
MOVLW 0x00
MOVWF SSPBUF
call snd_debug_esperar
banksel SSPBUF
MOVFW SSPBUF
MOVLW b'0111111' ; 0x7E inverted
MOVWF SSPBUF
call snd_debug_esperar
banksel SSPBUF
MOVFW SSPBUF
MOVLW 0x00
MOVWF SSPBUF
call snd_debug_esperar
banksel SSPBUF
MOVFW SSPBUF
CLRW
MOVWF SSPBUF
call snd_debug_esperar
banksel SND_PUERTO_SS
BSF SND_PUERTO_SS,SND_PIN_SS
return


Sorry for the code format, I couldn't find a way to post it properly formatted.

DAvid

midali
- 22nd April 2014, 00:04
I tried to play a recorded sound on ISD1730 but something is wrong. I use 16F1503 set at 4 MHZ. Can somebody help me..? Thx in advance


CODE:

#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _MCLRE_OFF & _CP_ON & _CLKOUTEN_OFF
__config _CONFIG2, _LVP_OFF & _LPBOR_OFF
#ENDCONFIG

DEFINE OSC 4
OSCCON = %01101000 ' set 4MHz internal osc


CM1CON0.7 = 0 ; Disable comparator 1
CM2CON0.7 = 0 ; Disable comparator 2

ADCON0 = 0 'all ports set as digital
ADCON1 = 0

TRISA = %00100000 'PORTA.5 as input
ANSELA = %00000000
PORTA = 0

TRISC = %00000100 'PORTC.3 as input
LATC = 0
PORTC = 0
ANSELC = 0


'******************** DEFINE VARIABLES ***********************

temp_bit VAR BIT

temp VAR BYTE
spi_cnt var byte ' counter for SPI transfer
bSPI var byte ' the byte being transferred on SPI

s_addr VAR WORD ' Start Address
e_addr VAR WORD ' End Address

ISD_Data var byte[7] ' This array contains data to/from ISD

SR0a var ISD_Data[0]
SR0b var ISD_Data[1]
SR1 var ISD_Data[2] ' only valid after ReadStatus

isCmdErr var SR0a.0 ' 1=previous command failed/ignored
isFull var SR0a.1 ' 1=memory full
isPU var SR0a.2 ' 1=ISD powered up
isEOM VAR SR0a.3 ' 1=EOM detected (clear by CLR_INT command)
isINT var SR0a.4 ' 1=current operation completed (clear by CLR_INT command)

isReady var SR1.0 ' 1=Ready to receive SPI command (only valid after ReadStatus)
' Some SPI commands can still be sent when isReady=0


'******************** PIN ASSIGNMENTS ************************


Symbol LED = PORTA.0 '
Symbol miso = PORTC.2 'ISD1730 SPI MISO
Symbol ss = PORTC.3 'ISD1730 SLAVE SELECT
Symbol sclk = PORTC.1 'ISD1730 SPI CLOCK
Symbol mosi = PORTC.0 'ISD1730 SPI MOSI

'******************** INITIALIZATION *************************
initialize:

HIGH ss 'start with Slave Select HIGH
HIGH sclk 'start with SPI Clock HIGH
LOW MOSI 'start with MOSI LOW
LOW led


start: 'Initialize the ISD
GoSub isd_pu
PAUSE 50 '50 mS Power Up Delay (per datasheet)
GoSub isd_clr_int 'clear interrupt and EOM


'********************* MAIN PROGRAM **************************

main_loop: '(MAIN PROGRAM LOOP)

Playloop:
if porta.5 = 1 then play
goto playloop

Play:
high led ' LED for play

if porta.5 = 1 then play 'wont play until button is released

s_addr = $010 'playing back from the same 16 rows
e_addr = $01f

GOSUB isd_set_play

PAUSE 2000

GOSUB isd_stop

low led
goto main_loop
end

'********************** SUBROUTINES **************************
isd_pu:
LOW ss
bSPI=$01 'Power Up Command
GoSub isd_spi
ISD_Data[0] = bSPI 'SR0a
bSPI=$00
GoSub isd_spi
ISD_Data[1] = bSPI 'SR0b
HIGH ss
RETURN

'--------------------------------------------------------------------------
isd_wait_ready:
GOSUB isd_rd_status
IF isReady = 0 THEN isd_wait_ready
RETURN

'--------------------------------------------------------------------------
isd_set_play:
LOW ss

bSPI = $80 'Set Play Command (7 bytes)
GoSub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI = $00
GoSub isd_spi
ISD_Data[1] = bSPI 'SR0b

bSPI = s_addr.LowByte ' Start Address low byte.
GoSub isd_spi
ISD_Data[2] = bSPI 'SR0a

bSPI = s_addr.HighByte ' Start Address high byte
GoSub isd_spi
ISD_Data[3] = bSPI 'SR0b

bSPI = e_addr.LowByte ' End Address low byte
GoSub isd_spi
ISD_Data[4] = bSPI 'SR0a

bSPI = e_addr.HighByte ' End Address high byte
GoSub isd_spi
ISD_Data[5] = bSPI 'SR0b

bSPI = $00 ' Reserved Address - set to "0"
GoSub isd_spi
ISD_Data[6] = bSPI 'SR0a

HIGH ss

RETURN

'--------------------------------------------------------------------------
isd_spi: ' shift SPI data out and into SPI byte
FOR spi_cnt = 0 to 7 '
MOSI = bSPI.0 ' shift LSB of byte onto MOSI line
LOW SCLK ' clock MISO data out to uC (Falling Edge)
temp_bit = miso '
HIGH SCLK ' clock MOSI into ISD1700 (Rising Edge)
bSPI = bSPI >> 1 ' shift SPI byte Right
bSPI.7 = temp_bit
NEXT spi_cnt

RETURN

'--------------------------------------------------------------------------
isd_clr_int: ' CLEAR INTERRUPT AND EOM BITS
LOW SS

bSPI=$04 'Clear Interrupt Command
gosub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI=$00
gosub isd_spi
ISD_Data[1] = bSPI 'SR0b

HIGH SS

RETURN

'--------------------------------------------------------------------------
isd_stop: ' Stop Immediately
LOW ss

bSPI=$02 'Stop Command
gosub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI=$00
gosub isd_spi
ISD_Data[1] = bSPI 'SR0b

HIGH ss

RETURN

'--------------------------------------------------------------------------
isd_rd_status: 'read status of ISD1700
LOW ss '

bSPI=$05 'Read Status Command
gosub isd_spi
ISD_Data[0] = bSPI 'SR0a

bSPI=$00
gosub isd_spi
ISD_Data[1] = bSPI 'SR0b

bSPI=$00
gosub isd_spi
ISD_Data[2] = bSPI 'SR1

HIGH ss

RETURN

midali
- 22nd April 2014, 10:00
I found the problem ..

TRISC = %00000000

Now all is ok !