Beispiel #1
0
//*****************************************************************************
//*****************************************************************************
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);
}
Beispiel #2
0
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);
	}
}