(H)SPI configuration options

mculibrk
Posts: 22
Joined: Mon Feb 09, 2015 3:35 am

(H)SPI configuration options

Postby mculibrk » Fri Apr 10, 2015 8:00 am

A few questions about some SPI configuration bits which are not described.

Code: Select all

#define SPI_SLAVE(i)                (REG_SPI_BASE(i)  + 0x30)
#define SPI_SYNC_RESET                  (BIT(31))

what does this SPI_SYNC_RESET do? what are the consequences on the SPI setup or functioning?
I saw this bit is set in the SPI samples in SPI Slave interrupt service but there is no hint on why or what this actually do.
Will the configuration of the SPI hardware stay unchanged or some bits gets reset by this?
Should this bit be set in the ISR when in master mode also?

Code: Select all

#define SPI_TRANS_CNT                   0x0000000F
#define SPI_TRANS_CNT_S                 23

What does this "operation counter" actually count? "RO - The operations counter in both the master mode and the slave mode."
As this is 4 bits only - is this related to the SPI_W0..15 fifo registers? Something like the index of the current W register in use?

Code: Select all

#define SPI_TRANS_DONE_EN               (BIT(9))
#define SPI_SLV_WR_STA_DONE_EN          (BIT(8))
#define SPI_SLV_RD_STA_DONE_EN          (BIT(7))
#define SPI_SLV_WR_BUF_DONE_EN          (BIT(6))
#define SPI_SLV_RD_BUF_DONE_EN          (BIT(5))

Is the SPI_TRANS_DONE flag the only interrupt "source" in master mode and the other _DONE flags are not used?

Code: Select all

#define SPI_USER(i)                 (REG_SPI_BASE(i) + 0x1C)
#define SPI_CK_OUT_EDGE                 (BIT(7))
#define SPI_CK_I_EDGE                   (BIT(6))
#define SPI_CS_SETUP                    (BIT(5))
#define SPI_CS_HOLD                     (BIT(4))

Is there a way to change the SPI CLOCK "plarity"? (the idle state of the clock)
Does the SPI_CK_OUT_EDGE control the "data out valid" on rising/falling clock? And the same for CK_I_EDGE for "data input valid"?

Best regards,
mculibrk

OverKill
Posts: 2
Joined: Thu Jun 18, 2015 10:29 am

Re: (H)SPI configuration options

Postby OverKill » Thu Jun 18, 2015 10:46 am

Did you get any of your answers?

0xPIT
Posts: 9
Joined: Mon Jan 05, 2015 9:26 pm

Re: (H)SPI configuration options

Postby 0xPIT » Thu Jul 09, 2015 2:01 am

Hello Espressif,

when can we get answers?

Thanks

- pit

Espressif_Kelly
Posts: 140
Joined: Mon Oct 27, 2014 10:40 am

Re: (H)SPI configuration options

Postby Espressif_Kelly » Wed Jul 22, 2015 7:51 pm

Hi 0xPIT,

1.The host can use ISR but the only interrupt source is SPI_TRANS_DONE and each transmission will be done with TRANS_DONE.

2.SPI_SYNC_RESET is only usefull for the slave mode. There is no need for SPI_SYNC_RESET in master mode.

3.SPI_CK_OUT_EDGE and CK_I_EDGE can be used to control the output and input clock polarity.

Thanks.

dkinzer
Posts: 52
Joined: Fri Jul 31, 2015 7:37 am

Re: (H)SPI configuration options

Postby dkinzer » Tue Sep 22, 2015 3:40 am

Espressif_Kelly wrote:3.SPI_CK_OUT_EDGE and CK_I_EDGE can be used to control the output and input clock polarity.
From my observation, this is not true. The SPI_CK_OUT_EDGE controls the clock phase with respect to MOSI and I suspect that CK_I_EDGE controls the phase with respect to MISO. Neither of them affect the SPI clock polarity in that the SPI clock always idles low irrespective of the state of those two bits.

In earlier versions of spi_register.h there were the following definitions associated with SPI_CTRL2. Although I didn't try all possible combinations, none of the several that I did try affected the clock polarity. What do these fields actually do?

Code: Select all

#define SPI_CK_OUT_HIGH_MODE 0x0000000F
#define SPI_CK_OUT_HIGH_MODE_S 12
#define SPI_CK_OUT_LOW_MODE 0x0000000F
#define SPI_CK_OUT_LOW_MODE_S 8


Is there a way to get SPI modes 2 and 3 in which the SPI clock idles high? Perhaps the functionality was intended but it doesn't work. Please advise.
Don Kinzer
Beaverton, OR, USA

