void digitalWrite( uint8_t pin, uint8_t val )
{
    if (pin >= NUM_DIGITAL_PINS) return;
	
    PinDescription *p = &g_APinDescription[pin];

    if (!p->ulInputMode) {
        if (p->ulGPIOType == SS_GPIO) {
            uint32_t reg = p->ulGPIOBase + SS_GPIO_SWPORTA_DR;
            if (val)
                SET_ARC_BIT(reg, p->ulGPIOId);
            else
                CLEAR_ARC_BIT(reg, p->ulGPIOId);
        }
        else if (p->ulGPIOType == SOC_GPIO) {
            uint32_t reg = p->ulGPIOBase + SOC_GPIO_SWPORTA_DR;
            if (val)
                SET_MMIO_BIT(reg, p->ulGPIOId);
            else
                CLEAR_MMIO_BIT(reg, p->ulGPIOId);
        }
    } else {
        if (val)
            SET_PIN_PULLUP(p->ulSocPin,1);
        else
            SET_PIN_PULLUP(p->ulSocPin,0);
    }
}
void pinMode( uint8_t pin, uint8_t mode )
{
    if (pin >= NUM_DIGITAL_PINS) return;
	
    PinDescription *p = &g_APinDescription[pin];

    if (mode == OUTPUT) {
        p->ulInputMode = OUTPUT_MODE;
        if (p->ulGPIOType == SS_GPIO) {
            uint32_t reg = p->ulGPIOBase + SS_GPIO_SWPORTA_DDR;
            SET_ARC_BIT(reg, p->ulGPIOId);
        }
        else if (p->ulGPIOType == SOC_GPIO) {
            uint32_t reg = p->ulGPIOBase + SOC_GPIO_SWPORTA_DDR;
            SET_MMIO_BIT(reg, p->ulGPIOId);
        }
    } else {
        p->ulInputMode = INPUT_MODE;
        if (p->ulGPIOType == SS_GPIO) {
            uint32_t reg = p->ulGPIOBase + SS_GPIO_SWPORTA_DDR;
            CLEAR_ARC_BIT(reg, p->ulGPIOId);
        }
        else if (p->ulGPIOType == SOC_GPIO) {
            uint32_t reg = p->ulGPIOBase + SOC_GPIO_SWPORTA_DDR;
            CLEAR_MMIO_BIT(reg, p->ulGPIOId);
        }
    }

    /* Set SoC pin mux configuration */
    SET_PIN_PULLUP(p->ulSocPin, (mode == INPUT_PULLUP) ? 1 : 0);
    if (p->ulPinMode != GPIO_MUX_MODE) {
        SET_PIN_MODE(p->ulSocPin, GPIO_MUX_MODE);
        p->ulPinMode = GPIO_MUX_MODE;
    }
}
uint32_t analogRead(uint32_t pin)
{

    uint32_t val = 0;

    /* allow for channel or pin numbers */
    if (pin < 6) pin += A0;

    PinDescription *p = &g_APinDescription[pin];

    /* Disable pull-up and set pin mux for ADC output */
    SET_PIN_MODE(p->ulSocPin, ADC_MUX_MODE);
    SET_PIN_PULLUP(p->ulSocPin,0);

    /* Reset sequence pointer */
    SET_ARC_MASK(ADC_CTRL, ADC_SEQ_PTR_RST);
    /* Update sequence table */
    WRITE_ARC_REG(p->ulAdcChan, ADC_SEQ);
    /* Reset sequence pointer & start sequencer */
    SET_ARC_MASK(ADC_CTRL, ADC_SEQ_PTR_RST | ADC_SEQ_START | ADC_ENABLE);
    /* Poll for ADC data ready status (DATA_A) */
    while((READ_ARC_REG(ADC_INTSTAT) & ADC_INT_DATA_A) == 0);
    /* Pop the data sample from FIFO to sample register */
    SET_ARC_MASK(ADC_SET, ADC_POP_SAMPLE);
    /* Read sample from sample register */
    val = READ_ARC_REG( ADC_SAMPLE);
    /* Clear the DATA_A status bit */
    SET_ARC_MASK( ADC_CTRL, ADC_CLR_DATA_A);

    return mapResolution(val, ADC_RESOLUTION, _readResolution);

}
void analogWrite(uint8_t pin, uint32_t val)
{
    if (! digitalPinHasPWM(pin))
    {
        if(val > 127)
        {
            digitalWrite(pin, HIGH);
        }
        else
        {
            digitalWrite(pin, LOW);
        }
        return;
    }

    if (val <= 0) {
        /* Use GPIO for 0% duty cycle (always off)  */
        pinMode(pin, OUTPUT);
        digitalWrite(pin, LOW);
    } else if (val >= ((1 << _writeResolution) - 1)) {
        /* Use GPIO for 100% duty cycle (always on)  */
        pinMode(pin, OUTPUT);
        digitalWrite(pin, HIGH);
    } else {
        /* PWM for everything in between */
        PinDescription *p = &g_APinDescription[pin];

        uint32_t offset;
        
        uint32_t hcnt = (val/(float)maxResolutionValue) * pwmPeriod[p->ulPwmChan];
        uint32_t lcnt = pwmPeriod[p->ulPwmChan] - hcnt;
        
        /* Set the high count period (duty cycle) */
        offset = ((p->ulPwmChan * QRK_PWM_N_LCNT2_LEN) + QRK_PWM_N_LOAD_COUNT2);
        MMIO_REG_VAL(QRK_PWM_BASE_ADDR + offset) = hcnt;
        
        /* Set the low count period (duty cycle) */
        offset = ((p->ulPwmChan * QRK_PWM_N_REGS_LEN) + QRK_PWM_N_LOAD_COUNT1);
        MMIO_REG_VAL(QRK_PWM_BASE_ADDR + offset) = lcnt;

        /* start the PWM output */
        offset = ((p->ulPwmChan * QRK_PWM_N_REGS_LEN) + QRK_PWM_N_CONTROL);
        SET_MMIO_MASK(QRK_PWM_BASE_ADDR + offset, QRK_PWM_CONTROL_ENABLE);
        
        if(pinmuxMode[pin] != PWM_MUX_MODE)
        {
            /* Disable pull-up and set pin mux for PWM output */
            SET_PIN_PULLUP(p->ulSocPin, 0);
            SET_PIN_MODE(p->ulSocPin, PWM_MUX_MODE);
            pinmuxMode[pin] = PWM_MUX_MODE;
        }
    }
}