コード例 #1
0
/* This clears the reset bit to enable monitoring immediately if monitoring
   recording sources or always if playback is in progress - we might be 
   switching samplerates on the fly */
void pcm_dma_apply_settings(void)
{
    int level = set_irq_level(DMA_IRQ_LEVEL);

    /* remember table entry */
    freq_ent = pcm_freq_parms[pcm_fsel];
 
    /* Reprogramming bits 15-12 requires FIFO to be in a reset
       condition - Users Manual 17-8, Note 11 */
    or_l(IIS_FIFO_RESET, &IIS_PLAY);
    /* Important for TLV320 - this must happen in the correct order
       or starting recording will sound absolutely awful once in
       awhile - audiohw_set_frequency then coldfire_set_pllcr_audio_bits
     */
    IIS_PLAY = IIS_PLAY_DEFPARM | IIS_FIFO_RESET;
    restore_irq(level);

    audiohw_set_frequency(pcm_fsel);
    coldfire_set_pllcr_audio_bits(PLLCR_SET_AUDIO_BITS_DEFPARM);

    level = set_irq_level(DMA_IRQ_LEVEL);

    IIS_PLAY = IIS_PLAY_DEFPARM;

    if ((DCR0 & DMA_EEXT) != 0 && is_playback_monitoring())
        PDOR3 = 0; /* Kick FIFO out of reset by writing to it */

    restore_irq(level);
} /* pcm_dma_apply_settings */
コード例 #2
0
void _backlight_set_brightness(int val)
{
    int oldlevel;

    if (current_dim < val)
    {
        do
        {
            oldlevel = disable_irq_save();
            GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
            udelay(10);
            GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
            restore_irq(oldlevel);
            udelay(10);
        }
        while (++current_dim < val);
    }
    else if (current_dim > val)
    {
        do
        {
            oldlevel = disable_irq_save();
            GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
            udelay(200);
            GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
            restore_irq(oldlevel);
            udelay(10);
        }
        while (--current_dim > val);
    }
    brightness = val;
}
コード例 #3
0
ファイル: thread-sdl.c プロジェクト: a-martinez/rockbox
void remove_thread(unsigned int thread_id)
#endif
{
    struct thread_entry *current = cores[CURRENT_CORE].running;
    struct thread_entry *thread = thread_id_entry(thread_id);

    SDL_Thread *t;
    SDL_sem *s;

    if (thread_id != THREAD_ID_CURRENT && thread->id != thread_id)
        return;

    int oldlevel = disable_irq_save();

    t = thread->context.t;
    s = thread->context.s;
    thread->context.t = NULL;

    if (thread != current)
    {
        switch (thread->state)
        {
        case STATE_BLOCKED:
        case STATE_BLOCKED_W_TMO:
            /* Remove thread from object it's waiting on */
            remove_from_list_l(thread->bqp, thread);

#ifdef HAVE_WAKEUP_EXT_CB
            if (thread->wakeup_ext_cb != NULL)
                thread->wakeup_ext_cb(thread);
#endif
            break;
        }

        SDL_SemPost(s);
    }

    THREAD_SDL_DEBUGF("Removing thread: %d (%s)\n",
        thread - threads, THREAD_SDL_GET_NAME(thread));

    new_thread_id(thread->id, thread);
    thread->state = STATE_KILLED;
    thread_queue_wake(&thread->queue);

    SDL_DestroySemaphore(s);

    if (thread == current)
    {
        /* Do a graceful exit - perform the longjmp back into the thread
           function to return */
        restore_irq(oldlevel);
        longjmp(thread_jmpbufs[current - threads], 1);
    }

    SDL_KillThread(t);
    restore_irq(oldlevel);
}
コード例 #4
0
ファイル: usb-s3c6400x.c プロジェクト: richq/rockbox
static void ep_transfer(int ep, void *ptr, int len, bool out)
{
    /* disable interrupts to avoid any race */
    int oldlevel = disable_irq_save();

    struct ep_type *endpoint = &endpoints[ep][out ? DIR_OUT : DIR_IN];
    endpoint->busy   = true;
    endpoint->size   = len;
    endpoint->status = -1;

    if (out)
        DEPCTL(ep, out) &= ~DEPCTL_stall;

    int mps = usb_drv_port_speed() ? 512 : 64;
    int nb_packets = (len + mps - 1) / mps;
    if (nb_packets == 0)
        nb_packets = 1;

    DEPDMA(ep, out) = len ? (void*)PHYSICAL_ADDR(ptr) : NULL;
    DEPTSIZ(ep, out) = (nb_packets << DEPTSIZ_pkcnt_bitp) | len;
    if(out)
        discard_dcache_range(ptr, len);
    else
        commit_dcache_range(ptr, len);

    logf("pkt=%d dma=%lx", nb_packets, DEPDMA(ep, out));

//    if (!out) while (((GNPTXSTS & 0xffff) << 2) < MIN(mps, length));

    DEPCTL(ep, out) |= DEPCTL_epena | DEPCTL_cnak;

    restore_irq(oldlevel);
}
コード例 #5
0
static void iis_play_reset_if_playback(bool if_playback)
{
    int level = set_irq_level(DMA_IRQ_LEVEL);
    if (is_playback_monitoring() == if_playback)
        iis_play_reset();
    restore_irq(level);
}
コード例 #6
0
ファイル: button-gigabeat-s.c プロジェクト: 4nykey/rockbox
/* Scan the keypad port and return the pressed buttons */
static int kpp_scan(void)
{
    static const struct key_mask_shift
    {
        uint8_t mask;
        uint8_t shift;
    } kms[3] =
    {
        { 0x1f, 0 }, /* BUTTON_LEFT...BUTTON_SELECT */
        { 0x03, 5 }, /* BUTTON_BACK...BUTTON_MENU   */
        { 0x1f, 7 }, /* BUTTON_VOL_UP...BUTTON_NEXT */
    };

    int button = BUTTON_NONE;
    int oldlevel = disable_irq_save();
    int col;

    for (col = 0; col < 3; col++) /* Col */
    {
        /* 2. Write 1s to KPDR[10:8] setting column data to 1s */
        KPP_KPDR |= (0x7 << 8);

        /* 3. Configure columns as totem pole outputs(for quick
         * discharging of keypad capacitance) */
        KPP_KPCR &= ~(0x7 << 8);

        /* Give the columns time to discharge */
        udelay(2);

        /* 4. Configure columns as open-drain */
        KPP_KPCR |= (0x7 << 8);

        /* 5. Write a single column to 0, others to 1.
         * 6. Sample row inputs and save data. Multiple key presses
         *    can be detected on a single column.
         * 7. Repeat steps 2 - 6 for remaining columns. */

        /* Col bit starts at 8th bit in KPDR */
        KPP_KPDR &= ~(0x100 << col);

        /* Delay added to avoid propagating the 0 from column to row
         * when scanning. */
        udelay(2);

        /* Read row input */
        button |= (~KPP_KPDR & kms[col].mask) << kms[col].shift;
    }

    /* 8. Return all columns to 0 in preparation for standby mode. */
    KPP_KPDR &= ~(0x7 << 8);

    /* 9. Clear KPKD and KPKR status bit(s) by writing to a .1.,
     *    set the KPKR synchronizer chain by writing "1" to KRSS register,
     *    clear the KPKD synchronizer chain by writing "1" to KDSC register */
    KPP_KPSR = KPP_KPSR_KRSS | KPP_KPSR_KDSC | KPP_KPSR_KPKR | KPP_KPSR_KPKD;

    restore_irq(oldlevel);

    return button;
}
コード例 #7
0
/* Up the semaphore's count and release any thread waiting at the head of the
 * queue. The count is saturated to the value of the 'max' parameter specified
 * in 'semaphore_init'. */
