Nuvoton ISD1700 Chip

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

maybe post a picture of your breadboard?

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.

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)

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.

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

ISD17XX.h (3.15 KB)

SoundTubes.pde (9.97 KB)

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

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

/*
  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);
}

Following ryoru feedback available at How to Controll Nuvoton ISD1760 Chip? - Libraries - Arduino Forum, I am posting a new version of the library:

ISD1700.h

/*
 ISD1700.h - Library for Nuvoton ISD1700 chipcorders
 Copyright (c) 2009 Marcelo Shiniti Uchimura.
 Author: Marcelo Shiniti Uchimura, CITS, <www.cits.br>
 Version: Jan 20, 2016

 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
*/

#ifndef ISD1700_h
#define ISD1700_h

#define SCK_PIN   13
#define MISO_PIN  12
#define MOSI_PIN  11

#include "Arduino.h"

class ISD1700
{
 private:
   uint8_t  _SSPin; // Arduino's digital pin which chipcorder is attached to

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

     /* private methods */
     uint8_t spi_transfer(uint8_t);
     void sendCmd(uint8_t);
     void sendCmd(uint8_t, uint16_t);
     void sendCmd(uint8_t, uint16_t, uint16_t);
 public:
   /* constructor */
   ISD1700(uint8_t);
     
     /* functions to enquire status */
     uint8_t RDY(void);
     uint8_t ERASE(void);
     uint8_t PLAY(void);
     uint8_t REC(void);
     uint8_t SE1(void);
     uint8_t SE2(void);
     uint8_t SE3(void);
     uint8_t SE4(void);
     uint8_t CMD_ERR(void);
     uint8_t FULL(void);
     uint8_t PU(void);
     uint8_t EOM(void);
     uint8_t INT(void);

     /* chipcorder commands */
     void     pu(void);
     void     stop(void);
     void     reset(void);
     void     clr_int(void);
     uint8_t  rd_status(void);
     uint16_t rd_play_ptr(void);
     void     pd(void);
     uint16_t rd_rec_ptr(void);
     uint8_t  devid(void);
     void     play(void);
     void     rec(void);
     void     erase(void);
     void     g_erase(void);
     uint16_t rd_apc(void);
     void     wr_apc1(uint16_t);
     void     wr_nvcfg(void);
     void     ld_nvcfg(void);
     void     fwd(void);
     void     chk_mem(void);
     void     extclk(void);
     void     wr_apc2(uint16_t);
     void     set_play(uint16_t, uint16_t);
     void     set_rec(uint16_t, uint16_t);
     void     set_erase(uint16_t, uint16_t);
};

#endif

(cont'd.)

ISD1700.cpp

/*
 ISD1700.cpp - Library for Nuvoton ISD1700 chipcorders
 Copyright (c) 2009 Marcelo Shiniti Uchimura.
 Author: Marcelo Shiniti Uchimura, CITS, <www.cits.br>
 Version: January 20, 2016

 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 "Arduino.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);
 delay(100);

 // 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);
 delay(1);
 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);
 delay(100);
 _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);
 delay(1);
 data[0] = spi_transfer(cmd);
 data[1] = spi_transfer( (uint8_t)(apc & 0xFF) );
 data[2] = spi_transfer( (uint8_t)(apc>>8) );
 digitalWrite(_SSPin, HIGH);
 delay(100);
 _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);
 delay(1);
 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);
 delay(100);
 _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);
}

(cont'd.)

Example sketch

#include <ISD1700.h>

ISD1700 chip(10); // Initialize chipcorder with
                 // SS at Arduino's digital pin 10

void setup()
{
 Serial.begin(9600);
 Serial.println("Sketch is starting up");
}

void loop()
{
 char c;
 
 if(Serial.available())
 {
   /* Power Up */
   chip.pu();
   c = Serial.read();
   switch(c)
   {
      case 'A':
        Serial.println(chip.rd_apc(), BIN);
        break;         
      case 'Y':
        chip.play();
        break;
      case 'P':
        chip.stop();
        break;
      case 'E':
        chip.erase();
        break;
      case 'R':
        chip.rec();
        break;
      case 'F':
        chip.fwd();
        break;
      case 'Z':
        chip.g_erase();
        break;
      case 'I':
        Serial.println(chip.devid(), BIN);
        break;
   }
   Serial.print("Status---> ");
   Serial.print(chip.CMD_ERR()? "CMD_ERR ": " ");
   Serial.print(chip.PU()? "PU ": " ");
   Serial.print(chip.RDY()? "RDY ": "Not_RDY");
   Serial.println();
   delay(1000);
 }
}

