예제 #1
0
파일: io_spi.cpp 프로젝트: dengcj0/QCA4010
AJ_Status AJS_TargetIO_SpiOpen(uint8_t mosi, uint8_t miso, uint8_t cs, uint8_t clk, uint32_t clock,
                               uint8_t master, uint8_t cpol, uint8_t cpha, uint8_t data, void** spiCtx)
{
    SPI_Pin* spi;
    uint8_t mode = 0;
    uint16_t mosiPin = AJS_TargetIO_GetInfo(mosi)->physicalPin;
    uint16_t misoPin = AJS_TargetIO_GetInfo(miso)->physicalPin;
    uint16_t csPin = AJS_TargetIO_GetInfo(cs)->physicalPin;
    uint16_t clkPin = AJS_TargetIO_GetInfo(clk)->physicalPin;

    uint8_t indexMosi, indexMiso, indexCs, indexClk;

    /*
     * Get the pin information for all the SPI pins
     */
    for (indexMosi = 0; indexMosi < ArraySize(spiInfo); ++indexMosi) {
        if (spiInfo[indexMosi].pinNum == mosiPin) {
            break;
        }
    }
    for (indexMiso = 0; indexMiso < ArraySize(spiInfo); ++indexMiso) {
        if (spiInfo[indexMiso].pinNum == misoPin) {
            break;
        }
    }
    for (indexCs = 0; indexCs < ArraySize(spiInfo); ++indexCs) {
        if (spiInfo[indexCs].pinNum == csPin) {
            break;
        }
    }
    for (indexClk = 0; indexClk < ArraySize(spiInfo); ++indexClk) {
        if (spiInfo[indexClk].pinNum == clkPin) {
            break;
        }
    }
    spi = (SPI_Pin*)AJS_Alloc(NULL, sizeof(SPI_Pin));
    spi->object = new SPI((PinName)spiInfo[indexMosi].pinId, (PinName)spiInfo[indexMiso].pinId, (PinName)spiInfo[indexClk].pinId);
    spi->cs = new DigitalOut((PinName)spiInfo[indexCs].pinId);
    spi->object->frequency(clock);
    /*
     * Mode     cpol    cpha
     * 0        0       0
     * 1        0       1
     * 2        1       0
     * 3        1       1
     */
    mode = (cpol << 1 | cpha << 0);
    if (mode > 3) {
        AJ_ErrPrintf(("AJS_TargetIO_SpiOpen(): cpol/cpha must be either 0 or 1\n"));
        return AJ_ERR_UNEXPECTED;
    }
    spi->object->format(data, mode);

    *spiCtx = spi;

    return AJ_OK;
}
예제 #2
0
AJ_Status AJS_TargetIO_I2cOpen(uint8_t sda, uint8_t scl, uint32_t clock, uint8_t mode, uint8_t ownAddress, void** ctx)
{
    GPIO_InitTypeDef i2cGPIO;
    I2C_InitTypeDef i2cInit;
    uint16_t sdaPin = AJS_TargetIO_GetInfo(sda)->physicalPin;
    uint16_t sclPin = AJS_TargetIO_GetInfo(scl)->physicalPin;
    uint8_t indexSda, indexScl;
    I2C_Pin* i2cPin;
    uint8_t pinSource;

    i2cPin = AJS_Alloc(NULL, sizeof(I2C_Pin));

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

    for (indexSda = 0; indexSda < ArraySize(i2cInfo); indexSda++) {
        if (i2cInfo[indexSda].pinNum == sda) {
            break;
        }
    }
    for (indexScl = 0; indexScl < ArraySize(i2cInfo); indexScl++) {
        if (i2cInfo[indexScl].pinNum == scl) {
            break;
        }
    }

    i2cGPIO.GPIO_Pin = i2cInfo[indexSda].physicalPin | i2cInfo[indexScl].physicalPin;
    i2cGPIO.GPIO_Mode = GPIO_Mode_AF;
    i2cGPIO.GPIO_OType = GPIO_OType_OD;
    i2cGPIO.GPIO_PuPd = GPIO_PuPd_UP;
    i2cGPIO.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(i2cInfo[indexSda].GPIOx, &i2cGPIO);
    pinSource = pinToSource(i2cInfo[indexSda].physicalPin);
    GPIO_PinAFConfig(i2cInfo[indexSda].GPIOx, pinSource, GPIO_AF_I2C1);
    pinSource = pinToSource(i2cInfo[indexScl].physicalPin);
    GPIO_PinAFConfig(i2cInfo[indexScl].GPIOx, pinSource, GPIO_AF_I2C1);

    i2cInit.I2C_Ack = I2C_Ack_Disable;
    i2cInit.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    i2cInit.I2C_ClockSpeed = clock;
    i2cInit.I2C_DutyCycle = I2C_DutyCycle_2;
    i2cInit.I2C_Mode = I2C_Mode_I2C;
    i2cInit.I2C_OwnAddress1 = 0x00;
    I2C_Init(I2C1, &i2cInit);

    I2C_Cmd(I2C1, ENABLE);

    *ctx = i2cCtx;

    return AJ_OK;
}
예제 #3
0
extern "C" AJ_Status AJS_TargetIO_PinOpen(uint16_t pinIndex, AJS_IO_PinConfig config, void** pinCtx)
{
    GPIO* gpio;
    size_t pin;
    uint16_t physicalPin = AJS_TargetIO_GetInfo(pinIndex)->physicalPin;
    for (pin = 0; pin < ArraySize(pinInfo); ++pin) {
        if (pinInfo[pin].pinNum == physicalPin) {
            break;
        }
    }
    if (pin >= ArraySize(pinInfo)) {
        return AJ_ERR_INVALID;
    }
    gpio = (GPIO*)AJS_Alloc(NULL, sizeof(GPIO));
    memset(gpio, 0, sizeof(GPIO));

    /*
     * Find if this is a digitalOut, digitalIn or both
     */
    uint32_t direction = AJS_TargetIO_GetInfo(pinIndex)->functions;

    if (direction & AJS_IO_FUNCTION_DIGITAL_OUT) {
        gpio->out = new DigitalOut((PinName)pinInfo[pin].pinId, 0);
        *(gpio->out) = 0;
    } else if ((direction & AJS_IO_FUNCTION_DIGITAL_IN) && (config != AJS_IO_PIN_OUTPUT)) {
        gpio->in = new DigitalIn((PinName)pinInfo[pin].pinId);
        switch (config) {
        case (AJS_IO_PIN_OPEN_DRAIN):
            //gpio->in->mode(OpenDrain); //TODO: This enum does not exist
            break;

        case (AJS_IO_PIN_PULL_UP):
            gpio->in->mode(PullUp);
            break;

        case (AJS_IO_PIN_PULL_DOWN):
            gpio->in->mode(PullDown);
            break;

        default:
            break;
        }
    } else {
        gpio->inOut = new DigitalInOut((PinName)pinInfo[pin].pinId);
    }
    gpio->trigId = -1;
    gpio->pinIdx = pinIndex;

    *pinCtx = gpio;

    return AJ_OK;
}
예제 #4
0
/*
 * Returns information about this pin
 */
