[Programmation] Bus SPI MISO retourne toujours 0
Répondre à la discussion
Affichage des résultats 1 à 11 sur 11

Bus SPI MISO retourne toujours 0



  1. #1
    PierreBoss

    Bus SPI MISO retourne toujours 0


    ------

    Bonjour,

    Je travaille avec un microcontrôleur SAM3X8E (datasheet : https://ww1.microchip.com/downloads/..._Datasheet.pdf, page 676 to 707 for SPI).


    Je veux faire du multi-transfert d'octets grâce au bus SPI donc j'ai initialisé mon CS comme un GPIO pour le piloter manuellement.
    Mon CS, mon CLK et mon MOSI sont corrects mais je ne sais pas pourquoi mon MISO me renvoie toujours 0...


    Voici ce que je vois actuellement avec mon oscilloscope :

    .CS :
    CS_Actual.png

    .MOSI :
    MOSI_Actual.png

    .MISO :
    MISO_Actual.png


    Et voici les signaux à l'oscilloscope d'un code qui fait exactement ce que je veux (mais sous Arduino et je suis sous Atmel 7) :

    .MOSI :
    MOSI__Correct.png

    .MISO :
    MISO_Correct.png

    Sur les bons oscilloscopes vous pouvez voir que le MISO est à 0 mais juste pour le premier octet et dans mon cas il est toujours à 0...

    Voici mon code pour initialiser mon Bus SPI :
    Code:
    /* Configure SPI0 pins */
    gpio_configure_pin(SPI0_MISO_GPIO, (PIO_PERIPH_A | PIO_DEFAULT));
    gpio_configure_pin(SPI0_MOSI_GPIO, (PIO_PERIPH_A | PIO_DEFAULT));
    gpio_configure_pin(SPI0_SPCK_GPIO, (PIO_PERIPH_A | PIO_DEFAULT));
    gpio_configure_pin(SPI0_NPCS0_GPIO, (PIO_OUTPUT_1 | PIO_DEFAULT)); //CS
    
    /* Configure an SPI peripheral. */
    spi_enable_clock(SPI0);
    
    spi_disable(SPI0);
    spi_reset(SPI0);
    
    //spi_set_lastxfer(SPI0);
    spi_set_master_mode(SPI0);
    
    spi_disable_mode_fault_detect(SPI0);
    spi_set_variable_peripheral_select(SPI0);
    spi_set_peripheral_chip_select_value(SPI0, SPI_CHIP_SEL); //SPI_CHIP_SEL == 0
    
    /* data samples on rising edge because Polarity = Phase = 0 */
    spi_set_clock_polarity(SPI0, SPI_CHIP_SEL, SPI_CLK_POLARITY);
    spi_set_clock_phase(SPI0, SPI_CHIP_SEL, SPI_CLK_PHASE);
    
    spi_set_bits_per_transfer(SPI0, SPI_CHIP_SEL, SPI_CSR_BITS_8_BIT);
    spi_set_baudrate_div(SPI0, SPI_CHIP_SEL, (sysclk_get_peripheral_hz() / gs_ul_spi_clock));
    
    SPI0->SPI_CSR[0] |= SPI_CSR_CSAAT;
    
    spi_enable(SPI0);

    Voici le code que j'utilise pour faire mon transfer :

    Code:
    uint8_t ftData8;
    
    EVE_cs_set(); //CS at 0
    
    spi_transmit_32(...); //Make 4 spi_transmit(...)
    ftData8 = spi_receive(0x00); /* read data byte by sending another dummy byte thanks to spi_transmit(...) */
    
    EVE_cs_clear(); //CS at 1
    
    return ftData8; /* return byte read */
    Et voici ma fonction spi_transmit(...) :

    Code:
    static inline uint8_t spi_transmit(uint8_t data)
    {
     while ((SPI0->SPI_SR & SPI_SR_TDRE) == 0);
    
     spi_write(SPI0, data, SPI_CHIP_SEL, 0);
    
     while ((SPI0->SPI_SR & SPI_SR_RDRF) == 0);
    
     uint8_t data_read, Chip_Sel_read;
    
     spi_read(SPI0, &data_read, &Chip_Sel_read);
    
     return data_read;
    }
    Pouvez-vous voir d'où vient le problème ?

    -----

  2. #2
    umfred

    Re : Bus SPI MISO retourne toujours 0

    est-ce que ton device esclave doit te répondre quelque chose ? (éventuellement nous montrer sa doc)
    de plus tu n'as pas la même base de temps (tu es 10 fois plus lent que les signaux qui fonctionnent (10us au lieu de 1us))
    ça semble vouloir dire que l'esclave n'a pas compris ton message. ou que la réponse est une succession de 0 et est bonne ?

  3. #3
    PierreBoss

    Re : Bus SPI MISO retourne toujours 0

    Bonjour oui l'esclave est un écran (https://fr.rs-online.com/web/p/ecrans-tftlcd/1931154/) et lors de son initialisation il doit me retourner quelque chose pour montrer que la communication se fait bien.
    La différence d'horloge est normal entre les deux signaux c'est juste que dans le code actuel on veux une communication plus rapide !

  4. #4
    umfred

    Re : Bus SPI MISO retourne toujours 0

    dans tes courbes, le code qui fonctionne est plus rapide que le tien
    Sinon, question peut-être bête, mais le MOSI de ton CPU va bien sur le MOSI de l'écran (idem MISO sur MISO) ?

  5. A voir en vidéo sur Futura
  6. #5
    PierreBoss

    Re : Bus SPI MISO retourne toujours 0

    Oups en tout cas on m'a dit que la différence d'horloge était pas importante pour l'instant.
    Oui ils sont bien reliés. Les screens corrects sont tiré d'une version Arduino du code mais donc avec les même PINs pour le MISO et MOSI et cela marche.

  7. #6
    umfred

    Re : Bus SPI MISO retourne toujours 0

    Edit: nop j'ai rien dit en fait
    Dernière modification par umfred ; 03/06/2021 à 15h56.

  8. #7
    PierreBoss

    Re : Bus SPI MISO retourne toujours 0

    Le truc c'est que justement j'ai configuré mon CS en output et pas en périphérique A car j'ai besoin de piloter mon CS parce que je fais des transferts de plusieurs octets. Avant j'avais la même initialisation que tu m'as donné mais je ne pouvais pas piloter le CS avec pio_set_pin_low(...) et pio_set_pin_high(...). Et de ce que j'ai vu sur plusieurs forum le seul moyen de faire des transferts de plusieurs bytes avec SPI c'est de configurer son CS en GPIO...
    De plus, si le CS était mal configuré je devrais avoir un mauvais signal pour le MOSI non ? Or ce n'est pas le cas donc comme l'envoie se passe bien le CS marche correctement non ?

  9. #8
    activmaker

    Re : Bus SPI MISO retourne toujours 0

    Bonsoir,

    Je confirme faire le même chose pour le CS..Faut utiliser une GPIO. Plus d'ennui avec le CS qui fait le yoyo . Je vois une différence entre le mosi qui fonctionne et celui qui ne fonctionne pas , c'est le temps entre 2 octets. Dans celui qui fonctionne le temps de repos est environ égal à la durée d'un octet. Dans le MOSI incorrect le temps de repos est très court. J'ai pas lu en détail le datasheet mais peut être qu'il faut laisser "respirer" le slave entre 2 octets ..Faut s'arranger pour comparer les mêmes choses => Les 2 MOSI doivent être identique ou très proches , la c'est pas le cas.

    Edit: c'est peut être une mauvaise piste, je viens de lire que le SPI supportait jusqu'a 30Mhz...On en est loin ici ...

    Bon courage
    Dernière modification par activmaker ; 03/06/2021 à 19h38.

  10. #9
    PierreBoss

    Re : Bus SPI MISO retourne toujours 0

    Merci, j'ai trouvé différentes pistes que j'essayerai Lundi car là je suis en télétravail. Je vous tiendrai au courant.

  11. #10
    PierreBoss

    Re : Bus SPI MISO retourne toujours 0

    Salut, j'ai du nouveaux !

    Je pensais que le problème venait de mon setup de SPI ou de PIN mais après de nombreux changement cela ne faisait rien.
    J'ai donc retravaillé mes fonctions et là j'ai un résultat (qui ne marche pas encore mais encourageant).

    Voici mon signal MISO :
    Nom : SDS00001.png
Affichages : 143
Taille : 28,3 Ko

    On voit bien qu'il y a une réponse de l'écran. Cependant, les multi transferts de 8 bits sont peut être un peu trop collé ( aucune coupure entre 5 les transferts) et mon CS se remet à 1 avant la fin de mon multi trasnfert.

    Voici ma fonction spi_trasnmit(data) :
    Code:
    static inline void spi_transmit(uint8_t data)
    {	
    	while ((SPI0->SPI_SR & SPI_SR_TXEMPTY) == 1);
    	
    	spi_write(SPI0, data, SPI_CHIP_SEL, 0);
    	
    	while ((SPI0->SPI_SR & SPI_SR_TDRE) == 1);
    }
    Voici ma fonction spi_receive(data) :
    Code:
    {	
    	uint8_t data_read, Chip_Sel_read;
    	
    	spi_transmit(data);
    	
    	while((SPI0->SPI_SR & SPI_SR_RDRF) == 0);
    	
    	spi_read(SPI0, &data_read, &Chip_Sel_read);
    	
    	return data_read;
    }
    et voici la fonction que j'appelle pour faire mon trasnfert de 5 octets :
    Code:
    uint8_t ftData8;
    
    EVE_cs_set(); //CS at 0
    
    spi_transmit_32(...); //Make 4 spi_transmit(...)
    ftData8 = spi_receive(0x00); /* read data byte by sending another dummy byte */
    
    EVE_cs_clear(); //CS at 1
    
    return ftData8; /* return byte read */

  12. #11
    PierreBoss

    Re : Bus SPI MISO retourne toujours 0

    J'ai trouvé la solution, tout marche grâce à cette fonction :
    Code:
    static inline uint8_t transmission(uint8_t data, uint8_t reception)
    {
    	spi_write(SPI0, data, SPI_CHIP_SEL, 0);
    	
    	while ((SPI0->SPI_SR & SPI_SR_TDRE) == SPI_SR_TDRE);
    	
    	if(reception)
    	{
    		uint8_t data_read, Chip_Sel_read;
    		
    		spi_read(SPI0, &data_read, &Chip_Sel_read);
    		
    		//return 0;
    		return data_read;
    	}
    	else
    	{
    		uint8_t poubelle_data, poubelle_CS;
    		spi_read(SPI0, &poubelle_data, &poubelle_CS);
    		return 1;
    	}
    }
    Merci à tous pour votre aide !

Discussions similaires

  1. enc28j60 pas de MISO signal
    Par socarto dans le forum Électronique
    Réponses: 3
    Dernier message: 25/04/2014, 20h11
  2. Le verre d'eau retourné
    Par verdae31 dans le forum Physique
    Réponses: 17
    Dernier message: 11/12/2009, 14h27
  3. Eh oh, eh oh, on retourne au boulot
    Par macros dans le forum Orientation après le BAC
    Réponses: 5
    Dernier message: 20/05/2009, 00h15
Découvrez nos comparatifs produits sur l'informatique et les technologies.