void imx233_chip_reset(void) { #if IMX233_SUBTARGET >= 3700 HW_CLKCTRL_RESET = BM_CLKCTRL_RESET_CHIP; #else HW_POWER_RESET = BF_OR2(POWER_RESET, UNLOCK_V(KEY), RST_DIG(1)); #endif }
void imx233_lcdif_dma_send(void *buf, unsigned width, unsigned height) { #if IMX233_SUBTARGET >= 3780 imx233_lcdif_enable_bus_master(true); HW_LCDIF_CUR_BUF = (uint32_t)buf; HW_LCDIF_TRANSFER_COUNT = BF_OR2(LCDIF_TRANSFER_COUNT, V_COUNT(height), H_COUNT(width)); BF_SET(LCDIF_CTRL, DATA_SELECT); BF_SET(LCDIF_CTRL, RUN); #endif }
void imx233_pwm_setup(int channel, int period, int cdiv, int active, int active_state, int inactive, int inactive_state) { /* stop */ bool enable = imx233_pwm_is_enabled(channel); if(enable) imx233_pwm_enable(channel, false); /* setup pin */ imx233_pinctrl_setup_vpin(VPIN_PWM(channel), "pwm", PINCTRL_DRIVE_4mA, false); /* watch the order ! active THEN period * NOTE: the register value is period-1 */ HW_PWM_ACTIVEn(channel) = BF_OR2(PWM_ACTIVEn, ACTIVE(active), INACTIVE(inactive)); HW_PWM_PERIODn(channel) = BF_OR4(PWM_PERIODn, PERIOD(period - 1), ACTIVE_STATE(active_state), INACTIVE_STATE(inactive_state), CDIV(cdiv)); /* restore */ imx233_pwm_enable(channel, enable); }
// bbp = bytes per pixel static void pio_send(unsigned len, unsigned bpp, uint8_t *buf) { /* WARNING: the imx233 has a limitation on count wrt to byte packing, the * count must be a multiple of 2 with maximum packing when word-length is * 16-bit! * On the other hand, 8-bit word length doesn't seem to have any limitations, * for example one can send 3 bytes with a packing format of 0xf * WARNING for this function to work properly with any swizzle, we have to * make sure we pack as many 32-bits as possible even when the data is not * word-aligned */ imx233_lcdif_set_byte_packing_format(0xf); /* compute shift between buf and next word-aligned pointer */ int shift = 0; uint32_t temp_buf = 0; int count = len * bpp; // number of bytes while(0x3 & (intptr_t)buf) { temp_buf = temp_buf | *buf++ << shift; shift += 8; count--; } /* starting from now, all read are 32-bit */ uint32_t *wbuf = (void *)buf; #if IMX233_SUBTARGET >= 3780 HW_LCDIF_TRANSFER_COUNT = BF_OR2(LCDIF_TRANSFER_COUNT, V_COUNT(1), H_COUNT(len)); #else BF_WR(LCDIF_CTRL, COUNT, len); #endif BF_SET(LCDIF_CTRL, RUN); while(count > 0) { uint32_t val = *wbuf++; imx233_lcdif_wait_fifo(); HW_LCDIF_DATA = temp_buf | val << shift; if(shift != 0) temp_buf = val >> (32 - shift); count -= 4; } /* send remaining bytes if any */ if(shift != 0) { imx233_lcdif_wait_fifo(); HW_LCDIF_DATA = temp_buf; } imx233_lcdif_wait_ready(); }
void imx233_timrot_setup(unsigned timer_nr, bool reload, unsigned count, unsigned src, unsigned prescale, bool polarity, imx233_timer_fn_t fn) { int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); /* only enable interrupt if function is set */ bool irq = fn != NULL; timer_fns[timer_nr] = fn; /* make sure we start from stop state */ HW_TIMROT_TIMCTRLn(timer_nr) = BF_OR2(TIMROT_TIMCTRLn, SELECT(BV_TIMROT_TIMCTRLn_SELECT__NEVER_TICK), UPDATE(1)); /* write count and take effect immediately with UPDATE * manual says count-1 for reload timers */ HW_TIMROT_TIMCOUNTn(timer_nr) = reload ? count - 1 : count; /* start timer */ HW_TIMROT_TIMCTRLn(timer_nr) = BF_OR6(TIMROT_TIMCTRLn, SELECT(src), PRESCALE(prescale), POLARITY(polarity), RELOAD(reload), IRQ(irq), IRQ_EN(irq)); imx233_icoll_enable_interrupt(INT_SRC_TIMER(timer_nr), irq); restore_interrupt(oldstatus); }