Add in a basic USART driver and echo test task.

This commit is contained in:
Richard Barry 2010-07-06 21:12:01 +00:00
parent 4ab0313273
commit 28b5ea32a4
10 changed files with 269 additions and 425 deletions

View File

@ -1,214 +0,0 @@
/*
FreeRTOS V6.0.5 - Copyright (C) 2010 Real Time Engineers Ltd.
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS eBook *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#include <string.h>
#include "FreeRTOS.h"
#include "CircularBuffer.h"
/*-----------------------------------------------------------*/
/* See the header file for function information. */
void vInitialiseCircularBuffer( xCircularBuffer *pxBuffer,
unsigned char *pucDataBuffer,
unsigned long ulBufferSizeInBytes,
unsigned long ulDataSizeInBytes,
void *pvTag
)
{
pxBuffer->pucDataBuffer = pucDataBuffer;
pxBuffer->ulBufferSizeInBytes = ulBufferSizeInBytes;
pxBuffer->pucNextByteToRead = pucDataBuffer;
pxBuffer->pucNextByteToWrite = pucDataBuffer;
pxBuffer->ulDataSizeInBytes = ulDataSizeInBytes;
pxBuffer->pvTag = pvTag;
}
/*-----------------------------------------------------------*/
/* See the header file for function information. */
unsigned long ulBytesInCircularBuffer( const xCircularBuffer * const pxBuffer )
{
unsigned char *pucNextByteToWrite;
unsigned long ulReturn;
if( pxBuffer->pvTag != NULL )
{
/* Locate the position that the DMA will next write to. */
pucNextByteToWrite = ( unsigned char * ) *( ( unsigned long * ) pxBuffer->pvTag );
}
else
{
/* Locate the position the application will next write to. */
pucNextByteToWrite = pxBuffer->pucNextByteToWrite;
}
/* Has the write pointer wrapped back to the start of the buffer
compared to our read pointer? */
if( ( unsigned long ) pucNextByteToWrite >= ( unsigned long ) pxBuffer->pucNextByteToRead )
{
/* The write pointer is still ahead of us in the buffer. The amount of
data available is simple the gap between the two pointers. */
ulReturn = ( unsigned long ) pucNextByteToWrite - ( unsigned long ) pxBuffer->pucNextByteToRead;
}
else
{
/* The write pointer has wrapped back to the start. The amount of data
available is equal to the data between the read pointer and the end of
the buffer...*/
ulReturn = ( unsigned long ) &( pxBuffer->pucDataBuffer[ pxBuffer->ulBufferSizeInBytes ] ) - ( unsigned long ) pxBuffer->pucNextByteToRead;
/*... plus the data between the start of the buffer and the write
pointer. */
ulReturn += ( unsigned long ) pucNextByteToWrite - ( unsigned long ) pxBuffer->pucDataBuffer;
}
return ulReturn;
}
/*-----------------------------------------------------------*/
unsigned long ulCopyReceivedBytes( xCircularBuffer *pxBuffer, unsigned char * pucBuffer, unsigned long ulWantedBytes )
{
unsigned char *pucNextByteToWrite;
unsigned long ulNumberOfBytesRead = 0, ulNumberOfBytesAvailable;
if( pxBuffer->pvTag != NULL )
{
/* Locate the position that the DMA will next write to. */
pucNextByteToWrite = ( unsigned char * ) *( ( unsigned long * ) pxBuffer->pvTag );
}
else
{
/* Locate the position that the application will next write to. */
pucNextByteToWrite = pxBuffer->pucNextByteToWrite;
}
if( ( unsigned long ) pucNextByteToWrite >= ( unsigned long ) pxBuffer->pucNextByteToRead )
{
/* The write pointer has not wrapped around from our read pointer.
Clip the number of bytes to read to the number available if the number
available is less than that wanted. */
ulNumberOfBytesAvailable = ( unsigned long ) pucNextByteToWrite - ( unsigned long ) ( pxBuffer->pucNextByteToRead );
if( ulNumberOfBytesAvailable < ulWantedBytes )
{
ulWantedBytes = ulNumberOfBytesAvailable;
}
/* Copy the data from ulRxBuffer into the application buffer. */
memcpy( pucBuffer, pxBuffer->pucNextByteToRead, ulWantedBytes );
/* Move up our read buffer. */
pxBuffer->pucNextByteToRead += ulWantedBytes;
ulNumberOfBytesRead = ulWantedBytes;
}
else
{
/* The write pointer has wrapped around from our read pointer. Is there
enough space from our read pointer to the end of the buffer without the
read pointer also wrapping around? */
ulNumberOfBytesAvailable = ( unsigned long ) &( pxBuffer->pucDataBuffer[ pxBuffer->ulBufferSizeInBytes ] ) - ( unsigned long ) pxBuffer->pucNextByteToRead;
if( ulNumberOfBytesAvailable >= ulWantedBytes )
{
/* There is enough space from our current read pointer up to the end
of the buffer to obtain the number of bytes requested. */
memcpy( pucBuffer, pxBuffer->pucNextByteToRead, ulWantedBytes );
/* Move up our read buffer. */
pxBuffer->pucNextByteToRead += ulWantedBytes;
ulNumberOfBytesRead = ulWantedBytes;
}
else
{
/* There is not enough space up to the end of the buffer to obtain
the number of bytes requested. Copy up to the end of the buffer. */
memcpy( pucBuffer, pxBuffer->pucNextByteToRead, ulNumberOfBytesAvailable );
ulNumberOfBytesRead = ulNumberOfBytesAvailable;
/* Then wrap back to the beginning of the buffer to attempt to
read the remaining bytes. */
pxBuffer->pucNextByteToRead = pxBuffer->pucDataBuffer;
pucBuffer += ulNumberOfBytesAvailable;
/* How many more bytes do we want to read? */
ulWantedBytes -= ulNumberOfBytesAvailable;
/* Clip the number of bytes we are going to read to the number
available if this is less than the number we want. */
ulNumberOfBytesAvailable = ( unsigned long ) pucNextByteToWrite - ( unsigned long ) pxBuffer->pucNextByteToRead;
if( ulNumberOfBytesAvailable < ulWantedBytes )
{
ulWantedBytes = ulNumberOfBytesAvailable;
}
/* Copy these into the buffer. */
memcpy( pucBuffer, pxBuffer->pucNextByteToRead, ulWantedBytes );
/* Move up our read buffer. */
pxBuffer->pucNextByteToRead += ulWantedBytes;
ulNumberOfBytesRead += ulWantedBytes;
}
}
/* Check we have not moved our read pointer off the end of the buffer. */
if( ( unsigned long ) pxBuffer->pucNextByteToRead >= ( unsigned long ) &( pxBuffer->pucDataBuffer[ pxBuffer->ulBufferSizeInBytes ] ) )
{
pxBuffer->pucNextByteToRead = pxBuffer->pucDataBuffer;
}
/* Return the number of bytes read. */
return ulNumberOfBytesRead;
}

