static sint8 nm_i2c_write_special(uint8 *wb1, uint16 sz1, uint8 *wb2, uint16 sz2) { static uint8 tmp[NM_BUS_MAX_TRX_SZ]; m2m_memcpy(tmp, wb1, sz1); m2m_memcpy(&tmp[sz1], wb2, sz2); return nm_i2c_write(tmp, sz1+sz2); }
/* * @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; }