//***************************************************************************** //***************************************************************************** void init_lcd_gpio(void) { gpio_enable_port(LCD_GPIO_BASE); gpio_enable_port(LCD_RST_BASE); // Configure SPI CLK gpio_config_digital_enable(LCD_GPIO_BASE, LCD_CLK_PIN); gpio_config_alternate_function(LCD_GPIO_BASE, LCD_CLK_PIN); gpio_config_port_control(LCD_GPIO_BASE, LCD_CLK_PIN_PCTL); // Configure SPI MOSI gpio_config_digital_enable(LCD_GPIO_BASE, LCD_MOSI_PIN); gpio_config_alternate_function(LCD_GPIO_BASE, LCD_MOSI_PIN); gpio_config_port_control(LCD_GPIO_BASE, LCD_MOSI_PIN_PCTL); // Configure CS to be a normal GPIO pin that is controlled // explicitly by software gpio_config_digital_enable(LCD_GPIO_BASE, LCD_CS_PIN); gpio_config_alternate_function(LCD_GPIO_BASE, LCD_CS_PIN); gpio_config_port_control(LCD_GPIO_BASE, LCD_CS_PIN_PCTL); // Configure CD to be a normal GPIO pin that is controlled // explicitly by software gpio_config_digital_enable(LCD_GPIO_BASE, LCD_CD_PIN); gpio_config_enable_output(LCD_GPIO_BASE, LCD_CD_PIN); // Configure RST_N to be a normal GPIO pin that is controlled // explicitly by software gpio_config_digital_enable(LCD_RST_BASE, LCD_RST_PIN); gpio_config_enable_output(LCD_RST_BASE, LCD_RST_PIN); initialize_spi(LCD_SPI_BASE, 3); }
int main() { initialize_io(); initialize_spi(); const int MAGIC_SPI_TRANSMIT_DELAY = 12; // actually seems to be 10 but let's be safe here const int MAGIC_MUX_SWITCH_DELAY = 100; // way to large but let's be generous int RGB_counter = 0; int LED_counter = 0; int LED_R = 0x01; int LED_G = 0x01; int LED_B = 0x01; const int CYCLE_SIZE = 16; bool isReadySPI = false; bool isCommResetting = false; bool isCommTransmitting = false; // Data variables. (NOTE: Not sure if these should be "volatile".) uint8_t t_isPressedDebugA = 0x00; // 1 bit (1 = true) uint8_t t_isPressedDebugB = 0x00; // 1 bit (1 = true) uint8_t t_XY_low = 0x00; // 8 bits uint8_t t_XY_high = 0x00; // 7 bits uint8_t t_Z_low = 0x00; // 8 bits uint8_t t_Z_high = 0x00; // 1 bit uint8_t t_bump_map = 0x00; // 8 bits uint8_t t_overheat_alert = 0x00; // 1 bit uint8_t t_overheat_map = 0x00; // 8 bits uint8_t t_IR_alert = 0x00; // 1 bit // Doesn't work on an ATmega8. //// Delay the clock frequency change to ensure re-programmability. //// The argument for the delay may be completely off because at this //// point in the program the specified `F_CPU` does not match the //// actual clock's frequency. //ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { // // Delay! _delay_ms(100); // // //CLKPR = 1 << CLKPCE; // "only updated when [... the other bits are] written to zero" // //CLKPR &= ~(1<<CLKPS0); // //CLKPR &= ~(1<<CLKPS1); // //CLKPR &= ~(1<<CLKPS2); // //CLKPR &= ~(1<<CLKPS3); // //// ^ (0b0000) Corresponds to a division factor of 1. // // // Someone else's way of doing it. // CLKPR = 0x80; // CLKPR = 0x00; //} // Check if other MCUs are ready to go. // TODO: Periodically check for connectivity later. resync_spi(); isReadySPI = true; // NOTE: FOR SOME REASON THIS LINE BREAKS THINGS :( sei(); // ready to go. while (true) { ++RGB_counter; RGB_counter %= 3; if (RGB_counter == 0) { ++LED_counter; LED_counter %= CYCLE_SIZE; } auto req_data = [](uint8_t SPI_code) -> uint8_t { _delay_us(MAGIC_SPI_TRANSMIT_DELAY); SPDR = SPI_code; while ( !(SPSR & (1<<SPIF)) ) { ; } // wait for reception to complete uint8_t byte_read = SPDR; return byte_read; }; // ask for stuff, update registers set_SPI_mux(MUX_1); _delay_us(MAGIC_MUX_SWITCH_DELAY); uint8_t check_link = req_data(SPI_REQ_DEBUG_A); if (check_link != SPI_ACK_READY) { resync_spi(); } t_isPressedDebugA = req_data(SPI_REQ_DEBUG_B); t_isPressedDebugB = req_data(SPI_REQ_Z_LOW); t_Z_low = req_data(SPI_REQ_Z_HIGH); t_Z_high = req_data(SPI_REQ_XY_LOW); t_XY_low = req_data(SPI_REQ_XY_HIGH); t_XY_high = req_data(SPI_REQ_BUMP_MAP); t_bump_map = req_data(SPI_REQ_OVERHEAT_ALERT); t_overheat_alert = req_data(SPI_REQ_OVERHEAT_MAP); t_overheat_map = req_data(SPI_REQ_IR_ALERT); t_IR_alert = req_data(SPI_TRANSMIT_OVER); set_SPI_mux(MUX_2); _delay_us(MAGIC_MUX_SWITCH_DELAY); // NOTE: get rid of this _delay_us(100); // pretend we do other stuff here if (t_isPressedDebugA == 0x00) { LED_G = 0x01; } else { LED_G = 0x00; } if (t_isPressedDebugB == 0x00) { LED_B = 0x01; } else { LED_B = 0x00; } // LED stuffs PORTC |= 0b111<<PC0; switch (RGB_counter) { case 0 : if (LED_counter < LED_R) { PORTC &= ~(1<<PC0); } break; case 1 : if (LED_counter < LED_G) { PORTC &= ~(1<<PC1); } break; case 2 : if (LED_counter < LED_B) { PORTC &= ~(1<<PC2); } break; } if (isReadySPI) { PORTC |= 1<<PC3; // always true for now } else { PORTC &= ~(1<<PC3); // R } //if (isCommResetting) { // PORTC |= 1<<PC4; //} else { // PORTC &= ~(1<<PC4); // Y //} //if (isCommTransmitting) { // PORTC |= 1<<PC5; //} else { // PORTC &= ~(1<<PC5); // G //} //// NOTE: Enable this delay if there aren't other delay sources. //_delay_us(10); } }