Skocz do zawartości

STM32F107RCT6 - SPI nadaje, ale nie odbiera


Pomocna odpowiedź

Próbuję właśnie uruchomić odtwarzacz MP3 VS1003 na jednej z moich płytek z STM32F107RCT6. Używam do tego biblioteki Andy'ego Karpova, którą kiedyś przeportowałem i przetestowałem na PIC32, a teraz próbuję ją przetestować na STM32. Kof wygląda następująco:

vs1003.c

/*
 Copyright (C) 2012 Andy Karpov <andy.karpov@gmail.com>
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 version 2 as published by the Free Software Foundation.
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#include "vs1003.h"
#include "time.h"
#include "stm32f1xx_hal.h"
#include "main.h"

#ifndef min
#define min(a,b)            (((a) < (b)) ? (a) : (b))
#endif

extern SPI_HandleTypeDef hspi1;

#define vs1003_chunk_size 32

/****************************************************************************/

// VS1003 SCI Write Command byte is 0x02
#define VS_WRITE_COMMAND 0x02

// VS1003 SCI Read COmmand byte is 0x03
#define VS_READ_COMMAND  0x03

// SCI Registers

#define SCI_MODE            0x0
#define SCI_STATUS          0x1
#define SCI_BASS            0x2
#define SCI_CLOCKF          0x3
#define SCI_DECODE_TIME     0x4
#define SCI_AUDATA          0x5
#define SCI_WRAM            0x6
#define SCI_WRAMADDR        0x7
#define SCI_HDAT0           0x8
#define SCI_HDAT1           0x9
#define SCI_AIADDR          0xa
#define SCI_VOL             0xb
#define SCI_AICTRL0         0xc
#define SCI_AICTRL1         0xd
#define SCI_AICTRL2         0xe
#define SCI_AICTRL3         0xf
#define SCI_num_registers   0xf

// SCI_MODE bits

#define SM_DIFF             0
#define SM_LAYER12          1
#define SM_RESET            2
#define SM_OUTOFWAV         3
#define SM_EARSPEAKER_LO    4
#define SM_TESTS            5
#define SM_STREAM           6
#define SM_EARSPEAKER_HI    7
#define SM_DACT             8
#define SM_SDIORD           9
#define SM_SDISHARE         10
#define SM_SDINEW           11
#define SM_ADPCM            12
#define SM_ADCPM_HP         13
#define SM_LINE_IN          14

// Register names

typedef enum {
    reg_name_MODE = 0,
    reg_name_STATUS,
    reg_name_BASS,
    reg_name_CLOCKF,
    reg_name_DECODE_TIME,
    reg_name_AUDATA,
    reg_name_WRAM,
    reg_name_WRAMADDR,
    reg_name_HDAT0,
    reg_name_HDAT1,
    reg_name_AIADDR,
    reg_name_VOL,
    reg_name_AICTRL0,
    reg_name_AICTRL1,
    reg_name_AICTRL2,
    reg_name_AICTRL3
} register_names_t;

const char * register_names[] =
{
  "MODE",
  "STATUS",
  "BASS",
  "CLOCKF",
  "DECODE_TIME",
  "AUDATA",
  "WRAM",
  "WRAMADDR",
  "HDAT0",
  "HDAT1",
  "AIADDR",
  "VOL",
  "AICTRL0",
  "AICTRL1",
  "AICTRL2",
  "AICTRL3",
};

 static inline void await_data_request(void);
 static inline void control_mode_on(void);
 static inline void control_mode_off(void);
 static inline void data_mode_on(void);
 static inline void data_mode_off(void);
 static uint8_t VS1003_SPI_transfer(uint8_t outB);


/****************************************************************************/

uint16_t VS1003_read_register(uint8_t _reg) {
  uint16_t result;
  control_mode_on();
  delay_us(1); // tXCSS
  VS1003_SPI_transfer(VS_READ_COMMAND); // Read operation
  VS1003_SPI_transfer(_reg); // Which register
  result = VS1003_SPI_transfer(0xff) << 8; // read high byte
  result |= VS1003_SPI_transfer(0xff); // read low byte
  delay_us(1); // tXCSH
  await_data_request();
  control_mode_off();
  return result;
}

