Project

General

Profile

Statistics
| Revision:

root / trunk / bootloader / rs485_poll.c @ 287

History | View | Annotate | Download (2.24 KB)

1
/**
2
 * @file rs485_poll.c
3
 * @brief RS485 implementation using UART hardware module and polling
4
 *
5
 * This uses the AVR's UART hardware module but does polling rather than
6
 * interrupts to handle transmission and receiving. It assumes the use
7
 * of an external UART<->RS485 converter with the RXEN and TXEN pins tied
8
 * together.
9
 *
10
 * @author Kevin Woo <kwoo@2ndt.com>
11
 **/
12

    
13
#include <rs485_poll.h>
14

    
15
/**
16
 * @brief Initializes the uart
17
 * @param baud The baudrate. Use the definitions in rs485_sw.h
18
 */
19
void rs485_init(uint16_t baud) {
20
        // Set baud rate
21
        UBRRH = (uint8_t)(baud>>8);
22
        UBRRL = (uint8_t)baud;
23
        
24
        // Enable RX/TX
25
        UCSRB = _BV(RXEN) | _BV(TXEN);
26
 
27
        // Enable the TXEN pin as output
28
        DDRD |= TX_EN;
29
    rs485_toggle_transmit(RS485_TX_OFF);
30
}
31

    
32
/**
33
 * @brief Non-blocking receive
34
 * 
35
 * Receives a byte from the UART if one exists. If none exist the function
36
 * will return an error code immediately. If there is a byte to receive,
37
 * it will be placed in a passed in pointer and return.
38
 *
39
 * @pre The RS485 TXEN line is not enabled
40
 * @param output_byte Byte to store the received message
41
 * @return 0 on success, negative if there is nothing to receive
42
 */
43
int8_t rs485_get_byte(uint8_t *output_byte) {
44
    if (UCSRA & _BV(RXC)) {
45
        *output_byte = UDR;
46
        return 0;
47
    } else {
48
        return -1;
49
    }
50
}
51

    
52
/**
53
 * @brief Blocking send
54
 *
55
 * Sends the byte in data onto the network. The function will block until
56
 * the transmit is complete so that the transmit enable line can be toggled
57
 * safely. It will wait until any current transmission completes before sending
58
 * and will wait until it completes before returning. The RS485 TX enable line
59
 * is automatically toggled by the function and should not be done so
60
 * outside the function.
61
 *
62
 * @param data The byte to send
63
 */
64
void rs485_send_byte(uint8_t data) {
65
        //Waits until current transmit is done
66
    while (!(UCSRA & _BV(UDRE)));
67

    
68
    // Perform the send
69
    UDR = data;
70

    
71
    // Waits until the transmit is done
72
    while(!(UCSRA & _BV(TXC)));
73
    UCSRA |= _BV(TXC);
74

    
75
        return;
76
}
77

    
78
/**
79
 * @brief Toggles the RS485 TXEN line
80
 *
81
 * @param state Whether to turn the pin on or off
82
 */
83
void rs485_toggle_transmit(uint8_t state) {
84
        if (state == RS485_TX_ON) {
85
                PORTD |= TX_EN;
86
        } else {
87
                PORTD &= ~TX_EN;
88
        }
89
}