bool hal_timer_pit_active_get(pitid_t pit_id) { // if bit two in the status register of the timer is 1, the timer is running switch (pit_id) { case IGNITION_DWELL_PIT: return (IORD32(A_TIMER_1, NIOS2_TIMER_STATUS) & 0x2) == 0x2; case IGNITION_FIRE_PIT: return (IORD32(A_TIMER_2, NIOS2_TIMER_STATUS) & 0x2) == 0x2; default: log_printf( "ERROR: invalid pit ID (%d) for hal_timer_pit_active_get\r\n", pit_id); break; } return false; }
void hal_timer_oc_output_set(channelid_t channel_id, ocmode_t mode) { uint32_t modeFlags = IORD32(A_SCCT, SCCT_CH_AS); switch (channel_id) { case INJECTION1_OUTPUT: hal_internal_calculate_mode_flags(2, mode, modeFlags) ; break; case INJECTION2_OUTPUT: hal_internal_calculate_mode_flags(3, mode, modeFlags) ; break; case INJECTION3_OUTPUT: hal_internal_calculate_mode_flags(4, mode, modeFlags) ; break; case INJECTION4_OUTPUT: hal_internal_calculate_mode_flags(5, mode, modeFlags) ; break; case INJECTION5_OUTPUT: hal_internal_calculate_mode_flags(6, mode, modeFlags) ; break; case INJECTION6_OUTPUT: hal_internal_calculate_mode_flags(7, mode, modeFlags) ; break; default: log_printf( "ERROR: invalid channel ID (%d) for hal_timer_oc_active_set\r\n", channel_id); break; } IOWR32(A_SCCT, SCCT_CH_AS, modeFlags); }
uint16_t hal_timer_pit_current_get(pitid_t pit_id) { /** * The NIOS2 PITs do not have a prescaler. The EMS code assumes all timers to * runn at 1.25MHz, so all scaling has to be done in software. */ switch (pit_id) { case IGNITION_DWELL_PIT: return (IORD32(A_TIMER_1, NIOS2_TIMER_SNAPL) / TIMER_0_PERIOD); case IGNITION_FIRE_PIT: return (IORD32(A_TIMER_2, NIOS2_TIMER_SNAPL) / TIMER_0_PERIOD); default: log_printf( "ERROR: invalid pit ID (%d) for hal_timer_pit_current_get\r\n", pit_id); break; } return -1; }
void hal_timer_pit_active_set(pitid_t pit_id, bool active) { // set bit two of the control register of the timer to start it, or // set bit three to stop it uint32_t bitToSet = active ? 0x4 : 0x8; switch (pit_id) { case IGNITION_DWELL_PIT: IOWR32(A_TIMER_1, NIOS2_TIMER_CONTROL, ((IORD32(A_TIMER_1, NIOS2_TIMER_CONTROL) & 0x3) | bitToSet)); break; case IGNITION_FIRE_PIT: IOWR32(A_TIMER_2, NIOS2_TIMER_CONTROL, ((IORD32(A_TIMER_2, NIOS2_TIMER_CONTROL) & 0x3) | bitToSet)); break; default: log_printf( "ERROR: invalid pit ID (%d) for hal_timer_pit_active_set\r\n", pit_id); break; } }
bool hal_timer_oc_active_get(channelid_t channel_id) { switch (channel_id) { case INJECTION1_OUTPUT: return IORD32(A_SCCT, SCCT_CH_IE) & SCCT_CH_BITS_1(2, 1); break; case INJECTION2_OUTPUT: return IORD32(A_SCCT, SCCT_CH_IE) & SCCT_CH_BITS_1(3, 1); break; case INJECTION3_OUTPUT: return IORD32(A_SCCT, SCCT_CH_IE) & SCCT_CH_BITS_1(4, 1); break; case INJECTION4_OUTPUT: return IORD32(A_SCCT, SCCT_CH_IE) & SCCT_CH_BITS_1(5, 1); break; case INJECTION5_OUTPUT: return IORD32(A_SCCT, SCCT_CH_IE) & SCCT_CH_BITS_1(6, 1); break; case INJECTION6_OUTPUT: return IORD32(A_SCCT, SCCT_CH_IE) & SCCT_CH_BITS_1(7, 1); break; default: log_printf( "ERROR: invalid channel ID (%d) for hal_timer_oc_active_get\r\n", channel_id); break; } return false; }
void hal_timer_oc_active_set(channelid_t channel_id, bool active) { int32_t interruptEnableFlags = IORD32(A_SCCT, SCCT_CH_IE); int32_t newFlags = 0; switch (channel_id) { case INJECTION1_OUTPUT: newFlags = active ? interruptEnableFlags | SCCT_CH_BITS_1(2, 1) : interruptEnableFlags & ~SCCT_CH_BITS_1(2, 1); break; case INJECTION2_OUTPUT: newFlags = active ? interruptEnableFlags | SCCT_CH_BITS_1(3, 1) : interruptEnableFlags & ~SCCT_CH_BITS_1(3, 1); break; case INJECTION3_OUTPUT: newFlags = active ? interruptEnableFlags | SCCT_CH_BITS_1(4, 1) : interruptEnableFlags & ~SCCT_CH_BITS_1(4, 1); break; case INJECTION4_OUTPUT: newFlags = active ? interruptEnableFlags | SCCT_CH_BITS_1(5, 1) : interruptEnableFlags & ~SCCT_CH_BITS_1(5, 1); break; case INJECTION5_OUTPUT: newFlags = active ? interruptEnableFlags | SCCT_CH_BITS_1(6, 1) : interruptEnableFlags & ~SCCT_CH_BITS_1(6, 1); break; case INJECTION6_OUTPUT: newFlags = active ? interruptEnableFlags | SCCT_CH_BITS_1(7, 1) : interruptEnableFlags & ~SCCT_CH_BITS_1(7, 1); break; default: log_printf( "ERROR: invalid channel ID (%d) for hal_timer_oc_active_set\r\n", channel_id); break; } IOWR32(A_SCCT, SCCT_CH_IE, newFlags); }
int32_t uart_puts(char *p) { uint32_t ctr = 0; if (p == NULL) { return -1; } do { // need to wait until UART gets ready to transmit if (IORD32(A_UART, UART_ST) & UART_ST_TRDY) { IOWR8(A_UART, UART_TX, *p); ++p; ++ctr; } } while (*p); return ctr; }
/* * inits all omap h/w */ uint32_t cy_as_hal_processor_hw_init(cy_as_omap_dev_kernel *dev_p) { int i, err; cy_as_hal_print_message(KERN_INFO "init OMAP3430 hw...\n"); iomux_vma = (u32)ioremap_nocache( (u32)CTLPADCONF_BASE_ADDR, CTLPADCONF_SIZE); cy_as_hal_print_message(KERN_INFO "PADCONF_VMA=%x val=%x\n", iomux_vma, IORD32(iomux_vma)); /* * remap gpio banks */ for (i = 0; i < 6; i++) { gpio_vma_tab[i].virt_addr = (u32)ioremap_nocache( gpio_vma_tab[i].phy_addr, gpio_vma_tab[i].size); cy_as_hal_print_message(KERN_INFO "%s virt_addr=%x\n", gpio_vma_tab[i].name, (u32)gpio_vma_tab[i].virt_addr); }; /* * force OMAP_GPIO_126 to rleased state, * will be configured to drive reset */ gpio_free(AST_RESET); /* *same thing with AStoria CS pin */ gpio_free(AST_CS); /* * initialize all the OMAP pads connected to astoria */ cy_as_hal_init_user_pads(user_pad_cfg); err = cy_as_hal_gpmc_init(dev_p); cy_as_hal_config_c_s_mux(); return err; }
pinstate_t hal_timer_oc_pin_get(channelid_t channel_id) { switch (channel_id) { case INJECTION1_OUTPUT: if (IORD32(A_SCCT, SCCT_CH_OUT) & SCCT_CH_BITS_1(2, 1)) { return HIGH; } else { return LOW; } case INJECTION2_OUTPUT: if (IORD32(A_SCCT, SCCT_CH_OUT) & SCCT_CH_BITS_1(3, 1)) { return HIGH; } else { return LOW; } case INJECTION3_OUTPUT: if (IORD32(A_SCCT, SCCT_CH_OUT) & SCCT_CH_BITS_1(4, 1)) { return HIGH; } else { return LOW; } case INJECTION4_OUTPUT: if (IORD32(A_SCCT, SCCT_CH_OUT) & SCCT_CH_BITS_1(5, 1)) { return HIGH; } else { return LOW; } case INJECTION5_OUTPUT: if (IORD32(A_SCCT, SCCT_CH_OUT) & SCCT_CH_BITS_1(6, 1)) { return HIGH; } else { return LOW; } case INJECTION6_OUTPUT: if (IORD32(A_SCCT, SCCT_CH_OUT) & SCCT_CH_BITS_1(7, 1)) { return HIGH; } else { return LOW; } default: log_printf( "ERROR: invalid channel ID (%d) for hal_timer_oc_pin_get\r\n", channel_id); break; } return LOW; }
/** * @author Andreas Meixner * @brief The one ISR NIOS calls * Whenever an interrupt is pending, NIOS2 will call this ISR. * This function will check which interrupts are pending and will call the * appropriate handler functions of FreeEMS. */ void do_irq() { uint32_t pending = __rdctl_ipending(); // if the flag for a pending timer event ist set if(pending & 0x40) { // see if timer 0 (RTC) is the interrupt source uint32_t timerFlag = IORD16(A_TIMER_0, NIOS2_TIMER_STATUS); //log_printf("t0F: %X\r\n", timerFlag); if((timerFlag & NIOS2_TIMER_STATUS_TO)) { // FreeEMS internaly keeps track of time. For this purpose it assumes the // hardware has a 16bit clock running at 1.25MHz, which generates a tick // interrupt on every tick, and an overflow interrupt everytime the 16bit // counter overflows (every 65536 ticks) NIOS2 has a 32 bit counter, so // the overflow has to be simulated, by generating the interrupt in the // software. check if the high word of the counter value has changed since // the last tick, if so call TimerOverfolw() uint16_t currentTickHighWord = IORD16(A_TIMER_0, NIOS2_TIMER_SNAPH); if(currentTickHighWord != lastTickHighWord) { lastTickHighWord = currentTickHighWord; TimerOverflow(); } // advance the internal RTC RTIISR(); // clear the flag IOWR16(A_TIMER_0, NIOS2_TIMER_STATUS, timerFlag & ~NIOS2_TIMER_STATUS_TO); } // see if Timer_1 (ignition dwell) is the interrupt source timerFlag = IORD16(A_TIMER_1, NIOS2_TIMER_STATUS); if((timerFlag & NIOS2_TIMER_STATUS_TO)) { IgnitionDwellISR(); // clear the flag IOWR16(A_TIMER_1, NIOS2_TIMER_STATUS, timerFlag & ~(NIOS2_TIMER_STATUS_TO)); } // see if Timer_2 (ignition fire) is the interrupt source timerFlag = IORD16(A_TIMER_2, NIOS2_TIMER_STATUS); if((timerFlag & NIOS2_TIMER_STATUS_TO)) { IgnitionFireISR(); IOWR16(A_TIMER_2, NIOS2_TIMER_STATUS, timerFlag & ~(NIOS2_TIMER_STATUS_TO)); } } // if the flag for a pending SCCT timer event is set if(pending & 0x400) { // external interrupt (SCCT) // see if the oc channel 0 (scct) was the interrupt source uint32_t isFlags = IORD32(A_SCCT, SCCT_CH_IS); // if IC channel 0 has a pending interrupt, call PrimaryRPMISR if(isFlags & SCCT_CH_BITS_1(0,1)) { // clear interrupt flags IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(0,1)); PrimaryRPMISR(); } // if IC channel 1 has a pending interrupt, call SecondaryRPMISR if(isFlags & SCCT_CH_BITS_1(1,1)) { // clear interrupt flags IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(1,1)); SecondaryRPMISR(); } // if OC channel 2 has a pending interrupt, call Injector1ISR if(isFlags & SCCT_CH_BITS_1(2,1)) { // clear interrupt flags IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(2,1)); Injector1ISR(); } // if OC channel 3 has a pending interrupt, call Injector2ISR if(isFlags & SCCT_CH_BITS_1(3,1)) { // clear interrupt flags IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(3,1)); Injector2ISR(); } // if OC channel 4 has a pending interrupt, call Injector3ISR if(isFlags & SCCT_CH_BITS_1(4,1)) { // clear interrupt flags IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(4,1)); Injector3ISR(); } // if OC channel 5 has a pending interrupt, call Injector4ISR if(isFlags & SCCT_CH_BITS_1(5,1)) { // clear interrupt flags IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(5,1)); Injector4ISR(); } // if OC channel 6 has a pending interrupt, call Injector5ISR if(isFlags & SCCT_CH_BITS_1(6,1)) { // clear interrupt flags IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(6,1)); Injector5ISR(); } // if OC channel 7 has a pending interrupt, call Injector6ISR if(isFlags & SCCT_CH_BITS_1(7,1)) { // clear interrupt flags IOWR32(A_SCCT, SCCT_CH_IS, SCCT_CH_BITS_1(7,1)); Injector6ISR(); } } }
uint32_t timer_getsnap(void) { IOWR16(A_TIMER, NIOS2_TIMER_SNAPL, 1); return IORD32(A_TIMER, NIOS2_TIMER_SNAPL); }
int32_t uart_read_byte(void){ char b = -1; while ( !(IORD32(A_UART, UART_ST) & UART_ST_RRDY) ); b = IORD8(A_UART, UART_RX); return (int32_t)b; }
void uart_write_byte(char b){ while ( !(IORD32(A_UART, UART_ST) & UART_ST_TRDY) ); IOWR8(A_UART, UART_TX, b); }
int32_t uart_putchar(int32_t c) { char vc = (char) (c & 0xff); while ( !(IORD32(A_UART, UART_ST) & UART_ST_TRDY) ); IOWR8(A_UART, UART_TX, vc); return (int32_t) vc; }
pinstate_t hal_io_get(channelid_t channel_id) { pinstate_t retVal = LOW; switch (channel_id) { case IGNITION1_OUTPUT: retVal = (IORD32(A_PIO_IGN, 0) & 0x1) ? HIGH : LOW; break; case IGNITION2_OUTPUT: retVal = (IORD32(A_PIO_IGN, 0) & 0x2) ? HIGH : LOW; break; case IGNITION3_OUTPUT: retVal = (IORD32(A_PIO_IGN, 0) & 0x4) ? HIGH : LOW; break; case IGNITION4_OUTPUT: retVal = (IORD32(A_PIO_IGN, 0) & 0x8) ? HIGH : LOW; break; case IGNITION5_OUTPUT: retVal = (IORD32(A_PIO_IGN, 0) & 0x10) ? HIGH : LOW; break; case IGNITION6_OUTPUT: retVal = (IORD32(A_PIO_IGN, 0) & 0x20) ? HIGH : LOW; break; case IGNITION7_OUTPUT: retVal = (IORD32(A_PIO_IGN, 0) & 0x40) ? HIGH : LOW; break; case IGNITION8_OUTPUT: retVal = (IORD32(A_PIO_IGN, 0) & 0x80) ? HIGH : LOW; break; case DEBUG_OUTPUT_1: retVal = (IORD32(A_PIO_IGN, 0) & 0x100) ? HIGH : LOW; break; case DEBUG_OUTPUT_2: retVal = (IORD32(A_PIO_IGN, 0) & 0x200) ? HIGH : LOW; break; case DEBUG_OUTPUT_3: retVal = (IORD32(A_PIO_IGN, 0) & 0x400) ? HIGH : LOW; break; case DEBUG_OUTPUT_4: retVal = (IORD32(A_PIO_IGN, 0) & 0x800) ? HIGH : LOW; break; case DEBUG_OUTPUT_5: retVal = (IORD32(A_PIO_IGN, 0) & 0x1000) ? HIGH : LOW; break; case DEBUG_OUTPUT_6: retVal = (IORD32(A_PIO_IGN, 0) & 0x2000) ? HIGH : LOW; break; case DEBUG_OUTPUT_7: retVal = (IORD32(A_PIO_IGN, 0) & 0x4000) ? HIGH : LOW; break; case DEBUG_OUTPUT_8: retVal = (IORD32(A_PIO_IGN, 0) & 0x8000) ? HIGH : LOW; break; default: log_printf("ERROR: invalid channel ID (%d) for hal_io_get\r\n", channel_id); break; } return false; }
void hal_io_set(channelid_t channel_id, pinstate_t value) { uint32_t registerValue = IORD32(A_PIO_IGN, 0); switch (channel_id) { case IGNITION1_OUTPUT: if (value == HIGH) { registerValue = registerValue | 0x1; } else { registerValue = registerValue & (~0x1); } break; case IGNITION2_OUTPUT: if (value == HIGH) { registerValue = registerValue | 0x2; } else { registerValue = registerValue & (~0x2); } break; case IGNITION3_OUTPUT: if (value == HIGH) { registerValue = registerValue | 0x4; } else { registerValue = registerValue & (~0x4); } break; case IGNITION4_OUTPUT: if (value == HIGH) { registerValue = registerValue | 0x8; } else { registerValue = registerValue & (~0x8); } break; case IGNITION5_OUTPUT: if (value == HIGH) { registerValue = registerValue | 0x10; } else { registerValue = registerValue & (~0x10); } break; case IGNITION6_OUTPUT: if (value == HIGH) { registerValue = registerValue | 0x20; } else { registerValue = registerValue & (~0x20); } break; case IGNITION7_OUTPUT: if (value == HIGH) { registerValue = registerValue | 0x40; } else { registerValue = registerValue & (~0x40); } break; case IGNITION8_OUTPUT: if (value == HIGH) { registerValue = registerValue | 0x80; } else { registerValue = registerValue & (~0x80); } break; case DEBUG_OUTPUT_1: if (value == HIGH) { registerValue = registerValue | 0x100; } else { registerValue = registerValue & (~0x100); } break; case DEBUG_OUTPUT_2: if (value == HIGH) { registerValue = registerValue | 0x200; } else { registerValue = registerValue & (~0x200); } break; case DEBUG_OUTPUT_3: if (value == HIGH) { registerValue = registerValue | 0x400; } else { registerValue = registerValue & (~0x400); } break; case DEBUG_OUTPUT_4: if (value == HIGH) { registerValue = registerValue | 0x800; } else { registerValue = registerValue & (~0x800); } break; case DEBUG_OUTPUT_5: if (value == HIGH) { registerValue = registerValue | 0x1000; } else { registerValue = registerValue & (~0x1000); } break; case DEBUG_OUTPUT_6: if (value == HIGH) { registerValue = registerValue | 0x2000; } else { registerValue = registerValue & (~0x2000); } break; case DEBUG_OUTPUT_7: if (value == HIGH) { registerValue = registerValue | 0x4000; } else { registerValue = registerValue & (~0x4000); } break; case DEBUG_OUTPUT_8: if (value == HIGH) { registerValue = registerValue | 0x8000; } else { registerValue = registerValue & (~0x8000); } break; default: log_printf("ERROR: invalid channel ID (%d) for hal_io_set\r\n", channel_id); break; } }
uint32_t cy_as_hal_gpmc_init(cy_as_omap_dev_kernel *dev_p) { u32 tmp32; int err; struct gpmc_timings timings; unsigned int cs_mem_base; unsigned int cs_vma_base; /* * get GPMC i/o registers base(already been i/o mapped * in kernel, no need for separate i/o remap) */ cy_as_hal_print_message(KERN_INFO "%s: mapping phys_to_virt\n", __func__); gpmc_base = (u32)ioremap_nocache(OMAP34XX_GPMC_BASE, SZ_16K); cy_as_hal_print_message(KERN_INFO "kernel has gpmc_base=%x , val@ the base=%x", gpmc_base, __raw_readl(gpmc_base) ); cy_as_hal_print_message(KERN_INFO "%s: calling gpmc_cs_request\n", __func__); /* * request GPMC CS for ASTORIA request */ if (gpmc_cs_request(AST_GPMC_CS, SZ_16M, (void *)&cs_mem_base) < 0) { cy_as_hal_print_message(KERN_ERR "error failed to request" "ncs4 for ASTORIA\n"); return -1; } else { cy_as_hal_print_message(KERN_INFO "got phy_addr:%x for " "GPMC CS%d GPMC_CFGREG7[CS4]\n", cs_mem_base, AST_GPMC_CS); } cy_as_hal_print_message(KERN_INFO "%s: calling request_mem_region\n", __func__); /* * request VM region for 4K addr space for chip select 4 phy address * technically we don't need it for NAND devices, but do it anyway * so that data read/write bus cycle can be triggered by reading * or writing this mem region */ if (!request_mem_region(cs_mem_base, SZ_16K, "AST_OMAP_HAL")) { err = -EBUSY; cy_as_hal_print_message(KERN_ERR "error MEM region " "request for phy_addr:%x failed\n", cs_mem_base); goto out_free_cs; } cy_as_hal_print_message(KERN_INFO "%s: calling ioremap_nocache\n", __func__); /* REMAP mem region associated with our CS */ cs_vma_base = (u32)ioremap_nocache(cs_mem_base, SZ_16K); if (!cs_vma_base) { err = -ENOMEM; cy_as_hal_print_message(KERN_ERR "error- ioremap()" "for phy_addr:%x failed", cs_mem_base); goto out_release_mem_region; } cy_as_hal_print_message(KERN_INFO "ioremap(%x) returned vma=%x\n", cs_mem_base, cs_vma_base); dev_p->m_phy_addr_base = (void *) cs_mem_base; dev_p->m_vma_addr_base = (void *) cs_vma_base; memset(&timings, 0, sizeof(timings)); /* cs timing */ timings.cs_on = WB_GPMC_CS_t_on; timings.cs_wr_off = WB_GPMC_BUSCYC_t; timings.cs_rd_off = WB_GPMC_BUSCYC_t; /* adv timing */ timings.adv_on = WB_GPMC_ADV_t_on; timings.adv_rd_off = WB_GPMC_ADV_t_off; timings.adv_wr_off = WB_GPMC_ADV_t_off; /* oe timing */ timings.oe_on = WB_GPMC_OE_t_on; timings.oe_off = WB_GPMC_OE_t_off; timings.access = WB_GPMC_RD_t_a_c_c; timings.rd_cycle = WB_GPMC_BUSCYC_t; /* we timing */ timings.we_on = WB_GPMC_WE_t_on; timings.we_off = WB_GPMC_WE_t_off; timings.wr_access = WB_GPMC_WR_t_a_c_c; timings.wr_cycle = WB_GPMC_BUSCYC_t; timings.page_burst_access = WB_GPMC_BUSCYC_t; timings.wr_data_mux_bus = WB_GPMC_BUSCYC_t; gpmc_cs_set_timings(AST_GPMC_CS, &timings); /* * by default configure GPMC into 8 bit mode * (to match astoria default mode) */ gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG1, (GPMC_CONFIG1_DEVICETYPE(0) | GPMC_CONFIG1_DEVICESIZE_16 | 0x10 //twhs )); /* * No method currently exists to write this register through GPMC APIs * need to change WAIT2 polarity */ tmp32 = IORD32(GPMC_VMA(GPMC_CONFIG_REG)); tmp32 = tmp32 | NAND_FORCE_POSTED_WRITE_B | 0x40; IOWR32(GPMC_VMA(GPMC_CONFIG_REG), tmp32); tmp32 = IORD32(GPMC_VMA(GPMC_CONFIG_REG)); cy_as_hal_print_message("GPMC_CONFIG_REG=0x%x\n", tmp32); cy_as_hal_print_omap_regs("GPMC_CONFIG", 1, GPMC_VMA(GPMC_CFG_REG(1, AST_GPMC_CS)), 7); return 0; out_release_mem_region: release_mem_region(cs_mem_base, SZ_16K); out_free_cs: gpmc_cs_free(AST_GPMC_CS); return err; }