Work in progress - checked in for backup only.

This commit is contained in:
Richard Barry 2010-06-07 15:24:50 +00:00
parent 02db572328
commit e03f239692
13 changed files with 1240 additions and 336 deletions

View File

@ -0,0 +1,214 @@
/*
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

@ -0,0 +1,115 @@
/*
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

@ -0,0 +1,482 @@
/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
* File Name : spi_flash.c
* Author : MCD Application Team
* Version : V2.0.0
* Date : 04/27/2009
* Description : This file provides a set of functions needed to manage the
* communication between SPI peripheral and SPI M25P64 FLASH.
********************************************************************************
* 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.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "spi_flash.h"
/* Private typedef -----------------------------------------------------------*/
#define SPI_FLASH_PageSize 0x100
/* Private define ------------------------------------------------------------*/
#define WRITE 0x02 /* Write to Memory instruction */
#define WRSR 0x01 /* Write Status Register instruction */
#define WREN 0x06 /* Write enable instruction */
#define READ 0x03 /* Read from Memory instruction */
#define RDSR 0x05 /* Read Status Register instruction */
#define RDID 0x9F /* Read identification */
#define SE 0xD8 /* Sector Erase instruction */
#define BE 0xC7 /* Bulk Erase instruction */
#define WIP_Flag 0x01 /* Write In Progress (WIP) flag */
#define Dummy_Byte 0xA5
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : SPI_FLASH_Init
* Description : Initializes the peripherals used by the SPI FLASH driver.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SPI_FLASH_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable SPI1 and GPIO clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA |
RCC_APB2Periph_GPIO_CS, ENABLE);
/* Configure SPI1 pins: SCK, MISO and MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure I/O for Flash Chip select */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CS;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIO_CS, &GPIO_InitStructure);
/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();
/* SPI1 configuration */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
/* Enable SPI1 */
SPI_Cmd(SPI1, ENABLE);
}
/*******************************************************************************
* Function Name : SPI_FLASH_SectorErase
* Description : Erases the specified FLASH sector.
* Input : SectorAddr: address of the sector to erase.
* Output : None
* Return : None
*******************************************************************************/
void SPI_FLASH_SectorErase(uint32_t SectorAddr)
{
/* Send write enable instruction */
SPI_FLASH_WriteEnable();
/* Sector Erase */
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* Send Sector Erase instruction */
SPI_FLASH_SendByte(SE);
/* Send SectorAddr high nibble address byte */
SPI_FLASH_SendByte((SectorAddr & 0xFF0000) >> 16);
/* Send SectorAddr medium nibble address byte */
SPI_FLASH_SendByte((SectorAddr & 0xFF00) >> 8);
/* Send SectorAddr low nibble address byte */
SPI_FLASH_SendByte(SectorAddr & 0xFF);
/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();
/* Wait the end of Flash writing */
SPI_FLASH_WaitForWriteEnd();
}
/*******************************************************************************
* Function Name : SPI_FLASH_BulkErase
* Description : Erases the entire FLASH.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SPI_FLASH_BulkErase(void)
{
/* Send write enable instruction */
SPI_FLASH_WriteEnable();
/* Bulk Erase */
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* Send Bulk Erase instruction */
SPI_FLASH_SendByte(BE);
/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();
/* Wait the end of Flash writing */
SPI_FLASH_WaitForWriteEnd();
}
/*******************************************************************************
* Function Name : SPI_FLASH_PageWrite
* Description : Writes more than one byte to the FLASH with a single WRITE
* cycle(Page WRITE sequence). The number of byte can't exceed
* the FLASH page size.
* Input : - pBuffer : pointer to the buffer containing the data to be
* written to the FLASH.
* - WriteAddr : FLASH's internal address to write to.
* - NumByteToWrite : number of bytes to write to the FLASH,
* must be equal or less than "SPI_FLASH_PageSize" value.
* Output : None
* Return : None
*******************************************************************************/
void SPI_FLASH_PageWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
/* Enable the write access to the FLASH */
SPI_FLASH_WriteEnable();
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* Send "Write to Memory " instruction */
SPI_FLASH_SendByte(WRITE);
/* Send WriteAddr high nibble address byte to write to */
SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
/* Send WriteAddr medium nibble address byte to write to */
SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8);
/* Send WriteAddr low nibble address byte to write to */
SPI_FLASH_SendByte(WriteAddr & 0xFF);
/* while there is data to be written on the FLASH */
while (NumByteToWrite--)
{
/* Send the current byte */
SPI_FLASH_SendByte(*pBuffer);
/* Point on the next byte to be written */
pBuffer++;
}
/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();
/* Wait the end of Flash writing */
SPI_FLASH_WaitForWriteEnd();
}
/*******************************************************************************
* Function Name : SPI_FLASH_BufferWrite
* Description : Writes block of data to the FLASH. In this function, the
* number of WRITE cycles are reduced, using Page WRITE sequence.
* Input : - pBuffer : pointer to the buffer containing the data to be
* written to the FLASH.
* - WriteAddr : FLASH's internal address to write to.
* - NumByteToWrite : number of bytes to write to the FLASH.
* Output : None
* Return : None
*******************************************************************************/
void SPI_FLASH_BufferWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;
Addr = WriteAddr % SPI_FLASH_PageSize;
count = SPI_FLASH_PageSize - Addr;
NumOfPage = NumByteToWrite / SPI_FLASH_PageSize;
NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;
if (Addr == 0) /* WriteAddr is SPI_FLASH_PageSize aligned */
{
if (NumOfPage == 0) /* NumByteToWrite < SPI_FLASH_PageSize */
{
SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
}
else /* NumByteToWrite > SPI_FLASH_PageSize */
{
while (NumOfPage--)
{
SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);
WriteAddr += SPI_FLASH_PageSize;
pBuffer += SPI_FLASH_PageSize;
}
SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
}
}
else /* WriteAddr is not SPI_FLASH_PageSize aligned */
{
if (NumOfPage == 0) /* NumByteToWrite < SPI_FLASH_PageSize */
{
if (NumOfSingle > count) /* (NumByteToWrite + WriteAddr) > SPI_FLASH_PageSize */
{
temp = NumOfSingle - count;
SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
WriteAddr += count;
pBuffer += count;
SPI_FLASH_PageWrite(pBuffer, WriteAddr, temp);
}
else
{
SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
}
}
else /* NumByteToWrite > SPI_FLASH_PageSize */
{
NumByteToWrite -= count;
NumOfPage = NumByteToWrite / SPI_FLASH_PageSize;
NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;
SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
WriteAddr += count;
pBuffer += count;
while (NumOfPage--)
{
SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);
WriteAddr += SPI_FLASH_PageSize;
pBuffer += SPI_FLASH_PageSize;
}
if (NumOfSingle != 0)
{
SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
}
}
}
}
/*******************************************************************************
* Function Name : SPI_FLASH_BufferRead
* Description : Reads a block of data from the FLASH.
* Input : - pBuffer : pointer to the buffer that receives the data read
* from the FLASH.
* - ReadAddr : FLASH's internal address to read from.
* - NumByteToRead : number of bytes to read from the FLASH.
* Output : None
* Return : None
*******************************************************************************/
void SPI_FLASH_BufferRead(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
{
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* Send "Read from Memory " instruction */
SPI_FLASH_SendByte(READ);
/* Send ReadAddr high nibble address byte to read from */
SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
/* Send ReadAddr medium nibble address byte to read from */
SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
/* Send ReadAddr low nibble address byte to read from */
SPI_FLASH_SendByte(ReadAddr & 0xFF);
while (NumByteToRead--) /* while there is data to be read */
{
/* Read a byte from the FLASH */
*pBuffer = SPI_FLASH_SendByte(Dummy_Byte);
/* Point to the next location where the byte read will be saved */
pBuffer++;
}
/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();
}
/*******************************************************************************
* Function Name : SPI_FLASH_ReadID
* Description : Reads FLASH identification.
* Input : None
* Output : None
* Return : FLASH identification
*******************************************************************************/
uint32_t SPI_FLASH_ReadID(void)
{
uint32_t Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* Send "RDID " instruction */
SPI_FLASH_SendByte(0x9F);
/* Read a byte from the FLASH */
Temp0 = SPI_FLASH_SendByte(Dummy_Byte);
/* Read a byte from the FLASH */
Temp1 = SPI_FLASH_SendByte(Dummy_Byte);
/* Read a byte from the FLASH */
Temp2 = SPI_FLASH_SendByte(Dummy_Byte);
/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();
Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
return Temp;
}
/*******************************************************************************
* Function Name : SPI_FLASH_StartReadSequence
* Description : Initiates a read data byte (READ) sequence from the Flash.
* This is done by driving the /CS line low to select the device,
* then the READ instruction is transmitted followed by 3 bytes
* address. This function exit and keep the /CS line low, so the
* Flash still being selected. With this technique the whole
* content of the Flash is read with a single READ instruction.
* Input : - ReadAddr : FLASH's internal address to read from.
* Output : None
* Return : None
*******************************************************************************/
void SPI_FLASH_StartReadSequence(uint32_t ReadAddr)
{
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* Send "Read from Memory " instruction */
SPI_FLASH_SendByte(READ);
/* Send the 24-bit address of the address to read from -----------------------*/
/* Send ReadAddr high nibble address byte */
SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
/* Send ReadAddr medium nibble address byte */
SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
/* Send ReadAddr low nibble address byte */
SPI_FLASH_SendByte(ReadAddr & 0xFF);
}
/*******************************************************************************
* Function Name : SPI_FLASH_ReadByte
* Description : Reads a byte from the SPI Flash.
* This function must be used only if the Start_Read_Sequence
* function has been previously called.
* Input : None
* Output : None
* Return : Byte Read from the SPI Flash.
*******************************************************************************/
uint8_t SPI_FLASH_ReadByte(void)
{
return (SPI_FLASH_SendByte(Dummy_Byte));
}
/*******************************************************************************
* Function Name : SPI_FLASH_SendByte
* Description : Sends a byte through the SPI interface and return the byte
* received from the SPI bus.
* Input : byte : byte to send.
* Output : None
* Return : The value of the received byte.
*******************************************************************************/
uint8_t SPI_FLASH_SendByte(uint8_t byte)
{
/* Loop while DR register in not emplty */
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
/* Send byte through the SPI1 peripheral */
SPI_I2S_SendData(SPI1, byte);
/* Wait to receive a byte */
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
/* Return the byte read from the SPI bus */
return SPI_I2S_ReceiveData(SPI1);
}
/*******************************************************************************
* Function Name : SPI_FLASH_SendHalfWord
* Description : Sends a Half Word through the SPI interface and return the
* Half Word received from the SPI bus.
* Input : Half Word : Half Word to send.
* Output : None
* Return : The value of the received Half Word.
*******************************************************************************/
uint16_t SPI_FLASH_SendHalfWord(uint16_t HalfWord)
{
/* Loop while DR register in not emplty */
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
/* Send Half Word through the SPI1 peripheral */
SPI_I2S_SendData(SPI1, HalfWord);
/* Wait to receive a Half Word */
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
/* Return the Half Word read from the SPI bus */
return SPI_I2S_ReceiveData(SPI1);
}
/*******************************************************************************
* Function Name : SPI_FLASH_WriteEnable
* Description : Enables the write access to the FLASH.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SPI_FLASH_WriteEnable(void)
{
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* Send "Write Enable" instruction */
SPI_FLASH_SendByte(WREN);
/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();
}
/*******************************************************************************
* Function Name : SPI_FLASH_WaitForWriteEnd
* Description : Polls the status of the Write In Progress (WIP) flag in the
* FLASH's status register and loop until write opertaion
* has completed.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SPI_FLASH_WaitForWriteEnd(void)
{
uint8_t FLASH_Status = 0;
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* Send "Read Status Register" instruction */
SPI_FLASH_SendByte(RDSR);
/* Loop as long as the memory is busy with a write cycle */
do
{
/* Send a dummy byte to generate the clock needed by the FLASH
and put the value of the status register in FLASH_Status variable */
FLASH_Status = SPI_FLASH_SendByte(Dummy_Byte);
}
while ((FLASH_Status & WIP_Flag) == SET); /* Write in progress */
/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();
}
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,289 @@
/*
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.
*/
/*
INTERRUPT DRIVEN SERIAL PORT DRIVER.
*/
/******************************************************************************
*** NOTE: COM0 == USART1, COM1 == USART2
******************************************************************************/
/* Scheduler includes. */
#include "FreeRTOS.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"
/*-----------------------------------------------------------*/
/* 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 )
/* 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 )
/*-----------------------------------------------------------*/
/* An Rx and a Tx buffer structure for each COM port. */
static xCircularBuffer xCOMBufferDefinitions[ serNUM_COM_PORTS ][ 2 ];
/* 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 ];
/* Semaphores used to block tasks that are waiting for characters to be
received. */
static xSemaphoreHandle xCOM0RxSemaphore, xCOM1RxSemaphore;
/*-----------------------------------------------------------*/
/* UART interrupt handler. */
void vUARTInterruptHandler( void );
/*-----------------------------------------------------------*/
/*
* See serial.h in this project for parameter descriptions.
*/
long lCOMPortInit( unsigned long ulPort, unsigned long ulWantedBaud )
{
long lReturn = pdFAIL;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
if( ulPort < serNUM_COM_PORTS )
{
/* The common (not port dependent) part of the initialisation. */
USART_InitStructure.USART_BaudRate = ulWantedBaud;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_KERNEL_INTERRUPT_PRIORITY;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/* Init the buffer structures with the buffer for the COM port being
initialised, and perform any non-common initialisation necessary. This
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 );
vInitialiseCircularBuffer( &( xCOMBufferDefinitions[ ulPort ][ serRX_BUFFER_INDEX ] ),
ucCOM0_Rx_Buffer,
configCOM0_RX_BUFFER_LENGTH,
sizeof( unsigned char ),
NULL
);
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. */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE );
/* Configure USART1 Rx (PA10) as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( GPIOA, &GPIO_InitStructure );
/* Configure USART1 Tx (PA9) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init( GPIOA, &GPIO_InitStructure );
USART_Init( USART1, &USART_InitStructure );
USART_ITConfig( USART1, USART_IT_RXNE, ENABLE );
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
NVIC_Init( &NVIC_InitStructure );
USART_DMACmd( USART1, ( USART_DMAReq_Tx | USART_DMAReq_Rx ), ENABLE );
USART_Cmd( USART1, ENABLE );
}
else
{
/* Create the semaphore used to enable tasks to block to wait for
characters to be received. */
xCOM1RxSemaphore = xSemaphoreCreateCounting( serSEMAPHORE_MAX_COUNT, 0 );
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
);
/* Enable COM0 clock - the ST libraries start numbering from 1. */
RCC_APB2PeriphClockCmd( RCC_APB1Periph_USART2 | RCC_APB2Periph_GPIOA, ENABLE );
/* Configure USART2 Rx (PA3) as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( GPIOA, &GPIO_InitStructure );
/* Configure USART2 Tx (PA2) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init( GPIOA, &GPIO_InitStructure );
USART_Init( USART2, &USART_InitStructure );
USART_ITConfig( USART2, USART_IT_RXNE, ENABLE );
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQChannel;
NVIC_Init( &NVIC_InitStructure );
USART_DMACmd( USART2, ( USART_DMAReq_Tx | USART_DMAReq_Rx ), ENABLE );
USART_Cmd( USART2, ENABLE );
}
/* Everything is ok. */
lReturn = pdPASS;
}
return lReturn;
}
/*-----------------------------------------------------------*/
signed long xUSARTGetChar( long lPort, signed char *pcRxedChar, portTickType xBlockTime )
{
return pdFALSE;
}
/*-----------------------------------------------------------*/
void vSerialPutString( long lPort, const signed char * const pcString, unsigned portSHORT usStringLength )
{
}
/*-----------------------------------------------------------*/
signed long xSerialPutChar( long lPort, signed char cOutChar, portTickType xBlockTime )
{
return pdFALSE;
}
/*-----------------------------------------------------------*/
void vUARTInterruptHandler( void )
{
long xHigherPriorityTaskWoken = pdFALSE;
char cChar;
if( USART_GetITStatus( USART1, USART_IT_TXE ) == SET )
{
/* The interrupt was caused by the THR becoming empty. Are there any
more characters to transmit? */
if( 0 )// if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE )
{
/* A character was retrieved from the queue so can be sent to the
THR now. */
USART_SendData( USART1, cChar );
}
else
{
USART_ITConfig( USART1, USART_IT_TXE, DISABLE );
}
}
if( USART_GetITStatus( USART1, USART_IT_RXNE ) == SET )
{
cChar = USART_ReceiveData( USART1 );
// xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );
}
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}

