#include #include #include #include #include "pins.h" #include "debug.h" /** UART notes * UCSR0A: * 0: MP communication mode * 1: U2X (double trans speed) * 2: USART parity error * 3: Data overrun (udr0 not read before next frame) * 4: Frame error * 5: Data register empty (new data can be transmitted) * 6: USART transmit complete * 7: USART recieve complete * ____________________________________________________________ * UCSR0B: * 0: transmit data bit 8 * 1: recieve data bit 8 * 2: USART char size 0 (used with UCSZ01 and UCSZ00 to set data frame size) * 3: Transmitter enable * 4: Reciever enable * 5: USART data reg empty interrupt table * 6: TX complete int enable * 7: RX complete int enable * ____________________________________________________________ * UCSR0C: * 0: Clock polarity (1: falling edge trasmit, recieve rising edge) * 1: USART char size 0 * 2: USART char size 1 * 3: USART stop bit select (1: 1 stop bit, 0: 2 stop bits) * 4: USART parity mode (00: async, 01: sync) * 5: USART Parity mode (02: master SPI) * 6: USART mode select (00: async 01: sync) * 7: USART mode select (02: master SPI) * ____________________________________________________________ * UBRR0(H,L): baudrates * * **/ void uart_debug_sendbyte(uint8_t byte) { loop_until_bit_is_set(UCSR0A, UDRE0); UDR0 = byte; } uint8_t uart_debug_recvbyte() { loop_until_bit_is_set(UCSR0A, RXC0); UART_PORT |= _BV(UART_RTS); return UDR0; } void uart_debug_init() { UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; /** TODO figure out why USE_2X is enable when it shoudn't be //set baud rate #ifdef USE_2X //is set by header UCSR0A |= _BV(U2X0); #else UCSR0A &= ~(_BV(U2X0)); #endif **/ UCSR0A &= ~(_BV(U2X0)); UCSR0C = ((_BV(UCSZ01)) | _BV(UCSZ00)); // set 8 bit char size, yes the '=' is intentional UCSR0B = (_BV(RXEN0) | _BV(TXEN0)); } #ifdef FLASH_EEPROM //this uart port recieves from the computer and writes the eeprom void uart_flash_init() { //syncronization UART_DDR |= _BV(UART_RTS); UART_DDR &= ~(_BV(UART_CTS)); //keep in mind cts/rts is inverted; low is 1 and high is 0 UART_PORT |= _BV(UART_RTS); //keep in mind cts/rts is inverted; low is 1 and high is 0 //for serial speed, we'll just use the same speed for now UBRR1H = UBRRH_VALUE; UBRR1L = UBRRL_VALUE; UCSR1A &= ~(_BV(U2X1)); UCSR1C = ((_BV(UCSZ11)) | _BV(UCSZ10)); // set 8 bit char size, yes the '=' is intentional UCSR1B = (_BV(RXEN1) | _BV(TXEN1)); //when the master initates serial via pyserial, for some reason it pulls our CTS low //for a brief moment. This hack avoids that printf("waiting for unwanted initation pulse...\r\n"); loop_until_bit_is_clear(UART_PIN, UART_CTS); loop_until_bit_is_set(UART_PIN, UART_CTS); printf("complete\r\n"); } void uart_flash_sendbyte(uint8_t byte) { printf("send start\r\n"); if(UART_PORT & _BV(UART_CTS)) { printf("send conflict!\r\n"); debug_crash(); //make sure they're not trying to send } UART_PORT &= ~(_BV(UART_RTS)); //us: ready to send printf("waiting on master\r\n"); loop_until_bit_is_clear(UART_PIN, UART_CTS); //them: go ahead printf("waiting for transmit buffer\r\n"); loop_until_bit_is_set(UCSR1A, UDRE1); //wait until buffer is empty UDR1 = byte; UART_PORT |= _BV(UART_RTS); //okay, we be done sending printf("done splurting out the data, still need to mark end of packet\r\n"); loop_until_bit_is_set(UART_PIN, UART_CTS); //wait for them to get the message so we don't double dip printf("we be done tho\r\n"); } uint8_t uart_flash_recvbyte() { char byte_in; loop_until_bit_is_clear(UART_PIN, UART_CTS); //wait for their request UART_PORT &= ~(_BV(UART_RTS)); //hey, you can send now loop_until_bit_is_set(UCSR1A, RXC1); //wait for them to actually send byte_in = UDR1; UART_PORT |= _BV(UART_RTS); //okay, you can no longer send loop_until_bit_is_set(UART_PIN, UART_CTS); //wait for them to get the message so we don't double dip return byte_in; } #endif