Post Go back to editing

SC589 SPI1 issues

Category: Hardware
Product Number: ADZS-SC589-MINI

Hi All,

I've been using the Bare Metal Framework to develop code for the SC-589 both on custom hardware, and the ADZS-SC589-MINI development board.

Using the bm_spi driver, the SPI0 peripheral works fine, but SPI1 does not. A logic probe confirms normal function is observed for SPI0, however for SPI1, only chip select is actuated, but nothing happens on CLK and MOSI lines. The CLK and MOSI can be toggled manually, so I'm sure it's not a hardware issue, but I also cannot find and kind of peripheral clash for the pins in question that might prevent operation. Has anyone else had similar issues?

Example initialisation below, 

		spi_initialize(&device->spi,
						   SPI_MODE_0,
						   SPI_SSEL_MANUAL,
						   SPI_WORDLEN_8BIT,
						   112500000,
						   SPI0);
spi_transfer(&device->spi, command);
// works correctly

		spi_initialize(&device->spi,
						   SPI_MODE_0,
						   SPI_SSEL_MANUAL,
						   SPI_WORDLEN_8BIT,
						   112500000,
						   SPI1);
spi_transfer(&device->spi, command);
// Does not						   

The correct CS, CLK and MOSI pins are monitored for each case, and CS is actuated manually within a transfer function.

Many thanks, 

James

