Any way to get a 27MHz HSPI SCLK with 2:1 mark:space ratio?
Posted: Sun Jul 05, 2020 3:22 pm
I am using the HSPI peripheral in master mode to communicate with another device. I want to run it as fast as possible, and the other device can handle 26.667MHz i.e. 80MHz divided by 3. I am using SPI mode 1 so the data is changed on the rising edge of SCLK and latched on the falling edge. SCLK is high for 12.5ns and low for 25ns, but unfortunately the other device takes up to 15ns to produce the data on MISO after the rising edge. So I really need SCLK to go high for 25ns and low for 12.5ns instead.
Is there any way to achieve this? I tried the following variations on the data written to the SPICLK register, with these results (HLL = clock high for 12.5ns then low for 2 * 12.5ns):
SPI1CLK = (2 << 12) | (2 << 6) | 2; // fails, clock remains high
SPI1CLK = (2 << 12) | (2 << 6) | 1; // fails, clock goes HLHLL
SPI1CLK = (2 << 12) | (2 << 6) | 0; // works but clock goes HLL
SPI1CLK = (2 << 12) | (1 << 6) | 2; // works but clock goes HLL
SPI1CLK = (2 << 12) | (1 << 6) | 1; // fails, clock is 80MHz
SPI1CLK = (2 << 12) | (1 << 6) | 0; // fails, clock goes HLHLL
SPI1CLK = (2 << 12) | (0 << 6) | 2; // fails, clock goes HLHLL
SPI1CLK = (2 << 12) | (0 << 6) | 1; // works but clock goes HLL
SPI1CLK = (2 << 12) | (0 << 6) | 0; // fails, clock is 80MHz
I thought I could get around it by using SPI mode 0 instead, but if I do that then the ESP8266 inverts the clock signal so that I get 25ns high and 12.5ns low, defeating the purpose of switching to mode 0.
Is there any way to achieve this? I tried the following variations on the data written to the SPICLK register, with these results (HLL = clock high for 12.5ns then low for 2 * 12.5ns):
SPI1CLK = (2 << 12) | (2 << 6) | 2; // fails, clock remains high
SPI1CLK = (2 << 12) | (2 << 6) | 1; // fails, clock goes HLHLL
SPI1CLK = (2 << 12) | (2 << 6) | 0; // works but clock goes HLL
SPI1CLK = (2 << 12) | (1 << 6) | 2; // works but clock goes HLL
SPI1CLK = (2 << 12) | (1 << 6) | 1; // fails, clock is 80MHz
SPI1CLK = (2 << 12) | (1 << 6) | 0; // fails, clock goes HLHLL
SPI1CLK = (2 << 12) | (0 << 6) | 2; // fails, clock goes HLHLL
SPI1CLK = (2 << 12) | (0 << 6) | 1; // works but clock goes HLL
SPI1CLK = (2 << 12) | (0 << 6) | 0; // fails, clock is 80MHz
I thought I could get around it by using SPI mode 0 instead, but if I do that then the ESP8266 inverts the clock signal so that I get 25ns high and 12.5ns low, defeating the purpose of switching to mode 0.