View File

@ -0,0 +1,60 @@
/*
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 STM_32_SERIAL_COMMS_H
#define STM_32_SERIAL_COMMS_H
long lCOMPortInit( unsigned long ulPort, unsigned long ulWantedBaud );
#endif

View File

@ -84,7 +84,7 @@
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
#define configUSE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_ALTERNATIVE_API 0
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_RECURSIVE_MUTEXES 1
@ -115,29 +115,12 @@ NVIC value of 255. */
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15
/*-----------------------------------------------------------
* Ethernet configuration.
* UART configuration.
*-----------------------------------------------------------*/
/* MAC address configuration. */
#define configMAC_ADDR0 0x00
#define configMAC_ADDR1 0x12
#define configMAC_ADDR2 0x13
#define configMAC_ADDR3 0x10
#define configMAC_ADDR4 0x15
#define configMAC_ADDR5 0x11
/* IP address configuration. */
#define configIP_ADDR0 172
#define configIP_ADDR1 25
#define configIP_ADDR2 218
#define configIP_ADDR3 202
/* Netmask configuration. */
#define configNET_MASK0 255
#define configNET_MASK1 255
#define configNET_MASK2 255
#define configNET_MASK3 0
#define configCOM0_RX_BUFFER_LENGTH 128
#define configCOM0_TX_BUFFER_LENGTH 128
#define configCOM1_RX_BUFFER_LENGTH 128
#define configCOM1_TX_BUFFER_LENGTH 128
#endif /* FREERTOS_CONFIG_H */