View File

@ -1,115 +0,0 @@
/*
FreeRTOS V6.0.5 - Copyright (C) 2010 Real Time Engineers Ltd.
***************************************************************************
* *
* If you are: *
* *
* + New to FreeRTOS, *
* + Wanting to learn FreeRTOS or multitasking in general quickly *
* + Looking for basic training, *
* + Wanting to improve your FreeRTOS skills and productivity *
* *
* then take a look at the FreeRTOS eBook *
* *
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
* http://www.FreeRTOS.org/Documentation *
* *
* A pdf reference manual is also available. Both are usually delivered *
* to your inbox within 20 minutes to two hours when purchased between 8am *
* and 8pm GMT (although please allow up to 24 hours in case of *
* exceptional circumstances). Thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
***NOTE*** The exception to the GPL is included to allow you to distribute
a combined work that includes FreeRTOS without being obliged to provide the
source code for proprietary components outside of the FreeRTOS kernel.
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
http://www.FreeRTOS.org - Documentation, latest information, license and
contact details.
http://www.SafeRTOS.com - A version that is certified for use in safety
critical systems.
http://www.OpenRTOS.com - Commercial support, development, porting,
licensing and training services.
*/
#ifndef CIRCULAR_BUFFER_H
#define CIRCULAR_BUFFER_H
/* Structure that holds the state of the circular buffer. */
typedef struct
{
unsigned char *pucDataBuffer;
unsigned long ulBufferSizeInBytes;
unsigned char *pucNextByteToRead;
unsigned char *pucNextByteToWrite;
unsigned long ulDataSizeInBytes;
void *pvTag;
} xCircularBuffer;
/*
* Setup a circular buffer ready for use.
*
* pxBuffer : The xCicularBuffer structure being initialised.
*
* pucDataBuffer : The buffer to be used by the xCicularBuffer object.
*
* ulBufferSizeInBytes : The dimention of pucDataBuffer in bytes.
*
* ulDataSizeInBytes : The size of the data that is to be stored in the
* circular buffer. For example, 4 if the buffer is used to hold
* unsigned longs, 1 if the buffer is used to hold chars.
*
* pvTag : Can be used for anything, although normally used in conjunction with
* a DMA register.
*/
void vInitialiseCircularBuffer( xCircularBuffer *pxBuffer,
unsigned char *pucDataBuffer,
unsigned long ulBufferSizeInBytes,
unsigned long ulDataSizeInBytes,
void *pvTag
);
/*
* Returns the number of bytes that are currently available within the
* buffer.
*/
unsigned long ulBytesInCircularBuffer( const xCircularBuffer * const pxBuffer );
/*
* Obtain bytes from the circular buffer. Data may have been placed in
* the circular buffer by a DMA transfer or simply written to the buffer by
* the application code.
*
* pxBuffer : The circular buffer from which data is to be read.
*
* pucBuffer : The buffer into which the received bytes should be copied.
*
* ulWantedBytes : The number of bytes we are going to attempt to receive
* from the circular buffer.
*
* return : The actual number of bytes received from the circular buffer.
* This might be less than the number of bytes we attempted to receive.
*/
unsigned long ulCopyReceivedBytes( xCircularBuffer *pxBuffer, unsigned char * pucBuffer, unsigned long ulWantedBytes );
#endif