/****************************************************************************/

void VS1003_write_register(uint8_t _reg,uint16_t _value) {
  control_mode_on();
  delay_us(1); // tXCSS
  VS1003_SPI_transfer(VS_WRITE_COMMAND); // Write operation
  VS1003_SPI_transfer(_reg); // Which register
  VS1003_SPI_transfer(_value >> 8); // Send hi byte
  VS1003_SPI_transfer(_value & 0xff); // Send lo byte
  delay_us(1); // tXCSH
  await_data_request();
  control_mode_off();
}

/****************************************************************************/

void VS1003_sdi_send_buffer(const uint8_t* data, int len) {
  int chunk_length;
  
  data_mode_on();
  while ( len ) {
    await_data_request();
    delay_us(3);
    chunk_length = min(len, vs1003_chunk_size);
    len -= chunk_length;
    while ( chunk_length-- ) VS1003_SPI_transfer(*data++);
  }
  data_mode_off();
}

/****************************************************************************/

void VS1003_sdi_send_zeroes(int len) {
  int chunk_length;  
  data_mode_on();
  while ( len ) {
    await_data_request();
    chunk_length = min(len,vs1003_chunk_size);
    len -= chunk_length;
    while ( chunk_length-- ) VS1003_SPI_transfer(0);
  }
  data_mode_off();
}

/****************************************************************************/

void VS1003_begin(void) {
  // Keep the chip in reset until we are ready
  HAL_GPIO_WritePin(VS_XRST_GPIO_Port, VS_XRST_Pin, 0);

  // The SCI and SDI will start deselected
  HAL_GPIO_WritePin(VS_XCS_GPIO_Port, VS_XCS_Pin, 1);
  HAL_GPIO_WritePin(VS_XDCS_GPIO_Port, VS_XDCS_Pin, 1);

  // Boot VS1003
  printf("Booting VS1003...\r\n");

  HAL_Delay(1);

  // init SPI slow mode
  //SPI configuration
  //8 bit master mode, CKE=1, CKP=0
  MODIFY_REG(hspi1.Instance->CR1, SPI_BAUDRATEPRESCALER_256, SPI_BAUDRATEPRESCALER_256); //281 kHz

  // release from reset
  HAL_GPIO_WritePin(VS_XRST_GPIO_Port, VS_XRST_Pin, 1);
  
  // Declick: Immediately switch analog off
  VS1003_write_register(SCI_VOL,0xffff); // VOL

  /* Declick: Slow sample rate for slow analog part startup */
  VS1003_write_register(SCI_AUDATA,10);

  HAL_Delay(100);

  /* Switch on the analog parts */
  VS1003_write_register(SCI_VOL,0xfefe); // VOL
  
  printf("VS1003 still booting\r\n");

  VS1003_write_register(SCI_AUDATA,44101); // 44.1kHz stereo

  VS1003_write_register(SCI_VOL,0x2020); // VOL
  
  // soft reset
  VS1003_write_register(SCI_MODE, (1 << SM_SDINEW) | (1 << SM_RESET) );
  HAL_Delay(1);
  await_data_request();
  VS1003_write_register(SCI_CLOCKF,0xB800); // Experimenting with higher clock settings
  HAL_Delay(1);
  await_data_request();

  // Now you can set high speed SPI clock
  //SPI configuration
  ////8 bit master mode, CKE=1, CKP=0
  MODIFY_REG(hspi1.Instance->CR1, SPI_BAUDRATEPRESCALER_256, SPI_BAUDRATEPRESCALER_32);       //2.5 MHz

  printf("VS1003 Set\r\n");
  VS1003_printDetails();
  printf("VS1003 OK\r\n");
}

/****************************************************************************/

void VS1003_setVolume(uint8_t vol) {
  uint16_t value = vol;
  value <<= 8;
  value |= vol;

  VS1003_write_register(SCI_VOL,value); // VOL
}

/****************************************************************************/

void VS1003_startSong(void) {
  VS1003_sdi_send_zeroes(10);
}

/****************************************************************************/