View File

@ -60,16 +60,13 @@
#include "task.h"
#include "partest.h"
/* Standard includes. */
#include <string.h>
/* Library includes. */
#include "stm32f10x_lib.h"
#define partstNUM_LEDs 8
#define partstMAX_OUTPUT_LED ( 4 )
#define partstFIRST_LED GPIO_Pin_6
/* Holds the current output state for each of the LEDs. */
static unsigned char ucBitStates[ partstNUM_LEDs ];
static unsigned portSHORT usOutputValue = 0;
/*-----------------------------------------------------------*/
@ -77,60 +74,64 @@ void vParTestInitialise( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure PE14, PD13, PD3 and PD4 output push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
/* Configure PC.06, PC.07, PC.08 and PC.09 as output push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOB, &GPIO_InitStructure );
memset( ucBitStates, 0x00, sizeof( ucBitStates ) );
GPIO_Init( GPIOC, &GPIO_InitStructure );
}
/*-----------------------------------------------------------*/
void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue )
{
if( uxLED < partstNUM_LEDs )
unsigned portSHORT usBit;
vTaskSuspendAll();
{
portENTER_CRITICAL();
if( uxLED < partstMAX_OUTPUT_LED )
{
if( xValue != pdFALSE )
usBit = partstFIRST_LED << uxLED;
if( xValue == pdFALSE )
{
ucBitStates[ uxLED ] = pdTRUE;
usBit ^= ( unsigned portSHORT ) 0xffff;
usOutputValue &= usBit;
}
else
{
ucBitStates[ uxLED ] = pdFALSE;
usOutputValue |= usBit;
}
GPIO_WriteBit( GPIOB, ( GPIO_Pin_8 << uxLED ), ucBitStates[ uxLED ] );
}
portEXIT_CRITICAL();
GPIO_Write( GPIOC, usOutputValue );
}
}
xTaskResumeAll();
}
/*-----------------------------------------------------------*/
void vParTestToggleLED( unsigned portBASE_TYPE uxLED )
{
if( uxLED < partstNUM_LEDs )
unsigned portSHORT usBit;
vTaskSuspendAll();
{
portENTER_CRITICAL();
if( uxLED < partstMAX_OUTPUT_LED )
{
ucBitStates[ uxLED ] = !ucBitStates[ uxLED ];
GPIO_WriteBit( GPIOB, ( GPIO_Pin_8 << uxLED ), ucBitStates[ uxLED ] );
usBit = partstFIRST_LED << uxLED;
if( usOutputValue & usBit )
{
usOutputValue &= ~usBit;
}
else
{
usOutputValue |= usBit;
}
GPIO_Write( GPIOC, usOutputValue );
}
portEXIT_CRITICAL();
}
xTaskResumeAll();
}
/*-----------------------------------------------------------*/
portBASE_TYPE xGetLEDState( unsigned portBASE_TYPE uxLED )
{
if( uxLED < partstNUM_LEDs )
{
return ( portBASE_TYPE ) ucBitStates[ uxLED ];
}
else
{
return 0;
}
}

