2 * Copyright 2017 Jonathan McDowell <noodles@earth.li>
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "spi_register.h"
24 #define spi_busy(spi_no) (READ_PERI_REG(SPI_CMD(spi_no)) & SPI_USR)
29 void ICACHE_FLASH_ATTR spi_init(void)
31 /* SPI clock = CPU clock/160 [(79 + 1) * 2]= 500KHz */
32 WRITE_PERI_REG(SPI_CLOCK(HSPI),
33 ((79 & SPI_CLKDIV_PRE) << SPI_CLKDIV_PRE_S) |
34 ((1 & SPI_CLKCNT_N) << SPI_CLKCNT_N_S) |
35 ((1 & SPI_CLKCNT_H) << SPI_CLKCNT_H_S) |
36 ((0 & SPI_CLKCNT_L) << SPI_CLKCNT_L_S));
39 * We use hardware SPI, but repurpose MISO for CS, as we don't need it.
41 WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105);
42 PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2); /* GPIO13: MOSI */
43 PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2); /* GPIO14: CLK */
44 /* FIXME: CS/SS is not this pin */
45 PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2); /* GPIO15 */
46 /* We don't use MISO, repurpose this pin for GPIO12 (used as CS) */
47 PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12);
48 PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTDI_U);
49 gpio_output_set(0, 0, BIT12, 0);
51 /* Configure up our SPI options */
52 SET_PERI_REG_MASK(SPI_USER(HSPI),
53 SPI_WR_BYTE_ORDER | /* MSB output first */
54 SPI_USR_MOSI /* Enable data (MOSI) output */
56 CLEAR_PERI_REG_MASK(SPI_USER(HSPI),
57 SPI_FLASH_MODE | /* Disable flash mode */
58 SPI_USR_MISO | SPI_USR_COMMAND |
59 SPI_USR_ADDR | SPI_USR_DUMMY | /* Disable non-data output */
60 SPI_CS_SETUP | SPI_CS_HOLD | /* We drive our own CS */
61 SPI_CK_OUT_EDGE /* Data valid on CLK leading */
63 /* Clock low when inactive */
64 CLEAR_PERI_REG_MASK(SPI_PIN(HSPI), SPI_IDLE_EDGE);
66 /* We're writing 8 bits at a time */
67 /* TODO: We could write up to 32 bits at once potentially. */
68 WRITE_PERI_REG(SPI_USER1(HSPI),
69 (7 & SPI_USR_MOSI_BITLEN) << SPI_USR_MOSI_BITLEN_S);
72 void ICACHE_FLASH_ATTR spi_write(size_t len, uint8_t *data)
76 for (i = 0; i < len; i++) {
77 /* Wait for SPI to be ready */
78 while (spi_busy(HSPI));
80 /* We just write the top 8 bits of the 32 bit value */
81 WRITE_PERI_REG(SPI_W0(HSPI), data[i] << 24);
83 /* Begin the SPI transaction */
84 SET_PERI_REG_MASK(SPI_CMD(HSPI), SPI_USR);
87 /* Don't return until it's done */
88 while (spi_busy(HSPI));