void semaphore_release(struct semaphore *s)
{
    unsigned int result = THREAD_NONE;

    int oldlevel = disable_irq_save();
    corelock_lock(&s->cl);

    struct thread_entry *thread = WQ_THREAD_FIRST(&s->queue);
    if(LIKELY(thread != NULL))
    {
        /* a thread was queued - wake it up and keep count at 0 */
        KERNEL_ASSERT(s->count == 0,
            "semaphore_release->threads queued but count=%d!\n", s->count);
        result = wakeup_thread(thread, WAKEUP_DEFAULT);
    }
    else
    {
        int count = s->count;
        if(count < s->max)
        {
            /* nothing waiting - up it */
            s->count = count + 1;
        }
    }

    corelock_unlock(&s->cl);
    restore_irq(oldlevel);

#if defined(HAVE_PRIORITY_SCHEDULING) && defined(is_thread_context)
    /* No thread switch if not thread context */
    if((result & THREAD_SWITCH) && is_thread_context())
        switch_thread();
#endif
    (void)result;
}
コード例 #8
0
bool ide_powered(void)
{
    int level = disable_irq_save();
    int value = pcf50606_read(0x3c);
    restore_irq(level);
    return (value & 0x07) != 0;
}
コード例 #9
0
int rtc_read_datetime(struct tm *tm)
{
    unsigned int i;
    int rc, oldlevel;
    unsigned char buf[7];

    oldlevel = disable_irq_save();

    if (get_pmu_type() == PCF50606)
        rc = pcf50606_read_multiple(PCF5060X_RTCSC, buf, sizeof(buf));
    else
        rc = pcf50635_read_multiple(PCF5063X_REG_RTCSC, buf, sizeof(buf));

    restore_irq(oldlevel);

    for (i = 0; i < sizeof(buf); i++)
        buf[i] = BCD2DEC(buf[i]);

    tm->tm_sec = buf[0];
    tm->tm_min = buf[1];
    tm->tm_hour = buf[2];
    tm->tm_wday = buf[3];
    tm->tm_mday = buf[4];
    tm->tm_mon = buf[5] - 1;
    tm->tm_year = buf[6] + 100;

    return rc;
}
コード例 #10
0
void ide_power_enable(bool on)
{
    /* GPOOD3 */
    int level = disable_irq_save();
    pcf50606_write(0x3c, on ? 0x07 : 0x00);
    restore_irq(level);
}
コード例 #11
0
/* Enables queue_send on the specified queue - caller allocates the extra
 * data structure. Only queues which are taken to be owned by a thread should
 * enable this however an official owner is not compulsory but must be
 * specified for priority inheritance to operate.
 *
 * Use of queue_wait(_w_tmo) by multiple threads on a queue using synchronous
 * messages results in an undefined order of message replies or possible default
 * replies if two or more waits happen before a reply is done.
 */