View File

@ -0,0 +1 @@
Only include one of the two ParTest source files in your build at any one time.

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" 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="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="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">
@ -24,7 +24,6 @@
<file file_name="../Common/Minimal/PollQ.c"/>
<file file_name="../Common/Minimal/QPeek.c"/>
</folder>
<file file_name="ParTest/ParTest.c"/>
<folder Name="ST Library">
<file file_name="ST Library/src/stm32f10x_gpio.c"/>
<file file_name="ST Library/src/stm32f10x_lib.c"/>
@ -36,7 +35,16 @@
<file file_name="ST Library/src/stm32f10x_can.c"/>
<file file_name="ST Library/src/stm32f10x_i2c.c"/>
</folder>
<file file_name="serial/serial.c"/>
<folder Name="Drivers">
<file file_name="Drivers/CircularBuffer.c"/>
<file file_name="Drivers/STM32_USART.c"/>
</folder>
<folder Name="ParTest">
<file file_name="ParTest/ParTest_MCBSTM32.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">
<file file_name="$(StudioDir)/source/thumb_crt0.s"/>

View File

@ -18,6 +18,10 @@
<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>
@ -49,11 +53,11 @@
<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\STM32F10x_Startup.s" y="148" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\STM32F10x_Startup.s" left="0" selected="0" name="unnamed" top="27" />
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="46" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\main.c" y="142" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\main.c" left="0" selected="1" name="unnamed" top="0" />
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="29" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\FreeRTOSConfig.h" y="88" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\FreeRTOSConfig.h" left="0" selected="0" name="unnamed" top="63" />
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Source\tasks.c" y="1385" path="C:\E\Dev\FreeRTOS\WorkingCopy\Source\tasks.c" left="0" selected="0" name="unnamed" top="1365" />
<SessionOpenFile useTextEdit="1" useBinaryEdit="0" codecName="Latin1" x="0" debugPath="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ST Library\src\stm32f10x_gpio.c" y="53" path="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\ST Library\src\stm32f10x_gpio.c" left="0" selected="0" name="unnamed" top="38" />
<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" />
</Files>
<ARMCrossStudioWindow activeProject="RTOSDemo" autoConnectTarget="USB CrossConnect for ARM" debugSearchFileMap="" fileDialogInitialDirectory="C:\E\Dev\FreeRTOS\WorkingCopy\Demo\CORTEX_STM32F103_GCC_Rowley\serial" 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\ST Library\src" fileDialogDefaultFilter="*.c" autoConnectCapabilities="388991" debugSearchPath="" buildConfiguration="THUMB Flash Debug" />
</session>

