#include #include #include #include #include #include #include #include #include #include #define SPI_SUCCESS 0 #define SPI_FAIL -1 typedef struct { uint32_t ch; int32_t handle; }spi_property_desc; typedef void *HANDLE; #define HI_SPI_NODE_PATH "/dev/soc_spi" #define MAX_CH 2 #define SPI_HANDLE(handle) ((spi_property_desc *)handle) typedef struct { uint8_t dev_id; uint8_t *s_data; uint32_t s_data_cnt; } spi_data_s; typedef struct { uint8_t dev_id; uint32_t s_data; uint32_t s_data_cnt; } spi_data_compat_s; typedef struct { uint8_t dev_id; uint8_t *s_data; uint32_t s_data_cnt; uint8_t *r_data; uint32_t r_data_cnt; } spi_dataex_s; typedef struct { uint8_t dev_id; uint32_t s_data; uint32_t s_data_cnt; uint32_t r_data; uint32_t r_data_cnt; } spi_dataex_compat_s; typedef struct { uint8_t dev_id; uint8_t mode; uint8_t spo; uint8_t sph; uint8_t dss; uint8_t cscfg; } spi_fform_s; typedef struct { uint8_t dev_id; uint32_t set_bend; } spi_blend_s; typedef struct { uint8_t dev_id; uint8_t set_loop; } spi_loop_s; #define MAX_SPI_CHANNEL 4 #define SOC_ID_SPI 23 #define CMD_SPI_READ _IOWR(SOC_ID_SPI, 0x1, spi_data_s) #define CMD_COMPAT_SPI_READ _IOWR(SOC_ID_SPI, 0x1, spi_data_compat_s) #define CMD_SPI_WRITE _IOWR(SOC_ID_SPI, 0x2, spi_data_s) #define CMD_COMPAT_SPI_WRITE _IOWR(SOC_ID_SPI, 0x2, spi_data_compat_s) #define CMD_SPI_SET_ATTR _IOWR(SOC_ID_SPI, 0x3, spi_fform_s) #define CMD_SPI_GET_ATTR _IOWR(SOC_ID_SPI, 0x4, spi_fform_s) #define CMD_SPI_OPEN _IOW (SOC_ID_SPI, 0x5, uint32_t) #define CMD_SPI_CLOSE _IOW (SOC_ID_SPI, 0x6, uint32_t) #define CMD_SPI_SET_BLEND _IOWR(SOC_ID_SPI, 0x7, spi_blend_s) #define CMD_SPI_GET_BLEND _IOWR(SOC_ID_SPI, 0x8, spi_blend_s) #define CMD_SPI_SET_CLK _IOW (SOC_ID_SPI, 0x9, uint32_t) #define CMD_SPI_READEX _IOWR(SOC_ID_SPI, 0xa, spi_dataex_s) #define CMD_COMPAT_SPI_READEX _IOWR(SOC_ID_SPI, 0xa, spi_dataex_compat_s) #define CMD_SPI_SET_LOOP _IOW (SOC_ID_SPI, 0xb, spi_loop_s) #define CMD_SPI_RW_LOOP _IOWR(SOC_ID_SPI, 0xc, spi_dataex_s) #define CMD_COMPAT_SPI_RW_LOOP _IOWR(SOC_ID_SPI, 0xc, spi_dataex_compat_s) HANDLE spi_init(uint32_t ch) { spi_property_desc *handle = malloc(sizeof(spi_property_desc)); if(handle == NULL) return NULL; handle->handle = open(HI_SPI_NODE_PATH, O_RDWR,0); if(handle->handle < 0) { printf("open dev %s fail.errno:%d,errstr:%s\n",HI_SPI_NODE_PATH,errno,strerror(errno)); free(handle); return NULL; } if(ch >= MAX_CH) { printf("spi init fail. ch:%d is invalid\n",ch); close(handle->handle); free(handle); return NULL; } handle->ch = ch; if(ioctl(handle->handle, CMD_SPI_OPEN, ch)!=0) { printf("spi init fail. open spi%d fail.errno:%d,errstr:%s\n",ch,errno,strerror(errno)); close(handle->handle); free(handle); return NULL; } spi_fform_s fform = {0}; fform.dev_id = ch; fform.mode = 0; fform.spo = 0; fform.sph = 1; fform.dss = 16; fform.cscfg = 0; if(ioctl(handle->handle, CMD_SPI_SET_ATTR, &fform)!=0) { printf("spi init fail. open spi%d set attr fail.errno:%d,errstr:%s\n",ch,errno,strerror(errno)); close(handle->handle); free(handle); return NULL; } spi_blend_s bigend = {0}; bigend.dev_id = ch; bigend.set_bend = 1; if(ioctl(handle->handle, CMD_SPI_SET_BLEND, &bigend)!=0) { printf("spi init fail. open spi%d set blend fail.errno:%d,errstr:%s\n",ch,errno,strerror(errno)); close(handle->handle); free(handle); return NULL; } return handle; } void spi_deinit(HANDLE handle) { if(handle == NULL) return; ioctl(SPI_HANDLE(handle)->handle, CMD_SPI_CLOSE, SPI_HANDLE(handle)->ch); close(SPI_HANDLE(handle)->handle); free(handle); handle = NULL; } int8_t spi_read(HANDLE handle,uint8_t *data,uint32_t len) { if(handle == NULL) return -1; spi_data_s spi_data = {0}; spi_data.dev_id = SPI_HANDLE(handle)->ch; spi_data.s_data = data; spi_data.s_data_cnt = len; if(ioctl(SPI_HANDLE(handle)->handle,CMD_SPI_READ,&data) != 0) { printf("spi read fail.errno:%d,errstr:%s\n",errno,strerror(errno)); return -1; } return 0; } int8_t spi_write(HANDLE handle,uint8_t *data,uint32_t len) { if(handle == NULL) return -1; spi_data_s spi_data = {0}; spi_data.dev_id = SPI_HANDLE(handle)->ch; spi_data.s_data = data; spi_data.s_data_cnt = len; if(ioctl(SPI_HANDLE(handle)->handle,CMD_SPI_WRITE,&data) != 0) { printf("spi write fail.errno:%d,errstr:%s\n",errno,strerror(errno)); return -1; } return 0; } int8_t spi_transmit(HANDLE handle,uint8_t *w_data,uint32_t w_len,uint8_t *r_data,uint32_t r_len) { if(handle == NULL) return -1; spi_dataex_s data = {0}; data.dev_id = SPI_HANDLE(handle)->ch; data.s_data = w_data; data.s_data_cnt = w_len; data.r_data = r_data; data.r_data_cnt = r_len; if(ioctl(SPI_HANDLE(handle)->handle,CMD_SPI_READEX,&data) != 0) { printf("spi transmit fail.errno:%d,errstr:%s\n",errno,strerror(errno)); return -1; } return 0; } //spi_ctl 0 type void PrintUsage() { printf("Usage: spi_ctl \n"); printf("\t type r:\n"); printf("\t type w: \n"); printf("\t type t: \n"); } #define CMD_TYPE_R "r" #define CMD_TYPE_W "w" #define CMD_TYPE_T "t" int main(int argc,char **argv) { if(argc < 2) { printf("invalid parameter.\n"); PrintUsage(); return 0; } uint32_t ch =(uint32_t)strtol(argv[1], NULL, 0); HANDLE handle = spi_init(ch); if(handle == NULL) return 0; char *type = argv[2]; if(strcmp(type,CMD_TYPE_R)==0) { if(argc < 3) { printf("invalid parameter.\n"); PrintUsage(); spi_deinit(handle); return 0; } uint32_t r_len = (uint32_t)strtol(argv[3], NULL, 0); uint8_t *r_data = (uint8_t *)malloc(r_len); if(r_data == NULL) { printf("malloc r_data size %d fail.\n",r_len); PrintUsage(); spi_deinit(handle); return 0; } memset(r_data,0,r_len); if(spi_read(handle,r_data,r_len)!=SPI_SUCCESS) { free(r_data); PrintUsage(); spi_deinit(handle); printf("recv bytes:\n"); for(int i=0;i",r_data[i]); printf("\n"); return 0; } printf("recv bytes:\n"); for(int i=0;i",r_data[i]); printf("\n"); free(r_data); } else if(strcmp(type,CMD_TYPE_W)==0) { if(argc < 3) { printf("invalid parameter.\n"); PrintUsage(); spi_deinit(handle); return 0; } uint32_t w_len = (uint32_t)strtol(argv[3], NULL, 0); uint8_t *w_data = (uint8_t *)malloc(w_len); if(w_data == NULL) { printf("malloc w_data size %d fail.\n",w_len); PrintUsage(); spi_deinit(handle); return 0; } memset(w_data,0,w_len); for(int i=0;i",w_data[i]); printf("\n"); if(spi_transmit(handle,w_data,w_len, r_data,r_len)!=SPI_SUCCESS) { free(w_data); free(r_data); PrintUsage(); spi_deinit(handle); return 0; } printf("recv bytes:\n"); for(int i=0;i",r_data[i]); printf("\n"); free(w_data); free(r_data); } else { printf("invalid parameter.\n"); PrintUsage(); spi_deinit(handle); return 0; } spi_deinit(handle); return 0; }