void VS1003_playChunk(const uint8_t* data, size_t len) {
  VS1003_sdi_send_buffer(data,len);
}

/****************************************************************************/

void VS1003_stopSong(void) {
  VS1003_sdi_send_zeroes(2048);
}

/****************************************************************************/

void VS1003_print_byte_register(uint8_t reg) {
  char extra_tab = strlen(register_names[reg]) < 5 ? '\t' : 0;
  printf("%02x %s\t%c = 0x%02x\r\n", reg, register_names[reg], extra_tab, VS1003_read_register(reg));
}

/****************************************************************************/

void VS1003_printDetails(void) {
  printf("VS1003 Configuration:\r\n");
  int i = 0;
  while ( i <= SCI_num_registers )
    VS1003_print_byte_register(i++);
}

/****************************************************************************/

void VS1003_loadUserCode(const uint16_t* buf, size_t len) {
  while (len) {
    uint16_t addr = *buf++; len--;
    uint16_t n = *buf++; len--;
    if (n & 0x8000U) { /* RLE run, replicate n samples */
      n &= 0x7FFF;
      uint16_t val = *buf++; len--;
      while (n--) {
	    printf("W %02x: %04x\r\n", addr, val);
        VS1003_write_register(addr, val);
      }
    } else {           /* Copy run, copy n samples */
      while (n--) {
	uint16_t val = *buf++; len--;
	printf("W %02x: %04x\r\n", addr, val);
        VS1003_write_register(addr, val);
      }
    }
  }
}


  static inline void await_data_request(void) {
    while ( !HAL_GPIO_ReadPin(VS_DREQ_GPIO_Port, VS_DREQ_Pin) );
  }

  static inline void control_mode_on(void) {
    HAL_GPIO_WritePin(VS_XDCS_GPIO_Port, VS_XDCS_Pin, 1);
    HAL_GPIO_WritePin(VS_XCS_GPIO_Port, VS_XCS_Pin, 0);
  }

  static inline void control_mode_off(void) {
	  HAL_GPIO_WritePin(VS_XCS_GPIO_Port, VS_XCS_Pin, 1);
  }

  static inline void data_mode_on(void) {
    HAL_GPIO_WritePin(VS_XCS_GPIO_Port, VS_XCS_Pin, 1);
    HAL_GPIO_WritePin(VS_XDCS_GPIO_Port, VS_XDCS_Pin, 0);
  }

  static inline void data_mode_off(void) {
	  HAL_GPIO_WritePin(VS_XDCS_GPIO_Port, VS_XDCS_Pin, 1);
  }
  
  static uint8_t VS1003_SPI_transfer(uint8_t outB) {
	uint8_t answer;

	HAL_SPI_TransmitReceive(&hspi1, &outB, &answer, 1, HAL_MAX_DELAY);
    return answer;
}
  

/*
void VS1003_SPI_conf(){
	//SPI1 configuration     
    SPI1CON = (_SPI1CON_ON_MASK  | _SPI1CON_CKE_MASK | _SPI1CON_MSTEN_MASK);    //8 bit master mode, CKE=1, CKP=0
    SPI1BRG = (GetPeripheralClock()-1ul)/2ul/4000000;       //4MHz
}

uint8_t VS1003_SPIPutChar(uint8_t outB){
    SPI1BUF = outB;
    while (SPI1STATbits.SPITBF);
    while (!SPI1STATbits.SPIRBF);
    return SPI1BUF;
}
*/

vs1003.h

/* 
 * File:   vs1003.h
 * Author: Przemyslaw Stasiak
 *
 * Created on 4 maja 2020, 10:33
 */

#ifndef VS1003_H
#define	VS1003_H

#include <stdlib.h>
#include <stdint.h>

#define RXNE    0x01
#define TXE     0x02
#define BSY     0x80