View File

@ -100,28 +100,16 @@ check task has detected an error or not. */
#define mainCHECK_DELAY_ERROR ( ( portTickType ) 500 / portTICK_RATE_MS )
/* The LED controlled by the 'check' task. */
#define mainCHECK_LED ( 7 )
#define mainCHECK_LED ( 3 )
/* Task priorities. */
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainLCD_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
/* The WEB server has a larger stack as it utilises stack hungry string
handling library calls. */
#define mainBASIC_WEB_STACK_SIZE ( configMINIMAL_STACK_SIZE * 4 )
/* The length of the queue used to send messages to the LCD task. */
#define mainQUEUE_SIZE ( 3 )
/* The period of the system clock in nano seconds. This is used to calculate
the jitter time in nano seconds. */
#define mainNS_PER_CLOCK ( ( unsigned long ) ( ( 1.0 / ( double ) configCPU_CLOCK_HZ ) * 1000000000.0 ) )
/*-----------------------------------------------------------*/
/*
@ -222,31 +210,31 @@ static void prvSetupHardware( void )
RCC_DeInit ();
/* Enable HSE. */
RCC_HSEConfig (RCC_HSE_ON);
RCC_HSEConfig( RCC_HSE_ON );
/* Wait till HSE is ready. */
while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
/* HCLK = SYSCLK. */
RCC_HCLKConfig (RCC_SYSCLK_Div1);
RCC_HCLKConfig( RCC_SYSCLK_Div1 );
/* PCLK2 = HCLK. */
RCC_PCLK2Config (RCC_HCLK_Div1);
RCC_PCLK2Config( RCC_HCLK_Div1 );
/* PCLK1 = HCLK/2. */
RCC_PCLK1Config (RCC_HCLK_Div2);
RCC_PCLK1Config( RCC_HCLK_Div2 );
/* ADCCLK = PCLK2/4. */
RCC_ADCCLKConfig (RCC_PCLK2_Div4);
RCC_ADCCLKConfig( RCC_PCLK2_Div4 );
/* Flash 2 wait state. */
*( volatile unsigned long * )0x40022000 = 0x01;
/* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig (RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_9 );
/* Enable PLL. */
RCC_PLLCmd (ENABLE);
RCC_PLLCmd( ENABLE );
/* Wait till PLL is ready. */
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
@ -271,6 +259,12 @@ static void prvSetupHardware( void )
/* Initialise the IO used for the LED outputs. */
vParTestInitialise();
/* SPI2 Periph clock enable */
RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );
/* Initialize the SPI FLASH driver */
SPI_FLASH_Init();
}
/*-----------------------------------------------------------*/

