Go Down

Topic: Nuvoton ISD1700 Chip (Read 5510 times) previous topic - next topic

anchan

I have been trying desperately to get talk to the Nuvoton ISD1700 Chip with an Arduino Pro 328 - 5V/16Mhz board.  I found this thread, but even on the new forum it is read-only http://arduino.cc/forum/index.php/topic,37348.0

First off, thank you the poster from that thread who wrote such wonderful code.  Unfortunately, I have not been able to get it to work.  All I can get from the Serial Monitor is "Not_RDY"

Everything compiled OK.  I have an identical ISD1700 hooked up in button mode, and works fine.  I swapped the chips, and its not the chip.

Has anyone worked on this recently?  Not sure where to start.
Thanks

eforman

maybe post a picture of your breadboard? 

anchan

Attached are a few photos of the breadboard.  I'm not sure exactly what you could really determine from the photos, but its all worth a shot.

I have the ISD1700 hooked up exactly as in example 2 (page 17) of the datasheet with a few exceptions:
http://www.nuvoton.com/hq/enu/ProductAndSales/ProductLines/ConsumerElectronicsIC/ISDVoiceIC/ISDChipCorder/Documents/ISD1700.pdf

The exception is that I am not using the Analn as shown there, but rather have a mic hooked up as in example 1 (page16) of the datasheet.
Also, I am supplying power to the chip from VCC and GND of the arduino, which is getting power from USB at the moment.
Also, I have a 100 ohm resistor in series with the speaker just to be safe, since I don't believe USB can drive an 8 ohm speaker.
If I put my ear right up against the speaker, I can hear a tiny bit of background noise, so I know it is on.  Plus the LED connected to Pin 2 of the chip is lit.

I will keep plugging away, but if anyone thinks of anything let me know.  Also, don't rule out the stupidest of suggestions.  I am a total newbie to the arduino, so I could have something really dumb going on.  I have other electronics experience, just not with the arduino.

Thanks in advance.

anchan

OK, I just realized a really stupid mistake.  I had pin 1 attached to ground not power!  Well, anyway, now when I type the letter R or P or whatever into serial monitor, I get "Status--->CMD_ERR PU RDY". 

On the arduino platform, I get the following errors:
Error inside Serial.serialEvent()
java.io.IOException: Bad file descriptor in nativeavailable
   at gnu.io.RXTXPort.nativeavailable(Native Method)
   at gnu.io.RXTXPort$SerialInputStream.available(RXTXPort.java:1532)
   at processing.app.Serial.serialEvent(Serial.java:215)
   at gnu.io.RXTXPort.sendEvent(RXTXPort.java:732)
   at gnu.io.RXTXPort.eventLoop(Native Method)
   at gnu.io.RXTXPort$MonitorThread.run(RXTXPort.java:1575)

anchan

And a bit more info:
Restarting my machine got rid of the java IO error messages.  But I still get "CMD_ERR PU RDY" whenever I enter a command.

I put a scope on Pin 13 of the arduino which according to the .h should be SCK.  I was assuming I would see some kind of clock output there, but instead its just at a solid +5.

anchan

Well, last one.

I uploaded the attached starter code I had from another source, and this DOES WORK.

I'm assuming the other code, which is much more polished and which I would love to use, is maybe written for a different arduino, because I just can't get it to work.

All for now.  Thanks

neuron_upheaval

The ISD1700 library is Arduino-Duemilanove compatible, so it should be okay with Arduino Pro.

Maybe there is a problem with the library itself, even if it is compiled okay.

I'll check it out.

Cheers,

nu

neuron_upheaval

#7
Mar 17, 2011, 12:12 pm Last Edit: Mar 17, 2011, 07:37 pm by neuron_upheaval Reason: 1
Please try this ISD1700.cpp below and see if it works. I changed the SPI mode. Now it is just like the Spi library that was used in your functioning code from post #5.

ISD1700.cpp
Code: [Select]
/*
 ISD1700.cpp - Library for Nuvoton ISD1700 chipcorders
 Copyright (c) 2009 Marcelo Shiniti Uchimura.
 Author: Marcelo Shiniti Uchimura, CITS, <www.cits.br>
 Version: March 17, 2011

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 of the License, or (at your option) any later version.

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

/*
* Includes
*/
#include "WProgram.h"
#include "ISD1700.h"

/*
* Definitions
*/