#ifdef	__cplusplus
extern "C" {
#endif

//public functions
void VS1003_begin(void);    
uint16_t VS1003_read_register(uint8_t _reg);
void VS1003_write_register(uint8_t _reg,uint16_t _value);
void VS1003_sdi_send_buffer(const uint8_t* data, int len);
void VS1003_sdi_send_zeroes(int len);
void VS1003_setVolume(uint8_t vol);
void VS1003_startSong(void);
void VS1003_playChunk(const uint8_t* data, size_t len);
void VS1003_stopSong(void);
void VS1003_print_byte_register(uint8_t reg);
void VS1003_printDetails(void);
void VS1003_loadUserCode(const uint16_t* buf, size_t len);


#ifdef	__cplusplus
}
#endif

#endif	/* VS1003_H */

Niestety, kod nie chce działać prawidłowo. Procedura inicjacji vs1003 przechodzi, ale na końcu zwracana jest dziwna zawartość rejestrów - wszystkie mają 0x00. Po wielokrotnym przeglądnięciu kodu nie znalazłem w nim niczego podejrzanego. Podpiąłem więc analizator logiczny do poszczególnych linii i uzyskałem następujący wynik:

 1716930985_Zrzutekranuz2021-02-0720-00-01.thumb.png.ef1be1eb977bfa6b6d6a927fb180218c.png709138564_Zrzutekranuz2021-02-0720-00-07.thumb.png.df5a1343b43956cf86496997995738de.png

Jak widzicie dane są wysyłane, ale nie ma aktywności na linii MISO, a więc za każdym razem odczytywane jest 0x00. Linia ta nie jest jednak zwarta do masy, bo jak widać domyślnie znajduje się w stanie wysokim i schodzi o niskiego dopiero po rozpoczęciu transmisji. Dane zwrócone przez analizator wydają się być konsystentne z programem. Mamy tutaj powtarzającą się sekwencję czterech bajtów: 3 (rozkaz odczytu rejestru), 0-15 (numer rejestru), 255, 255 (dwa bajty transmitowane podczas odczytu).

 

Konfiguracja SPI wygląda następująco:

1434673389_Zrzutekranuz2021-02-0720-08-15.thumb.png.7dc361eff7de3e454c5b0fbe5217e08f.png

Czy takie zachowanie interfejsu SPI może być spowodowane jakimś znanym błędem software'owym, czy też powinienem szukać przyczyny w sprzęcie? Jeśli chodzi o VS1003, to projekty płytki zostać "pożyczony" z działającego i przetestowanego urządzenia z PIC32. Oczywiście istnieje możliwość, że sam układ jest uszkodzony, jednak wolałbym wyeliminować wszystkie inne opcje, zanim zamówię jeszcze jeden egzemplarz i zacznę go wymieniać...

Link to post
Share on other sites

Pierwsza rzecz jaka rzuca się w oczy to to, że VS1003 wymaga zegara SCK "zaparkowanego" w stanie niskim. Wtedy odpalasz XCS i pierwsze zbocze narastające wpycha do chipu pierwszy bit danych. Na opadającym Twój Master powinien wystawić kolejny bit na MOSI. Jak działa ten mechanizm z punktu widzenia VS1003 gdy mu odwróciłeś zegar?

A następnym razem pokaż na ekranie analizatora w szczegółach jedną całą transakcję SPI tak by można było zobaczyć co się kiedy zmienia względem zegara a nie wszystko razem skompresowane tak, że nic nie widać albo tylko ostatni(?) bajt. Skoro jedna wymiana SPI nie działa to 4 też nie działają, to rozumiemy. Z żadnego z dwóch obrazków nie można wywnioskować czy poprawnie wysyłasz kod komendy i adres.

Link to post
Share on other sites
4 minuty temu, marek1707 napisał:

Pierwsza rzecz jaka rzuca się w oczy to to, że VS1003 wymaga zegara SCK "zaparkowanego" w stanie niskim. Wtedy odpalasz XCS i pierwsze zbocze narastające wpycha do chipu pierwszy bit danych. Na opadającym Twój Master powinien wystawić kolejny bit na MOSI. Jak działa ten mechanizm z punktu widzenia VS1003 gdy mu odwróciłeś zegar?

Który parametr za to odpowiada? Jak to zmienić?

4 minuty temu, marek1707 napisał:

A następnym razem pokaż na ekranie analizatora w szczegółach jedną całą transakcję SPI tak by można było zobaczyć co się kiedy zmienia względem zegara a nie wszystko razem skompresowane tak, że nic nie widać albo tylko ostatni(?) bajt. Skoro jedna wymiana SPI nie działa to 4 też nie działają, to rozumiemy. Z żadnego z dwóch obrazków nie można wywnioskować czy poprawnie wysyłasz kod komendy i adres.

Jakby coś,to wrzucam załącznik z wyeksportowanym kompletem danych z analizatora.

Swoją drogą zauważyłem, że jedna ze starszych wersji płytki (ta na PIC24) również ma do czynienia z podobnym błędem. Tam odtwarzanie co prawda działa, ale przy starcie zawartość wszystkich rejestrów również wyświetla się jako 0x00. Na płytce z PIC32 mam działający odtwarzacz oraz prawidłowe wartości rejestrów. Na STM32 jak na razie ani nie udało mi się uruchomić odtwarzania, ani wyświetlić zawartości rejestrów przy starcie.

STMVS1003.zip

Link to post
Share on other sites
27 minut temu, atlantis86 napisał:

Który parametr za to odpowiada? Jak to zmienić?

Musisz pracować w "najbardziej natywnym" trybie SPI, tzw, mode 0. Ustawiasz CPOL=0 i CPHA=0. W Cube to pewnie będzie "Polarity: Low, Phase: 1 edge".

Link to post
Share on other sites
4 minuty temu, marek1707 napisał:

Musisz pracować w "najbardziej natywnym" trybie SPI, tzw, mode 0. Ustawiasz CPOL=0 i CPHA=0. W Cube to pewnie będzie "Polarity: Low, Phase: 1 edge".

Ok. Ustawiłem "Polarity: Low" (CPOL=0), a potem próbowałem zarówno Phase 1 jak i Phase 2. Ciągle rejestry są odczytywane jako 0x00...

Gdzieś jeszcze znajdować się problem? Zastanawia mnie jeszcze konstrukcja, w której próbuję zmieniać prescaler:

MODIFY_REG(hspi1.Instance->CR1, SPI_BAUDRATEPRESCALER_256, SPI_BAUDRATEPRESCALER_32);       //2.5 MHz

To nie tutaj gdzieś coś się miesza?

Link to post
Share on other sites

Pokaż jedną pełną transakcję SPI odczytu z rejestru o którym wiesz, że nie powinien mieć 0x0000.

Link to post
Share on other sites
(edytowany)
1 godzinę temu, marek1707 napisał:

Pokaż jedną pełną transakcję SPI odczytu z rejestru o którym wiesz, że nie powinien mieć 0x0000.

W tej chwili dysponuję niestety tylko przykładem z błędnie ustalonym CPOL. To gotowa płytka i podpięcie się analizatorem wymaga lutowania kynaru do dość cienkich ścieżek. Dzisiaj zdążyłem już odłączyć te kable, podłączę je ponownie dopiero jutro, żeby zobaczyć jak zachowuje się układ przy nowej konfiguracji SPI.

Na obrazku przykład odczytu rejestru o adresie 0x00 (MODE), który na działającym układzie z PIC32 ma wartość 0x800.

759775835_Zrzutekranuz2021-02-0722-27-19.thumb.png.10668dc50522bad0025810c0a353b2a9.png

EDIT: Jednak podpiąłem ponownie analizator. Poniżej przebiegi podczas próby odczytu tego samego rejestru, z CPOL: Low i CPHA: 2 Edge.

1275183238_Zrzutekranuz2021-02-0723-24-42.thumb.png.f1ee7292035f2beb39d818e8acd09571.png

Edytowano przez atlantis86
Link to post
Share on other sites

No ale przecież CPHA miało być "1 edge". To nie jest wszystko jedno. Zobacz, wysyłasz pattern 00000011 czyli READ, ale pierwszy bit wysoki wystawiany jest teraz jednocześnie z narastającym zboczem szóstego zegara. Musi być pół okresu wcześniej, aby SLAVE mógł się na to przygotować. Może nie widzisz różnicy w działaniu, może błąd jest gdzie indziej, ale pewne warunki brzegowe musisz spełnić. Masz datasheet, masz analizator, patrzysz na to, nie widzisz jak jest i nie wiesz jak ma być? To po co Ci te narzędzia? Potwierdzasz sobie nimi, że "Wszystko w porządku więc od początku" jak śpiewa klasyk?

