/**
 * @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;
}
Exemple #2
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;
}
Exemple #3
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;
}
Exemple #4
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;
}