jfollas
Posts: 9
Joined: Sun Oct 18, 2015 1:23 pm

Re: (H)SPI configuration options

Postby jfollas » Sun Oct 18, 2015 1:46 pm

This seems to be an ongoing bug, short of any documentation to show how polarity can be achieved.

Polarity does not refer to when during the clock cycle that MOSI and MISO signals are sampled for new bits. That's the Phase, and we seem to be able to control that on the USER register.

Polarity is the state of the clock when idle, so that the first transition is properly detected by the slave device.

No matter what I try to do, I get a clock that looks like this:

Code: Select all

             _   _   _   _   _   _   _   _
____________| |_| |_| |_| |_| |_| |_| |_| |____________


The slave device is expecting a clock that is inverted so that it is normally high:

Code: Select all

____________   _   _   _   _   _   _   _   ____________
            |_| |_| |_| |_| |_| |_| |_| |_|


The best example code that we have tries to set the CTRL2 register using some undocumented bits:

Code: Select all

if (cpol == 1) {                                                                             
    SET_PERI_REG_MASK(SPI_CTRL2(spi_no), (SPI_CK_OUT_HIGH_MODE << SPI_CK_OUT_HIGH_MODE_S)); 
    CLEAR_PERI_REG_MASK(SPI_CTRL2(spi_no), (SPI_CK_OUT_LOW_MODE << SPI_CK_OUT_LOW_MODE_S)); 
} else {                                                                                     
    SET_PERI_REG_MASK(SPI_CTRL2(spi_no), (SPI_CK_OUT_LOW_MODE<<SPI_CK_OUT_LOW_MODE_S));     
    CLEAR_PERI_REG_MASK(SPI_CTRL2(spi_no), (SPI_CK_OUT_HIGH_MODE << SPI_CK_OUT_HIGH_MODE_S));
}


I'm not sure where this code first appeared or if it worked back then, but it is clearly not functional today with SDK 1.4.

Please show us code that will set up the registers to output the inverted clock waveform. If that is impossible on the ESP8266 due to a bug inside the microcontroller, then please declare that and we can implement a solution in hardware (i.e., perhaps use an inverter to flip the clock, and then maybe invert the phase? I'd have to test that).

EDIT: I added an inverter (logical NOT) circuit for my clock line, and this works in the interim for inverting the clock. You could do this with something like a 74HC04, or what I used in my test was a 2N3904 NPN transistor (10k for collector, 2.2k for base - not sure if these are ideal values, but they worked for inverting a 1MHz clock). The thing I'm working on now is adjusting the timing on the read/writes because they're a little off now.

The ideal solution is still for the ESP8266 to output the correct clock waveform when CPOL=1.

hiko07
Posts: 1
Joined: Wed Jan 06, 2016 5:30 pm

Re: (H)SPI configuration options

Postby hiko07 » Wed Jan 06, 2016 6:50 pm

I tried the following code or settings of the registers, but these did not work. Is this bug? We will not be able to change the CPOL?

Code: Select all

SET_PERI_REG_MASK(SPI_CTRL2(spi_no), (SPI_CK_OUT_HIGH_MODE << SPI_CK_OUT_HIGH_MODE_S));


Code: Select all

#define SPI_CK_OUT_EDGE                 (BIT(7))


Add definition(bit 29) of SPI_CTRL2.
viewtopic.php?f=49&t=1570&p=5242&hilit=SPI_IDLE_EDGE#p5242

Code: Select all

#define SPI_IDLE_EDGE (BIT(29))


In spi_overlap.c
viewtopic.php?t=439

Code: Select all

#define HSPI_FALLING_EDGE_SAMPLE()      SET_PERI_REG_MASK(SPI_USER(HSPI),  SPI_CK_OUT_EDGE)

jfollas
Posts: 9
Joined: Sun Oct 18, 2015 1:23 pm

Re: (H)SPI configuration options

Postby jfollas » Fri Jan 15, 2016 4:09 am

I think you're looking to do this to use mode 2 or 3:

Code: Select all

if (cpol == 1) {
    SET_PERI_REG_MASK(SPI_PIN(spi_no), SPI_IDLE_EDGE);
} else {
    CLEAR_PERI_REG_MASK(SPI_PIN(spi_no), SPI_IDLE_EDGE);
}


It's not SPI_CTRL2 that controls the clock polarity, but SPI_PIN bit 29.

Who is online

Users browsing this forum: No registered users and 3 guests