View File

@ -15,7 +15,7 @@
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "spi_flash.h"
#include "SPI_Flash_ST_Eval.h"
/* Private typedef -----------------------------------------------------------*/
#define SPI_FLASH_PageSize 0x100

View File

@ -0,0 +1,75 @@
/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
* File Name : spi_flash.h
* Author : MCD Application Team
* Version : V2.0.0
* Date : 04/27/2009
* Description : Header for spi_flash.c file.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SPI_FLASH_H
#define __SPI_FLASH_H
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "stm32f10x_spi.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#define uint32_t unsigned long
#define uint8_t unsigned char
#define uint16_t unsigned short
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Uncomment the line corresponding to the STMicroelectronics evaluation board
used to run the example */
#if !defined (USE_STM3210B_EVAL) && !defined (USE_STM3210E_EVAL)
//#define USE_STM3210B_EVAL
#define USE_STM3210E_EVAL
#endif
#ifdef USE_STM3210B_EVAL
#define GPIO_CS GPIOA
#define RCC_APB2Periph_GPIO_CS RCC_APB2Periph_GPIOA
#define GPIO_Pin_CS GPIO_Pin_4
#else /* USE_STM3210E_EVAL */
#define GPIO_CS GPIOB
#define RCC_APB2Periph_GPIO_CS RCC_APB2Periph_GPIOB
#define GPIO_Pin_CS GPIO_Pin_2
#endif
/* Exported macro ------------------------------------------------------------*/
/* Select SPI FLASH: Chip Select pin low */
#define SPI_FLASH_CS_LOW() __asm volatile( "NOP" );__asm volatile( "NOP" );__asm volatile( "NOP" );__asm volatile( "NOP" );GPIO_ResetBits(GPIO_CS, GPIO_Pin_CS);__asm volatile( "NOP" );__asm volatile( "NOP" );__asm volatile( "NOP" );__asm volatile( "NOP" )
/* Deselect SPI FLASH: Chip Select pin high */
#define SPI_FLASH_CS_HIGH() __asm volatile( "NOP" );__asm volatile( "NOP" );__asm volatile( "NOP" );__asm volatile( "NOP" );GPIO_SetBits(GPIO_CS, GPIO_Pin_CS);__asm volatile( "NOP" );__asm volatile( "NOP" );__asm volatile( "NOP" );__asm volatile( "NOP" )
/* Exported functions ------------------------------------------------------- */
/*----- High layer function -----*/
void SPI_FLASH_Init(void);
void SPI_FLASH_SectorErase(uint32_t SectorAddr);
void SPI_FLASH_BulkErase(void);
void SPI_FLASH_PageWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
void SPI_FLASH_BufferWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
void SPI_FLASH_BufferRead(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead);
uint32_t SPI_FLASH_ReadID(void);
void SPI_FLASH_StartReadSequence(uint32_t ReadAddr);
/*----- Low layer function -----*/
uint8_t SPI_FLASH_ReadByte(void);
uint8_t SPI_FLASH_SendByte(uint8_t byte);
uint16_t SPI_FLASH_SendHalfWord(uint16_t HalfWord);
void SPI_FLASH_WriteEnable(void);
void SPI_FLASH_WaitForWriteEnd(void);
#endif /* __SPI_FLASH_H */
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

View File

