SPI
It can be learned from the data manual that ssd20x has two SPI interfaces, one of which has been used for spiflash, so there is only one SPI interface for developers.
you need to open the SPI interface, you need to change the status in DTS to OK:
vi kernel/arch/arm/boot/dts/infinity2m-doublenet.dtsi
Then configure the corresponding pin as SPI_MODE:
vi kernel/arch/arm/boot/dts/infinity2m-ssc011a-s01a-padmux-rgb565-rmii-doublenet.dtsi
<PAD_GPIO8 PINMUX_FOR_SPI0_MODE_5 MDRV_PUSE_SPI0_CZ>,
<PAD_GPIO9 PINMUX_FOR_SPI0_MODE_5 MDRV_PUSE_SPI0_CK >,
<PAD_GPIO10 PINMUX_FOR_SPI0_MODE_5 MDRV_PUSE_SPI0_DI >,
<PAD_GPIO11 PINMUX_FOR_SPI0_MODE_5 MDRV_PUSE_SPI0_DO >,
The default is SPI_Mode, so you only need to ensure that it is not configured for other functions. Finally, load MspI driver:
# cd kernel && ARCH=arm make menuconfig
After configuration, save to the default configuration:
# cp .config ./arch/arm/configs/infinity2m_spinand_ssc011a_s01a_minigui_doublenet_defconfig -f
After compiling, view the SPI node:
# ls /dev/spi*
The SPI node has come out.
Using spi_test.c perform loop back (short circuit miso and mosi) test.
short circuit GPIO10-GPIO11
Compile spi_test.c to get spi_test, copy spi_test to the development board and execute.
# ./spi_test
SPI test ok.
spi_test.c source code
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <strings.h>
#include <string.h>
#include "../../project/kbuild/4.9.84/i2m/include/uapi/linux/spi/spidev.h"
static const char *device = "/dev/spidev0.0";
static uint8_t mode = 0; /* SPI 通信使用全双工,设置 CPOL=0,CPHA=0。 */
static uint8_t bits = 8; /* 8bits读写,MSB first。*/
static uint32_t speed = 12*1000*1000;/* 设置传输速度 */
static uint16_t delay = 0;
static int g_SPI_Fd = 0;
#define SPI_DEBUG 1
static void pabort(const char *s)
{
perror(s);
abort();
}
int SPI_Transfer(const uint8_t *TxBuf, uint8_t *RxBuf, int len)
{
int ret;
int fd = g_SPI_Fd;
struct spi_ioc_transfer tr ={
.tx_buf = (unsigned long) TxBuf,
.rx_buf = (unsigned long) RxBuf,
.len =len,
.delay_usecs = delay,
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1)
perror("can't send spi message\n");
else
{
#if SPI_DEBUG
int i;
printf("nsend spi message Succeed\n");
printf("nSPI Send [Len:%d]: \n", len);
for (i = 0; i < len; i++)
{
if (i % 8 == 0)
printf("nt\n");
printf("0x%02X \n", TxBuf[i]);
}
printf("n");
printf("SPI Receive [len:%d]:\n", len);
for (i = 0; i < len; i++)
{
if (i % 8 == 0)
printf("nt\n");
printf("0x%02X \n", RxBuf[i]);
}
#endif
}
return ret;
}
int SPI_Write(uint8_t *TxBuf, int len)
{
int ret;
int fd = g_SPI_Fd;
ret = write(fd, TxBuf, len);
if (ret < 0)
perror("SPI Write error\n");
else
{
#if SPI_DEBUG
int i;
printf("SPI Write [Len:%d]: \n", len);
for (i = 0; i < len; i++)
{
if (i % 8 == 0)
printf("\n\t");
printf("0x%02X \n", TxBuf[i]);
}
printf("\n");
#endif
}
return ret;
}
int SPI_Read(uint8_t *RxBuf, int len)
{
int ret;
int fd = g_SPI_Fd;
ret = read(fd, RxBuf, len);
if (ret < 0)
printf("SPI Read error\n");
else
{
#if SPI_DEBUG
int i;
printf("SPI Read [len:%d]:\n", len);
for (i = 0; i < len; i++)
{
if (i % 8 == 0)
printf("\n\t");
printf("0x%02X \n", RxBuf[i]);
}
printf("\n");
#endif
}
return ret;
}
int SPI_Open(void)
{
int fd;
int ret = 0;
if (g_SPI_Fd != 0) /* 设备已打开 */
return 0xF1;
fd = open(device, O_RDWR);
if (fd < 0)
pabort("can't open device\n");
else
printf("SPI - Open Succeed. Start Init SPI...\n");
g_SPI_Fd = fd;
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (ret == -1)
pabort("can't set spi mode\n");
ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
if (ret == -1)
pabort("can't get spi mode\n");
/*
* bits per word
*/
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't set bits per word\n");
ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
if (ret == -1)
pabort("can't get bits per word\n");
/*
* max speed hz
*/
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't set max speed hz\n");
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
if (ret == -1)
pabort("can't get max speed hz\n");
printf("spi mode: %d\n", mode);
printf("bits per word: %d\n", bits);
printf("max speed: %d KHz (%d MHz)\n", speed / 1000, speed / 1000 / 1000);
return ret;
}
int SPI_Close(void)
{
int fd = g_SPI_Fd;
if (fd == 0) /* SPI 是否已经打开*/
return 0;
close(fd);
g_SPI_Fd = 0;
return 0;
}
int SPI_LookBackTest(void)
{
int ret, i;
const int BufSize = 16;
uint8_t tx[BufSize], rx[BufSize];
bzero(rx, sizeof(rx));
for (i = 0; i < BufSize; i++)
tx[i] = i;
printf("nSPI - LookBack Mode Test...\n");
ret = SPI_Transfer(tx, rx, BufSize);
if (ret > 1)
{
ret = memcmp(tx, rx, BufSize);
if (ret != 0)
{
printf("tx:\n");
for (i = 0; i < BufSize; i++)
{
printf("%d ", tx[i]);
}
printf("\n");
printf("rx:\n");
for (i = 0; i < BufSize; i++)
{
printf("%d ", rx[i]);
}
printf("\n");
perror("LookBack Mode Test error\n");
}
else
printf("SPI - LookBack Mode OK\n");
}
return ret;
}
int main(void)
{
int ret;
ret = SPI_Open();
printf("************************* ret = %d***********************\n", ret);
//unsigned char buf[3] = {0xf3, 0x76, 0x59};
//SPI_Write(buf, 3);
SPI_LookBackTest();
SPI_Close();
return 0;
}