static int NativeInfoGetter(duk_context* ctx)
{
    int idx;
    uint32_t pin;
    const AJS_IO_Info* info;

    duk_push_this(ctx);
    pin = GetPinId(ctx, -1, 0);
    duk_pop(ctx);

    info = AJS_TargetIO_GetInfo(pin);
    if (!info) {
        duk_error(ctx, DUK_ERR_INTERNAL_ERROR, "Undefined I/O pin%d", pin);
        return 0;
    }
    duk_push_string(ctx, ", ");

    idx = duk_push_object(ctx);
    duk_push_int(ctx, info->physicalPin);
    duk_put_prop_string(ctx, idx, "physicalPin");
    duk_push_string(ctx, info->schematicId);
    duk_put_prop_string(ctx, idx, "schematicId");
    duk_push_string(ctx, info->datasheetId);
    duk_put_prop_string(ctx, idx, "datasheetId");
    duk_push_string(ctx, info->description);
    duk_put_prop_string(ctx, idx, "description");
    /*
     * Return the object we just created
     */
    return 1;
}
예제 #5
0
/*
 * Returns the IO functions supported by this pin
 */
static int NativeFunctionsGetter(duk_context* ctx)
{
    uint8_t bit;
    uint8_t numFuncs = 0;
    const AJS_IO_Info* info;
    uint32_t pin;

    duk_push_this(ctx);
    pin = GetPinId(ctx, -1, 0);
    duk_pop(ctx);

    info = AJS_TargetIO_GetInfo(pin);
    if (!info) {
        duk_error(ctx, DUK_ERR_INTERNAL_ERROR, "Undefined I/O pin%d", pin);
        return 0;
    }
    duk_push_string(ctx, ", ");
    /*
     * Test each function bit
     */
    for (bit = 0; bit < 32; ++bit) {
        if (info->functions & (1 << bit)) {
            const char* name = AJS_IO_FunctionName(1 << bit);
            duk_push_string(ctx, name);
            ++numFuncs;
        }
    }
    duk_join(ctx, numFuncs);
    return 1;
}
예제 #6
0
/*
 * Returns the pid id for a pin object. Also checks that the pin supports the requested function.
 */