@ -63,15 +63,12 @@
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
/* Driver includes. */
#include "CircularBuffer.h"
/* Library includes. */
#include "stm32f10x_lib.h"
#include "stm32f10x_rcc.h"
/* Driver includes. */
#include "STM32_USART.h"
@ -80,40 +77,43 @@
/* The number of COM ports that can be controlled at the same time. */
#define serNUM_COM_PORTS ( 2 )
/* Indexes into the xCOMBufferDefinitions array for the Rx and Tx buffers. */
#define serRX_BUFFER_INDEX ( 0 )
#define serTX_BUFFER_INDEX ( 1 )
/* Queues are used to hold characters that are waiting to be transmitted. This
constant sets the maximum number of characters that can be contained in such a
queue at any one time. */
#define serTX_QUEUE_LEN ( 100 )
/* A counting semaphore is used to allows tasks to block to wait for characters
to be received. This constant defines the max count. Making this value higher
does not change the amount of RAM used by the semaphore, so its worth making it
quite high. */
#define serSEMAPHORE_MAX_COUNT ( 100 )
/* Queues are used to hold characters that have been received but not yet
processed. This constant sets the maximum number of characters that can be
contained in such a queue. */
#define serRX_QUEUE_LEN ( 100 )
/* The maximum amount of time that calls to lSerialPutString() should wait for
there to be space to post each character to the queue of characters waiting
transmission. NOTE! This is the time to wait per character - not the time to
wait for the entire string. */
#define serPUT_STRING_CHAR_DELAY ( 5 / portTICK_RATE_MS )
/*-----------------------------------------------------------*/
/* An Rx and a Tx buffer structure for each COM port. */
static xCircularBuffer xCOMBufferDefinitions[ serNUM_COM_PORTS ][ 2 ];
/* References to the USART peripheral addresses themselves. */
static USART_TypeDef * const xUARTS[ serNUM_COM_PORTS ] = { ( ( USART_TypeDef * ) USART1_BASE ), ( ( USART_TypeDef * ) USART2_BASE ) };
/* The buffers themselves. */
static unsigned char ucCOM0_Rx_Buffer[ configCOM0_RX_BUFFER_LENGTH ];
static unsigned char ucCOM0_Tx_Buffer[ configCOM0_TX_BUFFER_LENGTH ];
static unsigned char ucCOM1_Rx_Buffer[ configCOM1_RX_BUFFER_LENGTH ];
static unsigned char ucCOM1_Tx_Buffer[ configCOM1_TX_BUFFER_LENGTH ];
/* Queues used to hold characters waiting to be transmitted - one queue per port. */
static xQueueHandle xCharsForTx[ serNUM_COM_PORTS ] = { 0 };
/* Semaphores used to block tasks that are waiting for characters to be
received. */
static xSemaphoreHandle xCOM0RxSemaphore, xCOM1RxSemaphore;
/* Queues holding received characters - one queue per port. */
static xQueueHandle xRxedChars[ serNUM_COM_PORTS ] = { 0 };
/*-----------------------------------------------------------*/
/* UART interrupt handler. */
void vUARTInterruptHandler( void );
/* UART interrupt handlers, as named in the vector table. */
void USART1_IRQHandler( void );
void USART2_IRQHandler( void );
/*-----------------------------------------------------------*/
/*
* See serial.h in this project for parameter descriptions.
* See header file for parameter descriptions.
*/
long lCOMPortInit( unsigned long ulPort, unsigned long ulWantedBaud )
{
@ -141,26 +141,13 @@ GPIO_InitTypeDef GPIO_InitStructure;
does not check to see if the COM port has already been initialised. */
if( ulPort == 0 )
{
/* Create the semaphore used to enable tasks to block to wait for
characters to be received. */
xCOM0RxSemaphore = xSemaphoreCreateCounting( serSEMAPHORE_MAX_COUNT, 0 );
/* Create the queue of chars that are waiting to be sent to COM0. */
xCharsForTx[ 0 ] = xQueueCreate( serTX_QUEUE_LEN, sizeof( char ) );
vInitialiseCircularBuffer( &( xCOMBufferDefinitions[ ulPort ][ serRX_BUFFER_INDEX ] ),
ucCOM0_Rx_Buffer,
configCOM0_RX_BUFFER_LENGTH,
sizeof( unsigned char ),
NULL
);
/* Create the queue used to hold characters received from COM0. */
xRxedChars[ 0 ] = xQueueCreate( serRX_QUEUE_LEN, sizeof( char ) );
vInitialiseCircularBuffer( &( xCOMBufferDefinitions[ ulPort ][ serTX_BUFFER_INDEX ] ),
ucCOM0_Tx_Buffer,
configCOM0_TX_BUFFER_LENGTH,
sizeof( unsigned char ),
NULL
);
/* Enable COM1 clock - the ST libraries start numbering from UART1,
making this UART 2. */
/* Enable COM0 clock - the ST libraries start numbering from UART1. */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE );
/* Configure USART1 Rx (PA10) as input floating */
@ -182,26 +169,17 @@ GPIO_InitTypeDef GPIO_InitStructure;
USART_DMACmd( USART1, ( USART_DMAReq_Tx | USART_DMAReq_Rx ), ENABLE );
USART_Cmd( USART1, ENABLE );
/* Everything is ok. */
lReturn = pdPASS;
}
else
else if( ulPort == 1 )
{
/* Create the semaphore used to enable tasks to block to wait for
characters to be received. */
xCOM1RxSemaphore = xSemaphoreCreateCounting( serSEMAPHORE_MAX_COUNT, 0 );
/* Create the queue of chars that are waiting to be sent to COM1. */
xCharsForTx[ 1 ] = xQueueCreate( serTX_QUEUE_LEN, sizeof( char ) );
vInitialiseCircularBuffer( &( xCOMBufferDefinitions[ ulPort ][ serRX_BUFFER_INDEX ] ),
ucCOM1_Rx_Buffer,
configCOM1_RX_BUFFER_LENGTH,
sizeof( unsigned char ),
NULL
);
vInitialiseCircularBuffer( &( xCOMBufferDefinitions[ ulPort ][ serTX_BUFFER_INDEX ] ),
ucCOM1_Tx_Buffer,
configCOM1_TX_BUFFER_LENGTH,
sizeof( unsigned char ),
NULL
);
/* Create the queue used to hold characters received from COM0. */
xRxedChars[ 1 ] = xQueueCreate( serRX_QUEUE_LEN, sizeof( char ) );
/* Enable COM0 clock - the ST libraries start numbering from 1. */
RCC_APB2PeriphClockCmd( RCC_APB1Periph_USART2 | RCC_APB2Periph_GPIOA, ENABLE );
@ -225,34 +203,89 @@ GPIO_InitTypeDef GPIO_InitStructure;
USART_DMACmd( USART2, ( USART_DMAReq_Tx | USART_DMAReq_Rx ), ENABLE );
USART_Cmd( USART2, ENABLE );
/* Everything is ok. */
lReturn = pdPASS;
}
/* Everything is ok. */
lReturn = pdPASS;
else
{
/* Nothing to do unless more than two ports are supported. */
}
}
return lReturn;
}
/*-----------------------------------------------------------*/
signed long xUSARTGetChar( long lPort, signed char *pcRxedChar, portTickType xBlockTime )
signed long xSerialGetChar( long lPort, signed char *pcRxedChar, portTickType xBlockTime )
{
return pdFALSE;
long lReturn = pdFAIL;
if( lPort < serNUM_COM_PORTS )
{
if( xQueueReceive( xRxedChars[ lPort ], pcRxedChar, xBlockTime ) == pdPASS )
{
lReturn = pdPASS;
}
}
return lReturn;
}
/*-----------------------------------------------------------*/
void vSerialPutString( long lPort, const signed char * const pcString, unsigned portSHORT usStringLength )
long lSerialPutString( long lPort, const char * const pcString, unsigned long ulStringLength )
{
long lReturn;
unsigned long ul;
if( lPort < serNUM_COM_PORTS )
{
lReturn = pdPASS;
for( ul = 0; ul < ulStringLength; ul++ )
{
if( xQueueSend( xCharsForTx[ lPort ], &( pcString[ ul ] ), serPUT_STRING_CHAR_DELAY ) != pdPASS )
{
/* Cannot fit any more in the queue. Try turning the Tx on to
clear some space. */
USART_ITConfig( xUARTS[ lPort ], USART_IT_TXE, ENABLE );
vTaskDelay( serPUT_STRING_CHAR_DELAY );
/* Go back and try again. */
continue;
}
}
USART_ITConfig( xUARTS[ lPort ], USART_IT_TXE, ENABLE );
}
else
{
lReturn = pdFAIL;
}
return lReturn;
}
/*-----------------------------------------------------------*/
signed long xSerialPutChar( long lPort, signed char cOutChar, portTickType xBlockTime )
{
return pdFALSE;
long lReturn;
if( xQueueSend( xCharsForTx[ lPort ], &cOutChar, xBlockTime ) == pdPASS )
{
lReturn = pdPASS;
USART_ITConfig( xUARTS[ lPort ], USART_IT_TXE, ENABLE );
}
else
{
lReturn = pdFAIL;
}
return lReturn;
}
/*-----------------------------------------------------------*/
void vUARTInterruptHandler( void )
void USART1_IRQHandler( void )
{
long xHigherPriorityTaskWoken = pdFALSE;
char cChar;
@ -261,9 +294,9 @@ char cChar;
{
/* The interrupt was caused by the THR becoming empty. Are there any
more characters to transmit? */
if( 0 )// if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE )
if( xQueueReceiveFromISR( xCharsForTx[ 0 ], &cChar, &xHigherPriorityTaskWoken ) )
{
/* A character was retrieved from the queue so can be sent to the
/* A character was retrieved from the buffer so can be sent to the
THR now. */
USART_SendData( USART1, cChar );
}
@ -276,14 +309,18 @@ if( 0 )// if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWo
if( USART_GetITStatus( USART1, USART_IT_RXNE ) == SET )
{
cChar = USART_ReceiveData( USART1 );
// xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );
xQueueSendFromISR( xRxedChars[ 0 ], &cChar, &xHigherPriorityTaskWoken );
}
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
/*-----------------------------------------------------------*/
void USART2_IRQHandler( void )
{
}

View File

@ -55,6 +55,9 @@
#define STM_32_SERIAL_COMMS_H
long lCOMPortInit( unsigned long ulPort, unsigned long ulWantedBaud );
signed long xSerialPutChar( long lPort, signed char cOutChar, portTickType xBlockTime );
signed long xSerialGetChar( long lPort, signed char *pcRxedChar, portTickType xBlockTime );
long lSerialPutString( long lPort, const char * const pcString, unsigned long ulStringLength );
#endif

View File

@ -1,7 +1,7 @@
<!DOCTYPE CrossStudio_Project_File>
<solution Name="RTOSDemo" version="2">
<project Name="RTOSDemo">
<configuration Name="Common" Target="STM32F103RB" arm_architecture="v7M" arm_core_type="Cortex-M3" arm_linker_fiq_stack_size="0" arm_linker_heap_size="128" arm_linker_irq_stack_size="0" arm_linker_jtag_pad_pre_dr="1" arm_linker_jtag_pad_pre_ir="5" arm_linker_stack_size="128" arm_simulator_memory_simulation_filename="$(PackagesDir)/targets/ST_STM32F10x/STM32F10xSimulatorMemory.dll" arm_simulator_memory_simulation_parameter="0x20000;0x4000" arm_target_debug_interface_type="ADIv5" arm_target_loader_parameter="8000000" c_only_additional_options="-Wall;-Wextra" c_system_include_directories="$(StudioDir)/include;$(PackagesDir)/include;$(PackagesDir)/targets/stm32/include" c_user_include_directories=".;../../Source/include/;../../Source/portable/GCC/ARM_CM3/;../Common/Include/;ST Library/inc/;./Drivers/" link_include_startup_code="No" linker_memory_map_file="$(TargetsDir)/ST_STM32F10x/ST_STM32F103RB_MemoryMap.xml" linker_printf_width_precision_supported="No" oscillator_frequency="8MHz" project_directory="" project_type="Executable" property_groups_file_path="$(PackagesDir)/targets/ST_STM32F10x/propertyGroups.xml"/>
<configuration Name="Common" Target="STM32F103RB" arm_architecture="v7M" arm_core_type="Cortex-M3" arm_linker_fiq_stack_size="0" arm_linker_heap_size="8" arm_linker_irq_stack_size="0" arm_linker_jtag_pad_pre_dr="1" arm_linker_jtag_pad_pre_ir="5" arm_linker_stack_size="256" arm_simulator_memory_simulation_filename="$(PackagesDir)/targets/ST_STM32F10x/STM32F10xSimulatorMemory.dll" arm_simulator_memory_simulation_parameter="0x20000;0x4000" arm_target_debug_interface_type="ADIv5" arm_target_loader_parameter="8000000" c_only_additional_options="-Wall;-Wextra" c_preprocessor_definitions="USE_STM3210B_EVAL" c_system_include_directories="$(StudioDir)/include;$(PackagesDir)/include;$(PackagesDir)/targets/stm32/include" c_user_include_directories=".;../../Source/include/;../../Source/portable/GCC/ARM_CM3/;../Common/Include/;ST Library/inc/;./Drivers/" link_include_startup_code="No" linker_memory_map_file="$(TargetsDir)/ST_STM32F10x/ST_STM32F103RB_MemoryMap.xml" linker_printf_width_precision_supported="No" oscillator_frequency="8MHz" project_directory="" project_type="Executable" property_groups_file_path="$(PackagesDir)/targets/ST_STM32F10x/propertyGroups.xml"/>
<configuration Name="RAM" Placement="RAM" linker_section_placement_file="$(StudioDir)/targets/sram_placement.xml" target_reset_script="SRAMReset()"/>
<configuration Name="Flash" Placement="Flash" arm_target_flash_loader_file_path="$(PackagesDir)/targets/ST_STM32F10x/Release/Loader_rpc.elf" arm_target_flash_loader_type="LIBMEM RPC Loader" linker_section_placement_file="$(StudioDir)/targets/flash_placement.xml" target_reset_script="FLASHReset()"/>
<folder Name="Source Files">
@ -36,14 +36,16 @@
<file file_name="ST Library/src/stm32f10x_i2c.c"/>
</folder>
<folder Name="Drivers">
<file file_name="Drivers/CircularBuffer.c"/>
<file file_name="Drivers/STM32_USART.c"/>
<file file_name="Drivers/SPI_Flash_ST_Eval.c"/>
</folder>
<folder Name="ParTest">
<file file_name="ParTest/ParTest_MCBSTM32.c">
<configuration Name="THUMB Flash Debug" build_exclude_from_build="No"/>
</file>
<file file_name="ParTest/ParTest_ST_Eval.c">
<configuration Name="THUMB Flash Debug" build_exclude_from_build="Yes"/>
</file>
<file file_name="ParTest/ParTest_ST_Eval.c"/>
</folder>
</folder>
<folder Name="System Files">

View File

@ -18,10 +18,6 @@
<Project>
<ProjectSessionItem path="RTOSDemo" name="unnamed" />
<ProjectSessionItem path="RTOSDemo;RTOSDemo" name="unnamed" />
<ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files" name="unnamed" />
<ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files;Drivers" name="unnamed" />
<ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files;FreeRTOS Source" name="unnamed" />
<ProjectSessionItem path="RTOSDemo;RTOSDemo;Source Files;ST Library" name="unnamed" />
<ProjectSessionItem path="RTOSDemo;RTOSDemo;System Files" name="unnamed" />
</Project>
<Register1>
@ -53,11 +49,14 @@
<Watches active="0" update="Never" />
</Watch4>
<Files>
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ParTest\ParTest.c" y="0" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ParTest\ParTest.c" left="0" selected="0" name="unnamed" top="39" />
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ParTest\ParTest_ST_Eval.c" y="80" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ParTest\ParTest_ST_Eval.c" left="0" selected="0" name="unnamed" top="60" />
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\stm32f10x_conf.h" y="83" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\stm32f10x_conf.h" left="0" selected="0" name="unnamed" top="63" />
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="15" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\main.c" y="266" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\main.c" left="0" selected="0" name="unnamed" top="235" />
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\STM32F10x_Startup.s" y="0" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\STM32F10x_Startup.s" left="0" selected="1" name="unnamed" top="0" />
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="56" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\Drivers\STM32_USART.c" y="93" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\Drivers\STM32_USART.c" left="0" selected="0" name="unnamed" top="74" />
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="5" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ST Library\src\stm32f10x_usart.c" y="353" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ST Library\src\stm32f10x_usart.c" left="0" selected="0" name="unnamed" top="336" />
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="33" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ST Library\inc\stm32f10x_usart.h" y="238" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ST Library\inc\stm32f10x_usart.h" left="0" selected="0" name="unnamed" top="218" />
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\main.c" y="138" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\main.c" left="0" selected="0" name="unnamed" top="119" />
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="41" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\Drivers\STM32_USART.h" y="59" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\Drivers\STM32_USART.h" left="0" selected="0" name="unnamed" top="36" />
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\STM32F10x_Startup.s" y="110" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\STM32F10x_Startup.s" left="0" selected="0" name="unnamed" top="91" />
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\Common\Minimal\semtest.c" y="221" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\Common\Minimal\semtest.c" left="0" selected="0" name="unnamed" top="205" />
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Source\queue.c" y="820" path="C:\E\Dev\FreeRTOS\WorkingCopy\Source\queue.c" left="0" selected="1" name="unnamed" top="801" />
</Files>
<ARMCrossStudioWindow activeProject="RTOSDemo" autoConnectTarget="USB CrossConnect for ARM" debugSearchFileMap="" fileDialogInitialDirectory="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ST Library\src" fileDialogDefaultFilter="*.c" autoConnectCapabilities="388991" debugSearchPath="" buildConfiguration="THUMB Flash Debug" />
<ARMCrossStudioWindow activeProject="RTOSDemo" autoConnectTarget="USB CrossConnect for ARM" debugSearchFileMap="" fileDialogInitialDirectory="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley" fileDialogDefaultFilter="*.c" autoConnectCapabilities="388991" debugSearchPath="" buildConfiguration="THUMB Flash Debug" />
</session>

View File

@ -61,27 +61,28 @@
* In addition to the standard demo tasks, the following tasks and tests are
* defined and/or created within this file:
*
* "Check" task - This only executes every five seconds but has the highest
* "Check" task - This only executes every five seconds but has the highest
* priority so is guaranteed to get processor time. Its main function is to
* check that all the standard demo tasks are still operational. The check task
* will toggle LED 7 (PB15) every five seconds so long as no errors have been
* will toggle LED 3 (PB11) every five seconds so long as no errors have been
* detected. The toggle rate will increase to half a second if an error has
* been found in any task.
*
* "Echo" task - This is a very basic task that simply echoes any characters
* received on COM0 (USART1). This can be tested by transmitting a text file
* from a dumb terminal to the STM32 USART.
*/
/* Standard includes. */
#include <stdio.h>
#include <string.h>
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
/* Library includes. */
#include "stm32f10x_it.h"
#include "stm32f10x_tim.h"
/* Demo app includes. */
#include "BlockQ.h"
@ -93,6 +94,9 @@
#include "QPeek.h"
#include "recmutex.h"
/* Driver includes. */
#include "STM32_USART.h"
/* The time between cycles of the 'check' task - which depends on whether the
check task has detected an error or not. */
@ -107,9 +111,14 @@ check task has detected an error or not. */
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainECHO_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* COM port and baud rate used by the echo task. */
#define mainCOM0 ( 0 )
#define mainBAUD_RATE ( 115200 )
/*-----------------------------------------------------------*/
/*
@ -120,6 +129,10 @@ static void prvSetupHardware( void );
/* The 'check' task as described at the top of this file. */
static void prvCheckTask( void *pvParameters );
/* A simple task that echoes all the characters that are received on COM0
(USART1). */
static void prvUSARTEchoTask( void *pvParameters );
/*-----------------------------------------------------------*/
int main( void )
@ -141,7 +154,10 @@ int main( void )
vStartQueuePeekTasks();
vStartRecursiveMutexTasks();
/* Create the 'check' task, which is defined within this file. */
/* Create the 'echo' task, which is also defined within this file. */
xTaskCreate( prvUSARTEchoTask, ( signed char * ) "Echo", configMINIMAL_STACK_SIZE, NULL, mainECHO_TASK_PRIORITY, NULL );
/* Create the 'check' task, which is also defined within this file. */
xTaskCreate( prvCheckTask, ( signed char * ) "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
/* Start the scheduler. */
@ -153,6 +169,7 @@ int main( void )
}
/*-----------------------------------------------------------*/
/* Described at the top of this file. */
static void prvCheckTask( void *pvParameters )
{
portTickType xLastExecutionTime;
@ -204,6 +221,49 @@ unsigned long ulTicksToWait = mainCHECK_DELAY_NO_ERROR;
}
/*-----------------------------------------------------------*/
/* Described at the top of this file. */
static void prvUSARTEchoTask( void *pvParameters )
{
signed char cChar;
/* String declared static to ensure it does not end up on the stack, no matter
what the optimisation level. */
static const char *pcLongishString =
"ABBA was a Swedish pop music group formed in Stockholm in 1972, consisting of Anni-Frid Frida Lyngstad, "
"Björn Ulvaeus, Benny Andersson and Agnetha Fältskog. Throughout the band's existence, Fältskog and Ulvaeus "
"were a married couple, as were Lyngstad and Andersson - although both couples later divorced. They became one "
"of the most commercially successful acts in the history of popular music, and they topped the charts worldwide "
"from 1972 to 1983. ABBA gained international popularity employing catchy song hooks, simple lyrics, sound "
"effects (reverb, phasing) and a Wall of Sound achieved by overdubbing the female singers' voices in multiple "
"harmonies. As their popularity grew, they were sought after to tour Europe, Australia, and North America, drawing "
"crowds of ardent fans, notably in Australia. Touring became a contentious issue, being particularly cumbersome for "
"Fältskog, but they continued to release studio albums to widespread commercial success. At the height of their "
"popularity, however, both relationships began suffering strain that led ultimately to the collapse of first the "
"Ulvaeus-Fältskog marriage (in 1979) and then of the Andersson-Lyngstad marriage in 1981. In the late 1970s and early "
"1980s these relationship changes began manifesting in the group's music, as they produced more thoughtful, "
"introspective lyrics with different compositions.";
/* Just to avoid compiler warnings. */
( void ) pvParameters;
/* Initialise COM0, which is USART1 according to the STM32 libraries. */
lCOMPortInit( mainCOM0, mainBAUD_RATE );
/* Try sending out a string all in one go, as a very basic test of the
lSerialPutString() function. */
lSerialPutString( mainCOM0, pcLongishString, strlen( pcLongishString ) );
for( ;; )
{
/* Block to wait for a character to be received on COM0. */
xSerialGetChar( mainCOM0, &cChar, portMAX_DELAY );
/* Write the received character back to COM0. */
xSerialPutChar( mainCOM0, cChar, 0 );
}
}
/*-----------------------------------------------------------*/
static void prvSetupHardware( void )
{
/* RCC system reset(for debug purpose). */
@ -262,9 +322,6 @@ static void prvSetupHardware( void )
/* SPI2 Periph clock enable */
RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );
/* Initialize the SPI FLASH driver */
SPI_FLASH_Init();
}
/*-----------------------------------------------------------*/

View File

@ -114,7 +114,7 @@
/************************************* SPI ************************************/
#define _SPI
#define _SPI1
//#define _SPI2
#define _SPI2
//#define _SPI3
/************************************* SysTick ********************************/