void uart_init(uint8_t uart, __unused uint8_t interrupts) { /* no interrupts, only polling so far */ uart_reg_write(uart, IER, 0x00); if (uart == cons_get_uart()) { cons_init(); } else if (uart == sercomm_get_uart()) { sercomm_init(); uart_irq_enable(uart, UART_IRQ_RX_CHAR, 1); } else { return; } uart_reg_write(uart, AUTOBAUD_EN, 0x00); /* disable AUTOBAUD */ uart_reg_write(uart, EFR, 0x10); /* Enhanced Features Register */ /* no XON/XOFF flow control, ENHANCED_EN, no auto-RTS/CTS */ uart_reg_write(uart, EFR, (1 << 4)); /* enable Tx/Rx FIFO, Tx trigger at 56 spaces, Rx trigger at 60 chars */ //FIXME check those FIFO settings uart_reg_write(uart, IIR, FIFO_EN | RX_FIFO_CLEAR | TX_FIFO_CLEAR | (3 << TX_FIFO_TRIG_SHIFT) | (1 << RX_FIFO_TRIG_SHIFT)); /* RBR interrupt only when TX FIFO and TX shift register are empty */ uart_reg_write(uart, SCR, (1 << 0));// | (1 << 3)); /* 8 bit, 1 stop bit, no parity, no break */ uart_reg_write(uart, LCR, 0x03); uart_set_lcr7bit(uart, 0); }
int main(void) { board_init(0); sercomm_uart = sercomm_get_uart(); /* Initialize HDLC subsystem */ sercomm_init(); /* Say hi */ // puts("\n\nOsmocomBB Loader (revision " GIT_REVISION ")\n"); puts("\n\nOsmocomBB Loader\n"); puts(hr); /* Identify environment */ printf("\nRunning on %s in environment %s\n", manifest_board, manifest_environment); printf("\nHW_CODE = 0x%04x", readw(MTK_CONFG_HW_CODE)); /* Set up loader communications */ sercomm_register_rx_cb(SC_DLCI_LOADER, &cmd_handler); /* Wait for events */ while (1) { uart_poll(sercomm_uart); } }
void uart_init(uint8_t uart, uint8_t interrupts) { uint8_t irq = uart2irq[uart]; uart_reg_write(uart, IER, 0x00); if (uart == cons_get_uart()) { cons_init(); if(interrupts) { irq_register_handler(irq, &uart_irq_handler_cons); irq_config(irq, 0, 0, 0xff); irq_enable(irq); } } else if (uart == sercomm_get_uart()) { sercomm_init(); if(interrupts) { irq_register_handler(irq, &uart_irq_handler_sercomm); irq_config(irq, 0, 0, 0xff); irq_enable(irq); } uart_irq_enable(uart, UART_IRQ_RX_CHAR, 1); } else { return; } #if 0 if (uart == 1) { /* assign UART to MCU and unmask interrupts*/ writeb(UART_REG_UIR, 0x00); } #endif /* if we don't initialize these, we get strange corruptions in the received data... :-( */ uart_reg_write(uart, MDR1, 0x07); /* turn off UART */ uart_reg_write(uart, XON1, 0x00); /* Xon1/Addr Register */ uart_reg_write(uart, XON2, 0x00); /* Xon2/Addr Register */ uart_reg_write(uart, XOFF1, 0x00); /* Xoff1 Register */ uart_reg_write(uart, XOFF2, 0x00); /* Xoff2 Register */ uart_reg_write(uart, EFR, 0x00); /* Enhanced Features Register */ /* select UART mode */ uart_reg_write(uart, MDR1, 0); /* no XON/XOFF flow control, ENHANCED_EN, no auto-RTS/CTS */ uart_reg_write(uart, EFR, (1 << 4)); /* enable Tx/Rx FIFO, Tx trigger at 56 spaces, Rx trigger at 60 chars */ uart_reg_write(uart, FCR, FIFO_EN | RX_FIFO_CLEAR | TX_FIFO_CLEAR | (3 << TX_FIFO_TRIG_SHIFT) | (3 << RX_FIFO_TRIG_SHIFT)); /* THR interrupt only when TX FIFO and TX shift register are empty */ uart_reg_write(uart, SCR, (1 << 0));// | (1 << 3)); /* 8 bit, 1 stop bit, no parity, no break */ uart_reg_write(uart, LCR, 0x03); uart_set_lcr7bit(uart, 0); }
static void uart_irq_handler_sercomm(__unused enum irq_nr irqnr) { const uint8_t uart = sercomm_get_uart(); uint8_t iir, ch; //uart_putchar_nb(uart, 'U'); iir = uart_reg_read(uart, IIR); if (iir & IIR_INT_PENDING) return; switch (iir & IIR_INT_TYPE) { case IIR_INT_TYPE_RX_TIMEOUT: case IIR_INT_TYPE_RHR: /* as long as we have rx data available */ while (uart_getchar_nb(uart, &ch)) { if (sercomm_drv_rx_char(ch) < 0) { /* sercomm cannot receive more data right now */ uart_irq_enable(uart, UART_IRQ_RX_CHAR, 0); } } break; case IIR_INT_TYPE_THR: /* as long as we have space in the FIFO */ while (!uart_tx_busy(uart)) { /* get a byte from sercomm */ if (!sercomm_drv_pull(&ch)) { /* no more bytes in sercomm, stop TX interrupts */ uart_irq_enable(uart, UART_IRQ_TX_EMPTY, 0); break; } /* write the byte into the TX FIFO */ uart_putchar_nb(uart, ch); } break; case IIR_INT_TYPE_MSR: printf("UART IRQ MSR\n"); break; case IIR_INT_TYPE_RX_STATUS_ERROR: printf("UART IRQ RX_SE\n"); break; case IIR_INT_TYPE_XOFF: printf("UART IRQXOFF\n"); break; } }
int main(void) { /* Simulate a compal loader saying "ACK" */ unsigned i = 0; for (i = 0; i < sizeof(phone_ack); i++) { putchar_asm(phone_ack[i]); } /* initialize board without interrupts */ board_init(0); sercomm_uart = sercomm_get_uart(); /* Say hi */ puts("\n\nOsmocomBB Loader (revision " GIT_REVISION ")\n"); puts(hr); fb_clear(); fb_setfg(FB_COLOR_BLACK); fb_setbg(FB_COLOR_WHITE); fb_setfont(FB_FONT_HELVB14); fb_gotoxy(2,20); fb_putstr("loader",framebuffer->width-4); fb_setfg(FB_COLOR_RED); fb_setbg(FB_COLOR_BLUE); fb_gotoxy(2,25); fb_boxto(framebuffer->width-3,38); fb_setfg(FB_COLOR_WHITE); fb_setfont(FB_FONT_HELVR08); fb_gotoxy(8,33); fb_putstr("osmocom-bb",framebuffer->width-4); fb_flush(); /* Identify environment */ printf("Running on %s in environment %s\n", manifest_board, manifest_environment); /* Initialize flash driver */ if (flash_init(&the_flash, 0)) { puts("Failed to initialize flash!\n"); } else { printf("Found flash of %zu bytes at 0x%p with %zu regions\n", the_flash.f_size, the_flash.f_base, the_flash.f_nregions); for (i = 0; i < the_flash.f_nregions; i++) { printf(" Region %d of %zu pages with %zu bytes each.\n", i, the_flash.f_regions[i].fr_bnum, the_flash.f_regions[i].fr_bsize); } } /* Set up a key handler for powering off */ keypad_set_handler(&key_handler); /* Set up loader communications */ sercomm_register_rx_cb(SC_DLCI_LOADER, &cmd_handler); /* Notify any running osmoload about our startup */ loader_send_init(SC_DLCI_LOADER); /* Wait for events */ while (1) { keypad_poll(); uart_poll(sercomm_uart); } /* NOT REACHED */ twl3025_power_off(); }