/************************************************************************************************** * @fn HalGpioResetSet * * * @brief Set Reset. * * @param * * @return STATUS **************************************************************************************************/ int HalGpioResetSet(uint8 state) { char tmpStr[128]; if(state == 0) { if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Reset set low. [Thread %u]\n", __FUNCTION__, (unsigned int) pthread_self()); time_printf(tmpStr); } if (ERROR == write(gpioResetFd, "0", 1)) { perror(resetGpioCfg.gpio.value); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] can't write in %s, is something already accessing it? abort everything for debug purpose...\n", __FUNCTION__, resetGpioCfg.gpio.value); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_RESET_GPIO_VAL_WRITE_SET_LOW; return NPI_LNX_FAILURE; } } else { if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Reset set high. [Thread %u]\n", __FUNCTION__, (unsigned int) pthread_self()); time_printf(tmpStr); } if(ERROR == write(gpioResetFd, "1", 1)) { perror(resetGpioCfg.gpio.value); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] can't write in %s, is something already accessing it? abort everything for debug purpose...\n", __FUNCTION__, resetGpioCfg.gpio.value); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_RESET_GPIO_VAL_WRITE_SET_HIGH; return NPI_LNX_FAILURE; } } if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Reset called with state = %d\n", __FUNCTION__, state); time_printf(tmpStr); } return NPI_LNX_SUCCESS; }
/************************************************************************************************** * @fn HalI2cInit * * @brief Initialize I2C Service * * @param None * * @return STATUS **************************************************************************************************/ int HalI2cInit(const char *devpath) { char tmpStr[128]; // If the device is open, attempt to close it first. if (i2cDevFd >= 0) { /* The device is open, attempt to close it first */ if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Closing %s...\n", __FUNCTION__, devpath); time_printf(tmpStr); } close(i2cDevFd); } /* open the device */ if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Opening %s...\n", __FUNCTION__, devpath); time_printf(tmpStr); } i2cDevFd = open(devpath, O_RDWR | O_NONBLOCK); if(i2cDevFd<0) { fprintf(stderr, "Error: Could not open file " "%s: %s, already used?\n", devpath, strerror(errno)); npi_ipc_errno = NPI_LNX_ERROR_HAL_I2C_INIT_FAILED_TO_OPEN_DEVICE; return NPI_LNX_FAILURE; } if(ioctl(i2cDevFd, I2C_SLAVE, RNP_I2C_ADDRESS) < 0) { fprintf(stderr, "Error: Could not set address to 0x%02x: %s\n", RNP_I2C_ADDRESS, strerror(errno)); close(i2cDevFd); npi_ipc_errno = NPI_LNX_ERROR_HAL_I2C_INIT_FAILED_TO_SET_ADDRESS; return NPI_LNX_FAILURE; } if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Open I2C Driver: %s for Address 0x%.2x ...\n", __FUNCTION__, devpath, RNP_I2C_ADDRESS); time_printf(tmpStr); } return NPI_LNX_SUCCESS; }
/************************************************************************************************** * @fn NPI_I2C_ResetSlave * * @brief do the HW synchronization between the host and the RNP * * input parameters * * @param none * * output parameters * * None. * * @return STATUS ************************************************************************************************** */ int NPI_I2C_ResetSlave(void) { int ret = NPI_LNX_SUCCESS; char tmpStr[128]; snprintf(tmpStr, sizeof(tmpStr), "[%s] -------------------- START RESET SLAVE -------------------\n", __FUNCTION__); time_printf(tmpStr); ret = HalGpioReset(); snprintf(tmpStr, sizeof(tmpStr), "[%s] Wait 1.2s for RNP to initialize after a Reset... This may change in the future, check for RTI_ResetInd()...\n", __FUNCTION__); time_printf(tmpStr); usleep(1200000); //wait 1.2s for RNP to initialize snprintf(tmpStr, sizeof(tmpStr), "[%s] ---------------------- END RESET SLAVE -------------------\n", __FUNCTION__); time_printf(tmpStr); return ret; }
/************************************************************************************************** * @fn HalGpioMrdySet * * * @brief Set MRDY. * * @param * * @return STATUS **************************************************************************************************/ int HalGpioMrdySet(uint8 state) { char tmpStr[128]; if(state == 0) { // debug_printf("[%u][GPIO] MRDY set to low\n", (unsigned int) pthread_self()); if (ERROR == write(gpioMrdyFd, "0", 1)) { perror(mrdyGpioCfg.gpio.value); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] can't write in %s, is something already accessing it? abort everything for debug purpose...\n", __FUNCTION__, mrdyGpioCfg.gpio.value); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_MRDY_GPIO_VAL_WRITE_SET_LOW; return NPI_LNX_FAILURE; } } else { // debug_printf("[%u][GPIO] MRDY set to High\n", (unsigned int) pthread_self()); if(ERROR == write(gpioMrdyFd, "1", 1)) { perror(mrdyGpioCfg.gpio.value); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] can't write in %s, is something already accessing it? abort everything for debug purpose...\n", __FUNCTION__, mrdyGpioCfg.gpio.value); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_MRDY_GPIO_VAL_WRITE_SET_HIGH; return NPI_LNX_FAILURE; } } return NPI_LNX_SUCCESS; }
/************************************************************************************************** * @fn HalGpioReset * * * @brief Set MRDY. * * @param None * * @return STATUS **************************************************************************************************/ int HalGpioReset(void) { if (__BIG_DEBUG_ACTIVE == TRUE) { time_printf("[%s] Reset High\n", __FUNCTION__); } if(ERROR == write(gpioResetFd, "1", 1)) { perror(resetGpioCfg.gpio.value); if (__BIG_DEBUG_ACTIVE == TRUE) { time_printf("[%s] can't write in %s , is something already accessing it? abort everything for debug purpose...\n", __FUNCTION__, resetGpioCfg.gpio.value); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_RESET_GPIO_VAL_WRITE_SET_HIGH; return NPI_LNX_FAILURE; } if (__BIG_DEBUG_ACTIVE == TRUE) { time_printf("[%s] Reset Low, [Thread: %u]\n", __FUNCTION__, (unsigned int) pthread_self()); } if(ERROR == write(gpioResetFd, "0", 1)) { perror(resetGpioCfg.gpio.value); if (__BIG_DEBUG_ACTIVE == TRUE) { time_printf("[%s] can't write in %s , is something already accessing it? abort everything for debug purpose...\n", __FUNCTION__, resetGpioCfg.gpio.value); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_RESET_GPIO_VAL_WRITE_SET_LOW; return NPI_LNX_FAILURE; } //Add A Delay here: // Reset Should last at least 1us from datasheet, set it to 500us. usleep(500); if (__BIG_DEBUG_ACTIVE == TRUE) { time_printf("[%s] Reset High, [Thread: %u]\n", __FUNCTION__, (unsigned int) pthread_self()); } if(ERROR == write(gpioResetFd, "1", 1)) { perror(resetGpioCfg.gpio.value); if (__BIG_DEBUG_ACTIVE == TRUE) { time_printf("[%s] can't write in %s , is something already accessing it? abort everything for debug purpose...\n", __FUNCTION__, resetGpioCfg.gpio.value); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_RESET_GPIO_VAL_WRITE_SET_HIGH; return NPI_LNX_FAILURE; } return NPI_LNX_SUCCESS; }
/************************************************************************************************** * @fn HalI2cClose * * @brief Close I2C Service * * @param None * * @return STATUS **************************************************************************************************/ int HalI2cClose(void) { char tmpStr[128]; if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Closing I2C file descriptor\n", __FUNCTION__); time_printf(tmpStr); } if (-1 ==close(i2cDevFd)) { fprintf(stderr, "Error: Could not Close I2C device file, reason: %s,\n", strerror(errno)); npi_ipc_errno = NPI_LNX_ERROR_HAL_I2C_CLOSE_GENERIC; return NPI_LNX_FAILURE; } else return NPI_LNX_SUCCESS; }
/************************************************************************************************** * @fn HalGpioSrdyCheck * * * @brief Check SRDY Clear. * * @param state - Active or Inactive * * @return STATUS if error, otherwise boolean TRUE/FALSE if state is matching **************************************************************************************************/ int HalGpioSrdyCheck(uint8 state) { char srdy=2; lseek(gpioSrdyFd,0,SEEK_SET); if(ERROR == read(gpioSrdyFd,&srdy, 1)) { perror(srdyGpioCfg.gpio.value); if (__BIG_DEBUG_ACTIVE == TRUE) { time_printf("[%s] can't write in %s , is something already accessing it? abort everything for debug purpose...\n", __FUNCTION__, srdyGpioCfg.gpio.value); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_SRDY_GPIO_VAL_READ_FAILED; return NPI_LNX_FAILURE; } // LOG_DEBUG("[%u][GPIO]===>check SRDY: %c [%d] (%c) \n", (unsigned int) pthread_self(), srdy, srdy, atoi(&srdy)); return (state == ((srdy == '1') ? 1 : 0)); }
/************************************************************************************************** * @fn HalGpioMrdyCheck * * * @brief Check MRDY Clear. * * @param state - Active or Inactive * * @return None **************************************************************************************************/ int HalGpioMrdyCheck(uint8 state) { char mrdy=2, tmpStr[128]; lseek(gpioMrdyFd,0,SEEK_SET); if(ERROR == read(gpioMrdyFd,&mrdy, 1)) { perror(mrdyGpioCfg.gpio.value); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] can't write in %s, is something already accessing it? abort everything for debug purpose...\n", __FUNCTION__, mrdyGpioCfg.gpio.value); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_MRDY_GPIO_VAL_READ; return NPI_LNX_FAILURE; } // debug_printf("[%u][GPIO]===>check MRDY: %c (%c) \n", (unsigned int) pthread_self(), mrdy, mrdy); return (state == ((mrdy == '1') ? 1 : 0)); }
void print_header(int argc, char *const *argv) { char hostname[3000]; gethostname(hostname, 1024); time_t now; time(&now); struct tm *ttm = localtime(&now); time_printf("benchmark-lifting.run (git-%s)\n", GIT_SHA1); time_printf("%s %04d-%02d-%02d %02d:%02d\n", hostname, ttm->tm_year + 1900, ttm->tm_mon + 1, ttm->tm_mday, ttm->tm_hour, ttm->tm_min); time_printf("Compile-time parameters:\n"); time_printf(" EPSILON: %e\n", EPSILON); char cmdline[5000] = {0}; for (int i = 0; i < argc; i++) sprintf(cmdline + strlen(cmdline), "%s ", argv[i]); time_printf("Command line arguments:\n"); time_printf(" %s\n", cmdline); }
/************************************************************************************************** * @fn HalGpioResetInit * * * @brief Initialise RESET GPIO. * * @param gpioCfg - Reset pin configuration parameters * * @return STATUS **************************************************************************************************/ int HalGpioResetInit(halGpioCfg_t *gpioCfg) { char tmpStr[512]; memcpy(resetGpioCfg.gpio.value, gpioCfg->gpio.value, strlen(gpioCfg->gpio.value)); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] resetGpioCfg.gpio.value = '%s'\n", __FUNCTION__, resetGpioCfg.gpio.value); time_printf(tmpStr); } memcpy(resetGpioCfg.gpio.direction, gpioCfg->gpio.direction, strlen(gpioCfg->gpio.direction)); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] resetGpioCfg.gpio.direction = '%s'\n", __FUNCTION__, resetGpioCfg.gpio.direction); time_printf(tmpStr); } resetGpioCfg.gpio.active_high_low = gpioCfg->gpio.active_high_low; if ( ( gpioCfg->levelshifter.value) && ( gpioCfg->levelshifter.active_high_low) && ( gpioCfg->levelshifter.direction)) { memcpy(resetGpioCfg.levelshifter.value, gpioCfg->levelshifter.value, strlen(gpioCfg->levelshifter.value)); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] resetGpioCfg.levelshifter.value = '%s'\n", __FUNCTION__, resetGpioCfg.levelshifter.value); time_printf(tmpStr); } memcpy(resetGpioCfg.levelshifter.direction, gpioCfg->levelshifter.direction, strlen(gpioCfg->levelshifter.direction)); resetGpioCfg.levelshifter.active_high_low = gpioCfg->levelshifter.active_high_low; if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] resetGpioCfg.levelshifter.direction = '%s'\n", __FUNCTION__, resetGpioCfg.levelshifter.direction); time_printf(tmpStr); } //open the GPIO DIR file for the level shifter direction signal gpioResetFd = open(resetGpioCfg.levelshifter.direction, O_RDWR); if(gpioResetFd == 0) { perror(resetGpioCfg.levelshifter.direction); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] %s open failed\n", __FUNCTION__, resetGpioCfg.levelshifter.direction); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_RESET_LVLSHFT_DIR_OPEN; return NPI_LNX_FAILURE; } //Set the direction of the GPIO to output if (ERROR == write(gpioResetFd, "out", 3)) { perror(resetGpioCfg.levelshifter.direction); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] can't write in %s \n", __FUNCTION__, resetGpioCfg.levelshifter.direction); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_RESET_LVLSHFT_DIR_WRITE; return NPI_LNX_FAILURE; } //close the DIR file close(gpioResetFd); //open the GPIO VALUE file for the level shifter direction signal gpioResetFd = open(resetGpioCfg.levelshifter.value, O_RDWR); if(gpioResetFd == 0) { perror(resetGpioCfg.levelshifter.value); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] %s open failed\n", __FUNCTION__, resetGpioCfg.levelshifter.value); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_RESET_LVLSHFT_VAL_OPEN; return NPI_LNX_FAILURE; } //Set the value of the GPIO to 0 (level shifter direction from Host to CC2531) if(ERROR == write(gpioResetFd, "1", 1)) { perror(resetGpioCfg.levelshifter.value); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] can't write in %s\n", __FUNCTION__, resetGpioCfg.levelshifter.value); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_RESET_LVLSHFT_VAL_WRITE; return NPI_LNX_FAILURE; } //close the DIR file close(gpioResetFd); } else { if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Wrong Configuration File, one of the following Key value are missing for MRDY.Level Shifter definition: '\n", __FUNCTION__); int strIndex = strlen(tmpStr); snprintf(tmpStr + strIndex, sizeof(tmpStr) - strIndex, "value: \t\t%s\n", resetGpioCfg.gpio.value); strIndex = strlen(tmpStr); snprintf(tmpStr + strIndex, sizeof(tmpStr) - strIndex, "direction: \t%s\n", resetGpioCfg.gpio.direction); strIndex = strlen(tmpStr); snprintf(tmpStr + strIndex, sizeof(tmpStr) - strIndex, "active_high_low: %d\n", resetGpioCfg.gpio.active_high_low); strIndex = strlen(tmpStr); snprintf(tmpStr + strIndex, sizeof(tmpStr) - strIndex, "Level Shifter is optional, please check if you need it or not before continuing...\n"); } } //open the RESET GPIO DIR file gpioResetFd = open(resetGpioCfg.gpio.direction, O_RDWR); if(gpioResetFd == 0) { perror(resetGpioCfg.gpio.direction); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] %s open failed\n", __FUNCTION__, resetGpioCfg.gpio.direction); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_RESET_GPIO_DIR_OPEN; return NPI_LNX_FAILURE; } //Set RESET GPIO as output if(ERROR == write(gpioResetFd, "out", 3)) { perror(resetGpioCfg.gpio.direction); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] can't write in %s\n", __FUNCTION__, resetGpioCfg.gpio.direction); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_RESET_GPIO_DIR_WRITE; return NPI_LNX_FAILURE; } //close RESET DIR file close(gpioResetFd); //open the RESET GPIO VALUE file so it can be written to using the file handle later gpioResetFd = open(resetGpioCfg.gpio.value, O_RDWR); if(gpioResetFd == 0) { perror(resetGpioCfg.gpio.value); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] %s open failed\n", __FUNCTION__, resetGpioCfg.gpio.value); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_RESET_GPIO_VAL_OPEN; return NPI_LNX_FAILURE; } //Set RESET GPIO to 1 as default if(ERROR == write(gpioResetFd, "1", 3)) { perror(resetGpioCfg.gpio.value); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] can't write in %s\n", __FUNCTION__, resetGpioCfg.gpio.value); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_RESET_GPIO_VAL_WRITE; return NPI_LNX_FAILURE; } return NPI_LNX_SUCCESS; }
/************************************************************************************************** * @fn HalGpioSrdyInit * * * @brief Initialise SRDY GPIO. * * @param gpioCfg - SRDY pin configuration parameters * * @return STATUS **************************************************************************************************/ int HalGpioSrdyInit(halGpioCfg_t *gpioCfg) { char tmpStr[512]; memcpy(srdyGpioCfg.gpio.value, gpioCfg->gpio.value, strlen(gpioCfg->gpio.value)); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] srdyGpioCfg.gpio.value = '%s'\n", __FUNCTION__, srdyGpioCfg.gpio.value); time_printf(tmpStr); } memcpy(srdyGpioCfg.gpio.direction, gpioCfg->gpio.direction, strlen(gpioCfg->gpio.direction)); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] srdyGpioCfg.gpio.direction = '%s'\n", __FUNCTION__, srdyGpioCfg.gpio.direction); time_printf(tmpStr); } srdyGpioCfg.gpio.active_high_low = gpioCfg->gpio.active_high_low; memcpy(srdyGpioCfg.gpio.edge, gpioCfg->gpio.edge, strlen(gpioCfg->gpio.edge)); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] srdyGpioCfg.gpio.edge = '%s'\n", __FUNCTION__, srdyGpioCfg.gpio.edge); time_printf(tmpStr); } if ( ( gpioCfg->levelshifter.value) && ( gpioCfg->levelshifter.active_high_low) && ( gpioCfg->levelshifter.direction)) { memcpy(srdyGpioCfg.levelshifter.value, gpioCfg->levelshifter.value, strlen(gpioCfg->levelshifter.value)); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] srdyGpioCfg.levelshifter.value = '%s'\n", __FUNCTION__, srdyGpioCfg.levelshifter.value); time_printf(tmpStr); } memcpy(srdyGpioCfg.levelshifter.direction, gpioCfg->levelshifter.direction, strlen(gpioCfg->levelshifter.direction)); srdyGpioCfg.levelshifter.active_high_low = gpioCfg->levelshifter.active_high_low; if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] srdyGpioCfg.levelshifter.direction = '%s'\n", __FUNCTION__, srdyGpioCfg.levelshifter.direction); time_printf(tmpStr); } //open the GPIO DIR file for the level shifter direction signal gpioSrdyFd = open(srdyGpioCfg.levelshifter.direction, O_RDWR); if(gpioSrdyFd == 0) { perror(srdyGpioCfg.levelshifter.direction); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] %s open failed\n", __FUNCTION__, srdyGpioCfg.levelshifter.direction); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_SRDY_LVLSHFT_DIR_OPEN; return NPI_LNX_FAILURE; } //Set the direction of the GPIO to output if (ERROR == write(gpioSrdyFd, "out", 3)) { perror(srdyGpioCfg.levelshifter.direction); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] can't write in %s \n", __FUNCTION__, srdyGpioCfg.levelshifter.direction); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_SRDY_LVLSHFT_DIR_WRITE; return NPI_LNX_FAILURE; } //close the DIR file close(gpioSrdyFd); //open the GPIO VALUE file for the level shifter direction signal gpioSrdyFd = open(srdyGpioCfg.levelshifter.value, O_RDWR); if(gpioSrdyFd == 0) { perror(srdyGpioCfg.levelshifter.value); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] %s open failed\n", __FUNCTION__, srdyGpioCfg.levelshifter.value); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_SRDY_LVLSHFT_VAL_OPEN; return NPI_LNX_FAILURE; } //Set the value of the GPIO to 0 (level shifter direction from CC2531 to Host) if (ERROR == write(gpioSrdyFd, "0", 1)) { perror(srdyGpioCfg.levelshifter.value); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] can't write in %s\n", __FUNCTION__, srdyGpioCfg.levelshifter.value); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_SRDY_LVLSHFT_VAL_WRITE; return NPI_LNX_FAILURE; } //close the DIR file close(gpioSrdyFd); } else { if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Wrong Configuration File, one of the following Key value are missing for SRDY.Level Shifter definition: '\n", __FUNCTION__); int strIndex = strlen(tmpStr); snprintf(tmpStr + strIndex, sizeof(tmpStr) - strIndex, "value: \t\t%s\n", srdyGpioCfg.gpio.value); strIndex = strlen(tmpStr); snprintf(tmpStr + strIndex, sizeof(tmpStr) - strIndex, "direction: \t%s\n", srdyGpioCfg.gpio.direction); strIndex = strlen(tmpStr); snprintf(tmpStr + strIndex, sizeof(tmpStr) - strIndex, "active_high_low: %d\n", srdyGpioCfg.gpio.active_high_low); strIndex = strlen(tmpStr); snprintf(tmpStr + strIndex, sizeof(tmpStr) - strIndex, "Level Shifter is optional, please check if you need it or not before continuing...\n"); } } //TODO: Lock the shift register GPIO. //open the SRDY GPIO DIR file gpioSrdyFd = open(srdyGpioCfg.gpio.direction, O_RDWR); if(gpioSrdyFd == 0) { perror(srdyGpioCfg.gpio.direction); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] %s open failed\n", __FUNCTION__, srdyGpioCfg.gpio.direction); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_SRDY_GPIO_DIR_OPEN; return NPI_LNX_FAILURE; } //Set SRDY GPIO as input if(ERROR == write(gpioSrdyFd, "in", 2)) { perror(srdyGpioCfg.levelshifter.direction); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] can't write in %s\n", __FUNCTION__, srdyGpioCfg.gpio.direction); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_SRDY_GPIO_DIR_WRITE; return NPI_LNX_FAILURE; } //close SRDY DIR file close(gpioSrdyFd); //open the SRDY GPIO Edge file gpioSrdyFd = open(srdyGpioCfg.gpio.edge, O_RDWR); if(gpioSrdyFd == 0) { perror(srdyGpioCfg.gpio.edge); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] %s open failed\n", __FUNCTION__, srdyGpioCfg.gpio.edge); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_SRDY_GPIO_EDGE_OPEN; return NPI_LNX_FAILURE; } //Set SRDY GPIO edge detection for both rising and falling if(ERROR == write(gpioSrdyFd, "both", 4)) { perror(srdyGpioCfg.levelshifter.edge); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] can't write in %s\n", __FUNCTION__, srdyGpioCfg.gpio.edge); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_SRDY_GPIO_EDGE_WRITE; return NPI_LNX_FAILURE; } //close SRDY edge file close(gpioSrdyFd); //open the SRDY GPIO VALUE file so it can be written to using the file handle later gpioSrdyFd = open(srdyGpioCfg.gpio.value, O_RDWR| O_NONBLOCK); if(gpioSrdyFd == 0) { perror(srdyGpioCfg.gpio.value); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] %s open failed\n", __FUNCTION__, srdyGpioCfg.gpio.value); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_SRDY_GPIO_VAL_OPEN; return NPI_LNX_FAILURE; } return(gpioSrdyFd); }
/************************************************************************************************** * @fn HalGpioWaitSrdySet * * @brief Check that SRDY is High, if not, wait until it gets high, or times out. * 0xFFFF means never time out. * * input parameters * * None * * output parameters * * None. * * @return STATUS ************************************************************************************************** */ int HalGpioWaitSrdySet() { char srdy= '0', first = 0, tmpStr[128]; int ret = NPI_LNX_SUCCESS, accTimeout = 0; // debug_printf("[%u][GPIO]Wait SRDY High, \n", (unsigned int) pthread_self()); struct pollfd ufds[1]; int pollRet; ufds[0].fd = gpioSrdyFd; ufds[0].events = POLLPRI; if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Wait for SRDY to go High. [Thread: %u]\n", __FUNCTION__, (unsigned int) pthread_self()); time_printf(tmpStr); } lseek(gpioSrdyFd,0,SEEK_SET); read(gpioSrdyFd,&srdy, 1); while( (srdy == '0') ) { // There is still a chance we can miss an interrupt. So we need to split the // big HAL_WAIT_SRDY_HIGH_TIMEOUT timeout into smaller timeouts if (first == 0) { pollRet = poll((struct pollfd*)&ufds, 1, HAL_WAIT_SRDY_HIGH_FIRST_TIMEOUT); } else { pollRet = poll((struct pollfd*)&ufds, 1, HAL_WAIT_SRDY_HIGH_INTERMEDIATE_TIMEOUT); } if (pollRet == -1) { // Error occured in poll() perror("poll"); } else if (pollRet == 0) { if (first == 0) { accTimeout += HAL_WAIT_SRDY_HIGH_FIRST_TIMEOUT; first++; } else { accTimeout += HAL_WAIT_SRDY_HIGH_INTERMEDIATE_TIMEOUT; } // Timeout lseek(gpioSrdyFd,0,SEEK_SET); read(gpioSrdyFd,&srdy, 1); if(srdy == '0') { if (accTimeout >= HAL_WAIT_SRDY_HIGH_TIMEOUT) { if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Waiting for SRDY to go high timed out. [Thread: %u]\n", __FUNCTION__, (unsigned int) pthread_self()); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_WAIT_SRDY_SET_POLL_TIMEDOUT; ret = NPI_LNX_FAILURE; break; } else { // This timeout is expected, and ok. Nothing to report, only for debug. if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Waiting for SRDY to go high intermediate timed out, %d. [Thread: %u]\n", __FUNCTION__, accTimeout, (unsigned int) pthread_self()); time_printf(tmpStr); } } } else { // Missed interrupt waiting for SRDY to go high // This timeout is expected, and ok. Nothing to report, only for debug. if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Waiting for SRDY to go high intermediate timed out, %d, but SRDY is now high. [Thread: %u]\n", __FUNCTION__, accTimeout, (unsigned int) pthread_self()); time_printf(tmpStr); } break; } } else { if (ufds[0].revents & POLLPRI) { lseek(gpioSrdyFd,0,SEEK_SET); if(ERROR == read(gpioSrdyFd,&srdy, 1)) { perror(srdyGpioCfg.gpio.value); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] can't write in %s , is something already accessing it? abort everything for debug purpose...\n", __FUNCTION__, srdyGpioCfg.gpio.value); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_WAIT_SRDY_SET_READ_FAILED; return NPI_LNX_FAILURE; } } if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] ufds[0].revents = 0x%X\n", __FUNCTION__, ufds[0].revents); time_printf(tmpStr); } } } if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] SRDY: %c (%d). [Thread: %u]\n", __FUNCTION__, srdy, (int)srdy, (unsigned int) pthread_self()); time_printf(tmpStr); } return ret; }
int GREEDY_BSEARCH_compute_bounds(int nrows, int nrays, const double *f, const double *rays, double *bounds) { int rval = 0; struct LP lp; double e_upper = 2 * GREEDY_BIG_E; double e_lower = 0.0; int cplex_count = 0; double cplex_time = 0; int iteration_count = 0; double *x = 0; x = (double *) malloc((nrays + nrows) * sizeof(double)); abort_if(!x, "could not allocate x"); for (int i = 0; i < nrays; i++) bounds[i] = GREEDY_BIG_E; for (int it = 0;; it++) { abort_if(it > 2*nrays, "stuck in an infinite loop"); log_verbose("Starting iteration %d...\n", it); iteration_count++; int solution_found = 0; int inner_count = 0; while (fabs(e_upper - e_lower) > GREEDY_MAX_GAP) { inner_count++; double e = (e_upper + e_lower) / 2; log_verbose(" e=%.12lf\n", e); rval = LP_open(&lp); abort_if(rval, "LP_open failed"); rval = create_greedy_lp(nrows, nrays, f, rays, bounds, e, &lp); abort_if(rval, "create_greedy_lp failed"); if_verbose_level { rval = LP_write(&lp, "greedy.lp"); abort_if(rval, "LP_write failed"); } int infeasible; cplex_count++; double initial_time = get_user_time(); log_verbose(" Optimizing...\n"); rval = LP_optimize(&lp, &infeasible); if (rval) { // Workaround for CPLEX bug. If CPLEX tell us that this problem // is unbounded, we disable presolve and try again. LP_free(&lp); LP_open(&lp); rval = create_greedy_lp(nrows, nrays, f, rays, bounds, e, &lp); abort_if(rval, "create_greedy_lp failed"); LP_disable_presolve(&lp); rval = LP_optimize(&lp, &infeasible); abort_if(rval, "LP_optimize failed"); } cplex_time += get_user_time() - initial_time; if (infeasible) { e_lower = e; log_verbose(" infeasible\n"); if (e > GREEDY_BIG_E-1) { LP_free(&lp); goto OUT; } } else { log_verbose(" feasible\n"); e_upper = e; solution_found = 1; rval = LP_get_x(&lp, x); abort_if(rval, "LP_get_x failed"); } LP_free(&lp); } if (solution_found) { for (int j = 0; j < nrays; j++) { if (!DOUBLE_geq(x[nrows + j], 0.001)) continue; bounds[j] = fmin(bounds[j] * 0.99, e_lower * 0.99); } } log_verbose(" %d iterations %12.8lf gap\n", inner_count, e_upper - e_lower); e_lower = e_upper; e_upper = 2 * GREEDY_BIG_E; } OUT: log_debug(" %6d IPs (%.2lfms per call, %.2lfs total)\n", cplex_count, cplex_time * 1000.0 / cplex_count, cplex_time); for(int i = 0; i < nrays; i++) abort_if(DOUBLE_iszero(bounds[i]), "bounds should be positive"); if_verbose_level { time_printf("Bounds:\n"); for (int k = 0; k < nrays; k++) time_printf(" %12.8lf %12.8lf\n", k, bounds[k], 1 / bounds[k]); } CLEANUP: if (x) free(x); return rval; }
/************************************************************************************************** * @fn npi_event_entry * * @brief Poll Thread entry function * * input parameters * * @param ptr * * output parameters * * None. * * @return None. ************************************************************************************************** */ static void *npi_event_entry(void *ptr) { #define I2C_ISR_POLL_TIMEOUT_MS_MIN 3 #define I2C_ISR_POLL_TIMEOUT_MS_MAX 100 int result = -1; int missedInterrupt = 0; int consecutiveTimeout = 0; int whileIt = 0; int ret = NPI_LNX_SUCCESS; int timeout = I2C_ISR_POLL_TIMEOUT_MS_MAX; /* Timeout in msec. Drop down to I2C_ISR_POLL_TIMEOUT_MS_MIN if two consecutive interrupts are missed */ struct pollfd pollfds[1]; int val; char tmpStr[1024]; snprintf(tmpStr, sizeof(tmpStr), "[%s] Interrupt Event Thread Started \n", __FUNCTION__); time_printf(tmpStr); ((void)ptr); /* thread loop */ while (!npi_poll_terminate) { whileIt++; memset((void*) pollfds, 0, sizeof(pollfds)); pollfds[0].fd = GpioSrdyFd; /* Wait for input */ pollfds[0].events = POLLPRI; /* Wait for input */ result = poll(pollfds, 1, timeout); // Make sure we're not in Asynch data or Synch data, so check if npiSrdyLock is available if (pthread_mutex_trylock(&npiSrdyLock) != 0) { if ( __BIG_DEBUG_ACTIVE == TRUE ) { // We are in Asynch or Synch, so return to poll if (HAL_RNP_SRDY_SET() == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] SRDY found to be de-asserted while we are transmitting\n", __FUNCTION__); time_printf(tmpStr); } else { snprintf(tmpStr, sizeof(tmpStr), "[%s] SRDY found to be asserted while we are transmitting\n", __FUNCTION__); time_printf(tmpStr); } } continue; } else { if ( __BIG_DEBUG_ACTIVE == TRUE && (consecutiveTimeout % 5000 == 0) ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Event thread has SRDY mutex lock, result = %d\n", __FUNCTION__, result); time_printf(tmpStr); } // We got lock, move on switch (result) { case 0: { //Should not happen by default no Timeout. int bigDebugWas = __BIG_DEBUG_ACTIVE; if (bigDebugWas == TRUE) { __BIG_DEBUG_ACTIVE = FALSE; } if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] poll() timeout (timeout set to %d), poll() returned %d\n", __FUNCTION__, timeout, result); time_printf(tmpStr); } result = 2; //Force wrong result to avoid deadlock caused by timeout //#ifdef __BIG_DEBUG__ if ( NPI_LNX_FAILURE == (val = HalGpioSrdyCheck(1))) { ret = val; npi_poll_terminate = 1; error_printf("%s:%d: ERROR! Terminating poll because HalGpioSrdyCheck() returned error %d.\n", __FUNCTION__, __LINE__, ret); } else { // Accept this case as a missed interrupt. We may stall if not attempting to handle asserted SRDY if (!val) { if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Missed interrupt: %d (it #%d)\n", __FUNCTION__, missedInterrupt, whileIt); time_printf(tmpStr); } missedInterrupt++; consecutiveTimeout = 0; } else { // Timed out. If we're in rapid poll mode, i.e. timeout == I2C_ISR_POLL_TIMEOUT_MS_MIN // then we should only allow 100 consecutive such timeouts before resuming normal // timeout consecutiveTimeout++; if ( (timeout < I2C_ISR_POLL_TIMEOUT_MS_MAX) && (consecutiveTimeout > 100) ) { // Timed out 100 times, for 300ms, without a single // SRDY assertion. Set back to 100ms timeout. consecutiveTimeout = 0; // Set timeout back to 100ms timeout = I2C_ISR_POLL_TIMEOUT_MS_MAX; } missedInterrupt = 0; } result = global_srdy = val; // Update global SRDY tracker here as well, as no errors has occurred. } //#endif if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] SRDY: %d\n", __FUNCTION__, global_srdy); time_printf(tmpStr); } __BIG_DEBUG_ACTIVE = bigDebugWas; break; } case -1: { if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] poll() error (%s)\n", __FUNCTION__, strerror(errno)); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_I2C_EVENT_THREAD_FAILED_POLL; ret = NPI_LNX_FAILURE; consecutiveTimeout = 0; // Exit clean so main knows... npi_poll_terminate = 1; error_printf("%s:%d: ERROR! Terminating poll because poll() error (%s).\n", __FUNCTION__, __LINE__, strerror(errno)); break; } default: { consecutiveTimeout = 0; // char * buf[64]; // read(pollfds[0].fd, buf, 64); if (missedInterrupt) { if ( (pollfds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0 ) { if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Poll returned error (it #%d), revent[0] = %d", __FUNCTION__, whileIt, pollfds[0].revents); time_printf(tmpStr); } } else { if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Clearing missed INT (it #%d), results = %d, revent[0] = %d", __FUNCTION__, whileIt, result, pollfds[0].revents); time_printf(tmpStr); } missedInterrupt = 0; // Set timeout back to 100ms if (timeout != I2C_ISR_POLL_TIMEOUT_MS_MAX) { timeout = I2C_ISR_POLL_TIMEOUT_MS_MAX; } } } result = global_srdy = HalGpioSrdyCheck(1); if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Set global SRDY: %d\n", __FUNCTION__, global_srdy); time_printf(tmpStr); } break; } //default: } //switch (result) } // else of if (pthread_mutex_trylock(npiSrdyLock) != 0) fflush(stdout); if (FALSE == result) //Means SRDY switch to low state { if (clock_gettime(CLOCK_MONOTONIC, &curTimeI2CisrPoll) == 0) // Adjust poll timeout based on time between packets, limited downwards // to I2C_ISR_POLL_TIMEOUT_MS_MIN and upwards to I2C_ISR_POLL_TIMEOUT_MS_MAX { // Calculate delta long int diffPrev; if (curTimeI2CisrPoll.tv_nsec >= prevTimeI2CisrPoll.tv_nsec) { diffPrev = (curTimeI2CisrPoll.tv_nsec - prevTimeI2CisrPoll.tv_nsec) / 1000; } else { diffPrev = ((curTimeI2CisrPoll.tv_nsec + 1000000000) - prevTimeI2CisrPoll.tv_nsec) / 1000; } prevTimeI2CisrPoll = curTimeI2CisrPoll; if (diffPrev < (I2C_ISR_POLL_TIMEOUT_MS_MIN * 1000) ) { timeout = I2C_ISR_POLL_TIMEOUT_MS_MIN; } else if (diffPrev > (I2C_ISR_POLL_TIMEOUT_MS_MAX * 1000) ) { if (timeout != I2C_ISR_POLL_TIMEOUT_MS_MAX) { timeout = I2C_ISR_POLL_TIMEOUT_MS_MAX; } } else { timeout = diffPrev / 1000; } } else if (timeout != I2C_ISR_POLL_TIMEOUT_MS_MAX) { // Not good, can't trust time. Set timeout to its max timeout = I2C_ISR_POLL_TIMEOUT_MS_MAX; } if ( (NPI_LNX_FAILURE == (ret = HalGpioMrdyCheck(1)))) { if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Failed to check MRDY\n", __FUNCTION__); time_printf(tmpStr); } // Exit clean so main knows... npi_poll_terminate = 1; error_printf("%s:%d: ERROR! Terminating poll because HalGpioMrdyCheck() returned error %d.\n", __FUNCTION__, __LINE__, ret); } if (ret != NPI_LNX_FAILURE) { if (missedInterrupt > 0) { // Two consecutive interrupts; turn down timeout to I2C_ISR_POLL_TIMEOUT_MS_MIN if (timeout > I2C_ISR_POLL_TIMEOUT_MS_MIN) { timeout = I2C_ISR_POLL_TIMEOUT_MS_MIN; } if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Missed interrupt, but SRDY is asserted! %d (it #%d)\n", __FUNCTION__, missedInterrupt, whileIt); time_printf(tmpStr); } } if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Event thread is releasing SRDY mutex lock, line %d\n", __FUNCTION__, __LINE__); time_printf(tmpStr); } // Unlock before signaling poll thread pthread_mutex_unlock(&npiSrdyLock); if ( __BIG_DEBUG_ACTIVE == TRUE ) { //MRDY High, This is a request from the RNP snprintf(tmpStr, sizeof(tmpStr), "[%s] MRDY High??: %d, send H2L to POLL (srdy = %d)\n", __FUNCTION__, ret, global_srdy); time_printf(tmpStr); } // Before we can signal poll thread we need to make sure SynchData has completed pthread_mutex_lock(&npiPollLock); // Wait for it to call cond_wait, which releases mutex if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Signaling poll thread to perform a poll ...\n", __FUNCTION__); time_printf(tmpStr); } pthread_cond_signal(&npi_srdy_H2L_poll); // Signal it (let it get cond) pthread_mutex_unlock(&npiPollLock); // Release mutex so it can re-acquire it. } else { if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Event thread is releasing SRDY mutex lock, line %d\n", __FUNCTION__, __LINE__); time_printf(tmpStr); } pthread_mutex_unlock(&npiSrdyLock); } } else { //Unknown Event //Do nothing for now ... if ( __BIG_DEBUG_ACTIVE == TRUE && (consecutiveTimeout % 5000 == 0) ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Event thread is releasing SRDY mutex lock, result = %d, line %d\n", __FUNCTION__, result, __LINE__); time_printf(tmpStr); } pthread_mutex_unlock(&npiSrdyLock); } } pthread_cond_signal(&npi_srdy_H2L_poll); char const *errorMsg; if (ret == NPI_LNX_FAILURE) errorMsg = "I2C Event thread exited with error. Please check global error message\n"; else errorMsg = "I2C Event thread exited without error\n"; NPI_LNX_IPC_NotifyError(NPI_LNX_ERROR_MODULE_MASK(NPI_LNX_ERROR_I2C_EVENT_THREAD_FAILED_LOCK), errorMsg); return ptr; }
void print_header(int argc, char *const *argv) { char hostname[3000]; gethostname(hostname, 1024); time_t now; time(&now); struct tm *ttm = localtime(&now); time_printf("multirow (git-%s)\n", GIT_SHA1); time_printf("%s %04d-%02d-%02d %02d:%02d\n", hostname, ttm->tm_year + 1900, ttm->tm_mon + 1, ttm->tm_mday, ttm->tm_hour, ttm->tm_min); time_printf("Compile-time parameters:\n"); time_printf(" EPSILON: %e\n", EPSILON); time_printf(" GREEDY_BIG_E: %e\n", GREEDY_BIG_E); time_printf(" GREEDY_MAX_GAP: %e\n", GREEDY_MAX_GAP); time_printf(" MAX_CUTS: %d\n", MAX_CUTS); time_printf(" MAXIMUM_SCORE: %e\n", MAXIMUM_SCORE); time_printf(" MAX_TOTAL_TIME: %d\n", MAX_TOTAL_TIME); time_printf(" MINIMUM_SCORE: %e\n", MINIMUM_SCORE); char cmdline[5000] = {0}; for (int i = 0; i < argc; i++) sprintf(cmdline + strlen(cmdline), "%s ", argv[i]); time_printf("Command line arguments:\n"); time_printf(" %s\n", cmdline); }
/************************************************************************************************** * @fn npi_poll_entry * * @brief Poll Thread entry function * * input parameters * * @param ptr * * output parameters * * None. * * @return None. ************************************************************************************************** */ static void *npi_poll_entry(void *ptr) { int ret = NPI_LNX_SUCCESS; uint8 readbuf[128]; char tmpStr[1024]; #ifndef SRDY_INTERRUPT uint8 pollStatus = FALSE; #endif //SRDY_INTERRUPT ((void)ptr); snprintf(tmpStr, sizeof(tmpStr), "[%s] Locking Mutex for Poll Thread \n", __FUNCTION__); time_printf(tmpStr); /* lock mutex in order not to lose signal */ pthread_mutex_lock(&npi_poll_mutex); snprintf(tmpStr, sizeof(tmpStr), "[%s] Poll Thread Started\n", __FUNCTION__); time_printf(tmpStr); //This lock wait for Initialization to finish (reset) pthread_mutex_lock(&npiPollLock); snprintf(tmpStr, sizeof(tmpStr), "[%s] Poll Thread Continues After Synchronization\n", __FUNCTION__); time_printf(tmpStr); #ifdef SRDY_INTERRUPT if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Lock Poll mutex (SRDY=%d) \n", __FUNCTION__, global_srdy); time_printf(tmpStr); } pthread_cond_wait(&npi_srdy_H2L_poll, &npiPollLock); if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Locked Poll mutex (SRDY=%d) \n", __FUNCTION__, global_srdy); time_printf(tmpStr); } #else pthread_mutex_unlock(&npiPollLock); #endif /* thread loop */ while(!npi_poll_terminate) { #ifndef SRDY_INTERRUPT pthread_mutex_lock(&npiPollLock); #endif if (PollLockVar) { ret = PollLockVarError(__LINE__, PollLockVar); } else { PollLockVar = 1; if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] PollLockVar set to %d\n", __FUNCTION__, PollLockVar); time_printf(tmpStr); } } //Ready SRDY Status // This Test check if RNP has asserted SRDY line because it has some Data pending. // If SRDY is not Used, then this line need to be commented, and the Poll command need // to be sent regularly to check if any data is pending. this is done every 10ms (see below npi_poll_cond) #ifndef SRDY_INTERRUPT ret = HAL_RNP_SRDY_CLR(); if(TRUE == ret) #else //Interruption case, In case of a SREQ, SRDY will go low a end generate an event. // the npiPollLock will prevent us to arrive to this test, // BUT an AREQ can immediately follow a SREQ: SRDY will stay low for the whole process // In this case, we need to check that the SRDY line is still LOW or is HIGH. if (HalGpioSrdyCheck(0) == TRUE) #endif { if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Polling received... \n", __FUNCTION__); time_printf(tmpStr); } //RNP is polling, retrieve the data *readbuf = 0; //Poll Command has zero data bytes. *(readbuf+1) = RPC_CMD_POLL; *(readbuf+2) = 0; ret = npi_i2c_pollData((npiMsgData_t *)readbuf); if (ret == NPI_LNX_SUCCESS) { //Check if polling was successful if ((readbuf[RPC_POS_CMD0] & RPC_CMD_TYPE_MASK) == RPC_CMD_AREQ) { // ((uint8 *)readbuf)[RPC_POS_CMD0] = RPC_SUBSYSTEM_MASK; ret = NPI_AsynchMsgCback((npiMsgData_t *)(readbuf)); if (ret != NPI_LNX_SUCCESS) { // Exit thread to invoke report to main thread npi_poll_terminate = 1; error_printf("%s:%d: ERROR! Terminating poll because RPC_CMD_AREQ.\n", __FUNCTION__, __LINE__); } } } else { // An error has occurred // Check what error it is, some errors are expected char *errorMsg; switch (npi_ipc_errno) { case NPI_LNX_ERROR_HAL_GPIO_WAIT_SRDY_CLEAR_POLL_TIMEDOUT: errorMsg = "npi_i2c_pollData timed out waiting for SRDY. Could be SBL which only responds to SREQ. Please check global error message\n"; NPI_LNX_IPC_NotifyError(NPI_LNX_ERROR_MODULE_MASK(NPI_LNX_ERROR_HAL_GPIO_WAIT_SRDY_CLEAR_POLL_TIMEDOUT), errorMsg); // The RNP may be in SBL or may only respond to SREQ. We should not exit POLL thread. ret = NPI_LNX_SUCCESS; break; case NPI_LNX_ERROR_HAL_I2C_READ_TIMEDOUT: // The RNP may have reset unexpectedly, keep going ret = NPI_LNX_SUCCESS; break; case NPI_LNX_ERROR_HAL_I2C_WRITE_TIMEDOUT: // The RNP may have reset unexpectedly, keep going ret = NPI_LNX_SUCCESS; break; default: // Exit clean so main knows... npi_poll_terminate = 1; error_printf("%s:%d: ERROR! Terminating poll because error return (ret=%d, npi_ipc_errno=%d).\n", __FUNCTION__, __LINE__, ret, npi_ipc_errno); break; } } if (!PollLockVar) { ret = PollLockVarError(__LINE__, !PollLockVar); } else { PollLockVar = 0; if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] PollLockVar set to %d\n", __FUNCTION__, PollLockVar); time_printf(tmpStr); } } #ifndef SRDY_INTERRUPT if ( 0 == pthread_mutex_unlock(&npiPollLock)) { pollStatus = TRUE; if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Unlock SRDY mutex \n", __FUNCTION__); time_printf(tmpStr); } } else { if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Failed to unlock SRDY mutex \n", __FUNCTION__); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_I2C_POLL_THREAD_POLL_UNLOCK; ret = NPI_LNX_FAILURE; npi_poll_terminate = 1; error_printf("%s:%d: ERROR! Terminating poll because POLL mutex unlock failed.\n", __FUNCTION__, __LINE__); } #endif //SRDY_INTERRUPT } else { if (!PollLockVar) { ret = PollLockVarError(__LINE__, !PollLockVar); } else { PollLockVar = 0; if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] PollLockVar set to %d\n", __FUNCTION__, PollLockVar); time_printf(tmpStr); } } #ifdef SRDY_INTERRUPT if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] SRDY was not 0 when we expected!\n", __FUNCTION__); time_printf(tmpStr); } #else if ( 0 == pthread_mutex_unlock(&npiPollLock)) { if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Unlock SRDY mutex \n", __FUNCTION__); time_printf(tmpStr); } } else { if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Failed to unlock SRDY mutex \n", __FUNCTION__); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_I2C_POLL_THREAD_POLL_UNLOCK; ret = NPI_LNX_FAILURE; npi_poll_terminate = 1; error_printf("%s:%d: ERROR! Terminating poll because POLL mutex unlock failed.\n", __FUNCTION__, __LINE__); } pollStatus = FALSE; #endif //SRDY_INTERRUPT } #ifdef SRDY_INTERRUPT if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Unlock POLL mutex by conditional wait (SRDY=%d) \n", __FUNCTION__, global_srdy); time_printf(tmpStr); } if (TRUE == HAL_RNP_SRDY_SET()) { if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Waiting for SRDY to go low\n", __FUNCTION__); time_printf(tmpStr); } int condWaitRetVal = pthread_cond_wait(&npi_srdy_H2L_poll, &npiPollLock); if (condWaitRetVal) { snprintf(tmpStr, sizeof(tmpStr), "[%s] pthread_cond_wait returned with %d (%s, %s)\n", __FUNCTION__, condWaitRetVal, strerror(condWaitRetVal), strerror(errno)); time_printf(tmpStr); if (condWaitRetVal == 1) exit(-1); } } else if (npi_poll_terminate) { // Just unlock mutex, while loop will exit next pthread_mutex_unlock(&npiPollLock); } else { if (PollLockVar) { ret = PollLockVarError(__LINE__, PollLockVar); } if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] SRDY found high after poll, poll again\n", __FUNCTION__); time_printf(tmpStr); } // After a synchronous request we need to poll RNP again. The RNP will only release SRDY after // replying with 0x00 0x00 0x00 to a poll request. } if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Locked POLL mutex because condition was met (SRDY=%d) \n", __FUNCTION__, global_srdy); time_printf(tmpStr); } #else if (!pollStatus) //If previous poll failed, wait 10ms to do another one, else do it right away to empty the RNP queue. { struct timespec expirytime; clock_gettime(CLOCK_REALTIME, &expiryTime); expirytime.tv_nsec += 10000000; // 10ms if (expirytime.tv_nsec >= 1000000000) { expirytime.tv_nsec -= 1000000000; expirytime.tv_sec++; } pthread_cond_timedwait(&npi_poll_cond, &npi_poll_mutex, &expirytime); } #endif } error_printf("[POLL] WARNING. Thread exiting with ret=%d, npi_ipc_errno0x%x...\n", ret, npi_ipc_errno); pthread_mutex_unlock(&npi_poll_mutex); char const *errorMsg; if (ret == NPI_LNX_FAILURE) { errorMsg = "[POLL] Thread exited with error. Please check global error message\n"; } else { errorMsg = "[POLL] Thread exited without error\n"; } NPI_LNX_IPC_NotifyError(NPI_LNX_ERROR_MODULE_MASK(NPI_LNX_ERROR_I2C_POLL_THREAD_FAILED_LOCK), errorMsg); return ptr; }
/************************************************************************************************** * @fn NPI_I2C_SendSynchData * * @brief This function is called by the client when it has data ready to * be sent synchronously. This routine allocates a SREQ buffer, * copies the client's payload, sends the data, and waits for the * reply. The input buffer is used for the output data. * * input parameters * * @param *pMsg - Pointer to data to be sent synchronously (i.e. the SREQ). * * output parameters * * @param *pMsg - Pointer to replay data (i.e. the SRSP). * * @return STATUS ************************************************************************************************** */ int NPI_I2C_SendSynchData(npiMsgData_t *pMsg) { int i, ret = NPI_LNX_SUCCESS; int lockRetPoll = 0, lockRetSrdy = 0, strIndex = 0; char tmpStr[1024]; // Do not attempt to send until polling is finished if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Lock Poll mutex \n", __FUNCTION__); time_printf(tmpStr); } //Lock the polling until the command is send lockRetPoll = pthread_mutex_lock(&npiPollLock); if (lockRetPoll) { error_printf("[SYNCH] [ERR] Error %d getting POLL mutex lock\n", lockRetPoll); perror("mutex lock"); npi_ipc_errno = NPI_LNX_ERROR_I2C_SEND_SYNCH_FAILED_LOCK; ret = NPI_LNX_FAILURE; } else { if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Poll mutex locked\n", __FUNCTION__); time_printf(tmpStr); } #ifdef SRDY_INTERRUPT if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Lock SRDY mutex \n", __FUNCTION__); time_printf(tmpStr); } lockRetSrdy = pthread_mutex_lock(&npiSrdyLock); if (lockRetSrdy) { error_printf("[SYNCH] [ERR] Error %d getting SRDY mutex lock\n", lockRetSrdy); perror("mutex lock"); ret = NPI_LNX_FAILURE; } else { if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] SRDY mutex locked\n", __FUNCTION__); time_printf(tmpStr); } } #endif } if (ret == NPI_LNX_SUCCESS) { if (PollLockVar) { ret = PollLockVarError(__LINE__, PollLockVar); } else { PollLockVar = 1; if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] PollLockVar set to %d\n", __FUNCTION__, PollLockVar); time_printf(tmpStr); } } if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] =================== START SEND SYNCH DATA ====================\n", __FUNCTION__); time_printf(tmpStr); } } if (ret == NPI_LNX_SUCCESS) { #ifdef __BIG_DEBUG__ if (TRUE == HAL_RNP_SRDY_CLR()) printf("[SYNCH] SRDY set\n"); else printf("[SYNCH] SRDY Clear\n"); #endif // Add Proper RPC type to header ((uint8*)pMsg)[RPC_POS_CMD0] = (((uint8*)pMsg)[RPC_POS_CMD0] & RPC_SUBSYSTEM_MASK) | RPC_CMD_SREQ; ret = HAL_RNP_MRDY_CLR(); } if ( NPI_LNX_SUCCESS == ret) { //Wait for SRDY Clear ret = HalGpioWaitSrdyClr(); if (ret != NPI_LNX_SUCCESS) error_printf("[SYNCH] [SREQ] ERROR! Waiting for SRDY assert failed, ret=0x%x\n", ret); else { if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Synch Data Command ...", __FUNCTION__); strIndex = strlen(tmpStr); for (i = 0 ; i < (RPC_FRAME_HDR_SZ+pMsg->len); i++ ) { snprintf(tmpStr + strIndex, sizeof(tmpStr) - strIndex, " 0x%.2X", ((uint8*)pMsg)[i]); strIndex += 5; } snprintf(tmpStr + strIndex, sizeof(tmpStr) - strIndex, "\n"); time_printf(tmpStr); } //This wait is only valid if RNP manage MRDY line, if not SRDY will never be set low on SREQ. // To avoid any problem, just add a timeout, or ignore it. ret = HalGpioWaitSrdyClr(); //Send LEN, CMD0 and CMD1 (comand Header) if (ret == NPI_LNX_SUCCESS) ret = HalI2cWrite(0, (uint8*) pMsg, RPC_FRAME_HDR_SZ + (pMsg->len)); if (ret == NPI_LNX_SUCCESS) { //Do a Three Byte Dummy Write to read the RPC Header memset(pMsg, 0, RPC_FRAME_HDR_SZ); ret = HalI2cRead( 0, (uint8*) pMsg, RPC_FRAME_HDR_SZ); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Synch Data Command ...", __FUNCTION__); strIndex = strlen(tmpStr); for (i = 0 ; i < (RPC_FRAME_HDR_SZ); i++ ) { snprintf(tmpStr + strIndex, sizeof(tmpStr) - strIndex, " 0x%.2X", ((uint8*)pMsg)[i]); strIndex += 5; } snprintf(tmpStr + strIndex, sizeof(tmpStr) - strIndex, "\n"); time_printf(tmpStr); } if (ret != NPI_LNX_SUCCESS) { error_printf("[%s] HalI2cRead() returned 0x%x, line %d, errno=0x%x\n", __FUNCTION__, ret, __LINE__, npi_ipc_errno); } else if (pMsg->len > 0) { if (pMsg->len == 0xFF && pMsg->subSys == 0xFF && pMsg->cmdId == 0xFF) { error_printf("[%s] Received 0xFF 0xFF 0xFF. Ignoring it and returning an error!\n", __FUNCTION__); ret = NPI_LNX_FAILURE; } else { // Do a write/read of the corresponding length // Fill data with 0s first (aids in debugging): memset(pMsg->pData, 0, pMsg->len); ret = HalI2cRead( 0, pMsg->pData, pMsg->len); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Read %d bytes more", __FUNCTION__, pMsg->len); strIndex = strlen(tmpStr); for (i = 0 ; i < (pMsg->len); i++ ) { snprintf(tmpStr, sizeof(tmpStr) - strIndex, " 0x%.2X", pMsg->pData[i]); strIndex += 5; } snprintf(tmpStr + strIndex, sizeof(tmpStr) - strIndex, "\n"); time_printf(tmpStr); } } } } } } //Release the polling lock if (ret == NPI_LNX_SUCCESS) ret = HAL_RNP_MRDY_SET(); else (void)HAL_RNP_MRDY_SET(); if (!PollLockVar) { ret = PollLockVarError(__LINE__, !PollLockVar); } else { PollLockVar = 0; if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] PollLockVar set to %d\n", __FUNCTION__, PollLockVar); time_printf(tmpStr); } } //Release the polling lock if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] =================== END SEND SYNCH DATA ====================\n", __FUNCTION__); time_printf(tmpStr); } if (!lockRetPoll) { // Also signal poll thread so it can poll for a NULL message from the RNP. Otherwise we won't later get // the interrupt from the RNP, since the RNP will keep SRDY low until it has answered NULL to a poll. if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Signaling poll thread to perform a final 0 response poll ...\n", __FUNCTION__); time_printf(tmpStr); } pthread_cond_signal(&npi_srdy_H2L_poll); // Signal it (let it get cond) pthread_mutex_unlock(&npiPollLock); // Release mutex so it can re-acquire it. } #ifdef SRDY_INTERRUPT if (!lockRetSrdy) { pthread_mutex_unlock(&npiSrdyLock); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Unlocked SRDY mutex\n", __FUNCTION__); time_printf(tmpStr); } } #endif return ret; }
/************************************************************************************************** * @fn npi_i2c_pollData * * @brief This function is called by the client when it has data ready to * be sent synchronously. This routine allocates a SREQ buffer, * copies the client's payload, sends the data, and waits for the * reply. The input buffer is used for the output data. * * input parameters * * @param *pMsg - Pointer to data to be sent synchronously (i.e. the SREQ). * * output parameters * * @param *pMsg - Pointer to replay data (i.e. the SRSP). * * @return STATUS ************************************************************************************************** */ int npi_i2c_pollData(npiMsgData_t *pMsg) { int ret = NPI_LNX_SUCCESS; char tmpStr[1024]; if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] -------------------- START POLLING DATA --------------------\n", __FUNCTION__); time_printf(tmpStr); } #ifdef SRDY_INTERRUPT pthread_mutex_lock(&npiSrdyLock); #endif #ifdef __STRESS_TEST__ // debug_ static struct timeval prevTimePoll; time_printf_always_localized("MRDY Low\n", NULL, NULL, &prevTimePoll) #endif //__STRESS_TEST__ ret = HAL_RNP_MRDY_CLR(); if (NPI_LNX_SUCCESS == ret) { //This wait is only valid if RNP manage MRDY line, if not SRDY will never be set low on SREQ. // To avoid any problem, just add a timeout, or ignore it. ret = HalGpioWaitSrdyClr(); //Send LEN, CMD0 and CMD1 (command Header) and payload if (ret == NPI_LNX_SUCCESS) ret = HalI2cWrite(0, (uint8*) pMsg, RPC_FRAME_HDR_SZ + (pMsg->len)); if (ret == NPI_LNX_SUCCESS) ret = HalI2cRead(0, (uint8*) pMsg, RPC_FRAME_HDR_SZ); if (ret == NPI_LNX_SUCCESS) { if ( (pMsg->len == 0xFF) && (pMsg->subSys == 0xFF) && (pMsg->cmdId == 0xFF) ) { // Do nothing error_printf("[POLL] WARNING: Invalid header (FF FF FF) received!\n"); } else if (pMsg->len > 0) { if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] I2C Read Response \n", __FUNCTION__); time_printf(tmpStr); } //Zero buffer for length about to read, then do a write/read of the corresponding length memset(pMsg->pData, 0, ((uint8*)pMsg)[0]); ret = HalI2cRead(0, pMsg->pData, pMsg->len); } } } if (ret == NPI_LNX_SUCCESS) ret = HAL_RNP_MRDY_SET(); else (void)HAL_RNP_MRDY_SET(); if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] -------------------- END POLLING DATA --------------------\n", __FUNCTION__); time_printf(tmpStr); } #ifdef SRDY_INTERRUPT pthread_mutex_unlock(&npiSrdyLock); #endif return ret; }
/************************************************************************************************** * @fn NPI_I2C_SendAsynchData * * @brief This function is called by the client when it has data ready to * be sent asynchronously. This routine allocates an AREQ buffer, * copies the client's payload, and sets up the send. * * input parameters * * @param *pMsg - Pointer to data to be sent asynchronously (i.e. AREQ). * * output parameters * * None. * * @return STATUS ************************************************************************************************** */ int NPI_I2C_SendAsynchData(npiMsgData_t *pMsg) { int ret = NPI_LNX_SUCCESS; char tmpStr[1024]; if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Locking POLL and SRDY\n", __FUNCTION__); time_printf(tmpStr); } fflush(stdout); //Lock the polling until the command is send pthread_mutex_lock(&npiPollLock); #ifdef SRDY_INTERRUPT pthread_mutex_lock(&npiSrdyLock); #endif if (PollLockVar) { ret = PollLockVarError(__LINE__, PollLockVar); } else { PollLockVar = 1; if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] PollLockVar set to %d\n", __FUNCTION__, PollLockVar); time_printf(tmpStr); } } if (ret == NPI_LNX_SUCCESS) { if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] (Sync) success\n", __FUNCTION__); time_printf(tmpStr); } } if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] ******************** START SEND ASYNC DATA ********************\n", __FUNCTION__); time_printf(tmpStr); } // Add Proper RPC type to header ((uint8*)pMsg)[RPC_POS_CMD0] = (((uint8*)pMsg)[RPC_POS_CMD0] & RPC_SUBSYSTEM_MASK) | RPC_CMD_AREQ; if (ret == NPI_LNX_SUCCESS) { ret = HAL_RNP_MRDY_CLR(); if ( NPI_LNX_SUCCESS != ret) { return ret; } } if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] AREQ\n", __FUNCTION__); time_printf(tmpStr); } //Wait for SRDY Clear ret = HalGpioWaitSrdyClr(); //Send LEN, CMD0 and CMD1 (command Header) if (ret == NPI_LNX_SUCCESS) ret = HalI2cWrite(0, (uint8*) pMsg, RPC_FRAME_HDR_SZ + (pMsg->len)); if (ret == NPI_LNX_SUCCESS) ret = HAL_RNP_MRDY_SET(); else (void)HAL_RNP_MRDY_SET(); if (!PollLockVar) { ret = PollLockVarError(__LINE__, !PollLockVar); } else { PollLockVar = 0; if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] PollLockVar set to %d\n", __FUNCTION__, PollLockVar); time_printf(tmpStr); } } // Also signal poll thread so it can poll for a NULL message from the RNP. Otherwise we won't later get // the interrupt from the RNP, since the RNP will keep SRDY low until it has answered NULL to a poll. if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Signaling poll thread to perform a final 0 response poll ...\n", __FUNCTION__); time_printf(tmpStr); } pthread_cond_signal(&npi_srdy_H2L_poll); // Signal it (let it get cond) pthread_mutex_unlock(&npiPollLock); // Release mutex so it can re-acquire it. #ifdef SRDY_INTERRUPT pthread_mutex_unlock(&npiSrdyLock); #endif if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Unlock SRDY mutex\n", __FUNCTION__); time_printf(tmpStr); snprintf(tmpStr, sizeof(tmpStr), "[%s] ******************** STOP SEND ASYNC DATA ********************\n", __FUNCTION__); time_printf(tmpStr); } return ret; }
/****************************************************************************** * @fn NPI_OpenDevice * * @brief This function establishes a serial communication connection with * a network processor device. * As windows machine does not have a single dedicated serial * interface, this function will designate which serial port shall * be used for communication. * * input parameters * * @param portName – name of the serial port * @param gpioCfg – GPIO settings for SRDY, MRDY and RESET * * output parameters * * None. * * @return TRUE if the connection is established successfully. * FALSE, otherwise. ****************************************************************************** */ int NPI_I2C_OpenDevice(const char *portName, void *pCfg) { int ret = NPI_LNX_SUCCESS; char tmpStr[256]; if(npiOpenFlag) { npi_ipc_errno = NPI_LNX_ERROR_I2C_OPEN_ALREADY_OPEN; return NPI_LNX_FAILURE; } npiOpenFlag = TRUE; if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Opening Device File: %s\n", __FUNCTION__, portName); time_printf(tmpStr); } ret = HalI2cInit(portName); if (ret != NPI_LNX_SUCCESS) return ret; if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] ((npiI2cCfg_t *)pCfg)->gpioCfg[0] \t @%p\n", __FUNCTION__, (void *)&(((npiI2cCfg_t *)pCfg)->gpioCfg[0])); time_printf(tmpStr); } if ( NPI_LNX_FAILURE == (GpioSrdyFd = HalGpioSrdyInit(((npiI2cCfg_t *)pCfg)->gpioCfg[0]))) { error_printf("%s(): ERROR returned from HalGpioSrdyInit!\n", __FUNCTION__); ret = GpioSrdyFd; } if ( NPI_LNX_FAILURE == (ret = HalGpioMrdyInit(((npiI2cCfg_t *)pCfg)->gpioCfg[1]))) { error_printf("%s(): ERROR returned from HalGpioMrdyInit!\n", __FUNCTION__); } if ( NPI_LNX_FAILURE == (ret = HalGpioResetInit(((npiI2cCfg_t *)pCfg)->gpioCfg[2]))) { error_printf("%s(): ERROR returned from HalGpioResetInit!\n", __FUNCTION__); } if (ret == NPI_LNX_SUCCESS) { // initialize thread synchronization resources if ( NPI_LNX_FAILURE == (ret = npi_initsyncres())) return ret; // Reset The RNP ret = NPI_I2C_ResetSlave(); // TODO: it is ideal to make this thread higher priority // but Linux does not allow real time of FIFO scheduling policy for // non-privileged threads. if (ret == NPI_LNX_SUCCESS) { // create Polling thread ret = npi_initThreads(); } else { error_printf("%s() ERROR: Did not attempt to start Threads\n", __FUNCTION__); } } if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] returning %d\n", __FUNCTION__, ret); time_printf(tmpStr); } return ret; }
/* thread_slow_log */ void entry_thread_slow_log(void* parameter) { int fd = -1; int size; int count_bef = 1; int second = 0; char buf[256]; char dir[64]; const char file_name[] = "slow.log"; const char instruction[] = "This is a slow log from Deep Blue Plane.\n" "second\t" "time\t" "cpu\t" "airtemp\t" "battery.v\t" "battery.a\t" "gps.lng\t" "gps.lat\t" "gps.star\t" "ctrl.stat\t" "wp.lng\t" "wp.lat\t" "wp.seaalt\t" "airspeed\n"; //复制工作区 目录 strcpy(dir, log_dir); //打开记录文件 strcat(dir, file_name); //try to open the working file while(fd < 0) { fd = open(dir, O_WRONLY | O_CREAT, 0); rt_thread_delay(RT_TICK_PER_SECOND); } rt_kprintf("slow log has been created.\n"); //写入说明 write(fd, instruction, strlen(instruction)); //主循环 while(1) { //1s while(second +1 > system_info.startup_second) rt_thread_delay(1); second = system_info.startup_second; { sprintf(buf,"%6d\t%s\t%3.2f\t%3.2f\t%3.2f\t%3.2f\t" "%f\t%f\t%d\t%d\t%f\t%f\t%f\t%f\t\n", system_info.startup_second, time_printf(), system_info.mcu.usage, air_info.temperature.temp, system_info.power_battery.v, system_info.power_battery.a, gps.lon, gps.lat, gps.stars, control.state, navigation.current.longitude, navigation.current.latiude, navigation.current.sea_altitude, air_speed.speed); } size = write(fd, buf, strlen(buf)); if(size>0) { //rt_kprintf(buf); } else { rt_kprintf("slow log write to file wrong !"); while(1)rt_thread_delay(1000); //相当于停止这个线程 } if(system_info.startup_second %5 == 1) { close(fd); fd = open(dir, O_WRONLY | O_CREAT | O_APPEND, 0);//末尾重新打开 } } }
/************************************************************************************************** * @fn HalGpioWaitSrdyClr * * @brief Check that SRDY is low, if not, wait until it gets low. * * input parameters * * @param None. * * output parameters * * None. * * @return STATUS ************************************************************************************************** */ int HalGpioWaitSrdyClr(void) { char srdy= '1', tmpStr[128]; int ret = NPI_LNX_SUCCESS, accTimeout = 0; if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Wait for SRDY to go Low. [Thread: %u]\n", __FUNCTION__, (unsigned int) pthread_self()); time_printf(tmpStr); } struct pollfd ufds[1]; int pollRet; ufds[0].fd = gpioSrdyFd; ufds[0].events = POLLPRI; lseek(gpioSrdyFd,0,SEEK_SET); read(gpioSrdyFd,&srdy, 1); while(srdy == '1') { pollRet = poll((struct pollfd*)&ufds, 1, HAL_WAIT_SRDY_LOW_INTERMEDIATE_TIMEOUT); if (pollRet == -1) { // Error occured in poll() perror("poll"); } else if (pollRet == 0) { accTimeout++; // Timeout lseek(gpioSrdyFd,0,SEEK_SET); read(gpioSrdyFd,&srdy, 1); if(srdy == '1') { if (accTimeout >= (HAL_WAIT_SRDY_LOW_TIMEOUT / HAL_WAIT_SRDY_LOW_INTERMEDIATE_TIMEOUT) ) { if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Waiting for SRDY to go low timed out. [Thread: %u]\n", __FUNCTION__, (unsigned int) pthread_self()); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_WAIT_SRDY_CLEAR_POLL_TIMEDOUT; ret = NPI_LNX_FAILURE; break; } else { // This timeout is expected, and ok. Nothing to report, only for debug. if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Waiting for SRDY to go low intermediate timed out, %d. [Thread: %u]\n", __FUNCTION__, accTimeout, (unsigned int) pthread_self()); time_printf(tmpStr); } } } else { // Missed interrupt waiting for SRDY to go high // This timeout is expected, and ok. Nothing to report, only for debug. if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Waiting for SRDY to go low intermediate timed out, %d, but SRDY is now low. [Thread: %u]\n", __FUNCTION__, accTimeout, (unsigned int) pthread_self()); time_printf(tmpStr); } break; } } else { if (ufds[0].revents & POLLPRI) { lseek(gpioSrdyFd,0,SEEK_SET); if(ERROR == read(gpioSrdyFd,&srdy, 1)) { perror(srdyGpioCfg.gpio.value); if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] can't write in %s , is something already accessing it? abort everything for debug purpose...\n", __FUNCTION__, srdyGpioCfg.gpio.value); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_GPIO_WAIT_SRDY_CLEAR_READ_FAILED; ret = NPI_LNX_FAILURE; break; } } else { if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] ufds[0].revents = 0x%X\n", __FUNCTION__, ufds[0].revents); time_printf(tmpStr); } } } } if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] SRDY: %c (%d). [Thread: %u]\n", __FUNCTION__, srdy, (int)srdy, (unsigned int) pthread_self()); time_printf(tmpStr); } return ret; }
/************************************************************************************************** * @fn HalI2cRead * * @brief Read a buffer from the I2C Slave. * * @param port - I2C port. * pBuf - Pointer to the buffer that will be written. * len - Number of bytes to write/read. * * @return STATUS **************************************************************************************************/ int HalI2cRead(uint8 port, uint8 *pBuf, uint8 len) { int timeout = I2C_OPEN_100MS_TIMEOUT, ret = NPI_LNX_SUCCESS; int i, strIndex = 0; int res = -1; char tmpStr[1024]; pthread_mutex_lock(&I2cMutex1); while( (-1 == (res = read(i2cDevFd,pBuf,len))) && timeout) { timeout--; sprintf(tmpStr, "[%s] I2C Read timeout %d, %s \n", __FUNCTION__, timeout, strerror(errno)); time_printf(tmpStr); if (timeout == 90) { exit(-1); } if ((errno == ETIMEDOUT) && (timeout < (I2C_OPEN_100MS_TIMEOUT - 2)) ) { // When ETIMEDOUT is received the function did not immediately return, so the 100 ms timeout // is not accurate. Hence, cut it short after 3 attempts. timeout = 0; } else { usleep(1000); //Wait 1ms before re-trying } } if ( (-1 == res) && !timeout) { /* ERROR HANDLING: i2c transaction failed */ if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] Failed to write to the i2c bus for %d ms. read %d byte(s)...reason: (#%d)%s\n", __FUNCTION__, I2C_OPEN_100MS_TIMEOUT, res, errno, strerror(errno)); time_printf(tmpStr); } if (errno == ETIMEDOUT) { // RNP may be hung, report error and perform reset. if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] May have to reset RNP...\n", __FUNCTION__); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_I2C_READ_TIMEDOUT_PERFORM_RESET; } else { if ( __BIG_DEBUG_ACTIVE == TRUE ) { snprintf(tmpStr, sizeof(tmpStr), "[%s] RNP may have reset unexpectedly. Keep going...\n", __FUNCTION__); time_printf(tmpStr); } npi_ipc_errno = NPI_LNX_ERROR_HAL_I2C_READ_TIMEDOUT; } ret = NPI_LNX_FAILURE; } else { if (__BIG_DEBUG_ACTIVE == TRUE) { snprintf(tmpStr, sizeof(tmpStr), "[%s] I2C Read: \t", __FUNCTION__); strIndex = strlen(tmpStr); for (i = 0 ; i < len; i++ ) { snprintf(tmpStr + strIndex, sizeof(tmpStr) - strIndex, " 0x%.2X", pBuf[i]); strIndex += 5; } snprintf(tmpStr + strIndex, sizeof(tmpStr) - strIndex, "\n"); time_printf(tmpStr); } } pthread_mutex_unlock(&I2cMutex1); return ret; }