View File

@ -1,247 +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.
*/
/*
BASIC INTERRUPT DRIVEN SERIAL PORT DRIVER FOR UART0.
*/
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "queue.h"
#include "semphr.h"
/* Library includes. */
#include "stm32f10x_lib.h"
/* Demo application includes. */
#include "serial.h"
/*-----------------------------------------------------------*/
/* Misc defines. */
#define serINVALID_QUEUE ( ( xQueueHandle ) 0 )
#define serNO_BLOCK ( ( portTickType ) 0 )
#define serTX_BLOCK_TIME ( 40 / portTICK_RATE_MS )
/*-----------------------------------------------------------*/
/* The queue used to hold received characters. */
static xQueueHandle xRxedChars;
static xQueueHandle xCharsForTx;
/*-----------------------------------------------------------*/
/* UART interrupt handler. */
void vUARTInterruptHandler( void );
/*-----------------------------------------------------------*/
/*
* See the serial2.h header file.
*/
xComPortHandle xSerialPortInitMinimal( unsigned portLONG ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
{
xComPortHandle xReturn;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Create the queues used to hold Rx/Tx characters. */
xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );
xCharsForTx = xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) );
/* If the queue/semaphore was created correctly then setup the serial port
hardware. */
if( ( xRxedChars != serINVALID_QUEUE ) && ( xCharsForTx != serINVALID_QUEUE ) )
{
/* Enable USART1 clock */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE );
/* Configure USART1 Rx (PA10) as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( GPIOA, &GPIO_InitStructure );
/* Configure USART1 Tx (PA9) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init( GPIOA, &GPIO_InitStructure );
USART_InitStructure.USART_BaudRate = ulWantedBaud;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init( USART1, &USART_InitStructure );
USART_ITConfig( USART1, USART_IT_RXNE, ENABLE );
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_KERNEL_INTERRUPT_PRIORITY;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init( &NVIC_InitStructure );
USART_Cmd( USART1, ENABLE );
}
else
{
xReturn = ( xComPortHandle ) 0;
}
/* This demo file only supports a single port but we have to return
something to comply with the standard demo header file. */
return xReturn;
}
/*-----------------------------------------------------------*/
signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed portCHAR *pcRxedChar, portTickType xBlockTime )
{
/* The port handle is not required as this driver only supports one port. */
( void ) pxPort;
/* Get the next character from the buffer. Return false if no characters
are available, or arrive before xBlockTime expires. */
if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )
{
return pdTRUE;
}
else
{
return pdFALSE;
}
}
/*-----------------------------------------------------------*/
void vSerialPutString( xComPortHandle pxPort, const signed portCHAR * const pcString, unsigned portSHORT usStringLength )
{
signed portCHAR *pxNext;
/* A couple of parameters that this port does not use. */
( void ) usStringLength;
( void ) pxPort;
/* NOTE: This implementation does not handle the queue being full as no
block time is used! */
/* The port handle is not required as this driver only supports UART1. */
( void ) pxPort;
/* Send each character in the string, one at a time. */
pxNext = ( signed portCHAR * ) pcString;
while( *pxNext )
{
xSerialPutChar( pxPort, *pxNext, serNO_BLOCK );
pxNext++;
}
}
/*-----------------------------------------------------------*/
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed portCHAR cOutChar, portTickType xBlockTime )
{
signed portBASE_TYPE xReturn;
/* Just to remove the compiler warning. */
( void ) pxPort;
if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) == pdPASS )
{
xReturn = pdPASS;
USART_ITConfig( USART1, USART_IT_TXE, ENABLE );
}
else
{
xReturn = pdFAIL;
}
return xReturn;
}
/*-----------------------------------------------------------*/
void vUARTInterruptHandler( void )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
portCHAR cChar;
if( USART_GetITStatus( USART1, USART_IT_TXE ) == SET )
{
/* The interrupt was caused by the THR becoming empty. Are there any
more characters to transmit? */
if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE )
{
/* A character was retrieved from the queue so can be sent to the
THR now. */
USART_SendData( USART1, cChar );
}
else
{
USART_ITConfig( USART1, USART_IT_TXE, DISABLE );
}
}
if( USART_GetITStatus( USART1, USART_IT_RXNE ) == SET )
{
cChar = USART_ReceiveData( USART1 );
xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );
}
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}

View File

@ -81,7 +81,7 @@
#define _GPIO
#define _GPIOA
#define _GPIOB
//#define _GPIOC
#define _GPIOC
#define _GPIOD
#define _GPIOE
//#define _GPIOF
@ -134,7 +134,7 @@
/************************************* USART **********************************/
#define _USART
#define _USART1
//#define _USART2
#define _USART2
//#define _USART3
//#define _UART4
//#define _UART5