void queue_enable_queue_send(struct event_queue *q,
                             struct queue_sender_list *send,
                             unsigned int owner_id)
{
    int oldlevel = disable_irq_save();
    corelock_lock(&q->cl);

    if(send != NULL && q->send == NULL)
    {
        memset(send, 0, sizeof(*send));
#ifdef HAVE_PRIORITY_SCHEDULING
        send->blocker.wakeup_protocol = wakeup_priority_protocol_release;
        send->blocker.priority = PRIORITY_IDLE;
        if(owner_id != 0)
        {
            send->blocker.thread = thread_id_entry(owner_id);
            q->blocker_p = &send->blocker;
        }
#endif
        q->send = send;
    }

    corelock_unlock(&q->cl);
    restore_irq(oldlevel);

    (void)owner_id;
}
コード例 #12
0
int tick_remove_task(void (*f)(void))
{
    int oldlevel = disable_irq_save();
    int rc = remove_array_ptr((void **)tick_funcs, f);
    restore_irq(oldlevel);
    return rc;
}
コード例 #13
0
int rtc_write_datetime(const struct tm *tm)
{
    unsigned int i;
    int rc, oldlevel;
    unsigned char buf[7];

    buf[0] = tm->tm_sec;
    buf[1] = tm->tm_min;
    buf[2] = tm->tm_hour;
    buf[3] = tm->tm_wday;
    buf[4] = tm->tm_mday;
    buf[5] = tm->tm_mon + 1;
    buf[6] = tm->tm_year - 100;

    for (i = 0; i < sizeof(buf); i++)
         buf[i] = DEC2BCD(buf[i]);

    oldlevel = disable_irq_save();

    if (get_pmu_type() == PCF50606)
        rc = pcf50606_write_multiple(PCF5060X_RTCSC, buf, sizeof(buf));
    else
        rc = pcf50635_write_multiple(PCF5063X_REG_RTCSC, buf, sizeof(buf));

    restore_irq(oldlevel);

    return rc;
}
コード例 #14
0
/* set brightness by changing the PWM */
void _backlight_set_brightness(int val)
{
    /* disable IRQs while bitbanging */
    int old_irq_level = disable_irq_save();
    pcf50606_write(0x35, (val << 1) | 0x01); /* 512Hz, Enable PWM */
    /* enable IRQs again */
    restore_irq(old_irq_level);
}
コード例 #15
0
void usb_drv_cancel_all_transfers(void)
{
    logf("usb_drv_cancel_all_transfers()\n");
    return;

    int flags = disable_irq_save();
    reset_endpoints(0);
    restore_irq(flags);
}
コード例 #16
0
ファイル: pcm-rk27xx.c プロジェクト: CoreDumpling/rockbox
/* Mask the DMA interrupt */
void pcm_play_lock(void)
{
    if (++locked == 1)
    {
        int old = disable_irq_save();
        INTC_IMR &= ~(1<<12); /* mask HDMA interrupt */ 
        restore_irq(old);
    }
}
コード例 #17
0
ファイル: pcm-rk27xx.c プロジェクト: CoreDumpling/rockbox
/* Unmask the DMA interrupt if enabled */
void pcm_play_unlock(void)
{
    if(--locked == 0)
    {
        int old = disable_irq_save();
        INTC_IMR |= (1<<12); /* unmask HDMA interrupt */
        restore_irq(old);
    }
}
コード例 #18
0
void _backlight_off(void)
{
    int level = disable_irq_save();
    pcf50606_write(0x38, 0x80); /* Backlight OFF, GPO1INV=1, GPO1ACT=000 */
    restore_irq(level);
#ifdef HAVE_LCD_ENABLE
    lcd_enable(false); /* power off visible display */
#endif
}
コード例 #19
0
void _backlight_on(void)
{
    int level;
#ifdef HAVE_LCD_ENABLE
    lcd_enable(true); /* power on lcd + visible display */
#endif
    level = disable_irq_save();
    pcf50606_write(0x38, 0xb0); /* Backlight ON, GPO1INV=1, GPO1ACT=011 */
    restore_irq(level);
}
コード例 #20
0
ファイル: si4700.c プロジェクト: kugel-/rockbox
/* tuner abstraction layer: read something from the tuner */
int si4700_get(int setting)
{
    int val = -1; /* default for unsupported query */

    if(!tuner_powered() && setting != RADIO_PRESENT)
        return -1;

    mutex_lock(&fmr_mutex);

    switch(setting)
    {
        case RADIO_PRESENT:
            val = tuner_present;
            break;

        case RADIO_TUNED:
            val = si4700_tuned();
            break;

        case RADIO_STEREO:
            val = si4700_st();
            break;
    
        case RADIO_RSSI:
            val = STATUSRSSI_RSSIr(si4700_read_reg(STATUSRSSI));
            break;

        case RADIO_RSSI_MIN:
            val = RSSI_MIN;
            break;

        case RADIO_RSSI_MAX:
            val = RSSI_MAX;
            break;
            
#ifdef HAVE_RDS_CAP
        case RADIO_EVENT:
        {
        #ifdef RDS_ISR_PROCESSING
            int oldlevel = disable_irq_save();
        #endif
            val = rds_event;
            rds_event = 0;
        #ifdef RDS_ISR_PROCESSING
            restore_irq(oldlevel);
        #endif
            break;
            }
#endif
    }

    mutex_unlock(&fmr_mutex);

    return val;
}
コード例 #21
0
unsigned short adc_scan(int channel)
{
    int level = disable_irq_save();
    unsigned char data = 0;
    int i;
    
    CS_LO;

    DI_HI;  /* Start bit */
    DELAY;
    CLK_HI;
    DELAY;
    CLK_LO;
    
    DI_HI;  /* Single channel */
    DELAY;
    CLK_HI;
    DELAY;
    CLK_LO;

    if(channel & 1) /* LSB of channel number */
        DI_HI;
    else
        DI_LO;
    DELAY;
    CLK_HI;
    DELAY;
    CLK_LO;
    
    if(channel & 2) /* MSB of channel number */
        DI_HI;
    else
        DI_LO;
    DELAY;
    CLK_HI;
    DELAY;
    CLK_LO;

    DELAY;

    for(i = 0;i < 8;i++) /* 8 bits of data */
    {
        CLK_HI;
        DELAY;
        CLK_LO;
        DELAY;
        data <<= 1;
        data |= DO?1:0;
    }

    CS_HI;

    restore_irq(level);
    return data;
}
コード例 #22
0
ファイル: button.c プロジェクト: 4nykey/rockbox
/*
 * set the flip attribute
 * better only call this when the queue is empty
 */
