drv_spi.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * Copyright (c) 2006-2024, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-03-28 qiujingbao first version
  9. */
  10. #ifndef __DRV_SPI_H__
  11. #define __DRV_SPI_H__
  12. #include "rtdevice.h"
  13. #include <rthw.h>
  14. #include <rtthread.h>
  15. #include "mmio.h"
  16. #include "pinctrl.h"
  17. #define SPI0 0x0
  18. #define SPI1 0x1
  19. #define SPI2 0x2
  20. #define SPI3 0x3
  21. #define SPI0_BASE 0x04180000
  22. #define SPI1_BASE 0x04190000
  23. #define SPI2_BASE 0x041A0000
  24. #define SPI3_BASE 0x041B0000
  25. #define SPI_IRQ_MSAK 0x3e
  26. #define SPI_FREQUENCY 187500000
  27. /* Transmit FiFO Threshold Level */
  28. #define SPI_TXFTLR 0xf
  29. #define SPI_CTRL0_DATA_FREAM_SHIFT 0
  30. #define SPI_CTRL0_FREAM_FORMAT_SHIFT 4
  31. #define SPI_CTRL0_CPHA_SHIFT 6
  32. #define SPI_CTRL0_CPOL_SHIFT 7
  33. #define SPI_CTRL0_TRANS_MODE 8
  34. #define SPI_CTRL0_LOOP_SHIFT 11
  35. #define SPI_CTRL0_CTRL_FREAM_SHIFT 12
  36. struct cv1800_spi {
  37. uint8_t spi_id;
  38. char *device_name;
  39. uint8_t fifo_len;
  40. uint8_t data_width;
  41. const void *send_buf;
  42. void *recv_buf;
  43. const void *send_end;
  44. void *recv_end;
  45. struct rt_spi_bus spi_bus;
  46. struct spi_regs *reg;
  47. };
  48. struct spi_regs {
  49. uint32_t spi_ctrl0; // 0x00
  50. uint32_t spi_ctrl1; // 0x04
  51. uint32_t spi_ssienr; // 0x08
  52. uint32_t spi_mwcr; // 0x0c
  53. uint32_t spi_ser; // 0x10
  54. uint32_t spi_baudr; // 0x14
  55. uint32_t spi_txftlr; // 0x18
  56. uint32_t spi_rxftlr; // 0x1c
  57. uint32_t spi_txflr; // 0x20
  58. uint32_t spi_rxflr; // 0x24
  59. uint32_t spi_sr; // 0x28
  60. uint32_t spi_imr; // 0x2c
  61. uint32_t spi_isr; // 0x30
  62. uint32_t spi_risr; // 0x34
  63. uint32_t spi_txoicr; // 0x38
  64. uint32_t spi_rxoicr; // 0x3c
  65. uint32_t spi_rxuicr; // 0x40
  66. uint32_t spi_msticr; // 0x44
  67. uint32_t spi_icr; // 0x48
  68. uint32_t spi_dmacr; // 0x4c
  69. uint32_t spi_dmatdlr; // 0x50
  70. uint32_t spi_dmardlr; // 0x54
  71. uint32_t spi_idr; // 0x58
  72. uint32_t spi_version; // 0x5c
  73. uint32_t spi_dr; // 0x60
  74. uint32_t spi_rx_sample_dly; // 0xf0
  75. uint32_t spi_cs_override; // 0xf4
  76. };
  77. uint32_t gen_spi_mode(struct rt_spi_configuration *cfg, uint32_t *mode)
  78. {
  79. uint32_t value = 0;
  80. if (cfg->data_width != 8 && cfg->data_width != 16)
  81. return -1;
  82. value |= (cfg->data_width - 1) >> SPI_CTRL0_DATA_FREAM_SHIFT;
  83. value |= cfg->mode >> SPI_CTRL0_CPHA_SHIFT;
  84. *mode = value;
  85. return 0;
  86. }
  87. /* set spi mode */
  88. static inline void spi_set_mode(struct spi_regs *reg, uint32_t mode)
  89. {
  90. mmio_write_32((uintptr_t)&reg->spi_ctrl0, mode);
  91. }
  92. /* clear irq */
  93. static inline void spi_clear_irq(struct spi_regs *reg, uint32_t mode)
  94. {
  95. mmio_write_32((uintptr_t)&reg->spi_imr, mode);
  96. }
  97. static inline void spi_enable_cs(struct spi_regs *reg, uint32_t enable)
  98. {
  99. if (enable)
  100. enable = 0x1;
  101. else
  102. enable = 0x0;
  103. mmio_write_32((uintptr_t)&reg->spi_ser, enable);
  104. }
  105. /* set spi frequency*/
  106. static inline rt_err_t spi_set_frequency(struct spi_regs *reg, uint32_t speed)
  107. {
  108. uint16_t value;
  109. /* The value of the BAUDR register must be an even number between 2-65534 */
  110. value = SPI_FREQUENCY / speed;
  111. if (value % 2 != 0)
  112. value++;
  113. if (value < 4 || value > 65534)
  114. value = 4;
  115. mmio_write_32((uintptr_t)&reg->spi_baudr, value);
  116. return RT_EOK;
  117. }
  118. static inline void spi_enable(struct spi_regs *reg, uint32_t enable)
  119. {
  120. if (enable)
  121. enable = 0x1;
  122. else
  123. enable = 0x0;
  124. mmio_write_32((uintptr_t)&reg->spi_ssienr, enable);
  125. }
  126. #endif /* __DRV_SPI_H__ */