I'm trying to use this lib you (neuron_upheaval) posted in a Aduino Pro Mini without success.

I will use my first Arduino forum post to thank you neuron_upheaval. Your library made my life easier in my Industrial Design final bachelor project. One thing, in my project I am using the ISD 1760 with a Pro Mini and an RC522 Rdif Reader. I struggled at the beginning making them both work over SPI ( because of different SPI settings for the two chips). I fanally made it work by inserting the SPI settings line "SPCR = (1<<CPHA) | (1<<CPOL) | (1<<DORD) | (1<<SPE) | (1<<MSTR);" in every send cmnd function. Maybe this will help someone who is trying to make the ISD and another chip work toghether over SPI. Once again 10000 thanks.

thanks: neuron_upheaval , now it works ok !!!

Hi Guys,
I am pretty new to Arduino and are trying to get my ISD1760 chip to be controlled using a Arduino Uno.
I have been following multiple posts from neuron_upheaval about using the ISD chips an I are yet to get it working.
neuron_upheaval has the most polished code I have found.

I just cant get it to work.
I read through your instructions a few times and have everything wired correctly but I am not sure what I have done wrong.

It looks like it should work but nothing ever happens when I send the commands.

I get this on the serial monitor when I send the Erase command:

Sketch is starting up
Status---> RDY
Erase
Status---> PU Not_RDY
Status---> RDY

If I use the ISD1700 by the buttons it works fine, no problem it is just getting it to work through the Arduino SPI interface.

What do the replys mean? PU means Power Up, but not sure why it gives Power Up not Ready.

When I deliberately send the wrong message I get a different answer so I know something is happening.

I have also tried the codes listed here How to Controll Nuvoton ISD1760 Chip? - Libraries - Arduino Forum
They look promising but wont verify as are full of errors.

Is anyone able to help me work out what I have done wrong please?

//**************************************************************
// Module d'enregistrement de son IDS1760 autonome ou piloté par ARDUINO
// tiptopboards.com
// Code adapté de code: interfacing a chipcorder isd1760 - Interfacing - Arduino Forum
// Unsped 2008
// Modifs en français C Rolland 18 12 2013
//
//**************************************************************
// Broches Arduino utilisées
#define DATAOUT 11 //MOSI (bleu)
#define DATAIN 12 //MISO (vert)
#define SPICLOCK 13 //SCK (marron)
#define SLAVESELECT 10 //SS (rouge)
// Relier aussi les pins +5V et GND

