Lines Matching +full:spi +full:- +full:cs +full:- +full:sck +full:- +full:delay
4 * SPDX-License-Identifier: Apache-2.0
15 #include <zephyr/drivers/spi.h>
28 * SPI API defers the choice of default values to the drivers.
146 * for SPI protocol, this will be performed by sending 10 0xff values in sdhc_spi_init_card()
147 * to the card (this should result in 80 SCK cycles) in sdhc_spi_init_card()
149 const struct sdhc_spi_config *config = dev->config; in sdhc_spi_init_card()
150 struct sdhc_spi_data *data = dev->data; in sdhc_spi_init_card()
151 struct spi_config *spi_cfg = data->spi_cfg; in sdhc_spi_init_card()
154 if (spi_cfg->frequency == 0) { in sdhc_spi_init_card()
156 spi_cfg->frequency = SDMMC_CLOCK_400KHZ; in sdhc_spi_init_card()
159 /* Request SPI bus to be active */ in sdhc_spi_init_card()
160 if (pm_device_runtime_get(config->spi_dev) < 0) { in sdhc_spi_init_card()
161 return -EIO; in sdhc_spi_init_card()
164 /* the initial 74 clocks must be sent while CS is high */ in sdhc_spi_init_card()
165 spi_cfg->operation |= SPI_CS_ACTIVE_HIGH; in sdhc_spi_init_card()
166 ret = sdhc_spi_rx(config->spi_dev, spi_cfg, data->scratch, 10); in sdhc_spi_init_card()
168 /* Release lock on SPI bus */ in sdhc_spi_init_card()
169 ret2 = spi_release(config->spi_dev, spi_cfg); in sdhc_spi_init_card()
170 spi_cfg->operation &= ~SPI_CS_ACTIVE_HIGH; in sdhc_spi_init_card()
172 /* Release request for SPI bus to be active */ in sdhc_spi_init_card()
173 (void)pm_device_runtime_put(config->spi_dev); in sdhc_spi_init_card()
178 /* Checks if SPI SD card is sending busy signal */
181 const struct sdhc_spi_config *config = dev->config; in sdhc_spi_card_busy()
182 struct sdhc_spi_data *data = dev->data; in sdhc_spi_card_busy()
187 ret = sdhc_spi_rx(config->spi_dev, data->spi_cfg, &response, 1); in sdhc_spi_card_busy()
189 return -EIO; in sdhc_spi_card_busy()
199 /* Waits for SPI SD card to stop sending busy signal */
204 const struct sdhc_spi_config *config = dev->config; in sdhc_spi_wait_unbusy()
205 struct sdhc_spi_data *data = dev->data; in sdhc_spi_wait_unbusy()
210 ret = sdhc_spi_rx(config->spi_dev, data->spi_cfg, &response, 1); in sdhc_spi_wait_unbusy()
218 timeout_ms -= k_ticks_to_ms_floor32(interval_ticks); in sdhc_spi_wait_unbusy()
220 return -ETIMEDOUT; in sdhc_spi_wait_unbusy()
224 /* Read SD command from SPI response */
228 const struct sdhc_spi_config *config = dev->config; in sdhc_spi_response_get()
229 struct sdhc_spi_data *dev_data = dev->data; in sdhc_spi_response_get()
230 uint8_t *response = dev_data->scratch; in sdhc_spi_response_get()
232 int ret, timeout = cmd->timeout_ms; in sdhc_spi_response_get()
236 * All SPI responses start with R1, which will have MSB of zero. in sdhc_spi_response_get()
248 response = dev_data->scratch; in sdhc_spi_response_get()
251 ret = sdhc_spi_rx(config->spi_dev, dev_data->spi_cfg, in sdhc_spi_response_get()
259 /* Delay for a bit, and poll the card again */ in sdhc_spi_response_get()
261 timeout -= 10; in sdhc_spi_response_get()
264 return -ETIMEDOUT; in sdhc_spi_response_get()
268 cmd->response[0] = *response++; in sdhc_spi_response_get()
270 if (cmd->response[0] != 0) { in sdhc_spi_response_get()
271 if (cmd->response[0] & (SD_SPI_R1PARAMETER_ERR | SD_SPI_R1ADDRESS_ERR)) { in sdhc_spi_response_get()
272 return -EFAULT; /* Bad address */ in sdhc_spi_response_get()
273 } else if (cmd->response[0] & (SD_SPI_R1ILLEGAL_CMD_ERR)) { in sdhc_spi_response_get()
274 return -EINVAL; /* Invalid command */ in sdhc_spi_response_get()
275 } else if (cmd->response[0] & (SD_SPI_R1CMD_CRC_ERR)) { in sdhc_spi_response_get()
276 return -EILSEQ; /* Illegal byte sequence */ in sdhc_spi_response_get()
277 } else if (cmd->response[0] & (SD_SPI_R1ERASE_SEQ_ERR | SD_SPI_R1ERASE_RESET)) { in sdhc_spi_response_get()
278 return -EIO; in sdhc_spi_response_get()
282 switch ((cmd->response_type & SDHC_SPI_RESPONSE_TYPE_MASK)) { in sdhc_spi_response_get()
284 /* R1 response - one byte*/ in sdhc_spi_response_get()
287 /* R1b response - one byte plus busy signal */ in sdhc_spi_response_get()
296 value = cmd->timeout_ms; in sdhc_spi_response_get()
297 response--; in sdhc_spi_response_get()
305 /* R2/R5 response - R1 response + 1 byte*/ in sdhc_spi_response_get()
307 response = dev_data->scratch; in sdhc_spi_response_get()
310 ret = sdhc_spi_rx(config->spi_dev, in sdhc_spi_response_get()
311 dev_data->spi_cfg, in sdhc_spi_response_get()
317 cmd->response[0] = (*response) << 8; in sdhc_spi_response_get()
322 /* R3/R4/R7 response - R1 response + 4 bytes */ in sdhc_spi_response_get()
323 cmd->response[1] = 0; in sdhc_spi_response_get()
325 cmd->response[1] <<= 8; in sdhc_spi_response_get()
328 response = dev_data->scratch; in sdhc_spi_response_get()
331 ret = sdhc_spi_rx(config->spi_dev, in sdhc_spi_response_get()
332 dev_data->spi_cfg, in sdhc_spi_response_get()
338 cmd->response[1] |= *response++; in sdhc_spi_response_get()
343 return -ENOTSUP; in sdhc_spi_response_get()
348 /* Send SD command using SPI */
352 const struct sdhc_spi_config *config = dev->config; in sdhc_spi_send_cmd()
353 struct sdhc_spi_data *dev_data = dev->data; in sdhc_spi_send_cmd()
356 /* To reduce overhead, we will send entire command in one SPI in sdhc_spi_send_cmd()
358 * - all ones byte to ensure card is ready in sdhc_spi_send_cmd()
359 * - opcode byte (which includes start and transmission bits) in sdhc_spi_send_cmd()
360 * - 4 bytes for argument in sdhc_spi_send_cmd()
361 * - crc7 byte (with end bit) in sdhc_spi_send_cmd()
364 * the maximum spi response length is 5 bytes, so we provide an in sdhc_spi_send_cmd()
375 .buf = dev_data->scratch, in sdhc_spi_send_cmd()
376 .len = sizeof(dev_data->scratch), in sdhc_spi_send_cmd()
390 * bytes, since the min value of NCR (see SD SPI timing in sdhc_spi_send_cmd()
395 memset(dev_data->scratch, 0xFF, sizeof(dev_data->scratch)); in sdhc_spi_send_cmd()
396 cmd_buf = dev_data->scratch + 1; in sdhc_spi_send_cmd()
401 * [45-40]: command index in sdhc_spi_send_cmd()
402 * [39-8]: argument in sdhc_spi_send_cmd()
403 * [7-1]: CRC in sdhc_spi_send_cmd()
408 cmd_buf[0] = (cmd->opcode & SD_SPI_CMD); in sdhc_spi_send_cmd()
411 sys_put_be32(cmd->arg, &cmd_buf[1]); in sdhc_spi_send_cmd()
414 LOG_DBG("cmd%d arg 0x%x", cmd->opcode, cmd->arg); in sdhc_spi_send_cmd()
415 /* Set data, will lock SPI bus */ in sdhc_spi_send_cmd()
416 err = spi_transceive(config->spi_dev, dev_data->spi_cfg, &buf_set, &buf_set); in sdhc_spi_send_cmd()
427 const struct sdhc_spi_config *config = dev->config; in sdhc_skip()
428 struct sdhc_spi_data *data = dev->data; in sdhc_skip()
434 ret = sdhc_spi_rx(config->spi_dev, data->spi_cfg, in sdhc_skip()
439 } while (buf == skip_val && retries--); in sdhc_skip()
441 return -ETIMEDOUT; in sdhc_skip()
443 /* Return first non-skipped value */ in sdhc_skip()
447 /* Handles reading data from SD SPI device */
450 const struct sdhc_spi_config *config = dev->config; in sdhc_spi_read_data()
451 struct sdhc_spi_data *dev_data = dev->data; in sdhc_spi_read_data()
452 uint8_t *read_location = data->data; in sdhc_spi_read_data()
453 uint32_t remaining = data->blocks; in sdhc_spi_read_data()
461 if (data->block_size > sizeof(sdhc_ones)) { in sdhc_spi_read_data()
462 return -ENOTSUP; in sdhc_spi_read_data()
468 .len = data->block_size, in sdhc_spi_read_data()
484 .len = data->block_size, in sdhc_spi_read_data()
503 return -EIO; in sdhc_spi_read_data()
507 while (remaining--) { in sdhc_spi_read_data()
508 ret = spi_transceive(config->spi_dev, in sdhc_spi_read_data()
509 dev_data->spi_cfg, tx_ptr, &rx); in sdhc_spi_read_data()
515 ret = sdhc_spi_rx(config->spi_dev, dev_data->spi_cfg, in sdhc_spi_read_data()
517 if (crc16_itu_t(0, read_location, data->block_size) != in sdhc_spi_read_data()
521 return -EILSEQ; in sdhc_spi_read_data()
524 read_location += data->block_size; in sdhc_spi_read_data()
531 return -EIO; in sdhc_spi_read_data()
538 /* Handles writing data to SD SPI device */
541 const struct sdhc_spi_config *config = dev->config; in sdhc_spi_write_data()
542 struct sdhc_spi_data *dev_data = dev->data; in sdhc_spi_write_data()
545 uint8_t *write_location = data->data, crc[SD_SPI_CRC16_SIZE]; in sdhc_spi_write_data()
546 uint32_t remaining = data->blocks; in sdhc_spi_write_data()
555 .len = data->block_size, in sdhc_spi_write_data()
568 /* Set the token- single block reads use different token in sdhc_spi_write_data()
577 while (remaining--) { in sdhc_spi_write_data()
579 sys_put_be16(crc16_itu_t(0, write_location, data->block_size), in sdhc_spi_write_data()
581 ret = spi_write(config->spi_dev, dev_data->spi_cfg, &tx); in sdhc_spi_write_data()
586 ret = sdhc_spi_rx(config->spi_dev, dev_data->spi_cfg, in sdhc_spi_write_data()
594 return -EILSEQ; in sdhc_spi_write_data()
596 return -EIO; in sdhc_spi_write_data()
599 return -EIO; in sdhc_spi_write_data()
602 write_location += data->block_size; in sdhc_spi_write_data()
605 ret = sdhc_spi_wait_unbusy(dev, data->timeout_ms, 0); in sdhc_spi_write_data()
610 if (data->blocks > 1) { in sdhc_spi_write_data()
614 ret = spi_write(config->spi_dev, dev_data->spi_cfg, &tx); in sdhc_spi_write_data()
619 ret = sdhc_spi_wait_unbusy(dev, data->timeout_ms, 0); in sdhc_spi_write_data()
631 const struct sdhc_spi_config *config = dev->config; in sdhc_spi_request()
632 struct sdhc_spi_data *dev_data = dev->data; in sdhc_spi_request()
633 int ret, ret2, stop_ret, retries = cmd->retries; in sdhc_spi_request()
642 /* Request SPI bus to be active */ in sdhc_spi_request()
643 if (pm_device_runtime_get(config->spi_dev) < 0) { in sdhc_spi_request()
644 return -EIO; in sdhc_spi_request()
650 } while ((ret != 0) && (retries-- > 0)); in sdhc_spi_request()
653 retries--; in sdhc_spi_request()
658 if ((cmd->opcode == SD_WRITE_SINGLE_BLOCK) || in sdhc_spi_request()
659 (cmd->opcode == SD_WRITE_MULTIPLE_BLOCK)) { in sdhc_spi_request()
664 if (ret || (cmd->opcode == SD_READ_MULTIPLE_BLOCK)) { in sdhc_spi_request()
665 int stop_retries = cmd->retries; in sdhc_spi_request()
678 stop_retries--; in sdhc_spi_request()
684 /* Release SPI bus */ in sdhc_spi_request()
685 ret2 = spi_release(config->spi_dev, dev_data->spi_cfg); in sdhc_spi_request()
687 /* Release request for SPI bus to be active */ in sdhc_spi_request()
688 (void)pm_device_runtime_put(config->spi_dev); in sdhc_spi_request()
695 const struct sdhc_spi_config *cfg = dev->config; in sdhc_spi_set_io()
696 struct sdhc_spi_data *data = dev->data; in sdhc_spi_set_io()
698 if (ios->clock != data->spi_cfg->frequency) { in sdhc_spi_set_io()
699 if (ios->clock > cfg->spi_max_freq) { in sdhc_spi_set_io()
700 return -ENOTSUP; in sdhc_spi_set_io()
703 * swap to a new configuration structure to reconfigure SPI. in sdhc_spi_set_io()
705 if (ios->clock != 0) { in sdhc_spi_set_io()
706 if (data->spi_cfg == &data->cfg_a) { in sdhc_spi_set_io()
707 data->cfg_a.frequency = ios->clock; in sdhc_spi_set_io()
708 memcpy(&data->cfg_b, &data->cfg_a, in sdhc_spi_set_io()
710 data->spi_cfg = &data->cfg_b; in sdhc_spi_set_io()
712 data->cfg_b.frequency = ios->clock; in sdhc_spi_set_io()
713 memcpy(&data->cfg_a, &data->cfg_b, in sdhc_spi_set_io()
715 data->spi_cfg = &data->cfg_a; in sdhc_spi_set_io()
719 if (ios->bus_mode != SDHC_BUSMODE_PUSHPULL) { in sdhc_spi_set_io()
720 /* SPI mode supports push pull */ in sdhc_spi_set_io()
721 return -ENOTSUP; in sdhc_spi_set_io()
723 if (data->power_mode != ios->power_mode) { in sdhc_spi_set_io()
724 if (ios->power_mode == SDHC_POWER_ON) { in sdhc_spi_set_io()
725 if (cfg->pwr_gpio.port) { in sdhc_spi_set_io()
726 if (gpio_pin_set_dt(&cfg->pwr_gpio, 1)) { in sdhc_spi_set_io()
727 return -EIO; in sdhc_spi_set_io()
742 return -EIO; in sdhc_spi_set_io()
745 if (cfg->pwr_gpio.port) { in sdhc_spi_set_io()
746 if (gpio_pin_set_dt(&cfg->pwr_gpio, 0)) { in sdhc_spi_set_io()
747 return -EIO; in sdhc_spi_set_io()
752 data->power_mode = ios->power_mode; in sdhc_spi_set_io()
754 if (ios->bus_width != SDHC_BUS_WIDTH1BIT) { in sdhc_spi_set_io()
755 /* SPI mode supports 1 bit bus */ in sdhc_spi_set_io()
756 return -ENOTSUP; in sdhc_spi_set_io()
758 if (ios->signal_voltage != SD_VOL_3_3_V) { in sdhc_spi_set_io()
759 /* SPI mode does not support UHS voltages */ in sdhc_spi_set_io()
760 return -ENOTSUP; in sdhc_spi_set_io()
767 /* SPI has no card presence method, assume card is in slot */ in sdhc_spi_get_card_present()
774 const struct sdhc_spi_config *cfg = dev->config; in sdhc_spi_get_host_props()
778 props->f_min = SDMMC_CLOCK_400KHZ; in sdhc_spi_get_host_props()
779 props->f_max = cfg->spi_max_freq; in sdhc_spi_get_host_props()
780 props->power_delay = cfg->power_delay_ms; in sdhc_spi_get_host_props()
781 props->host_caps.vol_330_support = true; in sdhc_spi_get_host_props()
782 props->is_spi = true; in sdhc_spi_get_host_props()
788 struct sdhc_spi_data *data = dev->data; in sdhc_spi_reset()
791 data->spi_cfg->frequency = SDMMC_CLOCK_400KHZ; in sdhc_spi_reset()
797 const struct sdhc_spi_config *cfg = dev->config; in sdhc_spi_init()
798 struct sdhc_spi_data *data = dev->data; in sdhc_spi_init()
801 if (!device_is_ready(cfg->spi_dev)) { in sdhc_spi_init()
802 return -ENODEV; in sdhc_spi_init()
804 if (cfg->pwr_gpio.port) { in sdhc_spi_init()
805 if (!gpio_is_ready_dt(&cfg->pwr_gpio)) { in sdhc_spi_init()
806 return -ENODEV; in sdhc_spi_init()
808 ret = gpio_pin_configure_dt(&cfg->pwr_gpio, GPIO_OUTPUT_INACTIVE); in sdhc_spi_init()
814 data->power_mode = SDHC_POWER_OFF; in sdhc_spi_init()
815 data->spi_cfg = &data->cfg_a; in sdhc_spi_init()
816 data->spi_cfg->frequency = 0; in sdhc_spi_init()