/*
* Constructor
* Based on Cam Thompson's Spi library
*/
ISD1700::ISD1700(uint8_t SSPin)
{
 uint8_t dummy;
 
 _SSPin = SSPin;

 // initialize SPI communication
 pinMode(SCK_PIN, OUTPUT);
 pinMode(MOSI_PIN, OUTPUT);
 pinMode(MISO_PIN, INPUT);
 pinMode(_SSPin, OUTPUT);

 // initialize SPI communication
 SPCR = (1<<SPE) | (1<<MSTR);
 dummy = SPSR;
 dummy = SPDR;
 digitalWrite(_SSPin, HIGH);

 // initialize private vars
 _SR0 = 0;      // Status Register #0                   uint16_t <15:0>
 _SR1 = 0;      // Status Register #1                   uint8_t  <7:0>
 _APC = 0;      // Analog Path Configuration Register   uint16_t <11:0>
 _PP = 0;       // Playback Pointer                     uint16_t <10:0>
 _RP = 0;       // Record Pointer                       uint16_t <10:0>
 _DEVICEID = 0; // Device Identification Register       uint8_t  <7:3>

 // reset chipcorder
 reset();
}

/*
* Transfer data to SPI peripheral slaves
* Based on Cam Thompson's Spi library
*/
uint8_t ISD1700::spi_transfer(uint8_t data)
{
 SPDR = data;
 while (!(SPSR & (1<<SPIF)));
 return SPDR;
}

/*
* Send a command to chipcorder
*/
void ISD1700::sendCmd(uint8_t cmd)
{
 uint8_t data[4] = {0xFF,0xFF,0xFF,0xFF};

 digitalWrite(_SSPin, LOW);
 data[0] = spi_transfer(cmd);
 data[1] = spi_transfer(0);
 switch(cmd)
 {
   case 0x05:                     // RD_STATUS
     case 0x09:                     // DEVID
       data[2] = spi_transfer(0);
       break;
     case 0x06:                     // RD_PLAY_PTR
     case 0x08:                     // RD_REC_PTR
     case 0x44:                     // RD_APC
       data[2] = spi_transfer(0);
       data[3] = spi_transfer(0);
       break;
 }
 digitalWrite(_SSPin, HIGH);
 _SR0 = word(data[1],data[0]);
 switch(cmd)
 {
   case 0x05:    // RD_STATUS
       _SR1 = data[2];
       break;
     case 0x06:    // RD_PLAY_PTR
       _PP = word(data[3],data[2]);
       break;
     case 0x08:    // RD_REC_PTR
       _RP = word(data[3],data[2]);
       break;
     case 0x09:    // DEVID
       _DEVICEID = data[2];
       break;
     case 0x44:    // RD_APC
       _APC = word(data[3],data[2]);
       break;
 }
}

/*
* Send a command to chipcorder
* plus one 12-bit parameter
*
* Usage is valid for the following commands:
*   WR_APC1
*   WR_APC2
*/
void ISD1700::sendCmd(uint8_t cmd, uint16_t apc)
{
 uint8_t data[3] = {0xFF,0xFF,0xFF};

 // check if it is either WR_APC1 or WR_APC2 instruction
 // exit otherwise
 if(cmd != 0x45 && cmd != 0x65)
     return;

 digitalWrite(_SSPin, LOW);
 data[0] = spi_transfer(cmd);
 data[1] = spi_transfer( (uint8_t)(apc & 0xFF) );
 data[2] = spi_transfer( (uint8_t)(apc>>8) );
 digitalWrite(_SSPin, HIGH);
 _SR0 = word(data[1],data[2]);
}

/*
* Send a command to chipcorder
* plus two 11-bit parameters
*
* Usage is valid for the following commands:
*   SET_PLAY
*   SET_REC
*   SET_ERASE
*/
void ISD1700::sendCmd(uint8_t cmd, uint16_t startAddr, uint16_t endAddr)
{
 uint8_t data[2] = {0xFF,0xFF};

 // check if it is either SET_PLAY, SET_REC, or SET_ERASE instruction
 // if not, exit method
 if(cmd != 0x80 && cmd != 0x81 && cmd != 0x82)
     return;

 digitalWrite(_SSPin, LOW);
 data[0] = spi_transfer(cmd);
 data[1] = spi_transfer(0);
 data[0] = spi_transfer( (uint8_t)(startAddr & 0xFF) );
 data[1] = spi_transfer( (uint8_t)(startAddr>>8) );
 data[0] = spi_transfer( (uint8_t)(endAddr & 0xFF) );
 data[1] = spi_transfer( (uint8_t)(endAddr>>8) );
 data[0] = spi_transfer(0);
 digitalWrite(_SSPin, HIGH);
 _SR0 = word(data[1],data[0]);
}

/*
* Status flags
*/
uint8_t ISD1700::RDY(void)
{
 rd_status();
 return (_SR1 & 1);
}

uint8_t ISD1700::ERASE(void)
{
 rd_status();
 return (_SR1 & 2);
}

uint8_t ISD1700::PLAY(void)
{
 rd_status();
 return (_SR1 & 4);
}

uint8_t ISD1700::REC(void)
{
 rd_status();
 return (_SR1 & 8);
}

