#include #include #include #include #include void uart_putchar(char c); static inline void enable_input_fifo(void) { } static inline void disable_input_fifo(void) { } static inline void init_pio(void) { // Control mode - i.e. no parallel port communication port_b_ctrl = PIO_MODE_3; // A, B and five keys as inputs port_b_ctrl = 0x7F; // Load interrupt vector // port_b_ctrl = ISR_ADDRESS(port_b_isr_ptr); // Interrupt word - interrupt if any pin goes low, mask follows // port_b_ctrl = PIO_INT_CTRL(PIO_INT_EN | PIO_OR | PIO_LOW | PIO_MASK); // Mask - 0 means to check line // port_b_ctrl = 0x80; /* port_a_ctrl = PIO_MODE_3; */ /* port_a_ctrl = 0x7C; */ /* // Load interrupt vector */ /* port_a_ctrl = ISR_ADDRESS(port_a_isr_ptr); */ /* port_a_ctrl = PIO_INT_CTRL(PIO_INT_EN | PIO_OR | PIO_HIGH | PIO_MASK); */ /* port_a_ctrl = 0x83; */ /* // SDA and SCL high */ /* port_a_data = 0x03; */ } static inline void init_ctc(void) { /* 200Hz clock */ ctc_channel_1 = CTC_CTRL(CTC_INT_BIT | CTC_PRESCALER_BIT | CTC_TIME_CONST_BIT | CTC_RST_BIT); ctc_channel_1 = 0; /* 200Hz clock */ ctc_channel_2 = CTC_CTRL(CTC_INT_BIT | CTC_PRESCALER_BIT | CTC_TIME_CONST_BIT | CTC_RST_BIT); ctc_channel_2 = 0; /* ctc_channel_3 = (CPU_FREQ / 256 / 144); */ ctc_channel_3 = CTC_CTRL(CTC_INT_BIT | CTC_PRESCALER_BIT | CTC_TIME_CONST_BIT | CTC_RST_BIT); ctc_channel_3 = 0; // 256 // Interrupt table for CTC // Final address is (Ireg << 8) | ctc_isr_ptr | {00/01/10/11} | 0 ctc_channel_0 = ISR_ADDRESS(ctc0_isr_ptr); } static inline void init_sio(void) { static const u8 sio_a_cfg[] = { 0b00011000, // Reset channel 4 , // wr4 0b01000100, // X16 clock (115200), one stop bit, no parity 1 , // wr1 SIO_RX_INT_MD0 | SIO_RX_INT_MD1, // interrupt on every Rx, no wait function 3 , // wr3 0b11000001, // enable Rx - 8 bit char 5 , // wr5 0b01101000 // enable Tx - 8 bit char }; static const u8 sio_b_cfg[] = { 0b00011000, // Reset channel 2 , // load interrupt vector ISR_ADDRESS(rx_isr_ptr) // int_table_rx }; for (u8 i = 0; i < LENGTH(sio_a_cfg); ++i) sio_a_ctrl = sio_a_cfg[i]; for (u8 i = 0; i < LENGTH(sio_b_cfg); ++i) sio_b_ctrl = sio_b_cfg[i]; } // copy code to ram, so function pointer is modifyable static uint8_t tick = 0; void timer(void) __critical __interrupt(5) { static int prescale = 0; if (++prescale == 150) { prescale = 0; tick = 1; } } /* i2c_start_condition(); */ /* i2c_send(0xA0); */ /* i2c_send(0x00); */ /* i2c_send(0x00); */ /* i2c_restart_condition(); */ /* i2c_send(0xA1); */ /* b = i2c_recv(NACK); */ /* i2c_stop_condition(); */ void main(void) { tft_init(); init_ctc(); init_pio(); init_sio(); // Interrupt mode 2 IM(2); // Enable interrupts EI; // Boot menu addstr("1) Programming mode\r\n"); addstr("2) Normal boot (default)\r\n"); addstr("3) Boot address 0xC000\r\n"); for (int i = 5; i > 0; --i) { addch('\r'); addch(i + '0'); while (!tick) { u8 keys = poll_keys(); if (!(keys & KEY2)) { addch('\r'); bootloader(); } if (!(keys & KEY3)) { goto boot; } if (!(keys & KEY4)) { // Definitely safe looking C code ... void (*ptr)(void) = (void (*)(void))0xC000; ptr(); } } DI; tick = 0; EI; } addch('\r'); boot: addstr("Starting system ...\r\n"); // Load interrupt vector port_b_ctrl = ISR_ADDRESS(port_b_isr_ptr); // Interrupt word - interrupt if any pin goes low, mask follows port_b_ctrl = PIO_INT_CTRL(PIO_INT_EN | PIO_OR | PIO_LOW | PIO_MASK); // Mask - 0 means to check line port_b_ctrl = 0x80; _menu(); while (1) ; }