#include #include #include #include #include #include #include #include #include #include "../inc/ispi.h" #include "../inc/isys_com.h" static int openSpiDev(char *pDevName) { int fd ; int ret ; if(pDevName == NULL) return -2; if(!access(pDevName, F_OK)) { fd = open(pDevName, O_RDWR); if(fd < 0) { log_printf(LOG_ERR,I_NOUSED,"open error %s \n",pDevName); return -1; } } else { return -1; } //spidev_fd = fd; return (fd); } static int initSpiDev(int fd, u8 mode, u8 bits, int speed) { int err; err = ioctl(fd, SPI_IOC_WR_MODE, &mode); if (err == -1) { log_printf(LOG_ERR,I_NOUSED,"can't set spi SPI_IOC_WR_MODE\n"); return err; } err = ioctl(fd, SPI_IOC_RD_MODE, &mode); if (err == -1) { log_printf(LOG_ERR,I_NOUSED,"can't set spi SPI_IOC_RD_MODE\n"); return err; } err = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); if (err == -1) { log_printf(LOG_ERR,I_NOUSED,"can't set spi SPI_IOC_WR_BITS_PER_WORD\n"); return err; } err = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits); if (err == -1) { log_printf(LOG_ERR,I_NOUSED,"can't set spi SPI_IOC_RD_BITS_PER_WORD\n"); return err; } // err = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); // if (err == -1) // { // printf("can't set spi SPI_IOC_WR_MAX_SPEED_HZ\n"); // return err; // } err = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); if (err == -1) { log_printf(LOG_ERR,I_NOUSED,"can't set spi SPI_IOC_RD_MAX_SPEED_HZ\n"); return err; } return 0; } static int transfer_r(int fd, u16 addr, u8 *pdata) { int ret; uint8_t rx[3] = {0}; uint8_t tx[3] = {0}; u16 writeInstruct = 0; if(fd < 0 || pdata == NULL) return -1; writeInstruct= (addr|0x8000); tx[0]= writeInstruct>>8; tx[1]= (u8)(writeInstruct&0xff); struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)tx, .rx_buf = (unsigned long)rx, .len = ARRAY_SIZE(tx), .delay_usecs = SPI_DELAY, .speed_hz = SPEED, .bits_per_word = 8, }; ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); if (ret < 1) { log_printf(LOG_ERR,I_NOUSED,"can't send spi message,for read %d\n",fd); return -1; } //printf("addr=%.2x rd: ",addr); /*printf("r Tx:"); for (ret = 0; ret < ARRAY_SIZE(tx); ret++) { printf("%.2X ", tx[ret]); } printf("r Rx:"); for (ret = 0; ret < ARRAY_SIZE(tx); ret++) { printf("%.2X ", rx[ret]); } printf("\n"); */ *pdata = rx[2]; return 0; } static int transfer_w(int fd, u32 addr, u8 data) { int ret; uint8_t rx[3] = {0}; uint8_t tx[3] = {0}; if(fd < 0) return -1; addr &=~0x8000; tx[0] =(u8)((addr & 0xFF00) >> 8); tx[1] =(u8)(addr & 0x00FF); tx[2] = data; struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)tx, .rx_buf = (unsigned long)rx, .len = ARRAY_SIZE(tx), .delay_usecs = SPI_DELAY, .speed_hz = SPEED, .bits_per_word = 8, }; ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); if (ret < 1) { log_printf(LOG_ERR,I_NOUSED,"can't send spi message, for write fd %d\n",fd); return -1; } //printf("[sub]addr=%.2x w-rd: ",addr); /*printf("w Tx:"); for (ret = 0; ret < ARRAY_SIZE(tx); ret++) { printf(" %.2X ", tx[ret]); } printf("\n"); printf("w Rx:\n"); for (ret = 0; ret < ARRAY_SIZE(tx); ret++) { printf(" %.2X ", rx[ret]); } printf("\n");*/ return 0; } /* 4 wrie need tx and rx len : 3 ,return: ff xx xx*/ int spi_r(int fd, u8 addr, u16 *pdata) { int ret; uint8_t rx[3] = {0}; uint8_t tx[3] = {0}; if(fd < 0) return -1; tx[0] = (u8)(addr | 0x80); tx[1] = 0x00; tx[2] = 0x00; struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)tx, .rx_buf = (unsigned long)rx, .len = ARRAY_SIZE(tx), .delay_usecs = SPI_DELAY, .speed_hz = SPEED, .bits_per_word = 8, }; ret = ioctl(fd, SPI_IOC_MESSAGE(HALF_DUPLEX), &tr); if (ret < 1){ log_printf(LOG_ERR,I_NOUSED,"can't send spi message, for write fd %d\n",fd); return -1; } *pdata = (rx[1]<<8) + rx[2]; return 0; } /* 4 wrie need tx and rx len : 3 ,return: ff xx xx*/ int spi_r_addr16_data8(int fd, u16 addr, u8 *pdata) { int ret; uint8_t rx[3] = {0}; uint8_t tx[3] = {0}; if(fd < 0) return -1; tx[0] = (u8)((addr>>8)&0xff | 0x80); tx[1] = (u8)( addr&0xff); tx[2] = 0x00; struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)tx, .rx_buf = (unsigned long)rx, .len = ARRAY_SIZE(tx), .delay_usecs = SPI_DELAY, .speed_hz = SPEED, .bits_per_word = 8, }; ret = ioctl(fd, SPI_IOC_MESSAGE(HALF_DUPLEX), &tr); if (ret < 1){ log_printf(LOG_ERR,I_NOUSED,"can't send spi message, for write fd %d\n",fd); return -1; } *pdata = rx[2]; return 0; } uint8_t spi_rx_buff[35] = {0}; uint8_t spi_tx_buff[35] = {0}; int spi_transfer_big_block(int spi_fd, uint8 *pdata, int bytelen) { int ret; if(spi_fd < 0) return -1; if(bytelen>SPI_BUFF_MAX) printf("[%s,%d] buff full!! %d > 4KB\n", __func__,__LINE__, bytelen); memset(spi_tx_buff, 0, sizeof(spi_tx_buff)); memcpy(spi_tx_buff, pdata, bytelen); struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)spi_tx_buff, .rx_buf = (unsigned long)spi_rx_buff, .len = bytelen,//ARRAY_SIZE(spi_tx_buff), .delay_usecs = SPI_DELAY, .speed_hz = SPEED, .bits_per_word = 8, }; #if 1 /* SPI_IOC_MESSAGE(n) -- [n] means numbers of struct spi_ioc_transfer, so 1. */ ret = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr); if (ret < 1) { printf(" [%s,%d]send spi msg err, len=%d ret=%d rx[0]=%d tx[0]=%d (%d)\n", __func__,__LINE__, bytelen,ret, spi_rx_buff[0],spi_tx_buff[0], tr.len); //pabort("can't send spi message"); return -1; } #endif return 0; } int spi_receiver_big_block(int spi_fd, uint8 *pdata, int bytelen) { int ret; if(spi_fd < 0) return -1; if(bytelen>SPI_BUFF_MAX) printf("[%s,%d] buff full!! %d > 4KB\n", __func__,__LINE__, bytelen); memset(spi_tx_buff, 0, sizeof(spi_tx_buff)); memcpy(spi_tx_buff, pdata, 3); memset(spi_rx_buff, 0, sizeof(spi_rx_buff)); struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)spi_tx_buff, .rx_buf = (unsigned long)spi_rx_buff, .len = bytelen,//ARRAY_SIZE(spi_tx_buff), .delay_usecs = SPI_DELAY, .speed_hz = SPEED, .bits_per_word = 8, }; #if 1 /* SPI_IOC_MESSAGE(n) -- [n] means numbers of struct spi_ioc_transfer, so 1. */ ret = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr); if (ret < 1) { printf(" [%s,%d]send spi msg err, len=%d ret=%d rx[0]=%d tx[0]=%d (%d)\n", __func__,__LINE__, bytelen,ret, spi_rx_buff[0],spi_tx_buff[0], tr.len); return -1; } //printf(" rxbuf[3-4]= 0x%02x 0x%02x\n",spi_rx_buff[3], spi_rx_buff[4]); memcpy(pdata, spi_rx_buff, bytelen); #endif return 0; } int spi_w(int fd, u8 addr, uint16_t u16_data) { int ret; uint8_t rx[3] = {0}; uint8_t tx[3] = {0}; uint32 u32addr = (uint32)addr << 16; if(fd < 0) return -1; u32addr &= ~0x800000; u32addr |= u16_data; tx[0] = (u8)((u32addr >> 16) & 0xFF); tx[1] = (u8)((u32addr >> 8) & 0xFF); tx[2] = (u8)((u32addr >> 0) & 0xFF); struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)tx, .rx_buf = (unsigned long)rx, .len = ARRAY_SIZE(tx), .delay_usecs = SPI_DELAY, .speed_hz = SPEED, .bits_per_word = 8, }; ret = ioctl(fd, SPI_IOC_MESSAGE(HALF_DUPLEX), &tr); if (ret < 1){ log_printf(LOG_ERR,I_NOUSED,"can't send spi message, for write fd %d\n",fd); return -1; } return 0; } int spi_w_addr16_data8(int fd, u16 addr, uint8_t data) { int ret; uint8_t rx[3] = {0}; uint8_t tx[3] = {0}; uint32 u16addr=0; if(fd < 0) return -1; u16addr &= ~0x8000; u16addr |= (addr&0x7fff); tx[0] = (u8)((u16addr >> 8) & 0xFF); tx[1] = (u8)((u16addr) & 0xFF); tx[2] = (u8)((data) & 0xFF); struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)tx, .rx_buf = (unsigned long)rx, .len = ARRAY_SIZE(tx), .delay_usecs = SPI_DELAY, .speed_hz = SPEED, .bits_per_word = 8, }; ret = ioctl(fd, SPI_IOC_MESSAGE(HALF_DUPLEX), &tr); if (ret < 1){ log_printf(LOG_ERR,I_NOUSED,"can't send spi message, for write fd %d\n",fd); return -1; } return 0; } uint8_t iSPI_I2S_SendData(int spi_fd, uint16_t Data) { int ret; uint8_t rx[2] = {0}; uint8_t tx[2] = {0}; if(spi_fd < 0) return -1; tx[0] = (u8)((Data & 0xFF00) >> 8); tx[1] = (u8)((Data & 0x00FF) >> 0); struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)tx, .rx_buf = (unsigned long)rx, .len = ARRAY_SIZE(tx), .delay_usecs = SPI_DELAY, .speed_hz = SPEED, .bits_per_word = 8, }; ret = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr); if (ret < 1) { log_printf(LOG_ERR,I_NOUSED,"can't send spi message, for write fd %d\n",spi_fd); return -1; } return 0; } uint8_t iSPI_I2S_Send4Byte(int spi_fd, uint8 *pdata) { int ret; uint8_t rx[4] = {0}; uint8_t tx[4] = {0}; if(spi_fd < 0) return -1; memcpy(tx, pdata, 4); struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)tx, .rx_buf = (unsigned long)rx, .len = ARRAY_SIZE(tx), .delay_usecs = SPI_DELAY, .speed_hz = SPEED, .bits_per_word = 8, }; /* SPI_IOC_MESSAGE(n) -- [n] means numbers of struct spi_ioc_transfer, so 1. */ ret = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr); if (ret < 1) { log_printf(LOG_ERR,I_NOUSED,"can't send spi message, for write fd %d\n", spi_fd); return -1; } return 0; } int init_spi_dev(char *pspi_node_name, int *pfd, uint8 mode, uint8 bits, uint8 speed) { int ret; int fd=-1; /* wr/rd speed: defined through macro definitions[ SPEED ]. */ // unsigned char mode = SPI_MODE_3 ; // unsigned char bits = 8; // unsigned int speed = 100000; fd = openSpiDev(pspi_node_name); if(fd < 0) { log_printf(LOG_ERR, I_NOUSED, "init_spi_dev >%s< open failed!\n", pspi_node_name); } ret = initSpiDev(fd, mode, bits, speed); if(ret < 0 ) { log_printf(LOG_ERR, I_NOUSED, "init_spi_dev >%s< init failed!\n", pspi_node_name); return -1; } log_printf(LOG_INFO, I_SYS_STATUS, "init_spi_dev >%s< init ok!!\n", pspi_node_name); *pfd = fd; }