static uint32_t GetPinId(duk_context* ctx, int idx, uint32_t function)
{
    uint32_t id;
    if (!duk_is_object(ctx, idx)) {
        duk_error(ctx, DUK_ERR_TYPE_ERROR, "Requires a pin object");
    }
    /*
     * Get pin id
     */
    duk_get_prop_string(ctx, idx, "id");
    id = duk_require_int(ctx, -1);
    duk_pop(ctx);
    /*
     * Check that the required I/O function is supported
     */
    if (function) {
        const AJS_IO_Info* info = AJS_TargetIO_GetInfo(id);
        if (!info) {
            duk_error(ctx, DUK_ERR_INTERNAL_ERROR, "Undefined I/O pin%d", id);
            return 0;
        }
        if (!(info->functions & function)) {
            duk_error(ctx, DUK_ERR_TYPE_ERROR, "I/O function %s not supported on pin%d", AJS_IO_FunctionName(function), id);
        }
    }
    return id;
}
예제 #7
0
extern "C" AJ_Status AJS_TargetIO_PinEnableTrigger(void* pinCtx, AJS_IO_PinTriggerMode trigger, int32_t* trigId, uint8_t debounce)
{
    GPIO* gpio = (GPIO*)pinCtx;
    size_t pin;
    uint16_t pinId;
    uint16_t physicalPin = AJS_TargetIO_GetInfo(gpio->pinIdx)->physicalPin;
    for (pin = 0; pin < ArraySize(pinInfo); ++pin) {
        if (pinInfo[pin].pinNum == physicalPin) {
            pinId = pinInfo[pin].pinId;
            break;
        }
    }
    if (!pinInfo[pin].func) {
        return AJ_ERR_INVALID;
    }
    gpio->trigId = AllocTrigId(pin);
    if (gpio->trigId == AJS_IO_PIN_NO_TRIGGER) {
        return AJ_ERR_RESOURCES;
    }
    gpio->interrupt = new InterruptIn((PinName)pinId);
    if (trigger == AJS_IO_PIN_TRIGGER_ON_RISE) {
        gpio->interrupt->rise(pinInfo[pin].func);
    } else if (trigger == AJS_IO_PIN_TRIGGER_ON_FALL) {
        gpio->interrupt->fall(pinInfo[pin].func);
    }
    *trigId = gpio->trigId;
    return AJ_OK;
}
예제 #8
0
AJ_Status AJS_TargetIO_PinOpen(uint16_t pinIndex, AJS_IO_PinConfig config, void** pinCtx)
{
    GPIO* gpio;
    GPIO_InitTypeDef GPIO_Pin;
    size_t pin;
    uint16_t physicalPin = AJS_TargetIO_GetInfo(pinIndex)->physicalPin;
    for (pin = 0; pin < ArraySize(pinInfo); ++pin) {
        if (pinInfo[pin].pinNum == physicalPin) {
            break;
        }
    }
    if (pin >= ArraySize(pinInfo)) {
        return AJ_ERR_INVALID;
    }
    gpio = AJS_Alloc(NULL, sizeof(GPIO));
    memset(gpio, 0, sizeof(GPIO));
    gpio->trigId = -1;
    gpio->gpioAF = 0;
    gpio->GPIOx = pinInfo[pin].GPIOx;
    gpio->gpioPin = pinInfo[pin].physicalPin;

    GPIO_Pin.GPIO_Speed = GPIO_Speed_50MHz;
    if (config & AJS_IO_PIN_OUTPUT) {
        GPIO_Pin.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_Pin.GPIO_OType = GPIO_OType_PP;
        GPIO_Pin.GPIO_Pin = pinInfo[pin].physicalPin;
        GPIO_Pin.GPIO_PuPd = GPIO_PuPd_UP;
    } else if (config & AJS_IO_PIN_INPUT) {
        GPIO_Pin.GPIO_Mode = GPIO_Mode_IN;
        GPIO_Pin.GPIO_OType = GPIO_OType_PP;
        GPIO_Pin.GPIO_Pin = pinInfo[pin].physicalPin;
        GPIO_Pin.GPIO_PuPd = GPIO_PuPd_UP;
    } else {
        if (config & AJS_IO_PIN_OPEN_DRAIN) {
            GPIO_Pin.GPIO_Mode = GPIO_Mode_OUT;
            GPIO_Pin.GPIO_OType = GPIO_OType_OD;
            GPIO_Pin.GPIO_Pin = pinInfo[pin].physicalPin;
            GPIO_Pin.GPIO_PuPd = GPIO_PuPd_UP;
        } else if (config & AJS_IO_PIN_PULL_UP) {
            GPIO_Pin.GPIO_Mode = GPIO_Mode_OUT;
            GPIO_Pin.GPIO_OType = GPIO_OType_PP;
            GPIO_Pin.GPIO_Pin = pinInfo[pin].physicalPin;
            GPIO_Pin.GPIO_PuPd = GPIO_PuPd_UP;
        } else {
            GPIO_Pin.GPIO_Mode = GPIO_Mode_OUT;
            GPIO_Pin.GPIO_OType = GPIO_OType_PP;
            GPIO_Pin.GPIO_Pin = pinInfo[pin].physicalPin;
            GPIO_Pin.GPIO_PuPd = GPIO_PuPd_DOWN;
        }
    }
    GPIO_Init(gpio->GPIOx, &GPIO_Pin);

    *pinCtx = gpio;

    return AJ_OK;
}
예제 #9
0
AJ_Status AJS_TargetIO_PinOpen(uint16_t pinIndex, AJS_IO_PinConfig config, void** pinCtx)
{
    AJ_Status status = AJ_OK;
    int fd;
    uint16_t physicalPin = AJS_TargetIO_GetInfo(pinIndex)->physicalPin;
    size_t pin;
    GPIO* gpio;
    const char* dev;

    /*
     * Locate GPIO associated with the physical pin
     */
    for (pin = 0; pin < ArraySize(pinInfo); ++pin) {
        if (pinInfo[pin].physicalPin == physicalPin) {
            break;
        }
    }
    if (pin >= ArraySize(pinInfo)) {
        return AJ_ERR_INVALID;
    }
    dev = pinInfo[pin].gpioDev;
    status = ExportIfNeeded(dev, pinInfo[pin].gpioId, gpio_root);
    if (status != AJ_OK) {
        return status;
    }
    /*
     * Set the pin direction
     */
    status = SetDeviceProp(dev, gpio_root, "direction", (config == AJS_IO_PIN_OUTPUT) ? "out" : "in");
    if (status != AJ_OK) {
        return status;
    }
    /*
     * Save the open file handle
     */
    fd = OpenDeviceProp(dev, gpio_root, "value", (config == AJS_IO_PIN_OUTPUT) ? O_RDWR : O_RDONLY);
    if (fd >= 0) {
        gpio = malloc(sizeof(GPIO));
        if (!gpio) {
            AJ_ErrPrintf(("AJS_TargetIO_PinOpen(): Malloc failed to allocate %d bytes\n", sizeof(GPIO)));
            return AJ_ERR_RESOURCES;
        }
        gpio->fd = fd;
        gpio->pinId = pin;
        gpio->trigId = AJS_IO_PIN_NO_TRIGGER;
        gpio->pwmPeriod = 0;
        AJS_TargetIO_PinGet(gpio);
    } else {
        status = AJ_ERR_DRIVER;
    }
    *pinCtx = gpio;
    return status;
}
예제 #10
0
AJ_Status AJS_TargetIO_UartOpen(uint8_t txPin, uint8_t rxPin, uint32_t baud, void** uartCtx)
{
    UART* uart;
    uint16_t pinTx, pinRx;
    uint16_t physicalTxPin = AJS_TargetIO_GetInfo(txPin)->physicalPin;
    uint16_t physicalRxPin = AJS_TargetIO_GetInfo(rxPin)->physicalPin;

    for (pinTx = 0; pinTx < ArraySize(uartInfo); ++pinTx) {
        if (uartInfo[pinTx].pinNum == physicalTxPin) {
            break;
        }
    }
    // Make sure the pin exists and its a TX pin
    if (pinTx >= ArraySize(uartInfo) || uartInfo[pinTx].function != AJS_IO_FUNCTION_UART_TX) {
        return AJ_ERR_INVALID;
    }
    for (pinRx = 0; pinRx < ArraySize(uartInfo); ++pinRx) {
        if (uartInfo[pinRx].pinNum == physicalRxPin) {
            break;
        }
    }
    // Make sure the pin exists and its an RX pin
    if (pinRx >= ArraySize(uartInfo) || uartInfo[pinRx].function != AJS_IO_FUNCTION_UART_RX) {
        return AJ_ERR_INVALID;
    }
    // Dont initialize the UART peripheral, just point the object to the current UART class
    if (uartInfo[pinTx].init == false || uartInfo[pinRx].init == false) {
        uart->object = pc;
        *uartCtx = uart;
        return AJ_OK;
    }
    uart = (UART*)AJS_Alloc(NULL, sizeof(UART));
    uart->object = new Serial((PinName)uartInfo[pinTx].pinId, (PinName)uartInfo[pinRx].pinId);
    uart->object->baud(baud);
    *uartCtx = uart;
    return AJ_OK;
}
예제 #11
0
/*
 * Configures a pin as a digital output pin
 */