// Codes de commandes de ISD1760 depuis l'Arduino
// Pour plus de détails voir ici http://www.electroniccircuits.gr/files/ISD1700.pdf
#define PU 0x01 //Power Up the device
#define STOP 0x02 //Stop the current operation
#define RESET 0x03 //Reset the device
#define CLR_INT 0x04 //Clear interrupt and OEM bit
#define RD_STATUS 0x05 //Return Returns status bits & current row counter in first 1st 2 bytes and operating status in 3rd byte
#define RD_PLAY_PTR 0x06 //Returns status bits & current row counter in 1st 2 bytes and Play pointer in 3rd & 4th bytes
#define PD 0x07 //Power Down
#define RD_REC_PTR 0x08 //Returns status bits & current row counter in 1st 2 bytes and Record pointer in 3rd & 4th bytes
#define DEVID 0x09 //Read the deivce ID register.
#define PLAY 0x40 //Play from current location without LED action until EOM or STOP command received
#define REC 0x41 //Record from current location without LED action until end of memory or STOP command received
#define ERASE 0x42 //Erase current message to EOM location
#define G_ERASE 0x43 //Erase all messages (not include Sound Effects)
#define RD_APC 0x44 //Returns status bits & current row counter in first 1st 2 bytes and the contents of APC register in 3rd & 4th bytes.
#define WR_APC1 0x45 //Write the data D10:D0 into the APC register with volume setting from VOL pin
#define WR_APC2 0x65 //Write the data D10:D0 into the APC register with volume setting from bits D2:D0
#define WR_NVCFG 0x46 //Write the contents of APC to NVCFG
#define LD_NVCFG 0x47 //Load contents of NVCFG to APC Register
#define FWD 0x48 //Forward play pointer to start address of next message. Forward will be ignored during operating, except Play
#define CHK_MEM 0x49 //Check circular memory
#define EXTCLK 0x4A //Enable/disable external clock mode
#define SET_PLAY 0x80 //Play from start address S10:S0 to end address E10:E0 or stop at EOM, depending on the D11 of APC
#define SET_REC 0x81 //Record from start address to end address E10:E0
#define SET_ERASE 0x82 //Erase from start address S10:S0 to end address E10:E0 [Stop cmd is ignored]

void setup() {
// Configuration des 4 pins de commande
byte clr;
pinMode(DATAOUT, OUTPUT);
pinMode(DATAIN, INPUT);
pinMode(SPICLOCK,OUTPUT);
pinMode(SLAVESELECT,OUTPUT);

digitalWrite(SLAVESELECT,HIGH); //disable device
SPCR = B01111111; //data lsb, clock high when idle, samples on falling
clr=SPSR;
clr=SPDR;
delay(10);

//Moniteur série
Serial.begin(9600);

digitalWrite(SLAVESELECT,LOW); //Mettre le module en route
spi_transfer(PU); // Power Up
spi_transfer(0x00); // data byte
digitalWrite(SLAVESELECT,HIGH);
delay(100);
Serial.println("Power Up");

digitalWrite(SLAVESELECT,LOW); //Clear
spi_transfer(CLR_INT); // Clear interupt and EOM bit
spi_transfer(0x00); // data byte
digitalWrite(SLAVESELECT,HIGH);
delay(100);
Serial.println("Clear");
}

void loop() {

// Lire un son enregistré dans la mémoire flash puis passe au suivant, en boucle
digitalWrite(SLAVESELECT,LOW);
spi_transfer(PLAY); // PLAY écouter le son pointé par le curseur
spi_transfer(0x00); // data byte
digitalWrite(SLAVESELECT,HIGH);
Serial.println("PLAY");
ready_wait(); //Attendre la fin de ce son
delay(3000);

digitalWrite(SLAVESELECT,LOW);
spi_transfer(FWD); // Décaler le curseur au son suivant
spi_transfer(0x00); // data byte
digitalWrite(SLAVESELECT,HIGH);
Serial.println("FWD");
}

// Fonction ready_wait
void ready_wait(){
byte byte1;
byte byte2;
byte byte3;
//Pour savoir si le son est terminé, tester le 1er bit du 3eme octet MISO
while(byte3<<7 != 128){
digitalWrite(SLAVESELECT,LOW);
byte1 = spi_transfer(RD_STATUS);
// Returns status bits & current row counter in first 1st 2 bytes
// and operating status in 3rd byte
byte2 = spi_transfer(0x00); // data byte
byte3 = spi_transfer(0x00); // data byte
digitalWrite(SLAVESELECT,HIGH);
}
delay(100);
} //Fin de la fonction

char spi_transfer(volatile char data)
{
SPDR = data; // Start the transmission
while (!(SPSR & (1<<SPIF))) // Wait for the end of the transmission
{
};
return SPDR; // return the received byte
}

Thanks remesh123.

Is this code fully working?

There was no description so just making sure its a working piece of code not a question you wanted to ask.

Thanks for posting to the thread.