Re: Exploring the SPI Master interface
Posted: Wed Apr 08, 2015 10:35 am
Thanks for posting up the info you've got so far. It helped me get started with the SPI Clock settings and I think I've worked it out.
My full post is at http://d.av.id.au/blog/hardware-spi-clock-registers/
It is the difference between SPI_CLKCNT_H and SPI_CLKCNT_L that sets the duty cycle of the SPI clock. If _H is higher than _L, then the difference is the number of clock cycles the SPI clock out is high. If _H is lower than _L, it is the number of clock cycles the SPI clock out is low. (No matter what, the normal high first than low second transition remains).
If you had:
SPI_CLKCNT_N set to 0x09 (for 10 cycles)
SPI_CLKCNT_H set to 0x09
SPI_CLKCNT_L set to 0x03
Then the SPI clock out would be high for 6 cycles and low for 4 cycles. The actual offset from 0 for _H and _L doesn't matter, as long as both are equal to or less than SPI_CLKCNT_N.
SPI_CLKCNT_N set to 0x09 (for 10 cycles)
SPI_CLKCNT_H set to 0x06
SPI_CLKCNT_L set to 0x00
This would give the exact same results.
To get 80MHz sys clock, you need to set bit31 (SPI_CLK_EQU_SYSCLK) and also when you setup PERIPHS_IO_MUX make sure bit9 is set, otherwise it won't work.
My full post is at http://d.av.id.au/blog/hardware-spi-clock-registers/
It is the difference between SPI_CLKCNT_H and SPI_CLKCNT_L that sets the duty cycle of the SPI clock. If _H is higher than _L, then the difference is the number of clock cycles the SPI clock out is high. If _H is lower than _L, it is the number of clock cycles the SPI clock out is low. (No matter what, the normal high first than low second transition remains).
If you had:
SPI_CLKCNT_N set to 0x09 (for 10 cycles)
SPI_CLKCNT_H set to 0x09
SPI_CLKCNT_L set to 0x03
Then the SPI clock out would be high for 6 cycles and low for 4 cycles. The actual offset from 0 for _H and _L doesn't matter, as long as both are equal to or less than SPI_CLKCNT_N.
SPI_CLKCNT_N set to 0x09 (for 10 cycles)
SPI_CLKCNT_H set to 0x06
SPI_CLKCNT_L set to 0x00
This would give the exact same results.
To get 80MHz sys clock, you need to set bit31 (SPI_CLK_EQU_SYSCLK) and also when you setup PERIPHS_IO_MUX make sure bit9 is set, otherwise it won't work.
Code: Select all
void spi_debug_init(uint8 spi_no)
{
uint32 regvalue;
if(spi_no>1) return; //handle invalid input number
//bit9 of PERIPHS_IO_MUX should be cleared when HSPI clock doesn't equal CPU clock
//bit8 of PERIPHS_IO_MUX should be cleared when SPI clock doesn't equal CPU clock
if(spi_no==SPI){
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x005); //clear bit9,and bit8
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);//configure io to spi mode
}else if(spi_no==HSPI){
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x305); //set bit9
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);//configure io to spi mode
}
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CS_SETUP|SPI_CS_HOLD|SPI_USR_COMMAND);
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE|SPI_WR_BYTE_ORDER);
WRITE_PERI_REG(SPI_CLOCK(spi_no), SPI_CLK_EQU_SYSCLK);