Enable spi clock_div < 4. (#1283)

This commit is contained in:
Arnim Läuger 2016-06-15 21:01:52 +02:00 committed by GitHub
parent 7ff8326cc9
commit d445ae97fb
3 changed files with 18 additions and 23 deletions

View File

@ -70,7 +70,7 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_
if(spi_no>1) return; //handle invalid input number if(spi_no>1) return; //handle invalid input number
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CS_SETUP|SPI_CS_HOLD|SPI_RD_BYTE_ORDER|SPI_WR_BYTE_ORDER|SPI_DOUTDIN); SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CS_SETUP|SPI_CS_HOLD|SPI_RD_BYTE_ORDER|SPI_WR_BYTE_ORDER);
// set clock polarity (Reference: http://bbs.espressif.com/viewtopic.php?f=49&t=1570) // set clock polarity (Reference: http://bbs.espressif.com/viewtopic.php?f=49&t=1570)
// phase is dependent on polarity. See Issue #1161 // phase is dependent on polarity. See Issue #1161
@ -85,12 +85,10 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_
// Mode 3: MOSI is set on falling edge of clock // Mode 3: MOSI is set on falling edge of clock
// Mode 0: MOSI is set on falling edge of clock // Mode 0: MOSI is set on falling edge of clock
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_OUT_EDGE); CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_OUT_EDGE);
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_I_EDGE);
} else { } else {
// Mode 2: MOSI is set on rising edge of clock // Mode 2: MOSI is set on rising edge of clock
// Mode 1: MOSI is set on rising edge of clock // Mode 1: MOSI is set on rising edge of clock
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_OUT_EDGE); SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_OUT_EDGE);
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_I_EDGE);
} }
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE|SPI_USR_MISO|SPI_USR_ADDR|SPI_USR_COMMAND|SPI_USR_DUMMY); CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE|SPI_USR_MISO|SPI_USR_ADDR|SPI_USR_COMMAND|SPI_USR_DUMMY);
@ -98,31 +96,28 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_
//clear Dual or Quad lines transmission mode //clear Dual or Quad lines transmission mode
CLEAR_PERI_REG_MASK(SPI_CTRL(spi_no), SPI_QIO_MODE|SPI_DIO_MODE|SPI_DOUT_MODE|SPI_QOUT_MODE); CLEAR_PERI_REG_MASK(SPI_CTRL(spi_no), SPI_QIO_MODE|SPI_DIO_MODE|SPI_DOUT_MODE|SPI_QOUT_MODE);
// SPI clock = CPU clock / clock_div if (clock_div > 1) {
// the divider needs to be a multiple of 2 to get a proper waveform shape uint8 i, k;
if ((clock_div & 0x01) != 0) { i = (clock_div / 40) ? (clock_div / 40) : 1;
// bump the divider to the next N*2 k = clock_div / i;
clock_div += 0x02; WRITE_PERI_REG(SPI_CLOCK(spi_no),
(((i - 1) & SPI_CLKDIV_PRE) << SPI_CLKDIV_PRE_S) |
(((k - 1) & SPI_CLKCNT_N) << SPI_CLKCNT_N_S) |
((((k + 1) / 2 - 1) & SPI_CLKCNT_H) << SPI_CLKCNT_H_S) |
(((k - 1) & SPI_CLKCNT_L) << SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div
} else {
WRITE_PERI_REG(SPI_CLOCK(spi_no), SPI_CLK_EQU_SYSCLK); // 80Mhz speed
} }
clock_div >>= 1;
// clip to maximum possible CLKDIV_PRE
clock_div = clock_div > SPI_CLKDIV_PRE ? SPI_CLKDIV_PRE : clock_div - 1;
WRITE_PERI_REG(SPI_CLOCK(spi_no),
((clock_div&SPI_CLKDIV_PRE)<<SPI_CLKDIV_PRE_S)|
((1&SPI_CLKCNT_N)<<SPI_CLKCNT_N_S)|
((0&SPI_CLKCNT_H)<<SPI_CLKCNT_H_S)|
((1&SPI_CLKCNT_L)<<SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div
if(spi_no==SPI){ if(spi_no==SPI){
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x005); WRITE_PERI_REG(PERIPHS_IO_MUX, 0x005 | (clock_div <= 1 ? 0x100 : 0));
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);//configure io to spi mode 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_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_DATA0_U, 1);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_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){ else if(spi_no==HSPI){
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105); WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105 | (clock_div <= 1 ? 0x200 : 0));
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode 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_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_MTMS_U, 2);//configure io to spi mode

View File

@ -39,8 +39,8 @@ static int spi_setup( lua_State *L )
return luaL_error( L, "out of range" ); return luaL_error( L, "out of range" );
} }
if (clock_div < 4) { if (clock_div == 0) {
// defaulting to 8 // defaulting to 8 for backward compatibility
clock_div = 8; clock_div = 8;
} }

View File

@ -97,9 +97,9 @@ Refer to [Serial Peripheral Interface Bus](https://en.wikipedia.org/wiki/Serial_
- `spi.CPHA_LOW` - `spi.CPHA_LOW`
- `spi.CPHA_HIGH` - `spi.CPHA_HIGH`
- `databits` number of bits per data item 1 - 32 - `databits` number of bits per data item 1 - 32
- `clock_div` SPI clock divider, f(SPI) = f(CPU) / `clock_div` - `clock_div` SPI clock divider, f(SPI) = 80 MHz / `clock_div`, 1 .. n (0 defaults to divider 8)
- `duplex_mode` duplex mode - `duplex_mode` duplex mode
- `spi.HALFDUPLEX` (default when omitted) - `spi.HALFDUPLEX` (default when omitted)
- `spi.FULLDUPLEX` - `spi.FULLDUPLEX`
#### Returns #### Returns