welcome: please sign in

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.
  • [laden | anzeigen] (2017-06-12 18:26:24, 11.6 KB) [[attachment:pmc.c]]
  • [laden | anzeigen] (2017-06-12 18:26:24, 1.0 KB) [[attachment:pmc.config.h]]
  • [laden | anzeigen] (2017-06-12 18:26:24, 6.0 KB) [[attachment:pmc.h]]
  • [laden | anzeigen] (2017-06-12 18:26:24, 5.3 KB) [[attachment:uart.zip]]
 Alle Dateien | Ausgewählte Dateien: löschen verschieben auf Seite kopieren auf Seite

Sie dürfen keine Anhänge an diese Seite anhängen!