uint8_t ISD1700::SE1(void)
{
 rd_status();
 return (_SR1 & 16);
}

uint8_t ISD1700::SE2(void)
{
 rd_status();
 return (_SR1 & 32);
}

uint8_t ISD1700::SE3(void)
{
 rd_status();
 return (_SR1 & 64);
}

uint8_t ISD1700::SE4(void)
{
 rd_status();
 return (_SR1 & 128);
}

uint8_t ISD1700::CMD_ERR(void)
{
 return (uint8_t)(_SR0 & 1);
}

uint8_t ISD1700::FULL(void)
{
 return (uint8_t)(_SR0 & 2);
}

uint8_t ISD1700::PU(void)
{
 return (uint8_t)(_SR0 & 4);
}

uint8_t ISD1700::EOM(void)
{
 return (uint8_t)(_SR0 & 8);
}

uint8_t ISD1700::INT(void)
{
 return (uint8_t)(_SR0 & 16);
}


/*
* PU Power up
*/
void ISD1700::pu(void)
{
 sendCmd(0x01);
}

/*
* STOP Stop
*/
void ISD1700::stop(void)
{
 sendCmd(0x02);
}

/*
* RESET Reset
*/
void ISD1700::reset(void)
{
 sendCmd(0x03);
}

/*
* CLR_INT Clear interrupt
*/
void ISD1700::clr_int(void)
{
 sendCmd(0x04);
}

/*
* RD_STATUS Read status
*/
uint8_t ISD1700::rd_status(void)
{
 sendCmd(0x05);
 return _SR1;
}

/*
* RD_PLAY_PTR Read playback pointer
*/
uint16_t ISD1700::rd_play_ptr(void)
{
 sendCmd(0x06);
 return _PP;
}

/*
* PD Power down
*/
void ISD1700::pd(void)
{
 sendCmd(0x07);
}

/*
* RD_REC_PTR Read record pointer
*/
uint16_t ISD1700::rd_rec_ptr(void)
{
 sendCmd(0x08);
 return _RP;
}

/*
* DEVID Read device ID register
*/
uint8_t ISD1700::devid(void)
{
 sendCmd(0x09);
 return _DEVICEID;
}

/*
* PLAY Play from current location
*/
void ISD1700::play(void)
{
 sendCmd(0x40);
}

/*
* REC Record from current location
*/
void ISD1700::rec(void)
{
 sendCmd(0x41);
}

/*
* ERASE Erase current message
*/
void ISD1700::erase(void)
{
 sendCmd(0x42);
}

/*
* G_ERASE Erase all messages except Sound Effects
*/
void ISD1700::g_erase(void)
{
 sendCmd(0x43);
}

/*
* RD_APC Read Analog Path Configuration register
*/
uint16_t ISD1700::rd_apc(void)
{
 sendCmd(0x44);
 return _APC;
}

/*
* WR_APC1 Write data <11:0> into the Analog Path Configuration register
*         with volume settings from /VOL pin
*/
void ISD1700::wr_apc1(uint16_t apc)
{
 sendCmd(0x45, apc);
}

/*
* WR_NVCFG Write the contents of APC register into NVCFG register
*/
void ISD1700::wr_nvcfg(void)
{
 sendCmd(0x46);
}

/*
* LD_NVCFG Load contents of NVCFG into the APC register
*/
void ISD1700::ld_nvcfg(void)
{
 sendCmd(0x47);
}

/*
* FWD Forward playback pointer to the start address of the next message
*/
void ISD1700::fwd(void)
{
 sendCmd(0x48);
}

/*
* CHK_MEM Check circular memory
*/
void ISD1700::chk_mem(void)
{
 sendCmd(0x49);
}

/*
* EXTCLK Enable/disable external clock mode
*/
void ISD1700::extclk(void)
{
 sendCmd(0x4A);
}

/*
* WR_APC2 Write data <11:0> into the Analog Path Configuration register
*         with volume settings from bits <2:0>
*/
void ISD1700::wr_apc2(uint16_t apc)
{
 sendCmd(0x65, apc);
}


/*
* SET_PLAY Play from start address to end address, or stop at EOM
*          depending on D11 of APC
*/
void ISD1700::set_play(uint16_t startAddr, uint16_t endAddr)
{
 sendCmd(0x80, startAddr, endAddr);
}

/*
* SET_REC Record from start address to end address
*/
void ISD1700::set_rec(uint16_t startAddr, uint16_t endAddr)
{
 sendCmd(0x81, startAddr, endAddr);
}

/*
* SET_ERASE Erase from start address to end address
*/
void ISD1700::set_erase(uint16_t startAddr, uint16_t endAddr)
{
 sendCmd(0x82, startAddr, endAddr);
}

Go Up