void button_set_flip(bool flip)
{
    if (flip != flipped) /* not the current setting */
    {
        /* avoid race condition with the button_tick() */
        int oldlevel = disable_irq_save();
        lastbtn = button_flip(lastbtn);
        flipped = flip;
        restore_irq(oldlevel);
    }
}
コード例 #23
0
void pcm_rec_unlock(void)
{
    int oldlevel = disable_irq_save();

    if (--rec_locked == 0 && is_recording)
    {
        VIC_INT_ENABLE = INTERRUPT_I2SIN;
        I2SIN_MASK = (1<<2); /* I2SIN_MASK_POAF */
    }

    restore_irq(oldlevel);
}
コード例 #24
0
/* Cancels a timeout callback - can be called from the ISR */
void timeout_cancel(struct timeout *tmo)
{
    int oldlevel = disable_irq_save();
    int rc = remove_array_ptr((void **)tmo_list, tmo);

    if(rc >= 0 && *tmo_list == NULL)
    {
        tick_remove_task(timeout_tick); /* Last one - remove task */
    }

    restore_irq(oldlevel);
}
コード例 #25
0
/* Down the semaphore's count or wait for 'timeout' ticks for it to go up if
 * it is already 0. 'timeout' as TIMEOUT_NOBLOCK (0) will not block and may
 * safely be used in an ISR. */
