WM8805 receiver

lemon

Supreme Member
3 March 2009
4,041
Ξεκινώ πάλι τις δοκιμές δίχως την μετακίνηση του bit, γιατί παρατηρώντας το πινακάκι, αυτό μας λέει ότι μας ενδιαφέρει το byte3 και οι θέσεις bit 0,1,2,3 δηλ. <4 και όχι μεγαλύτερο του 3 που έδινα.

Αναμείνατε...

--- Αυτόματη συγχώνευση μηνύματος ---

Δοκιμή με reg16 & reg17 ως ακολούθως

if (input > 1) {
uint8_t INTSTAT = ReadRegister(wm8805, 11); // poll (and clear) interrupt register;
//uint8_t SPDSTAT = ReadRegister(wm8805, 12);
//uint8_t RXCHAN4 = ReadRegister(wm8805, 16);
uint8_t RXCHAN4 = ReadRegister(wm8805, 17);

//uint8_t SpdifSampleRate2 = SpdifReadSampleRate();
// uint8_t SpdifSampleRate = (SPDSTAT >> 4) & 0x07;
//uint8_t SpdifSampleRate2 =(RXCHAN4 << 4) & 0x07;
uint8_t SpdifSampleRate2 = RXCHAN4;
if (INTSTAT != 0 || SpdifSampleRate2 != SpdifSampleRateOld) {
// If something has changed do a screen refresh.
Serial.print("INTSTAT:");Serial.println(INTSTAT,HEX);
//Serial.print("SPDSTAT:");Serial.println(SPDSTAT,HEX);
Serial.print("Spdif Sample rate:");Serial.println(SpdifSampleRate2,HEX);
Serial.print("Spdif Sample rate:");Serial.println(RXCHAN4,HEX);
switch (SpdifSampleRate2) {
case 0:
...

Συνεχίζει να δίνει ως τιμή μόνο την τιμή 0 (case 0)

πάω με την πρόταση του ΔημΔημ...

--- Αυτόματη συγχώνευση μηνύματος ---

Τζίφος και πάλι!
 

lemon

Supreme Member
3 March 2009
4,041
Δημήτρη η reg16 διαβάζει την Indicated Sampling Frequency , ενώ η reg17 τη δειγματοληψία του Original Sampling Frequency, σύμφωνα με το datasheet του WM8805
Εάν τώρα ανατρέξουμε στην προδιαγραφή που ακολουθεί, για τη μεν reg16 θέλουμε byte3 με θέσεις bit 24...27, για τη δε reg17 θέλουμε byte4 με θέσεις bit 36...39

Δεδομένου, ότι λαμβάνω μηδέν και από τους δύο καταχωρητές αντιλαμβάνομαι ότι η εντολή διαβάσματος της RXCHAN4 δεν διαβάζει στα σωστά bit.

Ερώτημα αυτό το byte3/4 πως μεταφράζεται σε εντολή;
 
Τα πράγματα είναι απλά. Ο κάθε register αποθηκεύει από ένα byte.. Οπότε για να διαβάσεις το byte 3 απλά διαβάζεις τον register 16 και για το byte 4 τον 17.

Οπότε η εντολή "int RXCHAN4 = ReadRegister(wm8805, 17);" σου φέρνει στην μεταβλητή RXCHAN4 το byte 4.

Δοκίμασε και την εντολή "byte RXCHAN4 = ReadRegister(wm8805, 17);" και μετά τα γνωστά println.. είναι πιο σωστό.
 

lemon

Supreme Member
3 March 2009
4,041
Δυστυχώς δεν τα κατάφερα, έχω μόνιμα τιμή στο μηδέν.

Πέτρο έκανες τίποτα;
 

Peter52

Established Member
25 November 2010
202
Re: Απάντηση: WM8805 receiver

Θέλω να βγάλω το 8805 από τον προενισχυτή και να αρχίσω δοκιμές. Μάλλον αύριο θα έχω νέα.
 

lemon

Supreme Member
3 March 2009
4,041
Πέτρο γιατί να το βγάλεις;
Δεν φτάνουν τα καλώδια DuPont στον ελεγκτή για να περάσεις τις αλλαγές;

--- Αυτόματη συγχώνευση μηνύματος ---

Εν τω μεταξύ για να ενημερώσω καλύτερα, βλέποντας ότι έχω μόνιμα μηδέν στην τιμή που παίρνει η μεταβλητή, δοκίμασα ότι τρόπο βρήκα ή ήξερα για να διαβάσει, είτε να διαβάσει όλο, είτε να μετακινήσει το bit είτε και με μάσκα, αλλά καμία επιτυχία.

Το ίδιο πρόβλημα είχαν αντιμετωπίσει και άλλοι, έχει γίνει και ερώτηση πριν 3-4 χρόνια στο diyaudio ακριβώς για το ίδιο θέμα αλλά απάντηση δεν δόθηκε ποτέ.
Στο σύνδεσμο που σας είχα δώσει στο μήνυμα που σας έγραψα για τη συγκεκριμένη register, ο τύπος (προφανώς) το έχει υλοποιήσει (για να το δώσει προς την κοινότητα).
Εκεί εάν το κοιτάξουμε χρησιμοποιεί δύο αρχεία ένα .h & .ccp, στο ένα δηλώνει τη μεταβλητή στο άλλο διαβάζει δίνοντας την εντολή read(xxxx).
Ψάχνοντας, είδα ότι η εντολή read(xxxx) σκέτη δεν υποστηρίζεται στο arduino, τη βρήκα μόνο σε σειριακή λειτουργία...
Αυτός βέβαια τη χρησιμοποιεί ως read(RXCHAN4_BIT);
 

Peter52

Established Member
25 November 2010
202
Re: Απάντηση: WM8805 receiver

Βρέθηκε τελικά η λύση.

Ορίζουμε μια μεταβλητή int RXCHAN4;

Και μέσα στο Loop βάζουμε τις γραμμές κώδικα που ακολουθούν:


RXCHAN4 = ReadRegister(wm8805, 16);
Serial.print(RXCHAN4);



Στο Serial Monitor πήρα τιμή 0 για CD ήτοι 44,1 και 3 για DVD που είναι 48, όπως λέει στο δίκτυο.

Δεν έχω άλλες συχνότητες για να δοκιμάσω.
Όπως καταλαβαίνετε μπορούμε από τη R16 να παίρνουμε την σωστή συχνότητα.
Επίσης σε κάποιο καταχωρητή θα παίρνουμε και τα bit 16 ή 24. Θα κοιτάξω να το βρω και αυτό.
 

lemon

Supreme Member
3 March 2009
4,041
Φαίνεται στο παράδειγμά σου Πέτρο, ότι δουλεύει.
Δεν έχω κάνει μέχρι τώρα κάτι διαφορετικό, αλλά σε μένα παραμένει στο μηδέν.

Έτσι και αλλιώς είτε ορίσεις τις μεταβλητές RXCHAN4/RXCHAN5 είτε μέσα είτε έξω από το loop, είναι το ίδιο πράγμα.
Πρέπει να δω με τι άλλο ίσως σχετίζεται σε μένα και αδυνατεί να αλλάξει τιμή.
 

Peter52

Established Member
25 November 2010
202
Re: Απάντηση: WM8805 receiver

Η μεταβλητή έχει οριστεί στην αρχή.

Η αντιστοιχία τιμών στη R16 είναι:

RXCHAN4 -- Sample rate
0 - 44,1
1 - 0
2 - 48
3 - 32
4 - 22
6 - - 24
8 - 88
10 - 96
12 - 178
14 - 192

Αν έχεις τέτοια αρχεία δοκίμασε να δεις αν βγαίνει το αντίστοιχο νούμερο.

Τον κώδικά που έγραψα να τον βάλεις πρώτο-πρώτο στο Loop.

Loop {

RXCHAN4 = ReadRegister(wm8805, 16);
Serial.print(RXCHAN4);
 

lemon

Supreme Member
3 March 2009
4,041
Πέτρο ευχαριστώ για τον κόπο.

Δεν έχει καμία σχέση που θα βάλεις τον κώδικα τελικά...το σφάλμα μου είναι στη ψηφιακή γεννήτρια.
Μέσω της ψηφιακής γεννήτριας σημάτων spdif, το αποτέλεσμα είναι πάντα μηδέν.
Το γύρισα μέσω ARTA και Foobar και εγέννετο φως αλλά και πάλι ημίφως!

Εξηγούμαι για να μην παρεξηγηθώ!

Έχω βάλει να διαβάσει RXCHAN4/RXCHAN5

44 ...δίνει 2/11 για RXCHAN4/RXCHAN5 αντίστοιχα
48...δίνει 2/11

88...δίνει 10/11
96...δίνει 10/11

176...δίνει 14/11
192...δίνει 14/11

Τώρα τι συμπέρασμα βγαίνει; Ότι εξαρτάται από την πηγή;
Δεν έχω εύκαιρο στο εργαστήρι, νορμάλ πηγή cd με ψηφιακή έξοδο για να δοκιμάσω...σε σένα πάντως οι τιμές βγήκαν σωστές...σε μένα ομαδοποιημένες στο RXCHAN4 όπως και στο SPDSTAT και σταθερές για το RXCHAN5
 

Peter52

Established Member
25 November 2010
202
Re: Απάντηση: WM8805 receiver

Δοκίμασα με κανονικό DVD player και πήρα τις ενδείξεις που ανέφερα. Δεν έχω πρόχειρες ψηλότερες δειγματοληψίες.
Η R17 που διαβάζεις είναι το μήκος της λέξης ήτοι 0010 16 bits μα ανώτερη τιμή τα 20 bits ενώ 0011 πάλι 16 bits με ανώτερη τιμή τα 24 bits.
 

lemon

Supreme Member
3 March 2009
4,041
Με κούρασε και σταμάτησα μετά από πάμπολλες ώρες ενασχόλησης.
Είχα βάλει την έξοδο spdif της emu0404 και το δοκίμαζα μέσω αυτής.

Σε κάποιο σημείο άρχιζε να λειτουργεί αλλά όχι για όλες τις συχνότητες. 44/48/96 πήγαν μια χαρά, αλλά στα 88 και στο διπλό 176/192 μου τα έκανε μαντάρα δείχνοντας 44 επειδή σε αυτές τις συχνότητες το RXCHAN4 ταυτιζόταν με το μηδέν.
Κατά τη γνώμη μου θέλει περισσότερο ψάξιμο, γιατί δεν είναι θέμα να διαβάσουμε όλο το πεδίο...παρά μόνο τα συγκεκριμένα bit και με τη σωστή σειρά.
 
Έκανα και εγώ τις δοκιμές μου και πιστεύω ότι έβγαλα άκρη.

Για αρχή, θέλουμε να διαβάσουμε τον Register 16. Κάνουμε κάτι τέτοιο:

Code:
    SR = ReadRegister(wm8805, 16);
    Serial.print("Detected SR: ");
    switch (SR) {
      
      case B0001:
      Serial.println("not indicated");
      break;

      case B0011:
      Serial.println("32 kHz");
      break;

      case B1110:
      Serial.println("192 kHz");
      break;

      case B1010:
      Serial.println("96 kHz");
      break;

      case B0010:
      Serial.println("48 kHz");
      break;

      case B0110:
      Serial.println("24 kHz");
      break;
      
      case B1100:
      Serial.println("176.4 kHz");
      break;

      case B1000:
      Serial.println("88.2 kHz");
      break;

      case B0000:
      if (fs == 192) {
          Serial.println("192 kHz");
        }
        else
        Serial.println("44.1 kHz");
      break;

      case B0100:
      Serial.println("22.05 kHz");
      break;
    } // switch samplerate

Υπόψη, το variable "SR" πρέπει να το δηλώσετε ως byte στην αρχή του κώδικα.

Θα παρατηρήσετε μια "χακιά" στο case B0000, το οποίο δείχνει κανονικά τα 44.1Κ. Του έχω πει αν ταυτόχρονα το fs είναι 192, να δείχνει 192. Αυτό ήταν απαραίτητο για κάποιο λόγο, γιατί μερικές φορές μπερδευόταν όταν γύριζα από οτιδήποτε σε 192Κ. Στα 88.2Κ πάντως δεν παρατήρησα κανένα πρόβλημα.. Τα 176 δεν τα έχω δοκιμάσει γιατί δεν έχω πρόχειρο device που να δίνει τέτοιο SR.

Υπόψη, για να παίξει σωστά το παραπάνω, πρέπει να γίνει και αυτή η αλλαγή (το κόκκινο) σε πιο πάνω κομμάτι του κώδικα:

Code:
      case 0:
      Serial.println("192 kHz");
      fs = [COLOR=#FF0000]192[/COLOR];
      WriteRegister(wm8805, 29, 128);                 // set SPD_192K_EN to 1
      delay(500);
      break;
 

lemon

Supreme Member
3 March 2009
4,041
Δημήτρη, το fs=192 που το δηλώνεις νωρίτερα από την case της SR, είναι μέσα στη συνθήκη του ελέγχου για τα 192; Που προσπαθεί είτε με 192 κλείδωμα ή normal mode?

Είναι εύκολο να βάλεις και το τμήμα ελέγχου των 192/176 (το βλέπω σε case?)...γιατί σε μένα βλεπω ότι πέφτει σε ατέρμονη προσπάθεια ελέγχου όταν είναι ξεκλείδωτο το spdf με αποτέλεσμα να έχω ατέρμονη εμφάνιση 44,1/192 όταν είναι ξεκλείδωτο.

Για τα 176, μπορείς να βάλεις το Foobar να δίνει έξοδο fixed PCM 176 όταν παίζεις dsd αρχείο, οπότε μπορείς να κάνεις τις δοκιμές ... και με αυτόν τον τρόπο.
 

Peter52

Established Member
25 November 2010
202
Re: Απάντηση: WM8805 receiver

Για ενημέρωση δοκίμασα τον κώδικα του Δημήτρη αλλά στο Squeezebox Classic μάλλον δεν λαμβάνει πληροφορία και βγάζει SR = B1111. Εκεί κολλάει και δεν υπάρχει περίπτωση για να εμφανίσει κάτι. Δεν υπάρχει δηλαδή στον κώδικα αντίστοιχο case. Στο IEC 60958-3 ρυθμίζονται κάποια πράγματα που βάζουν οι κατασκευαστές ψηφιακών. Ενώ με το TOUCH δείχνει κανονικές ενδείξεις. Πιάνει και τα 44, 1 και τα 96.

Επί τη ευκαιρία πώς δείχνει δυαδικά νούμερα το Serial Monitor. ( Serial.print(SR, ???))?
 

lemon

Supreme Member
3 March 2009
4,041
BIN αν θυμάμαι καλώς από τις δοκιμές μου.

Αυτό που αναφέρεις είναι σωστότατο.
Η υλοποίηση της spdif από τους κατασκευαστές είναι ολίγο...κουκουρούκου!
Ήδη όπως ανέφερα η ψηφιακή γεννήτρια που έχω δεν δίνει πληροφορίες στα συγκεκριμένα byte, ενώ από ότι βλέπω η emu0404 δίνει μερικές και σε κάποιες άλλες δίνει απλά ένδειξη μηδέν δηλ. 44.1
Ετοιμάζω κάτι διαφορετικό αλλά εάν αποδειχτώ σωστός ... τελικά μάλλον δεν έχει νόημα η εμφάνιση της δειγματοληψίας στο spdif, γιατί δεν τηρείται το πρωτόκολλο από όλους...
 

lemon

Supreme Member
3 March 2009
4,041
Τελικά σε μένα με τον παρακάτω κώδικα μου δούλεψε άψογα.
Προσπάθησα να το φτιάξω με τέτοιο τρόπο που να δουλέψει και σε μία σωστή πηγή με spdif κατά τις προδιαγραφές που αναφέραμε και σε μια πηγή όπως η emu.
Τώρα εάν η έξοδος της emu είναι κάτι το σύνηθες...ποιος ξέρει!

Στις δηλώσεις των μεταβλητών έδωσα:
Code:
byte SPDIF_SR; 
uint8_t SPDSTAT;

Στην αρχή του loop έδωσα:
Code:
SPDSTAT = ReadRegister(wm8805, 12);
SPDIF_SR = ReadRegister(wm8805, 16);

Ενώ την case για τον έλεγχο της spdif δειγματοληψίας το δήλωσα ως εξής:
Υπόψη δεν έκανα καμία προσθήκη fs μεταβλητής.
Code:
switch (SPDIF_SR) {
      
      case B0001:
        Serial.println("not indicated");
        break;

      case B0011:
        Serial.println("32 kHz");
        mydisp.setColor(Snow);
        mydisp.drawBitmap(00, 51, 160, 78, usboneimage);
        break;

      case B1110:        
          Serial.println("192 kHz");
        break;

      case B1010:
        Serial.println("96 kHz");        
        break;

      case B0010:
        Serial.println("48 kHz");
        break;

      case B0110:
        Serial.println("24 kHz");
        break;
      
      case B1100:       
        Serial.println("176.4 kHz");
        break;

      case B1000:
        Serial.println("88.2 kHz");
        break;

      case B0000:
      
        if (SPDSTAT == 80) {
          Serial.println("88.2 kHz");
          break;
          }
        if (SPDSTAT == 4) {
          Serial.println("176.4 kHz");
           break;
          }
        if (SPDSTAT == 64) {
          Serial.println("192 kHz");
           break;
          }
       else {
            Serial.println("44.1 kHz");
          }       
        break;

Καιρός να τα φτιάξουμε όλα αυτά σε μια ωραία Void και να μην είναι όλο αυτό μέσα στο loop, τι πιστεύετε;
 

lemon

Supreme Member
3 March 2009
4,041
Μισή χαρά πήρα τελικά.
Δεν ξέρω μου φάνηκε άβυσσος η όλη διαδικασία. Μαθαίνουμε βέβαια αλλά πολύ παίδεμα.
Ενώ η δειγματοληψία πήγε περίφημα, στο εργαστήρι δεν δοκίμασα να ακούσω, μόλις το κατέβασα για να δω από dvd πως συμπεριφέρεται, διαπίσωσα αδυναμία παιξίματος από spdif.
Πολλές διακοπές σε σημείο που οι παύσεις να είναι περισσότερες του ήχου. Αυτό από όλες τις εισόδους.
Κατάλαβα ότι ναι μεν η δειγματοληψία διορθώθηκε κάτι άλλο χάλασε.

Εν κατακλείδι μετά από πάμπολο ψάξιμο βλέπω ότι το θέμα σχετίζεται με το τι υπάρχει πριν τον έλεγχο για κλείδωμα μεταξύ 192/normal mode.

O αρχικός κώδικας που είχαμε από το διαδίκτυο γράφει:
if (bitRead(SPDSTAT,6))
{...}
με αυτό παίζει κανονικά, αλλά οι δειγματοληψίες μου πάνε ανά ζευγάρια όπως δηλ. είχαμε μέσω SPDSTAT.

Εάν αλλάξει η συνθήκη σε κάτι
if (SPDIF_SR & 0x04)
ή
if (SPDIF_SR &= B00001111)
όπου SPDIF_SR είναι η τιμή που διαβάζουμε από τη reg16.
Tότε οι δειγματοληψίες βαίνουν άψογες αλλά οι διακοπές άπειρες!

Δοκιμάσατε να ακούσετε ή έχετε κάνει δοκιμές μόνο με το να βλέπετε τον κώδικα μέσω σειριακής;
 

Peter52

Established Member
25 November 2010
202
Re: Απάντηση: WM8805 receiver

Έχω βγάλει από το Loop τον έλεγχο του 8805 και έχω κανονίσει να επαναλαμβάνεται κατά ορισμένα χρονικά διαστήματα.

Σου στέλνω το void που έχει δημιουργηθεί. Προφανώς πρέπει να βάλεις μερικά δικά σου για την οθόνη και το USB.

Code:
void checkWM8805()
{
    previousMillis_3 = millis();
    
    uint8_t INTSTAT = ReadRegister(wm8805, 11); // poll (and clear) interrupt register;
    uint8_t SPDSTAT = ReadRegister(wm8805, 12);
    uint8_t SampleRate = (SPDSTAT >> 4) & 0x07;
    if (INTSTAT != 0 || SampleRate != SampleRateOld) {
      // If something has changed do a screen refresh.
      Serial.print("INTSTAT:");Serial.println(INTSTAT,HEX);
      Serial.print("SPDSTAT:");Serial.println(SPDSTAT,HEX);
      Serial.print("Sample rate:");
      switch (SampleRate) {
        case 0x03:
          Serial.println("32 kHz");
          if (strType != "32 kHz") {
            strType = "32 kHz";
            screenCurrent(); }
          break;
        case 0x02:
          Serial.println("44/48 kHz");
          if (strType != "44/48 kHz") {
            strType = "44/48 kHz";
            screenCurrent(); }
          break;
        case 0x01:
          Serial.println("88/96 kHz");
          if (strType != "88/96 kHz") {
            strType = "88/96 kHz";
            screenCurrent(); }
          break;
        case 0x00:
          Serial.println("192 kHz");
          if (strType != "192 kHz") {
            strType = "192 kHz";
            screenCurrent(); }
          break;
        default:
          Serial.println("Unlocked");
          if (strType != "Unlocked") {
            strType = "Unlocked";
            screenCurrent(); }
          break;
      }
      SampleRateOld = SampleRate;
    }
    if (SampleRate & 0x04) {
      // If this is unlocked then try and switch around normal and 192khz mode
      // until it locks. That is kinda hackish but it seems to work.
      if (toggle) {
        Serial.println("trying 192 kHz mode...");
        WriteRegister(wm8805, 6, 8);    // set PLL_N to 8
        WriteRegister(wm8805, 5, 12);   // set PLL_K to 0C49BA (0C)
        WriteRegister(wm8805, 4, 73);   // set PLL_K to 0C49BA (49)
        WriteRegister(wm8805, 3, 186);  // set PLL_K to 0C49BA (BA)
        WriteRegister(wm8805, 29, 1);   // This might not be needed set SPD_192K_EN to 1
        toggle = 0;
      } else {
        Serial.println("trying normal mode...");
        WriteRegister(wm8805, 6, 7);    // set PLL_N to 7
        WriteRegister(wm8805, 5, 54);   // set PLL_K to 36FD21 (36)
        WriteRegister(wm8805, 4, 253);  // set PLL_K to 36FD21 (FD)
        WriteRegister(wm8805, 3, 33);   // set PLL_K to 36FD21 (21)
        WriteRegister(wm8805, 29, 0);   // This might not be needed set SPD_192K_EN to 0
 
        toggle = 1;
      } // if toggle
      delay(100);  // Give some time for WM8805 to lock
    }
  }
 

lemon

Supreme Member
3 March 2009
4,041
Σήμερα ήταν η μέρα...
Ενώ μέσω της spdif (emu) αυτά που έγραψα στο #78 ισχύουν, μόλις το δοκίμασα μέσω ενός τυπικού toshiba dvd player και οι δειγματοληψίες στα 44/48 λειτουργούν κανονικά!
Με επιλογή if (bitRead(SPDSTAT,6).
Προφανώς τα κονσουμεράδικα μηχανάκια ακολουθούν κατά πόδας το πρότυπο, ενώ εταιρίες με υψηλές προδιαγραφές...το έχουν στείλει κάπως "αδιάβαστο".

Πέτρο, κοιτούσα τη void που έβαλες.
Αυτή λογικά την καλείς μέσα στο case επιλογής εισόδων, έτσι;
Αν όμως δεν αλλάξεις είσοδο για να ξανατρέξει την void, αλλά αλλάξεις αρχείο λογικά δεν θα έχεις αλλαγή της συχνότητας.
Έγραψες όμως ότι έχεις βάλει (μάλλον μέσα στο case της εισόδου) συνθήκη που ξανατρέχει τη void...