Commit d770d98b authored by Dean Camera's avatar Dean Camera
Browse files

Board Dataflash driver now allows for dataflash ICs which use different shifts...

Board Dataflash driver now allows for dataflash ICs which use different shifts for setting the current page/byte address (thanks to Kenneth Clubb).
parent e611b250
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
* - The NO_CLEARSET_FEATURE_REQUEST compile time token has been renamed to NO_FEATURELESS_CONTROL_ONLY_DEVICE, and its function expanded * - The NO_CLEARSET_FEATURE_REQUEST compile time token has been renamed to NO_FEATURELESS_CONTROL_ONLY_DEVICE, and its function expanded
* to also remove parts of the Get Status chapter 9 request to further reduce code usage * to also remove parts of the Get Status chapter 9 request to further reduce code usage
* - Makefile updated to include output giving the currently selected BOARD parameter value * - Makefile updated to include output giving the currently selected BOARD parameter value
* - Board Dataflash driver now allows for dataflash ICs which use different shifts for setting the current page/byte address (thanks
* to Kenneth Clubb)
* *
* \section Sec_ChangeLog090209 Version 090209 * \section Sec_ChangeLog090209 Version 090209
* *
......
...@@ -78,4 +78,40 @@ ...@@ -78,4 +78,40 @@
/** Total number of pages inside each of the board's dataflash ICs. */ /** Total number of pages inside each of the board's dataflash ICs. */
#define DATAFLASH_PAGES // TODO: Replace with the total number of pages inside one of the Dataflash ICs #define DATAFLASH_PAGES // TODO: Replace with the total number of pages inside one of the Dataflash ICs
/* Inline Functions: */
/** Selects a dataflash IC from the given page number, which should range from 0 to
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one
* dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside
* the total number of pages contained in the boards dataflash ICs, all dataflash ICs
* are deselected.
*
* \param PageAddress Address of the page to manipulate, ranging from
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1).
*/
static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress)
{
Dataflash_DeselectChip();
if (PageAddress >= (DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS))
return;
// TODO: If more than one dataflash chip, select the correct chip from the page address here
Dataflash_SelectChip(DATAFLASH_CHIP1);
}
/** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with
* dataflash commands which require a complete 24-byte address.
*
* \param PageAddress Page address within the selected dataflash IC
* \param BufferByte Address within the dataflash's buffer
*/
static inline void Dataflash_SendAddressBytes(uint16_t PageAddress, const uint16_t BufferByte)
{
// TODO: If more than one dataflash chip, adjust absolute page address to be correct for the current chip,
// also the shifts may need to be altered to suit the dataflash model being used
Dataflash_SendByte(PageAddress >> 5);
Dataflash_SendByte((PageAddress << 3) | (BufferByte >> 8));
Dataflash_SendByte(BufferByte);
}
#endif #endif
...@@ -52,21 +52,7 @@ ...@@ -52,21 +52,7 @@
/* Includes: */ /* Includes: */
#include "../AT90USBXXX/SPI.h" #include "../AT90USBXXX/SPI.h"
#include "../../Common/Common.h" #include "../../Common/Common.h"
#if !defined(BOARD)
#error BOARD must be set in makefile to a value specified in BoardTypes.h.
#elif (BOARD == BOARD_USBKEY)
#include "USBKEY/Dataflash.h"
#elif (BOARD == BOARD_STK525)
#include "STK525/Dataflash.h"
#elif (BOARD == BOARD_STK526)
#include "STK526/Dataflash.h"
#elif (BOARD == BOARD_USER)
#include "Board/Dataflash.h"
#else
#error The selected board does not contain a dataflash IC.
#endif
/* Enable C linkage for C++ Compilers: */ /* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
...@@ -89,19 +75,6 @@ ...@@ -89,19 +75,6 @@
#define Dataflash_DeselectChip() Dataflash_SelectChip(DATAFLASH_NO_CHIP) #define Dataflash_DeselectChip() Dataflash_SelectChip(DATAFLASH_NO_CHIP)
/* Inline Functions: */ /* Inline Functions: */
/** Initializes the dataflash driver (including the SPI driver) so that commands and data may be
* sent to an attached dataflash IC.
*
* \param PrescalerMask SPI prescaler mask, see SPI.h documentation
*/
static inline void Dataflash_Init(const uint8_t PrescalerMask)
{
DATAFLASH_CHIPCS_DDR |= DATAFLASH_CHIPCS_MASK;
DATAFLASH_CHIPCS_PORT |= DATAFLASH_CHIPCS_MASK;
SPI_Init(PrescalerMask, true);
}
/** Sends a byte to the currently selected dataflash IC, and returns a byte from the dataflash. /** Sends a byte to the currently selected dataflash IC, and returns a byte from the dataflash.
* *
* \param Byte of data to send to the dataflash * \param Byte of data to send to the dataflash
...@@ -133,21 +106,45 @@ ...@@ -133,21 +106,45 @@
{ {
return SPI_ReceiveByte(); return SPI_ReceiveByte();
} }
/* Includes: */
#if !defined(BOARD)
#error BOARD must be set in makefile to a value specified in BoardTypes.h.
#elif (BOARD == BOARD_USBKEY)
#include "USBKEY/Dataflash.h"
#elif (BOARD == BOARD_STK525)
#include "STK525/Dataflash.h"
#elif (BOARD == BOARD_STK526)
#include "STK526/Dataflash.h"
#elif (BOARD == BOARD_USER)
#include "Board/Dataflash.h"
#else
#error The selected board does not contain a dataflash IC.
#endif
/* Inline Functions: */
/** Initializes the dataflash driver (including the SPI driver) so that commands and data may be
* sent to an attached dataflash IC.
*
* \param PrescalerMask SPI prescaler mask, see SPI.h documentation
*/
static inline void Dataflash_Init(const uint8_t PrescalerMask)
{
DATAFLASH_CHIPCS_DDR |= DATAFLASH_CHIPCS_MASK;
DATAFLASH_CHIPCS_PORT |= DATAFLASH_CHIPCS_MASK;
SPI_Init(PrescalerMask, true);
}
/** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive /** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive
* a new command. * a new command.
*/ */
static inline void Dataflash_ToggleSelectedChipCS(void) static inline void Dataflash_ToggleSelectedChipCS(void)
{ {
#if (DATAFLASH_TOTALCHIPS == 2) uint8_t SelectedChipMask = Dataflash_GetSelectedChip();
uint8_t SelectedChipMask = Dataflash_GetSelectedChip();
Dataflash_DeselectChip(); Dataflash_DeselectChip();
Dataflash_SelectChip(SelectedChipMask); Dataflash_SelectChip(SelectedChipMask);
#else
Dataflash_DeselectChip();
Dataflash_SelectChip(DATAFLASH_CHIP1);
#endif
} }
/** Spinloops while the currently selected dataflash is busy executing a command, such as a main /** Spinloops while the currently selected dataflash is busy executing a command, such as a main
...@@ -162,28 +159,14 @@ ...@@ -162,28 +159,14 @@
/** Selects a dataflash IC from the given page number, which should range from 0 to /** Selects a dataflash IC from the given page number, which should range from 0 to
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one
* dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside the total number * dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside
* of pages contained in the boards dataflash ICs, all dataflash ICs are deselected. * the total number of pages contained in the boards dataflash ICs, all dataflash ICs
* are deselected.
* *
* \param PageAddress Address of the page to manipulate, ranging from * \param PageAddress Address of the page to manipulate, ranging from
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1).
*/ */
static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress) static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress);
{
Dataflash_DeselectChip();
if (PageAddress >= (DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS))
return;
#if (DATAFLASH_TOTALCHIPS == 2)
if (PageAddress & 0x01)
Dataflash_SelectChip(DATAFLASH_CHIP2);
else
Dataflash_SelectChip(DATAFLASH_CHIP1);
#else
Dataflash_SelectChip(DATAFLASH_CHIP1);
#endif
}
/** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with /** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with
* dataflash commands which require a complete 24-byte address. * dataflash commands which require a complete 24-byte address.
...@@ -191,16 +174,7 @@ ...@@ -191,16 +174,7 @@
* \param PageAddress Page address within the selected dataflash IC * \param PageAddress Page address within the selected dataflash IC
* \param BufferByte Address within the dataflash's buffer * \param BufferByte Address within the dataflash's buffer
*/ */
static inline void Dataflash_SendAddressBytes(uint16_t PageAddress, const uint16_t BufferByte) static inline void Dataflash_SendAddressBytes(uint16_t PageAddress, const uint16_t BufferByte);
{
#if (DATAFLASH_TOTALCHIPS == 2)
PageAddress >>= 1;
#endif
Dataflash_SendByte(PageAddress >> 5);
Dataflash_SendByte((PageAddress << 3) | (BufferByte >> 8));
Dataflash_SendByte(BufferByte);
}
/* Disable C linkage for C++ Compilers: */ /* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus) #if defined(__cplusplus)
......
...@@ -72,4 +72,37 @@ ...@@ -72,4 +72,37 @@
/** Total number of pages inside the board's dataflash IC. */ /** Total number of pages inside the board's dataflash IC. */
#define DATAFLASH_PAGES 8192 #define DATAFLASH_PAGES 8192
/* Inline Functions: */
/** Selects a dataflash IC from the given page number, which should range from 0 to
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one
* dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside
* the total number of pages contained in the boards dataflash ICs, all dataflash ICs
* are deselected.
*
* \param PageAddress Address of the page to manipulate, ranging from
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1).
*/
static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress)
{
Dataflash_DeselectChip();
if (PageAddress >= (DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS))
return;
Dataflash_SelectChip(DATAFLASH_CHIP1);
}
/** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with
* dataflash commands which require a complete 24-byte address.
*
* \param PageAddress Page address within the selected dataflash IC
* \param BufferByte Address within the dataflash's buffer
*/
static inline void Dataflash_SendAddressBytes(uint16_t PageAddress, const uint16_t BufferByte)
{
Dataflash_SendByte(PageAddress >> 5);
Dataflash_SendByte((PageAddress << 3) | (BufferByte >> 8));
Dataflash_SendByte(BufferByte);
}
#endif #endif
...@@ -72,4 +72,37 @@ ...@@ -72,4 +72,37 @@
/** Total number of pages inside the board's dataflash IC. */ /** Total number of pages inside the board's dataflash IC. */
#define DATAFLASH_PAGES 8192 #define DATAFLASH_PAGES 8192
/* Inline Functions: */
/** Selects a dataflash IC from the given page number, which should range from 0 to
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one
* dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside
* the total number of pages contained in the boards dataflash ICs, all dataflash ICs
* are deselected.
*
* \param PageAddress Address of the page to manipulate, ranging from
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1).
*/
static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress)
{
Dataflash_DeselectChip();
if (PageAddress >= (DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS))
return;
Dataflash_SelectChip(DATAFLASH_CHIP1);
}
/** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with
* dataflash commands which require a complete 24-byte address.
*
* \param PageAddress Page address within the selected dataflash IC
* \param BufferByte Address within the dataflash's buffer
*/
static inline void Dataflash_SendAddressBytes(uint16_t PageAddress, const uint16_t BufferByte)
{
Dataflash_SendByte(PageAddress >> 5);
Dataflash_SendByte((PageAddress << 3) | (BufferByte >> 8));
Dataflash_SendByte(BufferByte);
}
#endif #endif
...@@ -74,5 +74,43 @@ ...@@ -74,5 +74,43 @@
/** Total number of pages inside each of the board's dataflash ICs. */ /** Total number of pages inside each of the board's dataflash ICs. */
#define DATAFLASH_PAGES 8192 #define DATAFLASH_PAGES 8192
/* Inline Functions: */
/** Selects a dataflash IC from the given page number, which should range from 0 to
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one
* dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside
* the total number of pages contained in the boards dataflash ICs, all dataflash ICs
* are deselected.
*
* \param PageAddress Address of the page to manipulate, ranging from
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1).
*/
static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress)
{
Dataflash_DeselectChip();
if (PageAddress >= (DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS))
return;
if (PageAddress & 0x01)
Dataflash_SelectChip(DATAFLASH_CHIP2);
else
Dataflash_SelectChip(DATAFLASH_CHIP1);
}
/** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with
* dataflash commands which require a complete 24-byte address.
*
* \param PageAddress Page address within the selected dataflash IC
* \param BufferByte Address within the dataflash's buffer
*/
static inline void Dataflash_SendAddressBytes(uint16_t PageAddress, const uint16_t BufferByte)
{
PageAddress >>= 1;
Dataflash_SendByte(PageAddress >> 5);
Dataflash_SendByte((PageAddress << 3) | (BufferByte >> 8));
Dataflash_SendByte(BufferByte);
}
#endif #endif
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
* *
* <b>Non-USB Library Components</b> * <b>Non-USB Library Components</b>
* - The ATTR_ALWAYSINLINE function attribute macro has been renamed to ATTR_ALWAYS_INLINE. * - The ATTR_ALWAYSINLINE function attribute macro has been renamed to ATTR_ALWAYS_INLINE.
* - Custom board Dataflash drivers now require the implementation of Dataflash_SelectChipFromPage() and Dataflash_SendAddressBytes().
* *
* <b>Device Mode</b> * <b>Device Mode</b>
* - The NO_CLEARSET_FEATURE_REQUEST compile time token has been renamed to NO_FEATURELESS_CONTROL_ONLY_DEVICE, and its function expanded * - The NO_CLEARSET_FEATURE_REQUEST compile time token has been renamed to NO_FEATURELESS_CONTROL_ONLY_DEVICE, and its function expanded
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment