Dateianhang 'pmc.h'
Herunterladen 1 // This file has been prepared for Doxygen automatic documentation generation.
2 /** \file ********************************************************************
3 *
4 * Implementation of PoorMansCan Stack
5 *
6 * \date 1.4.2012
7 * \author : Dominic Rathje (dominic.rathje@uni-ulm.de)
8 * \version 1.2
9 * \note
10 * - Supported devices : any AVR CPU
11 *
12 * Changelog:
13 * - v 1.2 (2012-04-02)
14 * - added Loop Back option
15 * - id-filter now implemented by application. pmc_init() expects a pointer to a filter function
16 * - fixed bug with handling of crc errors -> bad packets where not discarded
17 * - v 1.1 (2012-03-30)
18 * - fixed error in collision detection which caused the main process to lock up.
19 * - moved pmc_rx_int to pmc.c
20 *
21 *****************************************************************************/
22
23 #ifndef _PMC_H_
24 #define _PMC_H_ 1
25
26 #include "pmc.config.h"
27
28 typedef enum {
29 PMC_MODE_IDLE,
30 PMC_MODE_RX_CTRL,
31 PMC_MODE_RX_DATA,
32 PMC_MODE_TX_REQUEST,
33 PMC_MODE_TX,
34 PMC_MODE_WAIT,
35 PMC_MODE_ERROR
36 }PMC_MODE;
37
38 #define PMC_ERROR_RX_BUFFER_FULL 0xE1
39 #define PMC_ERROR_RX_CRC_FAILED 0xE2
40 #define PMC_ERROR_TX_DATA_INVALID 0xE3
41 #define PMC_ERROR_TX_SEND_FAILED 0xE4
42 #define PMC_ERROR_TX_BUFFER_FULL 0xE5
43 #define PMC_ERROR_LINK_BAD 0xE6
44
45 extern volatile PMC_MODE pmc_mode;
46 extern const uint8_t pmc_crc_table[256];
47
48 /** \brief Initialize PMC Modules
49 *
50 * Call this function to initialize the PMC Stack. The application has to provide
51 * a pointer to a filter functions that decides if a message-id should be handled.
52 *
53 * An example filter function could look like this:
54 * \code
55 uint8_t filter(uint8_t data) {
56 if(data == PMC_ID) {
57 return 1;
58 }
59 return 0;
60 }
61 * \endcode
62 *
63 * pmc_init should be called like this:
64 *\code
65 pmc_init(&filter);
66 * \endcode
67
68 * \param pointer to filter function
69 * \return void
70 */
71 void pmc_init(uint8_t (*filter)(uint8_t data));
72
73 /** \brief PMC Main Process
74 *
75 * Call this function regularly in your main-loop.
76 * It does all the complex calculation stuff to keep the ISR small and fast.
77 * - Initalise a transmission if there is data in the TX Buffer. Therfore we have to wait some time and listen on the bus. We dont want do this in pmc_send_message().
78 * - If we are currently receiving a message: keep track of the timeout and reset the RX Buffer if we don't receive data for a long time.
79 *
80 *
81 * \param void
82 * \return Error Code if there was an error.
83 */
84 uint8_t pmc_process(void);
85
86 /** \brief Send a message
87 *
88 * \param id Message ID
89 * \param subid User definable value. The lengths is 4 bits and the data has to be in the lower nibble.
90 * \param datalength number of data bytes in the message. Valid values are between 0 an 15.
91 * \param data Pointer to a buffer containing the data bytes.
92 * \return true if buffer is empty and the message has been moved to TX Buffer, false if buffer is full and doesn't get empty for a while.
93 */
94 uint8_t pmc_send_message(uint8_t id, uint8_t subid, uint8_t datalength, uint8_t *data);
95
96 /** \brief Send a message and wait until all pending messages have been sent.
97 *
98 * same as pmc_send_message() but will not return until the tx buffer is empty
99 *
100 * \param id Message ID
101 * \param subid User definable value. The lengths is 4 bits and the data has to be in the lower nibble.
102 * \param datalength number of data bytes in the message. Valid values are between 0 an 15.
103 * \param data Pointer to a buffer containing the data bytes.
104 * \return true if buffer is empty and the message has been moved to TX Buffer, false if buffer is full and doesn't get empty for a while.
105 */
106 uint8_t pmc_send_message_wait(uint8_t id, uint8_t subid, uint8_t datalength, uint8_t *data);
107
108 /** \brief Pull a new message from Buffer
109 *
110 * Call this function regularly in your main-loop to avoid a buffer overflow.
111 * The function checks the RX Buffer. If there is a new message, it calculates the checksum and move the message id, control bits and data to the buffer given as parameter.
112 *
113 * \param id Message ID
114 * \param subid User definable value. The lengths is 4 bits and the data has to be in the lower nibble.
115 * \param datalength number of data bytes in the message. Valid values are between 0 an 15.
116 * \param data Pointer to a buffer containing the data bytes.
117 * \return 1 if a message was moved to the given buffer. 0 if there was no new message.
118 */
119 uint8_t pmc_get_message(uint8_t *id, uint8_t *subid, uint8_t *datalength, uint8_t *data);
120
121 /** \brief Flush RS Buffer
122 *
123 * just sets tail and head pointer equal.
124 *
125 */
126 void pmc_flush_rx_buffer(void);
127
128 /** \struct pmc_buffer
129 * \brief a simple fifo buffer
130 *
131 * This structure is used by the PMC implementation as FIFO Buffer for
132 * Transmission and Reception.
133 */
134 struct pmc_buffer {
135 uint8_t head; ///< Head index for write operation
136 uint8_t tail; ///< Tail index for read operation
137 /** 19 Bytes of fifo buffer
138 * - 1 Byte ID
139 * - 1 Byte Control bits and Data length
140 * - up to 15 Bytes data
141 * - 1 Byte CRC Checksum
142 */
143 uint8_t buffer[18];
144 };
145
146 /** \brief PMC RX Interrupt Process
147 *
148 * This function should be called by the ISR to handle the received data.
149 *
150 * \param mark High Byte containing the ninth Bit
151 * \param data Low Byte of the transmission.
152 * \return void
153 */
154 void pmc_rx_int(uint8_t mark, uint8_t data);
155
156 /** \brief PMC Timer Interrupt Process
157 *
158 * This function should be called regularly by a Timer Interrupt.
159 * The frequency depends on the BAUD rate and should around BAUD/11
160 * e.g. For 38400 BAUD it should be called every 250µs.
161 *
162 * \param void
163 * \return void
164 */
165 inline void pmc_timer_interrupt(void) {
166 extern volatile uint8_t pmc_tick;
167 extern volatile uint8_t pmc_timeout;
168
169 pmc_tick++;
170 pmc_timeout++;
171 }
172
173 /** \brief Calculate CRC
174 *
175 * Look-Up-Table based calculation of an 8-Bit CRC checksum.
176 * The Implementation is based on the Maxim 1-Wire CRC calculation as described in
177 * http://www.maxim-ic.com/app-notes/index.mvp/id/27
178 *
179 * The Polynomial is X^8 + x^5 + x^4 +1
180 *
181 * \param crc
182 * \param x
183 * \return updated crc value
184 */
185 inline uint8_t pmc_crc_update(uint8_t crc, uint8_t x) {
186 return pmc_crc_table[crc ^ x];
187 }
188
189 #endif /* _PMC_H_ */
190
Gespeicherte Dateianhänge
Um Dateianhänge in eine Seite einzufügen sollte unbedingt eine Angabe wie attachment:dateiname benutzt werden, wie sie auch in der folgenden Liste der Dateien erscheint. Es sollte niemals die URL des Verweises ("laden") kopiert werden, da sich diese jederzeit ändern kann und damit der Verweis auf die Datei brechen würde.Sie dürfen keine Anhänge an diese Seite anhängen!