Exemple #1
0
//******************************************************************************
void analogin_init(analogin_t *obj, PinName pin)
{
    // Make sure pin is an analog pin we can use for ADC
    MBED_ASSERT((ADCName)pinmap_peripheral(pin, PinMap_ADC) != (ADCName)NC);

    // Set the object pointer
    obj->adc = MXC_ADC;
    obj->adccfg = MXC_ADCCFG;
    obj->adc_fifo = MXC_ADC_FIFO;
    obj->adc_pin = pin;

    // Set the ADC clock to the system clock frequency
    MXC_SET_FIELD(&MXC_CLKMAN->clk_ctrl, MXC_F_CLKMAN_CLK_CTRL_ADC_SOURCE_SELECT,
        (MXC_F_CLKMAN_CLK_CTRL_ADC_GATE_N | (MXC_E_CLKMAN_ADC_SOURCE_SELECT_SYSTEM << 
        MXC_F_CLKMAN_CLK_CTRL_ADC_SOURCE_SELECT_POS)));

    // Enable AFE power
    MXC_PWRMAN->pwr_rst_ctrl |= MXC_F_PWRMAN_PWR_RST_CTRL_AFE_POWERED;

    // Setup and hold window
    MXC_SET_FIELD(&obj->adc->tg_ctrl0, MXC_F_ADC_TG_CTRL0_PGA_TRK_CNT, PGA_TRK_CNT);

    // Setup sampling count and timing
    MXC_SET_FIELD(&obj->adc->tg_ctrl1, (MXC_F_ADC_TG_CTRL1_PGA_ACQ_CNT | 
        MXC_F_ADC_TG_CTRL1_ADC_ACQ_CNT | MXC_F_ADC_TG_CTRL1_ADC_SLP_CNT),
        ((ADC_PGA_CNT << MXC_F_ADC_TG_CTRL1_PGA_ACQ_CNT_POS) | 
        (ADC_ACQ_CNT << MXC_F_ADC_TG_CTRL1_ADC_ACQ_CNT_POS) |
        (ADC_SLP_CNT << MXC_F_ADC_TG_CTRL1_ADC_SLP_CNT_POS) |
        (MXC_F_ADC_TG_CTRL1_ADC_BRST_CNT)));
}
Exemple #2
0
//******************************************************************************
void spi_frequency(spi_t *obj, int hz)
{
    // Maximum frequency is half the system frequency
    MBED_ASSERT((unsigned int)hz <= (SystemCoreClock / 2));
    unsigned clocks = ((SystemCoreClock / 2) / hz);

    // Figure out the divider ratio
    int clk_div = 1;
    while(clk_div < 10) {
        if(clocks < 0x10) {
            break;
        }
        clk_div++;
        clocks = clocks >> 1;
    }

    // Turn on the SPI clock
    if(obj->index == 0) {
        MXC_CLKMAN->sys_clk_ctrl_11_spi0 = clk_div;
    } else if(obj->index == 1) {
        MXC_CLKMAN->sys_clk_ctrl_12_spi1 = clk_div;
    } else if(obj->index == 2) {
        MXC_CLKMAN->sys_clk_ctrl_13_spi2 = clk_div;
    } else {
        MBED_ASSERT(0);
    }

    // Set the number of clocks to hold sclk high and low
    MXC_SET_FIELD(&obj->spi->mstr_cfg,
                  (MXC_F_SPIM_MSTR_CFG_SCK_HI_CLK | MXC_F_SPIM_MSTR_CFG_SCK_LO_CLK),
                  ((clocks << MXC_F_SPIM_MSTR_CFG_SCK_HI_CLK_POS) | (clocks << MXC_F_SPIM_MSTR_CFG_SCK_LO_CLK_POS)));
}
Exemple #3
0
//******************************************************************************
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
{
    MBED_ASSERT(obj->index < MXC_CFG_UART_INSTANCES);
    // objs[obj->index] = obj;

    switch (obj->index) {
        case 0:
            NVIC_SetVector(UART0_IRQn, (uint32_t)uart0_handler);
            NVIC_EnableIRQ(UART0_IRQn);
            break;
        case 1:
            NVIC_SetVector(UART1_IRQn, (uint32_t)uart1_handler);
            NVIC_EnableIRQ(UART1_IRQn);
            break;
        case 2:
            NVIC_SetVector(UART2_IRQn, (uint32_t)uart2_handler);
            NVIC_EnableIRQ(UART2_IRQn);
            break;
        case 3:
            NVIC_SetVector(UART3_IRQn, (uint32_t)uart3_handler);
            NVIC_EnableIRQ(UART3_IRQn);
            break;
        default:
            MBED_ASSERT(0);
    }

    if (irq == RxIrq) {
        // Enable RX FIFO Threshold Interrupt
        if (enable) {
            // Clear pending interrupts
            obj->uart->intfl = obj->uart->intfl;
            obj->uart->inten |= (MXC_F_UART_INTFL_RX_FIFO_NOT_EMPTY | UART_ERRORS);
        } else {
            // Clear pending interrupts
            obj->uart->intfl = obj->uart->intfl;
            obj->uart->inten &= ~(MXC_F_UART_INTFL_RX_FIFO_NOT_EMPTY | UART_ERRORS);
        }
    } else if (irq == TxIrq) {
        // Set TX Almost Empty level to interrupt when empty
        MXC_SET_FIELD(&obj->uart->tx_fifo_ctrl,
                      MXC_F_UART_TX_FIFO_CTRL_FIFO_AE_LVL,
                      (MXC_UART_FIFO_DEPTH - 1) << MXC_F_UART_TX_FIFO_CTRL_FIFO_AE_LVL_POS);

        // Enable TX Almost Empty Interrupt
        if (enable) {
            // Clear pending interrupts
            obj->uart->intfl = obj->uart->intfl;
            obj->uart->inten |= MXC_F_UART_INTFL_TX_FIFO_AE;
        } else {
            // Clear pending interrupts
            obj->uart->intfl = obj->uart->intfl;
            obj->uart->inten &= ~MXC_F_UART_INTFL_TX_FIFO_AE;
        }
    } else {
        MBED_ASSERT(0);
    }
}
Exemple #4
0
//******************************************************************************
static void pwmout_update(pwmout_t* obj)
{
    // Calculate and set the divider ratio
    int div = (obj->period * (SystemCoreClock/1000000))/32;
    if (div < 2){
        div = 2;
    }
    MXC_SET_FIELD(&obj->pwm->rate_length, MXC_F_PT_RATE_LENGTH_RATE_CONTROL, div);

    // Change the duty cycle to adjust the pulse width
    obj->pwm->train = (0xFFFFFFFF << (32-((32*obj->pulse_width)/obj->period)));
}
Exemple #5
0
//******************************************************************************
void pwmout_init(pwmout_t* obj, PinName pin)
{
    // Make sure the pin is free for GPIO use
    unsigned int port = (unsigned int)pin >> PORT_SHIFT;
    unsigned int port_pin = (unsigned int)pin & ~(0xFFFFFFFF << PORT_SHIFT);
    MBED_ASSERT(MXC_GPIO->free[port] & (0x1 << port_pin));

    int i = 0;
    PinMap pwm = PinMap_PWM[0];

    // Check if there is a pulse train already active on this port
    int pin_func = (MXC_GPIO->func_sel[port] & (0xF << (port_pin*4))) >> (port_pin*4);
    if((pin_func > 0) && (pin_func < 4)) {
        // Search through PinMap_PWM to find the active PT
        while(pwm.pin != (PinName)NC) {
            if((pwm.pin == pin) && (pwm.function == pin_func)) {
                break;
            }
            pwm = PinMap_PWM[++i];
        }

    } else {
       // Search through PinMap_PWM to find an available PT
        int i = 0;
        while(pwm.pin != (PinName)NC && (i > -1)) {
            pwm = PinMap_PWM[i++];
            if(pwm.pin == pin) {
                // Check each instance of PT
                while(1) {
                    // Check to see if this PT instance is already in use
                    if((((mxc_pt_regs_t*)pwm.peripheral)->rate_length & 
                        MXC_F_PT_RATE_LENGTH_MODE)) {
                        i = -1;
                        break;
                    } 

                    // If all instances are in use, overwrite the last 
                    pwm = PinMap_PWM[++i];
                    if(pwm.pin != pin) {
                        pwm = PinMap_PWM[--i];
                        i = -1; 
                        break;
                    }

                }
            }
        } 
    }

    // Make sure we found an available PWM generator
    MBED_ASSERT(pwm.pin != (PinName)NC);

    // Disable all pwm output
    MXC_PTG->ctrl = 0;

    // Enable the clock
    MXC_CLKMAN->clk_ctrl_2_pt = MXC_E_CLKMAN_CLK_SCALE_ENABLED;

    // Set the drive mode to normal
    MXC_SET_FIELD(&MXC_GPIO->out_mode[port], (0x7 << (port_pin*4)), (MXC_V_GPIO_OUT_MODE_NORMAL_DRIVE << (port_pin*4)));

    // Set the obj pointer to the propper PWM instance
    obj->pwm = (mxc_pt_regs_t*)pwm.peripheral;

    // Initialize object period and pulse width
    obj->period = -1; 
    obj->pulse_width = -1;

    // Disable the output
    obj->pwm->train = 0x0;
    obj->pwm->rate_length = 0x0;

    // Configure the pin
    pin_mode(pin, (PinMode)PullNone);
    pin_function(pin, pwm.function);

    // default to 20ms: standard for servos, and fine for e.g. brightness control
    pwmout_period_us(obj, 20000);
    pwmout_write    (obj, 0);

    // Enable the global pwm
    MXC_PTG->ctrl = MXC_F_PT_CTRL_ENABLE_ALL;
}
Exemple #6
0
//******************************************************************************
void analogout_init(dac_t *obj, PinName pin)
{
    // Make sure pin is an analog pin we can use for ADC
    DACName dac = (DACName)pinmap_peripheral(pin, PinMap_DAC);
    MBED_ASSERT((DACName)dac != (DACName)NC);

    // Set the object pointer
    obj->dac = ((mxc_dac_regs_t*)MXC_DAC_GET_DAC((pin & 0x3)));
    obj->dac_fifo = ((mxc_dac_fifo_t*)MXC_DAC_GET_FIFO((pin & 0x3)));
    obj->index = (pin & 0x3);

    // Set the ADC clock to the system clock frequency
    MXC_SET_FIELD(&MXC_CLKMAN->clk_ctrl, MXC_F_CLKMAN_CLK_CTRL_ADC_SOURCE_SELECT,
        (MXC_F_CLKMAN_CLK_CTRL_ADC_GATE_N | (MXC_E_CLKMAN_ADC_SOURCE_SELECT_SYSTEM << 
        MXC_F_CLKMAN_CLK_CTRL_ADC_SOURCE_SELECT_POS)));

    
    // Setup the OPAMP in follower mode
    switch(obj->index) {
        case 0:
            // Enable DAC clock
            MXC_CLKMAN->clk_ctrl_14_dac0 = MXC_E_CLKMAN_CLK_SCALE_ENABLED;

            // Enable OPAMP
            MXC_AFE->ctrl5 &= ~MXC_F_AFE_CTRL5_OP_CMP0;

            // Set the positive and negative inputs
            MXC_SET_FIELD(&MXC_AFE->ctrl4, (MXC_F_AFE_CTRL4_DAC_SEL_A | 
                MXC_F_AFE_CTRL4_P_IN_SEL_OPAMP0 | MXC_F_AFE_CTRL4_N_IN_SEL_OPAMP0), 
                ((0x1 << MXC_F_AFE_CTRL4_P_IN_SEL_OPAMP0_POS) |
                (0x1 << MXC_F_AFE_CTRL4_N_IN_SEL_OPAMP0_POS) |
                (0x0 << MXC_F_AFE_CTRL4_DAC_SEL_A_POS)));

            // Enable N and P channel inputs
            MXC_AFE->ctrl3 |= (MXC_F_AFE_CTRL3_EN_PCH_OPAMP0 | 
                MXC_F_AFE_CTRL3_EN_NCH_OPAMP0);
        break;
        case 1:
            // Enable DAC clock
            MXC_CLKMAN->clk_ctrl_15_dac1 = MXC_E_CLKMAN_CLK_SCALE_ENABLED;

            // Enable OPAMP
            MXC_AFE->ctrl5 &= ~MXC_F_AFE_CTRL5_OP_CMP1;

            // Set the positive and negative inputs
            MXC_SET_FIELD(&MXC_AFE->ctrl4, (MXC_F_AFE_CTRL4_DAC_SEL_B | 
                MXC_F_AFE_CTRL4_P_IN_SEL_OPAMP1 | MXC_F_AFE_CTRL4_N_IN_SEL_OPAMP1), 
                ((0x1 << MXC_F_AFE_CTRL4_P_IN_SEL_OPAMP1_POS) |
                (0x1 << MXC_F_AFE_CTRL4_N_IN_SEL_OPAMP1_POS) |
                (0x1 << MXC_F_AFE_CTRL4_DAC_SEL_B_POS)));

            // Enable N and P channel inputs
            MXC_AFE->ctrl3 |= (MXC_F_AFE_CTRL3_EN_PCH_OPAMP1 | 
                MXC_F_AFE_CTRL3_EN_NCH_OPAMP1);

        break;
        case 2:
            // Enable DAC clock
            MXC_CLKMAN->clk_ctrl_16_dac2 = MXC_E_CLKMAN_CLK_SCALE_ENABLED;

            // Enable OPAMP
            MXC_AFE->ctrl5 &= ~MXC_F_AFE_CTRL5_OP_CMP2;

            // Set the positive and negative inputs
            MXC_SET_FIELD(&MXC_AFE->ctrl4, (MXC_F_AFE_CTRL4_DAC_SEL_C | 
                MXC_F_AFE_CTRL4_P_IN_SEL_OPAMP2 | MXC_F_AFE_CTRL4_N_IN_SEL_OPAMP2), 
                ((0x1 << MXC_F_AFE_CTRL4_P_IN_SEL_OPAMP2_POS) |
                (0x1 << MXC_F_AFE_CTRL4_N_IN_SEL_OPAMP2_POS) |
                (0x2 << MXC_F_AFE_CTRL4_DAC_SEL_C_POS)));

            // Enable N and P channel inputs
            MXC_AFE->ctrl3 |= (MXC_F_AFE_CTRL3_EN_PCH_OPAMP2 | 
                MXC_F_AFE_CTRL3_EN_NCH_OPAMP2);
        break;
        case 3:
            // Enable DAC clock
            MXC_CLKMAN->clk_ctrl_17_dac3 = MXC_E_CLKMAN_CLK_SCALE_ENABLED;

            // Enable OPAMP
            MXC_AFE->ctrl5 &= ~MXC_F_AFE_CTRL5_OP_CMP3;

            // Set the positive and negative inputs
            MXC_SET_FIELD(&MXC_AFE->ctrl4, (MXC_F_AFE_CTRL4_DAC_SEL_D | 
                MXC_F_AFE_CTRL4_P_IN_SEL_OPAMP3 | MXC_F_AFE_CTRL4_N_IN_SEL_OPAMP3), 
                ((0x1 << MXC_F_AFE_CTRL4_P_IN_SEL_OPAMP3_POS) |
                (0x1 << MXC_F_AFE_CTRL4_N_IN_SEL_OPAMP3_POS) |
                (0x3 << MXC_F_AFE_CTRL4_DAC_SEL_D_POS)));

            // Enable N and P channel inputs
            MXC_AFE->ctrl3 |= (MXC_F_AFE_CTRL3_EN_PCH_OPAMP3 | 
                MXC_F_AFE_CTRL3_EN_NCH_OPAMP3);
        break;
    }

    // Enable AFE power
    MXC_PWRMAN->pwr_rst_ctrl |= MXC_F_PWRMAN_PWR_RST_CTRL_AFE_POWERED;

    // Setup internal voltage references
    MXC_SET_FIELD(&MXC_AFE->ctrl1, (MXC_F_AFE_CTRL1_REF_DAC_VOLT_SEL | MXC_F_AFE_CTRL1_REF_ADC_VOLT_SEL), 
        (MXC_F_AFE_CTRL1_REF_ADC_POWERUP | MXC_F_AFE_CTRL1_REF_BLK_POWERUP |
        (MXC_E_AFE_REF_VOLT_SEL_1500 << MXC_F_AFE_CTRL1_REF_ADC_VOLT_SEL_POS)));

    // Disable interpolation
    obj->dac->ctrl0 &= MXC_F_DAC_CTRL0_INTERP_MODE;
}