Link to post
Share on other sites
3 minuty temu, marek1707 napisał:

No ale przecież CPHA miało być "1 edge".

To też sprawdzę, tylko podczas testów uszkodziłem ścieżkę i wolę już tego nie lutować o tej porze.

Poza tym jak mówiłem - testowałem działanie programu przy "1 Edge" i zachowuje się od dokładnie tak samo - również wszystkie rejestry mają 0x00, więc nie widzę powodu, dla którego przebieg na analizatorze wyglądać inaczej.

Sprawdziłem też jak właściwie wygląda konfiguracja SPI w działającym układzie na PIC32:

SPI1CON = (_SPI1CON_ON_MASK  | _SPI1CON_CKE_MASK | _SPI1CON_MSTEN_MASK);    //8 bit master mode, CKE=1, CKP=0

Zgodnie z dokumentacją:

Cytat

CKE: SPI Clock Edge Select bit
1 = Serial output data changes on transition from active clock state to idle clock state (see CKP bit)
0 = Serial output data changes on transition from idle clock state to active clock state (see CKP bit)

bit 6 CKP: Clock Polarity Select bit
1 = Idle state for clock is a high level; active state is a low level
0 = Idle state for clock is a low level; active state is a high level

W moim kodzie na PIC32 CKP jest wyzerowany, czyli CLK w stanie bezczynności jest niski. CKE jest ustawiony, co w tym przypadku oznacza zmianę danych na zboczu opadającym zegara. To byłoby odpowiednikiem "2 edge" czy się mylę? I taka konfiguracja działa prawidłowo we wspomnianym układzie z PIC32...

 

Link to post
Share on other sites
(edytowany)

Mylisz się. Przeczytaj jeszcze raz co napisałeś (zmiana danych na opadającym zboczu zegara) i przyjrzyj się jak to zrobiłeś na STM i co widać na obrazku z analizatora (kiedy zmienia się MOSI).

EDIT: Tak jak napisałem: może przyczyn jest kilka (np. trzymasz układ w resecie), ale podstawy SPI muszą być dobre. Na razie to wygląda mi na "programowanie objawowe: zrobię jakkolwiek i może zadziała. Nie jest tak jak miało być, ale to przecież nie może mieć wpływu na działanie, bo "nie widzę powodu." Jeśli samochód nie odpala bo ewidentnie jest pusty bak, to najpierw nalewasz paliwo i jeśli wciąż nie możesz odjechać, szukasz innych usterek. 

Edytowano przez marek1707
  • Lubię! 1
Link to post
Share on other sites
(edytowany)
Dnia 8.02.2021 o 00:30, marek1707 napisał:

Mylisz się. Przeczytaj jeszcze raz co napisałeś (zmiana danych na opadającym zboczu zegara) i przyjrzyj się jak to zrobiłeś na STM i co widać na obrazku z analizatora (kiedy zmienia się MOSI).

EDIT: Tak jak napisałem: może przyczyn jest kilka (np. trzymasz układ w resecie), ale podstawy SPI muszą być dobre. Na razie to wygląda mi na "programowanie objawowe: zrobię jakkolwiek i może zadziała. Nie jest tak jak miało być, ale to przecież nie może mieć wpływu na działanie, bo "nie widzę powodu." Jeśli samochód nie odpala bo ewidentnie jest pusty bak, to najpierw nalewasz paliwo i jeśli wciąż nie możesz odjechać, szukasz innych usterek. 

