/** * @brief Hardware de-initialization * * The function will restore original pinshare value and deactivate GPIO pins. * * @param dev pointer to structure of device data * @return 0 on success, negative errno on error */ static int tsb_spi_hw_deinit(struct device *dev) { struct tsb_spi_info *info = NULL; uint32_t pinshare = 0; int i = 0; /* check input parameters */ if (!dev || !device_get_private(dev)) { return -EINVAL; } info = device_get_private(dev); /* release GPIO pins */ for (i = 0; i < info->caps.csnum; i++) { gpio_deactivate(info->chipselect[i]); } gpio_deactivate(SPI_SDO); gpio_deactivate(SPI_SDI); gpio_deactivate(SPI_SCK); /* restore pinshare#5 setting */ pinshare = tsb_get_pinshare() & TSB_PIN_GPIO10; /* current setting */ if ((info->pinshare & TSB_PIN_GPIO10)) { if (!pinshare) { tsb_set_pinshare(TSB_PIN_GPIO10); } } else { if (pinshare) { tsb_clr_pinshare(TSB_PIN_GPIO10); } } return 0; }
/** * @brief Hardware initialization * * The function initializes the GPIO pins used in the bit-bang interface and * also assigned a default output value for SPI signal. * * @param dev pointer to structure of device data * @return 0 on success, negative errno on error */ static int tsb_spi_hw_init(struct device *dev) { struct tsb_spi_info *info = NULL; int i = 0; int retval; /* check input parameters */ if (!dev || !device_get_private(dev)) { return -EINVAL; } info = device_get_private(dev); retval = tsb_request_pinshare(TSB_PIN_GPIO10); if (retval) { lowsyslog("SPI: cannot get ownership of GPIO10 pin.\n"); return retval; } /* backup pinshare#5 setting */ info->pinshare = tsb_get_pinshare(); /* set pinshare#5 (DBG) to normal GPIO */ if (!(info->pinshare & TSB_PIN_GPIO10)) { tsb_set_pinshare(TSB_PIN_GPIO10); } /* setup GPIO pins */ gpio_activate(SPI_SCK); gpio_direction_out(SPI_SCK, 0); gpio_activate(SPI_SDI); gpio_direction_in(SPI_SDI); gpio_activate(SPI_SDO); gpio_direction_out(SPI_SDO, 0); /* setup all chip-select pins */ for (i = 0; i < info->caps.csnum; i++) { gpio_activate(info->chipselect[i]); gpio_direction_out(info->chipselect[i], 1); } return 0; }
int main(int argc, FAR char *argv[]) { #else int etm_main(int argc, char *argv[]) { #endif char cmd; long drive_ma; unsigned short last_drive_ma = etm.drive_ma; if (argc < 2) { print_usage(); return EXIT_FAILURE; } else { cmd = argv[1][0]; } switch (cmd) { case 'h': case '?': print_usage(); break; case 'e': /* enable ETM */ if (argc == 2) { etm.drive_ma = DRIVE_MA_MAX; } else if (argc == 3) { drive_ma = strtol(argv[2], NULL, 10); if (drive_ma != DRIVE_MA_MIN && drive_ma != DRIVE_MA_DEFAULT && drive_ma != DRIVE_MA_MAX) { printf("Invalid drive strength of %ld ma when trying to enable ETM (%u|%u|%u are valid)\n", drive_ma, DRIVE_MA_MIN, DRIVE_MA_DEFAULT, DRIVE_MA_MAX); return EXIT_FAILURE; } etm.drive_ma = (unsigned short) drive_ma; } else { printf("Too many arguments specified when attempting to enable ETM\n"); return EXIT_FAILURE; } if (etm.enabled) { /* update drive strength if it has changed */ if (etm.drive_ma != last_drive_ma) { set_trace_drive_ma(etm.drive_ma); printf("ETM drive strength changed to %u milliamps\n", etm.drive_ma); } else printf("WARNING: ETM is already enabled\n"); } else { /* * perhaps we ought to be recording the old value * but the present API doesn't expose it */ etm.etm_pinshare_save = tsb_get_pinshare() & TSB_PIN_ETM; tsb_set_pinshare(TSB_PIN_ETM); /* set drive strength for the TRACE signals to the specified value */ etm.drive_ma_save = get_trace_drive_ma(); set_trace_drive_ma(etm.drive_ma); /* * record current value of the ETM lock status register so that we can restore * the original lock state if ETM TRACE is disabled */ etm.lsr_save = getreg32(ETMLSR); /* unlock ETM: may need a delay right after */ putreg32(ETM_UNLOCK, ETMLAR); /* put ETM into programming mode: may need a delay right after */ etm.cr_save = getreg32(ETMCR); putreg32(ETMCR_PROGRAM, ETMCR); /* Don't define a trigger for TRACE (NOT Always) */ etm.trigger_save = getreg32(ETMTRIGGER); putreg32(ETM_EVENT_NEVER, ETMTRIGGER); /* TRACE all memory */ etm.teevr_save = getreg32(ETMTEEVR); putreg32(ETM_EVENT_ALWAYS, ETMTEEVR); /* Set identifier for trace output (match what DTRACE selects) */ etm.traceidr_save = getreg32(ETMTRACEIDR); putreg32(0x2, ETMTRACEIDR); /* Set trace port width to 4 (versus 1) */ etm.cpsr_save = getreg32(TPIU_CPSR); putreg32(0x8, TPIU_CPSR); /* Set trace output type to parallel (versus 1 == serial) */ etm.sppr_save = getreg32(TPIU_SPPR); putreg32(0x0, TPIU_SPPR); /* And finally, set ETM to operational mode */ putreg32(ETMCR_OPERATE, ETMCR); etm.enabled = 1; printf("ETM enabled with a drive strength of %u milliamps\n", etm.drive_ma); } break; case 'd': /* Disable ETM */ if (!etm.enabled) { printf("WARNING: etm is already disabled\n"); } else { /* Put ETM back into programming mode */ putreg32(ETMCR_PROGRAM, ETMCR); /* Restore registers to saved values */ putreg32(etm.sppr_save, TPIU_SPPR); putreg32(etm.cpsr_save, TPIU_CPSR); putreg32(etm.traceidr_save, ETMTRACEIDR); putreg32(etm.teevr_save, ETMTEEVR); putreg32(etm.trigger_save, ETMTRIGGER); putreg32(etm.cr_save, ETMCR); /* Relock ETM if it was locked when we enabled TRACE */ if (etm.lsr_save & ETMLSR_LOCKED) putreg32(ETM_LOCK, ETMLAR); /* Restore the original drive strength */ set_trace_drive_ma(etm.drive_ma_save); /* Clear the ETM pinshare if it wasn't set on entry */ if (!etm.etm_pinshare_save) tsb_clr_pinshare(TSB_PIN_ETM); etm.enabled = 0; etm.drive_ma = 0; } break; case 's': /* Get the ETM state */ if (etm.enabled) { printf("ETM state = enabled, with a drive strength of %u milliamps\n", etm.drive_ma); } else { printf("ETM state = either never enabled or returned to original state\n"); } break; default: printf("ETM: Unknown command\n"); print_usage(); return EXIT_FAILURE; } return 0; }
int main(int argc, FAR char *argv[]) { #else int pinshare_main(int argc, char *argv[]) { #endif uint32_t mask = 0; char cmd = '\0'; int ret = 0; char *endptr = NULL; if (argc < 2) { print_usage(); return EXIT_FAILURE; } else { cmd = argv[1][0]; } switch (cmd) { case 'h': case '?': print_usage(); break; case 'r': case 'g': /* read current value of PINSHARE register */ if (argc != 2) { print_usage(); ret = EXIT_FAILURE; } else { printf("Current value of PINSHARE register is: 0x%x\n", tsb_get_pinshare()); } break; default: /* set or clear specified bits of PINSHARE register */ if (argc != 3) { print_usage(); ret = EXIT_FAILURE; } mask = strtoul(argv[2], &endptr, 16); if (*endptr) { printf("PINSHARE: Unable to parse provided hex bitmask \"%s\"\n", argv[2]); ret = EXIT_FAILURE; } else { switch(cmd) { case 's': tsb_set_pinshare(mask); printf("New value of PINSHARE register is: 0x%x\n", tsb_get_pinshare()); break; case 'c': if (mask & 0x1) { printf("PINSHARE: Leaving bit 0 set, to keep UART active!\n"); mask &= ~1; } tsb_clr_pinshare(mask); printf("New value of PINSHARE register is: 0x%x\n", tsb_get_pinshare()); break; default: printf("PINSHARE: Unknown command\n"); print_usage(); ret = EXIT_FAILURE; } } } return ret; }