static int NativeIoDigitalOut(duk_context* ctx)
{
    AJ_Status status;
    int idx;
    void* pinCtx;
    uint32_t pin = GetPinId(ctx, 0, AJS_IO_FUNCTION_DIGITAL_OUT);

    /*
     * Target specific I/O pin initialization
     */
    status = AJS_TargetIO_PinOpen(pin, AJS_IO_PIN_OUTPUT, &pinCtx);
    if (status != AJ_OK) {
        duk_error(ctx, DUK_ERR_INTERNAL_ERROR, "Failed to configure digital output pin: %s", AJ_StatusText(status));
    }
    idx = NewIOObject(ctx, pinCtx, AJS_IO_FUNCTION_DIGITAL_OUT, NativePinFinalizer);
    /*
     * Functions to set/get the pin level
     */
    AJS_SetPropertyAccessors(ctx, idx, "level", NativeLevelSetter, NativeLevelGetter);
    /*
     * Check for and set initial value
     */
    if (duk_is_number(ctx, 1)) {
        duk_dup(ctx, 1);
        duk_put_prop_string(ctx, idx, "level");
    }
    /*
     * Toggle function
     */
    duk_push_c_lightfunc(ctx, NativeTogglePin, 0, 0, 0);
    duk_put_prop_string(ctx, idx, "toggle");
    /*
     * Only allow if the PWM functions is supported
     */
    if (AJS_TargetIO_GetInfo(pin)->functions & AJS_IO_FUNCTION_PWM) {
        duk_push_c_lightfunc(ctx, NativePWM, 2, 0, 0);
        duk_put_prop_string(ctx, idx, "pwm");
    }
    /*
     * Return the digital output pin object
     */
    return 1;
}
예제 #12
0
AJ_Status AllocPWM(GPIO* pin)
{
    size_t i;
    size_t idx;
    uint16_t physicalPin = AJS_TargetIO_GetInfo(pin->pinIdx)->physicalPin;
    for (idx = 0; idx < ArraySize(pinInfo); ++idx) {
        if (pinInfo[idx].pinNum == physicalPin) {
            break;
        }
    }
    AJ_ASSERT(!pin->pwm.dutyCycle);
    for (i = 0; i < MAX_PWM_PINS; ++i) {
        if (!pwmPins[i]) {
            pwmPins[i] = pin;
            pin->pwm.count = 0;
            ++pwmCount;
            //pin->pwm.object = new PwmOut((PinName)pinInfo[idx].pinId);
            return AJ_OK;
        }
    }
    return AJ_ERR_RESOURCES;
}
예제 #13
0
AJ_Status AJS_TargetIO_AdcOpen(uint16_t pinIndex, void** adcCtx)
{
    ADC* adc;
    size_t pin;
    uint16_t physicalPin = AJS_TargetIO_GetInfo(pinIndex)->physicalPin;
    for (pin = 0; pin < ArraySize(pinInfo); ++pin) {
        if (pinInfo[pin].pinNum == physicalPin) {
            break;
        }
    }
    if (pin >= ArraySize(pinInfo)) {
        return AJ_ERR_INVALID;
    }
    adc = (ADC*)AJS_Alloc(NULL, sizeof(ADC));
    memset(adc, 0, sizeof(ADC));

    adc->adcObj = new AnalogIn((PinName)pinInfo[pin].pinId);

    *adcCtx = adc;

    return AJ_OK;
}