Parents
  • Hi  , can you share which physical pins on the SC589 you are using for SPI1 and share a screenshot of your pin-muxing for those pins? Looking at the baremetal framework, I only see pin-muxing set up for SPI0 (in pinmux_config.c):

  • Ah, that makes sense, I'd assumed the bm framework had already done that in the background. 

    I've altered pinmux_config.c to the code below, and can confirm this now works. 

    #define SPI0_CLK_PORTC_MUX  ((uint32_t) ((uint32_t) 0<<18))
    #define SPI0_MISO_PORTC_MUX  ((uint32_t) ((uint32_t) 0<<20))
    #define SPI0_MOSI_PORTC_MUX  ((uint32_t) ((uint32_t) 0<<22))
    
    #define SPI1_CLK_PORTE_MUX  ((uint32_t) ((uint32_t) 0<<26))
    #define SPI1_MISO_PORTE_MUX  ((uint32_t) ((uint32_t) 0<<28))
    #define SPI1_MOSI_PORTE_MUX  ((uint32_t) ((uint32_t) 0<<30))
    
    #define UART0_RX_PORTC_MUX  ((uint32_t) ((uint32_t) 0<<28))
    #define UART0_TX_PORTC_MUX  ((uint32_t) ((uint32_t) 0<<26))
    #define UART1_RX_PORTB_MUX  ((uint16_t) ((uint16_t) 1<<6))
    #define UART1_TX_PORTB_MUX  ((uint16_t) ((uint16_t) 1<<4))
    
    #define SPI0_CLK_PORTC_FER  ((uint32_t) ((uint32_t) 1<<9))
    #define SPI0_MISO_PORTC_FER  ((uint32_t) ((uint32_t) 1<<10))
    #define SPI0_MOSI_PORTC_FER  ((uint32_t) ((uint32_t) 1<<11))
    
    #define SPI1_CLK_PORTE_FER  ((uint32_t) ((uint32_t) 1<<13))
    #define SPI1_MISO_PORTE_FER  ((uint32_t) ((uint32_t) 1<<14))
    #define SPI1_MOSI_PORTE_FER  ((uint32_t) ((uint32_t) 1<<15))
    
    #define UART0_RX_PORTC_FER  ((uint32_t) ((uint32_t) 1<<14))
    #define UART0_TX_PORTC_FER  ((uint32_t) ((uint32_t) 1<<13))
    #define UART1_RX_PORTB_FER  ((uint16_t) ((uint16_t) 1<<3))
    #define UART1_TX_PORTB_FER  ((uint16_t) ((uint16_t) 1<<2))
    
    int32_t adi_initpinmux(void);
    
    /*
     * Initialize the Port Control MUX and FER Registers
     */
    int32_t adi_initpinmux(void) {
        /* PORTx_MUX registers */
        *pREG_PORTB_MUX = UART1_RX_PORTB_MUX | UART1_TX_PORTB_MUX;
        *pREG_PORTC_MUX = SPI0_CLK_PORTC_MUX | SPI0_MISO_PORTC_MUX
         | SPI0_MOSI_PORTC_MUX | UART0_RX_PORTC_MUX | UART0_TX_PORTC_MUX;
        *pREG_PORTE_MUX = SPI1_CLK_PORTE_MUX | SPI1_MISO_PORTE_MUX
         | SPI1_MOSI_PORTE_MUX;
    
        /* PORTx_FER registers */
        *pREG_PORTB_FER = UART1_RX_PORTB_FER | UART1_TX_PORTB_FER;
        *pREG_PORTC_FER = SPI0_CLK_PORTC_FER | SPI0_MISO_PORTC_FER
         | SPI0_MOSI_PORTC_FER | UART0_RX_PORTC_FER | UART0_TX_PORTC_FER;
        *pREG_PORTE_FER = SPI1_CLK_PORTE_FER | SPI1_MISO_PORTE_FER
             | SPI1_MOSI_PORTE_FER;
        return 0;
    }

     Many thanks for the advice! Just to round things off - I found the pinmux settings above for SPI1 in some code posted elsewhere on the forum (didn't think to check the pinmux settings at the time), but other than the memory map for e.g. PORTE _FER, I can't seem to find any more mention of them in the hardware reference document. Is there a recommended resource that describes these in a more general sense / for other peripherals? 

Reply
  • Ah, that makes sense, I'd assumed the bm framework had already done that in the background. 

    I've altered pinmux_config.c to the code below, and can confirm this now works. 

    #define SPI0_CLK_PORTC_MUX  ((uint32_t) ((uint32_t) 0<<18))
    #define SPI0_MISO_PORTC_MUX  ((uint32_t) ((uint32_t) 0<<20))
    #define SPI0_MOSI_PORTC_MUX  ((uint32_t) ((uint32_t) 0<<22))
    
    #define SPI1_CLK_PORTE_MUX  ((uint32_t) ((uint32_t) 0<<26))
    #define SPI1_MISO_PORTE_MUX  ((uint32_t) ((uint32_t) 0<<28))
    #define SPI1_MOSI_PORTE_MUX  ((uint32_t) ((uint32_t) 0<<30))
    
    #define UART0_RX_PORTC_MUX  ((uint32_t) ((uint32_t) 0<<28))
    #define UART0_TX_PORTC_MUX  ((uint32_t) ((uint32_t) 0<<26))
    #define UART1_RX_PORTB_MUX  ((uint16_t) ((uint16_t) 1<<6))
    #define UART1_TX_PORTB_MUX  ((uint16_t) ((uint16_t) 1<<4))
    
    #define SPI0_CLK_PORTC_FER  ((uint32_t) ((uint32_t) 1<<9))
    #define SPI0_MISO_PORTC_FER  ((uint32_t) ((uint32_t) 1<<10))
    #define SPI0_MOSI_PORTC_FER  ((uint32_t) ((uint32_t) 1<<11))
    
    #define SPI1_CLK_PORTE_FER  ((uint32_t) ((uint32_t) 1<<13))
    #define SPI1_MISO_PORTE_FER  ((uint32_t) ((uint32_t) 1<<14))
    #define SPI1_MOSI_PORTE_FER  ((uint32_t) ((uint32_t) 1<<15))
    
    #define UART0_RX_PORTC_FER  ((uint32_t) ((uint32_t) 1<<14))
    #define UART0_TX_PORTC_FER  ((uint32_t) ((uint32_t) 1<<13))
    #define UART1_RX_PORTB_FER  ((uint16_t) ((uint16_t) 1<<3))
    #define UART1_TX_PORTB_FER  ((uint16_t) ((uint16_t) 1<<2))
    
    int32_t adi_initpinmux(void);
    
    /*
     * Initialize the Port Control MUX and FER Registers
     */
    int32_t adi_initpinmux(void) {
        /* PORTx_MUX registers */
        *pREG_PORTB_MUX = UART1_RX_PORTB_MUX | UART1_TX_PORTB_MUX;
        *pREG_PORTC_MUX = SPI0_CLK_PORTC_MUX | SPI0_MISO_PORTC_MUX
         | SPI0_MOSI_PORTC_MUX | UART0_RX_PORTC_MUX | UART0_TX_PORTC_MUX;
        *pREG_PORTE_MUX = SPI1_CLK_PORTE_MUX | SPI1_MISO_PORTE_MUX
         | SPI1_MOSI_PORTE_MUX;
    
        /* PORTx_FER registers */
        *pREG_PORTB_FER = UART1_RX_PORTB_FER | UART1_TX_PORTB_FER;
        *pREG_PORTC_FER = SPI0_CLK_PORTC_FER | SPI0_MISO_PORTC_FER
         | SPI0_MOSI_PORTC_FER | UART0_RX_PORTC_FER | UART0_TX_PORTC_FER;
        *pREG_PORTE_FER = SPI1_CLK_PORTE_FER | SPI1_MISO_PORTE_FER
             | SPI1_MOSI_PORTE_FER;
        return 0;
    }

     Many thanks for the advice! Just to round things off - I found the pinmux settings above for SPI1 in some code posted elsewhere on the forum (didn't think to check the pinmux settings at the time), but other than the memory map for e.g. PORTE _FER, I can't seem to find any more mention of them in the hardware reference document. Is there a recommended resource that describes these in a more general sense / for other peripherals? 

Children
  • Hi  , I'm glad to hear that the software is now working for you!

    The reason that you didn't see SPI1 pin-muxing set in the baremetal framework already is because it is not currently used by default as a feature for the project - so these pins are left as inputs by default as best practice to avoid unexpected logic behavior and to avoid current draw on unused pins. 

    Just as an FYI - in the future, if your project has a CrossCore project associated with it (which the baremetal framework does), if you import the project and open the system.svc file, there is a Pin Multiplexing option available to you which will auto-generate the PORT_FER and PORT_MUX settings for you:

    Once you save - you will notice that the pinmux_config.c will be automatically updated for you:

    In general, the PORT_FER and PORT_MUX register settings will be described in the hardware reference manual: https://www.analog.com/media/en/dsp-documentation/processor-manuals/SC58x-2158x-hrm.pdf . Note that the PORT_FER register tells the processor to switch the pin from GPIO mode to function/peripheral mode: 

    And the PORT_MUX register tells the processor which peripheral mode to use: 

    However, as you rightly pointed out - this is not enough information to tell you which bit goes to which peripheral function. You will find that in the processor's datasheet. For the SC58x family - that datasheet can be found here: https://www.analog.com/media/en/technical-documentation/data-sheets/adsp-sc582_583_584_587_589_adsp-21583_584_587.pdf?isDownload=true . For that, generally  you would need to find the processor's specific package to then go to the Signal Multiplexing section to see which multiplexed function gets you SPI. For example:

    I hope this clears it up for you! Please do let me know if you have any other questions.