mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-11-09 20:45:41 +08:00
[bsp][CV1800B] add SPI driver for CV1800B
Signed-off-by: Jingbao Qiu <qiujingbao.dlmu@gmail.com>
This commit is contained in:
1 parent
d856f77a55
commit
c24280f6ef
6 files changed
+404
No files matched your search
@@ -56,6 +56,7 @@ $ scons
|
||||
| gpio | 支持 | |
|
||||
| i2c | 支持 | |
|
||||
| adc | 支持 | |
|
||||
| spi | 支持 | 默认CS引脚,每个数据之间CS会拉高,请根据时序选择GPIO作为CS。若读取数据,tx需持续dummy数据。|
|
||||
|
||||
## 支持开发板
|
||||
- milk-v duo: [https://milkv.io/duo](https://milkv.io/duo)
|
||||
|
||||
@@ -45,6 +45,11 @@ menu "General Drivers Configuration"
|
||||
select RT_USING_ADC
|
||||
default n
|
||||
|
||||
config BSP_USING_SPI
|
||||
bool "Using SPI"
|
||||
select RT_USING_SPI
|
||||
default n
|
||||
|
||||
menuconfig BSP_USING_WDT
|
||||
bool "Enable Watchdog Timer"
|
||||
select RT_USING_WDT
|
||||
|
||||
@@ -37,6 +37,11 @@ menu "General Drivers Configuration"
|
||||
select RT_USING_ADC
|
||||
default n
|
||||
|
||||
config BSP_USING_SPI
|
||||
bool "Using SPI"
|
||||
select RT_USING_SPI
|
||||
default n
|
||||
|
||||
menuconfig BSP_USING_PWM
|
||||
bool "Using PWM"
|
||||
select RT_USING_PWM
|
||||
|
||||
@@ -30,6 +30,9 @@ if GetDepend('BSP_USING_ADC'):
|
||||
if GetDepend('BSP_USING_WDT'):
|
||||
src += ['drv_wdt.c']
|
||||
|
||||
if GetDepend(['BSP_USING_SPI']):
|
||||
src += ['drv_spi.c']
|
||||
|
||||
if GetDepend('BSP_USING_PWM'):
|
||||
src += ['drv_pwm.c']
|
||||
CPPPATH += [cwd + r'/libraries/cv180x/pwm']
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2024-03-28 qiujingbao first version
|
||||
*/
|
||||
#ifndef __DRV_SPI_H__
|
||||
#define __DRV_SPI_H__
|
||||
|
||||
#include "rtdevice.h"
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
#include "mmio.h"
|
||||
#include "pinctrl.h"
|
||||
|
||||
#define SPI0 0x0
|
||||
#define SPI1 0x1
|
||||
#define SPI2 0x2
|
||||
#define SPI3 0x3
|
||||
|
||||
#define SPI0_BASE 0x04180000
|
||||
#define SPI1_BASE 0x04190000
|
||||
#define SPI2_BASE 0x041A0000
|
||||
#define SPI3_BASE 0x041B0000
|
||||
|
||||
#define SPI_IRQ_MSAK 0x3e
|
||||
#define SPI_FREQUENCY 187500000
|
||||
|
||||
/* Transmit FiFO Threshold Level */
|
||||
#define SPI_TXFTLR 0xf
|
||||
|
||||
#define SPI_CTRL0_DATA_FREAM_SHIFT 0
|
||||
#define SPI_CTRL0_FREAM_FORMAT_SHIFT 4
|
||||
#define SPI_CTRL0_CPHA_SHIFT 6
|
||||
#define SPI_CTRL0_CPOL_SHIFT 7
|
||||
#define SPI_CTRL0_TRANS_MODE 8
|
||||
#define SPI_CTRL0_LOOP_SHIFT 11
|
||||
#define SPI_CTRL0_CTRL_FREAM_SHIFT 12
|
||||
|
||||
struct cv1800_spi {
|
||||
uint8_t spi_id;
|
||||
char *device_name;
|
||||
|
||||
uint8_t fifo_len;
|
||||
uint8_t data_width;
|
||||
|
||||
const void *send_buf;
|
||||
void *recv_buf;
|
||||
|
||||
const void *send_end;
|
||||
void *recv_end;
|
||||
|
||||
struct rt_spi_bus spi_bus;
|
||||
struct spi_regs *reg;
|
||||
};
|
||||
|
||||
struct spi_regs {
|
||||
uint32_t spi_ctrl0; // 0x00
|
||||
uint32_t spi_ctrl1; // 0x04
|
||||
uint32_t spi_ssienr; // 0x08
|
||||
uint32_t spi_mwcr; // 0x0c
|
||||
uint32_t spi_ser; // 0x10
|
||||
uint32_t spi_baudr; // 0x14
|
||||
uint32_t spi_txftlr; // 0x18
|
||||
uint32_t spi_rxftlr; // 0x1c
|
||||
uint32_t spi_txflr; // 0x20
|
||||
uint32_t spi_rxflr; // 0x24
|
||||
uint32_t spi_sr; // 0x28
|
||||
uint32_t spi_imr; // 0x2c
|
||||
uint32_t spi_isr; // 0x30
|
||||
uint32_t spi_risr; // 0x34
|
||||
uint32_t spi_txoicr; // 0x38
|
||||
uint32_t spi_rxoicr; // 0x3c
|
||||
uint32_t spi_rxuicr; // 0x40
|
||||
uint32_t spi_msticr; // 0x44
|
||||
uint32_t spi_icr; // 0x48
|
||||
uint32_t spi_dmacr; // 0x4c
|
||||
uint32_t spi_dmatdlr; // 0x50
|
||||
uint32_t spi_dmardlr; // 0x54
|
||||
uint32_t spi_idr; // 0x58
|
||||
uint32_t spi_version; // 0x5c
|
||||
uint32_t spi_dr; // 0x60
|
||||
uint32_t spi_rx_sample_dly; // 0xf0
|
||||
uint32_t spi_cs_override; // 0xf4
|
||||
};
|
||||
|
||||
uint32_t gen_spi_mode(struct rt_spi_configuration *cfg, uint32_t *mode)
|
||||
{
|
||||
uint32_t value = 0;
|
||||
|
||||
if (cfg->data_width != 8 && cfg->data_width != 16)
|
||||
return -1;
|
||||
|
||||
value |= (cfg->data_width - 1) >> SPI_CTRL0_DATA_FREAM_SHIFT;
|
||||
value |= cfg->mode >> SPI_CTRL0_CPHA_SHIFT;
|
||||
|
||||
*mode = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* set spi mode */
|
||||
static inline void spi_set_mode(struct spi_regs *reg, uint32_t mode)
|
||||
{
|
||||
mmio_write_32((uintptr_t)®->spi_ctrl0, mode);
|
||||
}
|
||||
|
||||
/* clear irq */
|
||||
static inline void spi_clear_irq(struct spi_regs *reg, uint32_t mode)
|
||||
{
|
||||
mmio_write_32((uintptr_t)®->spi_imr, mode);
|
||||
}
|
||||
|
||||
static inline void spi_enable_cs(struct spi_regs *reg, uint32_t enable)
|
||||
{
|
||||
if (enable)
|
||||
enable = 0x1;
|
||||
else
|
||||
enable = 0x0;
|
||||
|
||||
mmio_write_32((uintptr_t)®->spi_ser, enable);
|
||||
}
|
||||
|
||||
/* set spi frequency*/
|
||||
static inline rt_err_t spi_set_frequency(struct spi_regs *reg, uint32_t speed)
|
||||
{
|
||||
uint16_t value;
|
||||
|
||||
/* The value of the BAUDR register must be an even number between 2-65534 */
|
||||
value = SPI_FREQUENCY / speed;
|
||||
if (value % 2 != 0)
|
||||
value++;
|
||||
|
||||
if (value < 4 || value > 65534)
|
||||
value = 4;
|
||||
|
||||
mmio_write_32((uintptr_t)®->spi_baudr, value);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static inline void spi_enable(struct spi_regs *reg, uint32_t enable)
|
||||
{
|
||||
if (enable)
|
||||
enable = 0x1;
|
||||
else
|
||||
enable = 0x0;
|
||||
|
||||
mmio_write_32((uintptr_t)®->spi_ssienr, enable);
|
||||
}
|
||||
|
||||
#endif /* __DRV_SPI_H__ */
|
||||
Reference in new issue
Block a user