How to enable the SPI master function with low layer hal?

frank_he
Posts: 7
Joined: Wed Apr 08, 2020 5:41 am

How to enable the SPI master function with low layer hal?

Postby frank_he » Thu Apr 23, 2020 12:47 pm

Hi,
i'm triying to use to enable the spi master function on esp32. with Pins (GPIO12~15 and a reset pin of GPIO4).
this is the spi init fucntion,
nt lgw_spi_open (void** spi_target_ptr) {
gpio_set_direction(CS_PIN, GPIO_MODE_OUTPUT);
PIN_FUNC_SELECT(IO_MUX_GPIO12_REG, FUNC_MTDI_HSPIQ); // Pin MTDI --> function 1: HSPI MISO (GPIO12)
PIN_FUNC_SELECT(IO_MUX_GPIO13_REG, FUNC_MTCK_HSPID); // Pin MTCK --> function 1: HSPI MOSI (GPIO13)
PIN_FUNC_SELECT(IO_MUX_GPIO14_REG, FUNC_MTMS_HSPICLK); // Pin MTMS --> function 1: HSPI SCLK (GPIO14)
PIN_FUNC_SELECT(IO_MUX_GPIO15_REG, FUNC_MTDO_GPIO15);
PIN_FUNC_SELECT(IO_MUX_GPIO4_REG, FUNC_GPIO4_GPIO4); //
gpio_set_level(RESET_PIN,0);
gpio_set_level(CS_PIN,1);

CLEAR_PERI_REG_MASK(SPI_CLOCK_REG(SPI_NUM_HSPI), SPI_CLK_EQU_SYSCLK);

WRITE_PERI_REG(SPI_CTRL_REG(SPI_NUM_HSPI), 0); // Clear CTRL register (disables "fast-read" mode)
WRITE_PERI_REG(SPI_CLOCK_REG(SPI_NUM_HSPI),
((0x01 & SPI_CLKDIV_PRE) << SPI_CLKDIV_PRE_S) // Pre-divide by 2 --> 40MHz
| ((0x04 & SPI_CLKCNT_N) << SPI_CLKCNT_N_S) // Further divide by 5 --> 8MHz
| ((0x01 & SPI_CLKCNT_H) << SPI_CLKCNT_H_S) // = ((SPI_CLKCNT_N+1)/2)-1
| ((0x04 & SPI_CLKCNT_L) << SPI_CLKCNT_L_S)); // = SPI_CLKCNT_N
WRITE_PERI_REG(SPI_USER_REG(SPI_NUM_HSPI),
SPI_CK_I_EDGE // Slave edge rising
| SPI_USR_MOSI // Enable data-out phase
| SPI_DOUTDIN); // Full-duplex (also do data-in during data-out)
WRITE_PERI_REG(SPI_CTRL1_REG(SPI_NUM_HSPI), 0); // Clear CTRL1 register (from Arduino lib)
//reset the slave device
gpio_set_level(RESET_PIN,1);
wait_ms(100);
gpio_set_level(RESET_PIN,0);
*spi_target_ptr = (void*) 1;
return LGW_SPI_SUCCESS;
}
Then for a spi transmit function, like this:

static void spi_ex (int len) {
int i, words = (len + 3) / 4;
WRITE_PERI_REG(SPI_CMD_REG(SPI_NUM_HSPI),
((len * 8 - 1) << SPI_USR_MOSI_DBITLEN_S) // bit count out
| ((len * 8 - 1) << SPI_USR_MOSI_DBITLEN_S)); // bit count in - Do we need this for full duplex?
for (i = 0; i < words; i++) {
WRITE_PERI_REG(SPI_Wx(SPI_NUM_HSPI, i), spibuf.words);
}

SET_PERI_REG_MASK(SPI_CMD_REG(SPI_NUM_HSPI), SPI_USR);

// Busy wait (64B @ 8Mbps --> 64us max)
while ((READ_PERI_REG(SPI_CMD_REG(SPI_NUM_HSPI)) & SPI_USR) != 0);
wait_ms(1); // XXX - not sure yet why this is necessary

for (i = 0; i < words; i++) {
spibuf.words = READ_PERI_REG(SPI_Wx(SPI_NUM_HSPI, i));
}
}

#define SPI_Wx(i,x) (SPI_CMD_REG(i) + (x * 4))

Currenly i can't capture any signals on clk ,MISO and MOSI when i tried to read register from slave. Can you help to check all configuration is right? By the way, i just can't find any detailed document for the registers? Can you share that?

Thanks vry much.

Who is online

Users browsing this forum: Google [Bot] and 185 guests