221 lines
7.2 KiB
C
221 lines
7.2 KiB
C
/**************************************************************************
|
|
* NAME: usart.h
|
|
* AUTHOR: Lennart Eriksson
|
|
* PURPOSE: USART implementation for sending data
|
|
* INFORMATION:
|
|
* This file includes 2 types of USARTS, regular polling or DMA based
|
|
* the polling version of the USART uses the processor in order to get
|
|
* messages while the DMA has Direct Memory Access and does not need the
|
|
* processor to receive the messages and can copy the entire message once.
|
|
* The DMA is implemented using a double buffer with fixed sizes of the
|
|
* buffers in order to work with fixed data sizes of the messages. The up
|
|
* side of this is that the system can read a complete message and not
|
|
* where the DMA is not writing on the same place. Though this means that
|
|
* the message sizes needs to be know on before hand
|
|
*
|
|
* GLOBAL VARIABLES:
|
|
* Variable Type Description
|
|
* -------- ---- -----------
|
|
**************************************************************************/
|
|
|
|
#ifndef DRIVERS_USART_H_
|
|
#define DRIVERS_USART_H_
|
|
|
|
#include "stm32f4xx.h"
|
|
|
|
typedef struct dma_usart_return {
|
|
uint8_t* buff;
|
|
bool new_data;
|
|
} dma_usart_return;
|
|
|
|
|
|
// Enumeration for USART stop bits
|
|
typedef enum stop_bits
|
|
{
|
|
STOP_BITS_1 = 0,
|
|
STOP_BITS_0_5,
|
|
STOP_BITS_2,
|
|
STOP_BITS_1_5
|
|
} stop_bits;
|
|
|
|
// Enuymeration for USART parity
|
|
typedef enum parity
|
|
{
|
|
PARITY_NONE = 0x0,
|
|
PARITY_EVEN = 0x2,
|
|
PARITY_ODD = 0x3
|
|
} parity;
|
|
|
|
// Struct to be used for regular USART with polling
|
|
typedef struct usart_profile
|
|
{
|
|
USART_TypeDef* usart_instance; // The USART used to send or receive data
|
|
} usart_profile;
|
|
|
|
// struct to be used for dma receiving of USART messages
|
|
typedef struct usart_dma_profile
|
|
{
|
|
usart_profile usart_pro; // The USART profile to be used
|
|
DMA_Stream_TypeDef* dma_usart_rx_instance; // The DMA profile corresponding to the rx buffer
|
|
DMA_Stream_TypeDef* dma_usart_tx_instance; // The DMA profile corresponding to the tx buffer
|
|
uint8_t* dma_rx_buffer1; // The first rx buffer used in double buffering
|
|
uint8_t* dma_rx_buffer2; // The second rx buffer used in double buffering
|
|
uint8_t* dma_tx_buffer; // The tx buffer used for sending messages
|
|
} usart_dma_profile;
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
* BRIEF: Initialize the USART with DMA reception of messages
|
|
* INFORMATION:
|
|
* Initialize the specified USART and enable the DMA for it so that the
|
|
* messages can be received without utilizing any processor load. This
|
|
* function returns false if any error occurred during the initialization
|
|
* and true of everything went well
|
|
***********************************************************************/
|
|
bool usart_init_dma(USART_TypeDef* usart_inst,
|
|
usart_dma_profile* profile_out,
|
|
uint32_t baud_rate,
|
|
stop_bits stopbits,
|
|
parity parity_mode,
|
|
uint32_t dma_rx_buffersize,
|
|
uint32_t dma_tx_buffersize);
|
|
|
|
|
|
/***********************************************************************
|
|
* BRIEF: Initialize a regular USART that can be used for polling
|
|
* INFORMATION:
|
|
* Initialize the specified USART in order to get polling and regular
|
|
* transmit of messages to work. If the initialization fails this function
|
|
* returns false and otherwise it returns true
|
|
* * For USART1 Inverter is ON on RX by default
|
|
***********************************************************************/
|
|
bool usart_init(USART_TypeDef* usart_inst,
|
|
usart_profile* profile_out,
|
|
uint32_t baud_rate,
|
|
stop_bits stopbits,
|
|
parity parity_mode);
|
|
|
|
/***********************************************************************
|
|
* BRIEF: Send message over USART
|
|
* INFORMATION:
|
|
* Try to send a message over USART, if the time exceeds the specified
|
|
* timeout the transmit will be stopped. This function returns the number
|
|
* of bytes that was successfully sent down to the USART bus even if
|
|
* the timeout was reached before it was done.
|
|
***********************************************************************/
|
|
uint32_t usart_transmit(usart_profile *profile,
|
|
uint8_t* buffer,
|
|
uint32_t size,
|
|
uint32_t timeout_us);
|
|
|
|
/***********************************************************************
|
|
* BRIEF: return if the USART has any data to be received in the buffer
|
|
* INFORMATION:
|
|
***********************************************************************/
|
|
bool usart_poll_data_ready(usart_profile* profile);
|
|
|
|
/***********************************************************************
|
|
* BRIEF: Poll messages from the USART
|
|
* INFORMATION:
|
|
* Try to get a message from the USART, if the time spent receiving
|
|
* exceeds the specified timeout the function will return the buffer
|
|
* that has been received to that point. The function returns the number
|
|
* of bytes received even if the timeout was exceeded.
|
|
***********************************************************************/
|
|
uint32_t usart_poll(usart_profile *profile,
|
|
uint8_t* buffer,
|
|
uint32_t size,
|
|
uint32_t timeout_us);
|
|
|
|
/***********************************************************************
|
|
* BRIEF: Get the DMA buffer that was most recently completed
|
|
* INFORMATION:
|
|
* This function will return the buffer that the DMA most recently
|
|
* completed so that the DMA can continue writing to the second buffer
|
|
* without interfering with the rest of the system
|
|
***********************************************************************/
|
|
dma_usart_return usart_get_dma_buffer(usart_dma_profile *profile);
|
|
|
|
/***********************************************************************
|
|
* BRIEF: NOT IMPLEMENTED YET
|
|
* INFORMATION:
|
|
* Use the usart_transmit function instead with the
|
|
* usart_dma_profile.usart_pro as input argument instead
|
|
***********************************************************************/
|
|
void usart_transmit_dma(usart_dma_profile *profile,
|
|
uint8_t* buffer,
|
|
uint32_t size);
|
|
|
|
#endif /* DRIVERS_USART_H_ */
|
|
|
|
// -------------------- EXAMPLE OF USART POLL -------------------------
|
|
/*
|
|
int main()
|
|
{
|
|
//Initialize the system
|
|
init_system();
|
|
|
|
//Set up a usart profile
|
|
usart_profile usart_p;
|
|
|
|
//Initiate the profile for specified USART
|
|
usart_init(USART1, &usart_p, 115200, STOP_BITS_1, PARITY_NONE);
|
|
|
|
//The data buffer used
|
|
uint8_t data = 0x00;
|
|
|
|
while(1)
|
|
{
|
|
//poll data from the USART
|
|
uint32_t num_received = usart_poll(&usart_p, &data, 1, 1000);
|
|
//if data was received send the data back over the USART
|
|
if(num_received > 0x00)
|
|
{
|
|
usart_transmit(&usart_p, &data, 1, 1000);
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
// -------------------- EXAMPLE OF USART DMA -------------------------
|
|
/*
|
|
#define USART_DMA_SIZE 4
|
|
|
|
int main(void)
|
|
{
|
|
//Init the system
|
|
init_system();
|
|
|
|
//Set up a usart DMA profile
|
|
usart_dma_profile dma_p;
|
|
|
|
//Initiate USART DMA profile
|
|
usart_init_dma(USART1, &dma_p, 115200, STOP_BITS_1, PARITY_NONE, USART_DMA_SIZE, 0);
|
|
|
|
//Temporary array to compare against
|
|
uint8_t tmp[USART_DMA_SIZE] = { 0x00 };
|
|
|
|
while(1)
|
|
{
|
|
uint8_t* buf;
|
|
// Get the dma finished buffer
|
|
buf = usart_get_dma_buffer(&dma_p);
|
|
bool change = false;
|
|
//compare against the previous buffer and copy the elements
|
|
for(int i = 0; i < USART_DMA_SIZE; i++)
|
|
{
|
|
if(tmp[i] != (tmp[i] = buf[i]))
|
|
change |= true;
|
|
}
|
|
|
|
//if the buffer has changed print the buffer back over USART
|
|
if(change)
|
|
{
|
|
usart_transmit(&dma_p, tmp, USART_DMA_SIZE, 1000);
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|