/********************************************************************* * @fn flash_cmd * * @brief write cmd header and its header param * * @param cmd: CMD ID * param: param for cmd * * @return received data */ void flash_cmd(unsigned char cmd, unsigned long param) { unsigned char temp; DESELECT(); SELECT(); temp = spi_rw(cmd); switch (cmd) { case READ_DATA: case PAGE_PROGRAM: temp = spi_rw((unsigned char) (param >> 16)); temp = spi_rw((unsigned char) (param >> 8)); temp = spi_rw((unsigned char) (param)); break; case BLOCK_ERASE: case SECTOR_ERASE: temp = spi_rw((unsigned char) (param >> 16)); temp = spi_rw((unsigned char) (param >> 8)); temp = spi_rw((unsigned char) (param)); DESELECT(); break; case WRITE_ENABLE: case WRITE_DISABLE: case CHIP_ERASE: case POWER_DOWN: DESELECT(); break; case READ_ID: break; } }
void mma_write( uint8_t address, uint8_t value ) { ACL_CS=0; spi_rw((address<<1)|0b10000000); spi_rw(value); ACL_CS=1; }
uint8_t mma_read( uint8_t address ) { uint8_t value; ACL_CS=0; spi_rw( address << 1 ); value = spi_rw(0x00 ); ACL_CS=1; return value; }
/* write wn bytes, read rn bytes and write to serial port */ void spi2serial(uint8_t *wbuf, uint16_t wn, uint16_t rn) { CS_LOW; spi_rw(wbuf, wn, NULL, 0, 0); uint16_t i; uint8_t temp; for(i = 0; i < rn; i++){ spi_rw(NULL, 0, &temp, 1, 0); serial_write(&temp, 1); } CS_HIGH; }
uint8_t nrf_status(void) { nrf_CSN_lo; uint8_t status=spi_rw(R_CONFIG); nrf_CSN_hi; return status; }
/********************************************************************* * @fn flash_WIP_poll * * @brief check and wait until write process is done * * @param none * * @return none */ void flash_WIP_poll(void) { unsigned char stat; flash_cmd(READ_STAT, 0); do { stat = spi_rw(0xFF); } while ((stat & 0x01) || stat == 0xFF); DESELECT(); }
/********************************************************************* * @fn flash_read * * @brief read flash data * * @param address: where to start read data out * p: where to save read data * cnt: number of byte want to read * * @return none: */ void flash_read(unsigned long address, unsigned char* p, unsigned int cnt) { flash_WIP_poll(); flash_cmd(READ_DATA, address); do { *p++ = spi_rw(0xFF); } while (--cnt); DESELECT(); }
static int mc13892_spi_reg_write(struct mc13892 *mc13892, enum mc13892_reg reg, u32 val) { uint32_t buf = MXC_PMIC_REG_NUM(reg) | MXC_PMIC_WRITE | (val & 0xffffff); spi_rw(mc13892->spi, &buf, 4); return 0; }
static inline void mpu_set(uint8_t _reg, uint8_t _val) { aspirin2_mpu60x0.mosi_buf[0] = _reg; aspirin2_mpu60x0.mosi_buf[1] = _val; spi_rw(&aspirin2_mpu60x0); while(aspirin2_mpu60x0.status != SPITransSuccess); }
/********************************************************************* * @fn flash_read_stat * * @brief read flash status register * * @param none * * @return stat value */ unsigned char flash_read_stat(void) { unsigned char rcv; flash_cmd(READ_STAT, 0); rcv = spi_rw(0xFF); DESELECT(); return rcv; }
/********************************************************************* * @fn flash_read_id * * @brief read device ID * * @param p: buffer to read device id out * * @return none: */ void flash_read_id(unsigned char *p) { unsigned char cnt = 4; flash_WIP_poll(); flash_cmd(READ_ID, 0); do { *p++ = spi_rw(0xFF); } while (--cnt); DESELECT(); }
int16_t mma_read10( uint8_t address ) { int16_t value=0xc000; uint8_t l,h; ACL_CS=0; spi_rw( address << 1 ); value = spi_rw(0x00); //<<6;//low byte ACL_CS=1; value=value<<6; ACL_CS=0; spi_rw( (address+1) << 1 ); h=spi_rw(0x00 ); value|= (h<<14);//high byte ACL_CS=1; //value=h; //value=value<<8; //value|=l; return value>>6; }
/********************************************************************* * @fn flash_page_program * * @brief program flash, limit inside 1 page * * @param address: where to start write data * p: data in array * cnt: number of byte want to write * * @return none: */ void flash_page_program(unsigned long address, unsigned char* p, unsigned int cnt) { unsigned char temp; flash_WIP_poll(); flash_cmd(WRITE_ENABLE, 0); flash_cmd(PAGE_PROGRAM, address); do { temp = spi_rw(*p++); } while (--cnt); DESELECT(); }
void spi_rw_n(uint8_t *send, uint8_t *receive, int num_bytes, SPI_channel_select_t SPI_channel) { int n; switch (SPI_channel){ case SPI_SRC_channel: SRC_CS_LATCH = 0; for (n = 0; n<num_bytes; n++){ *receive++ = spi_rw(*send++); } SRC_CS_LATCH = 1; break; case SPI_DAC_channel: DAC_CS_LATCH = 0; for (n = 0; n<num_bytes; n++){ *receive++ = spi_rw(*send++); // __delay_ms(10); } DAC_CS_LATCH = 1; break; } }
static inline void mpu_wait_slave4_ready(void) { uint8_t ret = 0x80; while (ret & 0x80) { aspirin2_mpu60x0.mosi_buf[0] = MPU60X0_REG_I2C_SLV4_CTRL | MPU60X0_SPI_READ ; aspirin2_mpu60x0.mosi_buf[1] = 0; spi_rw(&aspirin2_mpu60x0); while(aspirin2_mpu60x0.status != SPITransSuccess); ret = aspirin2_mpu60x0.miso_buf[1]; } }
/*! * This function is called to read a register on PMIC. * * @param reg_num number of the pmic register to be read * @param reg_val return value of register * * @return Returns 0 on success -1 on failure. */ int pmic_read(unsigned int reg_num, unsigned int *reg_val) { unsigned int frame = 0; int ret = 0; if (reg_num > MXC_PMIC_MAX_REG_NUM) return PMIC_ERROR; frame |= reg_num << MXC_PMIC_REG_NUM_SHIFT; ret = spi_rw(pmic_drv_data.spi, (u8 *) & frame, 1); *reg_val = frame & MXC_PMIC_FRAME_MASK; return ret; }
/*! * This function is called to write a value to the register on PMIC. * * @param reg_num number of the pmic register to be written * @param reg_val value to be written * * @return Returns 0 on success -1 on failure. */ int pmic_write(int reg_num, const unsigned int reg_val) { unsigned int frame = 0; int ret = 0; if (reg_num > MXC_PMIC_MAX_REG_NUM) return PMIC_ERROR; frame |= (1 << MXC_PMIC_WRITE_BIT_SHIFT); frame |= reg_num << MXC_PMIC_REG_NUM_SHIFT; frame |= reg_val & MXC_PMIC_FRAME_MASK; ret = spi_rw(pmic_drv_data.spi, (u8 *) & frame, 1); return ret; }
// 1 <= power_of_two <= 6 void mma_get_average( uint8_t power_of_two, int16_t * x, int16_t * y, int16_t * z ) { int16_t accu_x = 0; int16_t accu_y = 0; int16_t accu_z = 0; uint8_t i; for ( i = 0; i < ( 1 << power_of_two ); ++i ) { mma_wait_until_ready(); ACL_CS=0; spi_rw( 0x00 );//setup read accu_x += mma_read10( MMA_XOUT10 ); accu_y += mma_read10( MMA_YOUT10 ); accu_z += mma_read10( MMA_ZOUT10 ); ACL_CS=1; } *x = ( accu_x + ( 1 << ( power_of_two - 1 ) ) ) >> power_of_two; *y = ( accu_y + ( 1 << ( power_of_two - 1 ) ) ) >> power_of_two; *z = ( accu_z + ( 1 << ( power_of_two - 1 ) ) ) >> power_of_two; }
void imu_periodic(void) { if (imu_aspirin2.status == Aspirin2StatusUninit) { mpu_configure(); // imu_aspirin_arch_int_enable(); imu_aspirin2.status = Aspirin2StatusIdle; aspirin2_mpu60x0.length = 22; aspirin2_mpu60x0.mosi_buf[0] = MPU60X0_REG_INT_STATUS + MPU60X0_SPI_READ; for (int i=1;i<aspirin2_mpu60x0.length;i++) { aspirin2_mpu60x0.mosi_buf[i] = 0; } } else { // imu_aspirin2.imu_tx_buf[0] = MPU60X0_REG_WHO_AM_I + MPU60X0_SPI_READ; // imu_aspirin2.imu_tx_buf[1] = 0x00; spi_rw(&aspirin2_mpu60x0); } }
static int spi_rw(struct spi_device *spi, void * buf, size_t len) { int ret; struct spi_transfer t = { .tx_buf = (const void *)buf, .rx_buf = buf, .len = len, .cs_change = 0, .delay_usecs = 0, }; struct spi_message m; spi_message_init(&m); spi_message_add_tail(&t, &m); if ((ret = spi_sync(spi, &m))) return ret; return 0; } #define MXC_PMIC_REG_NUM(reg) (((reg) & 0x3f) << 25) #define MXC_PMIC_WRITE (1 << 31) static int mc13892_spi_reg_read(struct mc13892 *mc13892, enum mc13892_reg reg, u32 *val) { uint32_t buf; buf = MXC_PMIC_REG_NUM(reg); spi_rw(mc13892->spi, &buf, 4); *val = buf; return 0; }
/* * @fn nm_bus_ioctl * @brief send/receive from the bus * @param[IN] u8Cmd * IOCTL command for the operation * @param[IN] pvParameter * Arbitrary parameter depenging on IOCTL * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure * @note For SPI only, it's important to be able to send/receive at the same time */ sint8 nm_bus_ioctl(uint8 u8Cmd, void* pvParameter) { sint8 s8Ret = 0; switch(u8Cmd) { #ifdef CONF_WINC_USE_I2C case NM_BUS_IOCTL_R: { tstrNmI2cDefault *pstrParam = (tstrNmI2cDefault *)pvParameter; s8Ret = nm_i2c_read(pstrParam->pu8Buf, pstrParam->u16Sz); } break; case NM_BUS_IOCTL_W: { tstrNmI2cDefault *pstrParam = (tstrNmI2cDefault *)pvParameter; s8Ret = nm_i2c_write(pstrParam->pu8Buf, pstrParam->u16Sz); } break; case NM_BUS_IOCTL_W_SPECIAL: { tstrNmI2cSpecial *pstrParam = (tstrNmI2cSpecial *)pvParameter; s8Ret = nm_i2c_write_special(pstrParam->pu8Buf1, pstrParam->u16Sz1, pstrParam->pu8Buf2, pstrParam->u16Sz2); } break; #elif defined CONF_WINC_USE_SPI case NM_BUS_IOCTL_RW: { tstrNmSpiRw *pstrParam = (tstrNmSpiRw *)pvParameter; s8Ret = spi_rw(pstrParam->pu8InBuf, pstrParam->pu8OutBuf, pstrParam->u16Sz); } break; #endif default: s8Ret = -1; M2M_ERR("invalide ioclt cmd\n"); break; } return s8Ret; }
static s8_t spi_rw(u8_t *mosi, u8_t *miso, u16_t size) { const struct spi_buf buf_tx = { .buf = mosi, .len = size }; const struct spi_buf_set tx = { .buffers = &buf_tx, .count = 1 }; const struct spi_buf buf_rx = { .buf = miso, .len = miso ? size : 0 }; const struct spi_buf_set rx = { .buffers = &buf_rx, .count = 1 }; if (spi_transceive(winc1500.spi, &winc1500.spi_cfg, &tx, &rx)) { LOG_ERR("spi_transceive fail"); return M2M_ERR_BUS_FAIL; } return M2M_SUCCESS; } #endif s8_t nm_bus_init(void *pvinit) { /* configure GPIOs */ winc1500.gpios = winc1500_configure_gpios(); #ifdef CONF_WINC_USE_I2C /* Not implemented */ #elif defined CONF_WINC_USE_SPI /* setup SPI device */ winc1500.spi = device_get_binding(DT_ATMEL_WINC1500_0_BUS_NAME); if (!winc1500.spi) { LOG_ERR("spi device binding"); return -1; } winc1500.spi_cfg.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB; winc1500.spi_cfg.frequency = DT_ATMEL_WINC1500_0_SPI_MAX_FREQUENCY; winc1500.spi_cfg.slave = DT_ATMEL_WINC1500_0_BASE_ADDRESS; #ifdef CONFIG_WIFI_WINC1500_GPIO_SPI_CS cs_ctrl.gpio_dev = device_get_binding( DT_ATMEL_WINC1500_0_CS_GPIO_CONTROLLER); if (!cs_ctrl.gpio_dev) { LOG_ERR("Unable to get GPIO SPI CS device"); return -ENODEV; } cs_ctrl.gpio_pin = DT_ATMEL_WINC1500_0_CS_GPIO_PIN; cs_ctrl.delay = 0U; winc1500.spi_cfg.cs = &cs_ctrl; LOG_DBG("SPI GPIO CS configured on %s:%u", DT_ATMEL_WINC1500_0_CS_GPIO_CONTROLLER, DT_ATMEL_WINC1500_0_CS_GPIO_PIN); #endif /* CONFIG_WIFI_WINC1500_GPIO_SPI_CS */ nm_bsp_reset(); nm_bsp_sleep(1); nm_bsp_interrupt_ctrl(1); LOG_DBG("NOTICE:DONE"); #endif return 0; } s8_t nm_bus_ioctl(u8_t cmd, void *parameter) { sint8 ret = 0; switch (cmd) { #ifdef CONF_WINC_USE_I2C case NM_BUS_IOCTL_R: { struct nm_i2c_default *param = (struct nm_i2c_default *)parameter; ret = nm_i2c_read(param->buffer, param->size); } break; case NM_BUS_IOCTL_W: { struct nm_i2c_default *param = (struct nm_i2c_default *)parameter; ret = nm_i2c_write(param->buffer, param->size); } break; case NM_BUS_IOCTL_W_SPECIAL: { struct nm_i2c_special *param = (struct nm_i2c_special *)parameter; ret = nm_i2c_write_special(param->buffer1, param->size1, param->buffer2, param->size2); } break; #elif defined CONF_WINC_USE_SPI case NM_BUS_IOCTL_RW: { tstrNmSpiRw *param = (tstrNmSpiRw *)parameter; ret = spi_rw(param->pu8InBuf, param->pu8OutBuf, param->u16Sz); } break; #endif default: ret = -1; M2M_ERR("ERROR:invalid ioclt cmd\n"); break; } return ret; } s8_t nm_bus_deinit(void) { return M2M_SUCCESS; } s8_t nm_bus_reinit(void *config) { return 0; }