int semaphore_wait(struct semaphore *s, int timeout)
{
    int ret = OBJ_WAIT_TIMEDOUT;

    int oldlevel = disable_irq_save();
    corelock_lock(&s->cl);

    int count = s->count;
    if(LIKELY(count > 0))
    {
        /* count is not zero; down it */
        s->count = count - 1;
        ret = OBJ_WAIT_SUCCEEDED;
    }
    else if(timeout != 0)
    {
        ASSERT_CPU_MODE(CPU_MODE_THREAD_CONTEXT, oldlevel);

        /* too many waits - block until count is upped... */
        struct thread_entry *current = __running_self_entry();

        block_thread(current, timeout, &s->queue, NULL);
        corelock_unlock(&s->cl);

        /* ...and turn control over to next thread */
        switch_thread();

        /* if explicit wake indicated; do no more */
        if(LIKELY(!wait_queue_ptr(current)))
            return OBJ_WAIT_SUCCEEDED;

        disable_irq();
        corelock_lock(&s->cl);

        /* see if anyone got us after the expired wait */
        if(wait_queue_try_remove(current))
        {
            count = s->count;
            if(count > 0)
            {
                /* down it lately */
                s->count = count - 1;
                ret = OBJ_WAIT_SUCCEEDED;
            }
        }
    }
    /* else just polling it */

    corelock_unlock(&s->cl);
    restore_irq(oldlevel);

    return ret;
}
コード例 #26
0
ファイル: timer-jz4740.c プロジェクト: 4nykey/rockbox
bool timer_set(long cycles, bool start)
{
    unsigned int divider = cycles, prescaler_bit = 0, prescaler = 1, old_irq;

    if(cycles < 1)
        return false;

    if(start && pfn_unregister != NULL)
    {
        pfn_unregister();
        pfn_unregister = NULL;
    }

    /* Increase prescale values starting from 0 to make the cycle count fit */
    while(divider > 65535 && prescaler <= 1024)
    {
        prescaler <<= 2; /* 1, 4, 16, 64, 256, 1024 */
        prescaler_bit++;
        divider = cycles / prescaler;
    }

    old_irq = disable_irq_save();

    __tcu_stop_counter(1);
    if(start)
    {
        __tcu_disable_pwm_output(1);

        __tcu_mask_half_match_irq(1); 
        __tcu_unmask_full_match_irq(1);

        /* EXTAL clock = CFG_EXTAL (12Mhz in most targets) */
        __tcu_select_extalclk(1);
    }

    REG_TCU_TCSR(1) = (REG_TCU_TCSR(1) & ~TCU_TCSR_PRESCALE_MASK) | (prescaler_bit << TCU_TCSR_PRESCALE_BIT);
    REG_TCU_TCNT(1) = 0;
    REG_TCU_TDHR(1) = 0;
    REG_TCU_TDFR(1) = divider;

    __tcu_clear_full_match_flag(1);

    if(start)
    {
        system_enable_irq(IRQ_TCU1);
        __tcu_start_counter(1);
    }

    restore_irq(old_irq);

    return true;
}
コード例 #27
0
/* Unmask the DMA interrupt if enabled */
void pcm_play_unlock(void)
{
    if(--locked == 0 && is_playing)
    {
        int old = disable_irq_save();
        if(play_callback_pending)
        {
            play_callback_pending = false;
            dma_callback();
        }
        restore_irq(old);
    }
}
コード例 #28
0
void pcm_rec_lock(void)
{
    int oldlevel = disable_irq_save();

    if (++rec_locked == 1)
    {
        bitset32(&CGU_PERI, CGU_I2SIN_APB_CLOCK_ENABLE);
        VIC_INT_EN_CLEAR = INTERRUPT_I2SIN;
        I2SIN_MASK = 0; /* disables all interrupts */
    }

    restore_irq(oldlevel);
}
コード例 #29
0
void _backlight_off(void)
{
    if (get_pmu_type() == PCF50606)
    {
        GPIOA_CLEAR = (1<<6);
    }
    else
    {
        int level = disable_irq_save();
        pcf50635_write(PCF5063X_REG_LEDENA, 0);
        restore_irq(level);
    }
}
コード例 #30
0
void audio_set_output_source(int source)
{
    int level = set_irq_level(DMA_IRQ_LEVEL);
    unsigned long txsrc;

    if ((unsigned)source >= AUDIO_NUM_SOURCES)
        txsrc = (3 << 8); /* playback, PDOR3 */
    else
        txsrc = (4 << 8); /* recording, iis1RcvData */

    IIS1CONFIG = (IIS1CONFIG & ~(7 << 8)) | txsrc;
    restore_irq(level);
} /* audio_set_output_source */