char uart_read_char(void) {
    // Wait until a character is available to read
    while (uart_rx_buffer_empty());
 
    // Then return the character
    return (char)rx_ring_remove();
}
Beispiel #2
0
void State_Machine (void)
{
	uint8_t uart_tmp;

	// Início da máquina de estados para leitura da serial
		
	// Se deu timeout
	if (TimeOut)
	{
		CurState = SM_ERROR;
		TipoErro = CB_ERROR_TO;
		TOTicks = 0;
		TimeOut = FALSE;
	}

	// Se tiver algo no buffer, executa a máquina de estados.
	else if (CurState != SM_IDLE)
	{
		// Reseta os timers e contador de timeout para a serial
		TCNT2 = 0;					// Zera o timer 2
		GTCCR |= (1<<PSRASY);		// Zera o prescaler do timer2
		TOTicks = 0;
		TimeOut = FALSE;
	}

	switch (CurState)
	{
		case SM_IDLE:
			if (uart_rx_buffer_empty() == 0)		// Se tem alguma coisa no buffer
			{
				CurState = SM_START;
				TCCR2B = (1<<CS22) | (1<<CS21) | (1<<CS20);	// Inicia Timer2 p/ Timeout
			}
			break;

		// Confere se o primeiro byte é 'b', já que todos os comandos começam com ele
		case SM_START:
			
			switch (uart_getc())
			{
				case CB_INICIO:
					CurState = SM_GET_CMD;
					break;

				case VFD_INICIO:
					CurState = SM_VFD_CMD;
					break;

				default:
					CurState = SM_ERROR;
					TipoErro = CB_ERROR_START;
					break;
			}
			break;
				
		// Segundo byte - byte de comando
		// Verifica se é leitura ou escrita
		case SM_GET_CMD:

			switch (uart_getc())
			{
				case CB_CMD_RD:
					CurState = SM_READ;
					break;

			// Se for escrita, também inicializa as variáveis para
			// leitura dos novos valores
				case CB_CMD_WR:
					CurState = SM_WRITE;
					Counter = 0;
					tempu16 = 0;
					break;

				default:
					CurState = SM_ERROR;
					TipoErro = CB_ERROR_CMD;
					break;
			}
			break;

		// Veririfica qual variável se quer escrever
		// Atualmente só pode mexer no set-point
		case SM_WRITE:
			switch (uart_getc())
			{
				case CB_WR_SP:
					CurState = SM_WR_SP;
					break;

				case CB_WR_KP:
					CurState = SM_WR_KP;
					break;

				case CB_WR_KI:
					CurState = SM_WR_KI;
					break;

				case CB_WR_LD:
					CurState = SM_WR_LD;
					break;

				default:
					CurState = SM_ERROR;
					TipoErro = CB_ERROR_WR;
					break;
			}
			break;

		// Lê os próximos 3 bytes que terão o valor do novo set point
		case SM_WR_SP:
			uart_tmp = uart_getc();

			// só aceita se for número
			if ((uart_tmp >='0') && (uart_tmp <= '9'))
			{
				tempu16 *= 10;
				tempu16 += uart_tmp - '0';		// converte para valor numérico
				Counter++;

				if (Counter > 2)				// Se já leu os 3 bytes
				{
					// verifica se está dentro da faixa aceitável
					if ((tempu16 >= 80 ) && (tempu16 <= 240))
					{
						// Converte e salva o valor do set-point novo
						// Teoricamente deveria multiplicar por 3,92, mas como
						// não dá, faz uma leve gambiarra para somente utilizar 
						// números inteiros.
						tempu16 = ((tempu16 * 136 + 25) / 50);

						ATOMIC_BLOCK(ATOMIC_FORCEON)
						{
							tPIsat_params.sp = tempu16;
						}

						OSC_TRIGGER;

						eeprom_write_word(&ee_PI_SP, tempu16);

						CurState = SM_END;
					}
					else 
					{
						CurState = SM_ERROR;
						TipoErro = CB_ERROR_SP;
					}
				}