Ok, nie miałem dzisiaj za bardzo czasu na podpinanie analizatora logicznego, ale na szybko zrobiłem dwa inne testy - zastosowałem zaproponowaną przez Ciebie konfigurację SPI w poprzednich wersjach płytki, z mikrokontrolerami PIC24 i PIC32. Efekty wyglądają następująco:

  1. Płytka z PIC32. Było CPOL=0, CPHA=1 (w mikrokontrolerach PIC te bity mają nieco inne nazwy, ale wolę stosować jednolite nazewnictwo, żeby nie robić zamieszania). W takiej konfiguracji układ działał w 100%, to znaczy mogłem zarówno odczytać zawartość rejestrów, jak i odtwarzać muzykę. Teraz ustawiłem CPOL=0 i CPHA=0. Nic się nie zmieniło - układ nadal odtwarza muzykę, a odczytanie zawartości rejestrów jest możliwe.
  2. Płytka z PIC24. Było CPOL=0, CPHA=1. W tej konfiguracji płytka pozwalała na odtwarzanie muzyki, ale przy inicjacji układu również nie mogę odczytać rejestrów - podobnie jak w przypadku najnowszej wersji płytki z STM32. Zmiana na CPOL=0 CPHA=0 również niczego w tej materii nie zmieniła. Muzyka jest odtwarzana, ale nadal nie mogę odczytać rejestrów.

Wniosek z tego jest taki, że przynajmniej w przypadku PIC24 problem z odczytem zawartości rejestrów musi mieć źródło jeszcze gdzie indziej.

Jutro postaram się w końcu zrobić ten ostatni test z analizatorem logicznym. Sprawdzę też czy płytka z STM32 jest w stanie odtworzyć muzykę - wcześniej nie udało mi się tego odpalić, ale za to mogło odpowiadać ustawienie CPOL na 1, które miałem na początku.

Zaczynam się zastanawiać czy przypadkiem nie trafiły do mnie jakieś wadliwe egzemplarze VS1003, które mają problem z komunikacją w jedną stronę...

EDIT: Jeszcze jedno pytanie. STM32CubeMX ustawia gdzieś pull-up na linii MISO, czy trzeba to ręcznie wyklikać? Objawy co prawda nie wydają się pasować do pływającego wejścia, ale próbuję sprawdzić wszelkie możliwości...

Edytowano przez atlantis86
Link to post
Share on other sites
(edytowany)

Niewykluczone, że znalazłem możliwą przyczynę, chociaż ciągle nie wiem co mogło za nią odpowiadać...

Ponieważ podczas prób delikatnie uszkodziłem płytkę, postanowiłem wytrawić i złożyć ją ponownie. Przy tej okazji przeniosłem na nowe PCB wszystkie elementy za wyjątkiem VS1003. Efekt uruchomienia układu był taki, że tym razem rejestry zostały odczytane jako 0xFFFF, bo nie miało ich co ściągnąć do masy (jak widać na obrazku wrzuconym wcześniej, po ustawieniu pinu CS na stan nisku, VS1003 sprowadzał linię MISO do masy).

Na tym etapie postanowiłem upewnić się co do działania linii CS, DCS, RST oraz DREQ. Wejście DRE od początku działało prawidłowo. Nie było również problemów z CS i DCS - ich stan zmieniał się stosownie do programu. Natomiast RST z jakiegoś powodu pozostawało w stanie niskim, chociaż w pętli co dwie sekundy odpalałem na nim funkcję HAL_GPIO_PinToggle(). Zajrzałem jeszcze raz do konfiguracji - funkcję tę pełni linia PC13, której alternatywną funkcją jest "TAMPER". W żadnym momencie nie włączałem tej funkcji, a w konfiguracji PC13 było ustawione jako zwykłe "GPIO Output". Nie bardzo mając jakiś pomysł jeszcze raz przeklikałem się przez konfigurację: wyczyściłem ustawienia PC13 i ponownie ustawiłem je jako wyjście, wyłączyłem RTC i ponownie upewniłem się, że TAMPER jest nieaktywne.

Po tych zabiegach stan PC13 zaczął się zmieniać.

Jest więc niewykluczone, że z jakiegoś powodu VS1003 był trzymany w stanie resetu. Czemu się tak działo - nie mam pojęcia. Jakaś pozostałość po projekcie stworzonym w starej wersji STM32CubeMX i błąd przy konwersji do nowej wersji pliku?

W wolnej chwili spróbuję wlutować VS1003 i zobaczę czy tym razem zadziała...

Edytowano przez atlantis86
Link to post
Share on other sites
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.