initial commit

This commit is contained in:
2022-10-23 23:45:43 -07:00
commit e190fa5193
6450 changed files with 8626944 additions and 0 deletions
@@ -0,0 +1,81 @@
//*****************************************************************************
//
//! @file am_devices.h
//!
//! @brief Includes for all devices.
//!
//! @addtogroup devices External Device Control Library
//! @ingroup devices
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_DEVICES_H
#define AM_DEVICES_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// All DEVICES includes
//
//*****************************************************************************
#include "am_devices_button.h"
#include "am_devices_da14581.h"
#include "am_devices_em9304.h"
#include "am_devices_led.h"
#include "am_devices_spiflash.h"
#ifdef __cplusplus
}
#endif
#endif // AM_DEVICES_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,225 @@
//*****************************************************************************
//
//! @file am_devices_button.c
//!
//! @brief Functions for controlling an array of LEDs
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
#include "am_devices_button.h"
//*****************************************************************************
//
//! @brief Configures the necessary pins for an array of buttons.
//!
//! @param psButton is a pointer to a button structure.
//!
//! This function configures a GPIO to read a button in a low-power way.
//!
//! @return None.
//
//*****************************************************************************
void
am_devices_button_init(am_devices_button_t *psButton)
{
//
// Disable the pin to save power.
//
#if AM_APOLLO3_GPIO
am_hal_gpio_pinconfig(psButton->ui32GPIONumber, g_AM_HAL_GPIO_DISABLE);
#else // AM_APOLLO3_GPIO
am_hal_gpio_pin_config(psButton->ui32GPIONumber, AM_HAL_PIN_DISABLE);
#endif // AM_APOLLO3_GPIO
//
// Initialize the state variables.
//
psButton->ui32Count = 0;
psButton->bPressed = false;
psButton->bChanged = false;
}
//*****************************************************************************
//
//! @brief Configures the necessary pins for an array of buttons.
//!
//! @param psButtons is an array of button structures.
//! @param ui32NumButtons is the total number of buttons in the array.
//!
//! This function configures the GPIOs for an array of buttons.
//!
//! @return None.
//
//*****************************************************************************
void
am_devices_button_array_init(am_devices_button_t *psButtons,
uint32_t ui32NumButtons)
{
uint32_t i;
//
// Loop through the list of buttons, configuring each one individually.
//
for ( i = 0; i < ui32NumButtons; i++ )
{
am_devices_button_init(psButtons + i);
}
}
//*****************************************************************************
//
//! @brief Configures the necessary pins for an array of buttons.
//!
//! @param psButtons is an array of button structures.
//! @param ui32NumButtons is the total number of buttons in the array.
//!
//! This function configures the GPIOs for an array of buttons.
//!
//! @return None.
//
//*****************************************************************************
void
am_devices_button_tick(am_devices_button_t *psButton)
{
uint32_t ui32PinState;
bool bRawButtonPressed;
//
// Enable the button pin.
//
#if AM_APOLLO3_GPIO
am_hal_gpio_pinconfig(psButton->ui32GPIONumber, g_AM_HAL_GPIO_INPUT);
#else // AM_APOLLO3_GPIO
am_hal_gpio_pin_config(psButton->ui32GPIONumber, AM_HAL_PIN_INPUT);
#endif // AM_APOLLO3_GPIO
//
// Read the pin state. If the pin is in its normal (unpressed) state, set
// its "state" counter to zero.
//
#if AM_APOLLO3_GPIO
am_hal_gpio_state_read(psButton->ui32GPIONumber, AM_HAL_GPIO_INPUT_READ, &ui32PinState);
#else // AM_APOLLO3_GPIO
ui32PinState = am_hal_gpio_input_bit_read(psButton->ui32GPIONumber);
#endif // AM_APOLLO3_GPIO
//
// Check to see if the button is "pressed" according to our GPIO reading.
//
bRawButtonPressed = (ui32PinState != psButton->ui32Polarity);
//
// Is this button state different from the last saved state?
//
if ( bRawButtonPressed != psButton->bPressed )
{
//
// If so, increase the debounce count.
//
psButton->ui32Count++;
}
else
{
//
// Otherwise, set the count back to zero.
//
psButton->ui32Count = 0;
}
//
// If we hit the button debounce delay, record a button press to the
// structure, and reset the count.
//
if ( psButton->ui32Count >= AM_DEVICES_BUTTON_DEBOUNCE_DELAY )
{
psButton->bPressed = bRawButtonPressed;
psButton->bChanged = true;
psButton->ui32Count = 0;
}
else
{
//
// If we didn't just record a press/release event, update the structure
// to say that the current state isn't new.
//
psButton->bChanged = false;
}
//
// Disable the button pin to save power.
//
#if AM_APOLLO3_GPIO
am_hal_gpio_pinconfig(psButton->ui32GPIONumber, g_AM_HAL_GPIO_DISABLE);
#else // AM_APOLLO3_GPIO
am_hal_gpio_pin_config(psButton->ui32GPIONumber, AM_HAL_PIN_DISABLE);
#endif // AM_APOLLO3_GPIO
}
//*****************************************************************************
//
//! @brief Configures the necessary pins for an array of buttons.
//!
//! @param psButtons is an array of button structures.
//! @param ui32NumButtons is the total number of buttons in the array.
//!
//! This function configures the GPIOs for an array of buttons.
//!
//! @return None.
//
//*****************************************************************************
void
am_devices_button_array_tick(am_devices_button_t *psButtons,
uint32_t ui32NumButtons)
{
uint32_t i;
//
// Run the "tick" function for each button in the list.
//
for ( i = 0; i < ui32NumButtons; i++ )
{
am_devices_button_tick(psButtons + i);
}
}
@@ -0,0 +1,128 @@
//*****************************************************************************
//
//! @file am_devices_button.h
//!
//! @brief Functions for controlling an array of buttons.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_DEVICES_BUTTON_H
#define AM_DEVICES_BUTTON_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Number of "ticks" to delay before registering a button press or release.
//
//*****************************************************************************
#define AM_DEVICES_BUTTON_DEBOUNCE_DELAY 0x4
//*****************************************************************************
//
// Button polarity macros
//
//*****************************************************************************
#define AM_DEVICES_BUTTON_NORMAL_HIGH 0x1
#define AM_DEVICES_BUTTON_NORMAL_LOW 0x0
//*****************************************************************************
//
// Structure for keeping track of buttons.
//
//*****************************************************************************
typedef struct
{
uint32_t ui32GPIONumber;
uint32_t ui32Polarity;
uint32_t ui32Count;
bool bPressed;
bool bChanged;
}
am_devices_button_t;
//*****************************************************************************
//
// Macro for declaring a button structure.
//
//*****************************************************************************
#define AM_DEVICES_BUTTON(ui32GPIONumber, ui32Polarity) \
{ui32GPIONumber, ui32Polarity, 0, 0, 0}
//*****************************************************************************
//
// Macros for checking button state.
//
//*****************************************************************************
#define am_devices_button_is_up(button) \
((button).bPressed == false)
#define am_devices_button_is_down(button) \
((button).bPressed == true)
#define am_devices_button_pressed(button) \
(((button).bPressed == true) && ((button).bChanged == true))
#define am_devices_button_released(button) \
(((button).bPressed == false) && ((button).bChanged == true))
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern void am_devices_button_init(am_devices_button_t *psButton);
extern void am_devices_button_array_init(am_devices_button_t *psButtons,
uint32_t ui32NumButtons);
extern void am_devices_button_tick(am_devices_button_t *psButton);
extern void am_devices_button_array_tick(am_devices_button_t *psButtons,
uint32_t ui32NumButtons);
#ifdef __cplusplus
}
#endif
#endif // AM_DEVICES_BUTTON_H
@@ -0,0 +1,199 @@
//*****************************************************************************
//
//! @file am_devices_da14581.c
//!
//! @brief Support functions for the Dialog Semiconductor DA14581 BTLE radio.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_bsp.h"
#include "am_devices_da14581.h"
//*****************************************************************************
//
// Macro definitions
//
//*****************************************************************************
#define DIALOG_BOOT_STX 0x02
#define DIALOG_BOOT_SOH 0x01
#define DIALOG_BOOT_ACK 0x06
#define DIALOG_BOOT_NACK 0x15
//*****************************************************************************
//
// BLE MAC address for the Dialog radio.
//
//*****************************************************************************
static uint8_t g_BLEMacAddress[6] =
{0x01, 0x00, 0x00, 0xCA, 0xEA, 0x80};
//*****************************************************************************
//
// Location in the Diaog binary where the MAC address is stored.
//
//*****************************************************************************
static const uint32_t g_ui32MacIndex = 1000;
//*****************************************************************************
//
// Sets the MAC address to send to the dialog radio on the next boot up.
//
//*****************************************************************************
void
am_devices_da14581_mac_set(const uint8_t *pui8MacAddress)
{
uint32_t i;
//
// Copy the 6-byte MAC address into our global variable.
//
for ( i = 0; i < 6; i++ )
{
g_BLEMacAddress[i] = *pui8MacAddress++;
}
}
//*****************************************************************************
//
//! @brief Runs a UART based boot sequence for a Dialog radio device.
//!
//! @param pui8BinData - pointer to an array of bytes containing the firmware
//! for the DA14581
//!
//! @param ui32NumBytes - length of the DA14581 firmware image.
//!
//! This function allows the Ambiq device to program a "blank" DA14581 device
//! on startup. It will handle all of the necessary UART negotiation for the
//! Dialog boot procedure, and will verify that the CRC value for the
//! downloaded firmware image is correct.
//!
//! @return true if successful.
//
//*****************************************************************************
bool
am_devices_da14581_uart_boot(const uint8_t *pui8BinData, uint32_t ui32NumBytes,
uint32_t ui32UartModule)
{
uint32_t ui32Index;
uint8_t ui8CRCValue;
uint8_t ui8TxData;
char ui8RxChar;
//
// Poll the RX lines until we get some indication that the dialog radio is
// present and ready to receive data.
//
do
{
am_hal_uart_char_receive_polled(ui32UartModule, &ui8RxChar);
}
while (ui8RxChar != DIALOG_BOOT_STX);
//
// Send the Start-of-Header signal and the length of the data download.
//
am_hal_uart_char_transmit_polled(ui32UartModule, DIALOG_BOOT_SOH);
am_hal_uart_char_transmit_polled(ui32UartModule, ui32NumBytes & 0xFF);
am_hal_uart_char_transmit_polled(ui32UartModule, (ui32NumBytes & 0xFF00) >> 8);
//
// Poll for the 'ACK' from the dialog device that signifies that the header
// was recieved correctly.
//
do
{
am_hal_uart_char_receive_polled(ui32UartModule, &ui8RxChar);
}
while (ui8RxChar != DIALOG_BOOT_ACK);
//
// Initialize the CRC value to zero.
//
ui8CRCValue = 0;
//
// Send the binary image over to the dialog device one byte at a time,
// keeping track of the CRC as we go.
//
for (ui32Index = 0; ui32Index < ui32NumBytes; ui32Index++)
{
if ((ui32Index >= g_ui32MacIndex) && (ui32Index < g_ui32MacIndex + 6))
{
ui8TxData = g_BLEMacAddress[ui32Index - g_ui32MacIndex];
}
else
{
ui8TxData = pui8BinData[ui32Index];
}
ui8CRCValue ^= ui8TxData;
am_hal_uart_char_transmit_polled(ui32UartModule, ui8TxData);
}
//
// The Dialog device should respond back with a CRC value at the end of the
// programming cycle. We should check here to make sure that they got the
// same CRC result that we did. If it doesn't match, return with an error.
//
am_hal_uart_char_receive_polled(ui32UartModule, &ui8RxChar);
if ( ui8RxChar != ui8CRCValue )
{
return 1;
}
//
// If all is well, send the final 'ACK' to tell the dialog device that its
// new image is correct. After this point, the dialog device should start
// running the downloaded firmware.
//
am_hal_uart_char_transmit_polled(ui32UartModule, DIALOG_BOOT_ACK);
//
// Wait until the FIFO is actually empty and the UART is no-longer busy.
//
while (!AM_BFR(UART, FR, TXFE) || AM_BFR(UART, FR, BUSY));
return 0;
}
@@ -0,0 +1,107 @@
//*****************************************************************************
//
//! @file am_devices_da14581.h
//!
//! @brief Support functions for the Dialog Semiconductor DA14581 BTLE radio.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_DEVICES_DA14581_H
#define AM_DEVICES_DA14581_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Defines
//
//*****************************************************************************
#define AM_DEVICES_DA14581_UART_MODE (0)
#define AM_DEVICES_DA14581_SPI_MODE (1)
#define AM_DEVICES_DA14581_SPI_XPORT_CTS (0x06)
#define AM_DEVICES_DA14581_SPI_XPORT_NOT_CTS (0x07)
//*****************************************************************************
//
// DA14581 device structure
//
//*****************************************************************************
typedef struct
{
//
// MODE UART vs IOM SPI
//
uint32_t ui32Mode;
//
// IOM Module #
//
uint32_t ui32IOMModule;
//
// IOM Chip Select NOTE: this driver uses GPIO for chip selects
//
uint32_t ui32IOMChipSelect;
//
// GPIO # for DA14581 DREADY signal
//
uint32_t ui32DREADY;
}
am_devices_da14581_t;
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern void am_devices_da14581_mac_set(const uint8_t *pui8MacAddress);
extern bool am_devices_da14581_uart_boot(const uint8_t *pui8BinData,
uint32_t ui32NumBytes,
uint32_t ui32UartModule);
#ifdef __cplusplus
}
#endif
#endif // AM_DEVICES_DA14581_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,139 @@
//*****************************************************************************
//
//! @file am_devices_em9304.h
//!
//! @brief Support functions for the EM Micro EM9304 BTLE radio.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_DEVICES_EM9304_H
#define AM_DEVICES_EM9304_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// EM9304 device structure
//
//*****************************************************************************
typedef struct
{
//
// MODE UART vs IOM SPI
//
uint32_t ui32Mode;
//
// IOM Module #
//
uint32_t ui32IOMModule;
//
// IOM Chip Select NOTE: this driver uses GPIO for chip selects
//
uint32_t ui32IOMChipSelect;
//
// GPIO # for EM9304 DREADY signal
//
uint32_t ui32DREADY;
}
am_devices_em9304_t;
extern const am_devices_em9304_t g_sEm9304;
#if defined(AM_PART_APOLLO) || defined(AM_PART_APOLLO2)
extern const am_hal_iom_config_t g_sEm9304IOMConfigSPI;
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern bool am_devices_em9304_mac_set(const uint8_t *pui8MacAddress);
extern uint32_t am_devices_em9304_block_read(const am_devices_em9304_t *psDevice,
uint32_t *pui32Values,
uint32_t ui32NumBytes);
extern void am_devices_em9304_block_write(const am_devices_em9304_t *psDevice,
uint8_t type,
uint8_t *pui8Values,
uint32_t ui32NumBytes);
extern void am_devices_em9304_spi_init(uint32_t ui32Module, const am_hal_iom_config_t *psIomConfig);
extern uint8_t am_devices_em9304_tx_starts(const am_devices_em9304_t *psDevice);
extern void am_devices_em9304_tx_ends(void);
extern void am_devices_em9304_config_pins(void);
extern void am_devices_em9304_spi_sleep(uint32_t ui32Module);
extern void am_devices_em9304_spi_awake(uint32_t ui32Module);
extern void am_devices_em9304_enable_interrupt(void);
extern void am_devices_em9304_disable_interrupt(void);
#endif // defined(AM_PART_APOLLO) || defined(AM_PART_APOLLO2)
#if (defined(AM_PART_APOLLO3) || defined(AM_PART_APOLLO3P))
typedef enum
{
AM_DEVICES_EM9304_STATUS_SUCCESS,
AM_DEVICES_EM9304_STATUS_ERROR
} am_devices_em9304_status_t;
typedef struct
{
uint32_t ui32ClockFreq;
uint32_t *pNBTxnBuf;
uint32_t ui32NBTxnBufLength;
} am_devices_em9304_config_t;
#define AM_DEVICES_EM9304_MAX_DEVICE_NUM 1
extern uint32_t am_devices_em9304_init(uint32_t ui32Module, am_devices_em9304_config_t *pDevConfig, void **ppHandle, void **ppIomHandle);
extern uint32_t am_devices_em9304_term(void *pHandle);
#endif // defined(AM_PART_APOLLO3)
#ifdef __cplusplus
}
#endif
#endif // AM_DEVICES_EM9304_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,242 @@
//*****************************************************************************
//
//! @file am_devices_fireball.h
//!
//! @brief Fireball board control.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_DEVICES_FIREBALL_H
#define AM_DEVICES_FIREBALL_H
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
//
// Fireball driver is included.
//
//#define AM_DEVICES_FIREBALL 1
//
// Fireball version info.
// These 16-bit values are returned by a call to:
// am_devices_fireball_control(AM_DEVICES_FIREBALL_STATE_ID_GET, &x);
//
#define FIREBALL_ID 0x7710
#define FIREBALL2_ID 0x7712
#define FIREBALL3_ID 0x7713
//*****************************************************************************
//
//! Enums for am_devices_fireball_control()
//
//*****************************************************************************
typedef enum
{
//
// General
//
AM_DEVICES_FIREBALL_STATE_FBGEN_GET = 1, // 1=Orig Fireball, 2=Fireball2
AM_DEVICES_FIREBALL_STATE_ID_GET, // Get actual ID from Fireball
AM_DEVICES_FIREBALL_STATE_VER_GET, // Get Fireball firmware version
AM_DEVICES_FIREBALL_STATE_LED_BLINK, // Blink LED n times (n is the call parameter)
//
// Fireball device resets
//
AM_DEVICES_FIREBALL_STATE_ALL_RESET,
AM_DEVICES_FIREBALL_STATE_SX9300_RESET,
AM_DEVICES_FIREBALL_STATE_BNO055_RESET,
AM_DEVICES_FIREBALL_STATE_MSPI_RESET,
AM_DEVICES_FIREBALL_STATE_MKB1_RESET,
AM_DEVICES_FIREBALL_STATE_MKB2_RESET,
//
// States for Fireball
//
AM_DEVICES_FIREBALL_STATE_SPI_FLASH,
AM_DEVICES_FIREBALL_STATE_SPI_FRAM,
AM_DEVICES_FIREBALL_STATE_I2C_IOM0,
AM_DEVICES_FIREBALL_STATE_I2C_IOM1,
AM_DEVICES_FIREBALL_STATE_I2C_IOM2,
AM_DEVICES_FIREBALL_STATE_I2C_IOM3,
AM_DEVICES_FIREBALL_STATE_I2C_IOM4,
AM_DEVICES_FIREBALL_STATE_I2C_IOM5,
AM_DEVICES_FIREBALL_STATE_OCTAL_FLASH_CE0,
AM_DEVICES_FIREBALL_STATE_OCTAL_FLASH_CE1,
AM_DEVICES_FIREBALL_STATE_TWIN_QUAD_CE0_CE1,
//
// Fireball2 device resets
//
AM_DEVICES_FIREBALL2_STATE_GLOBAL_RESET, // New for Fireball2 global reset
AM_DEVICES_FIREBALL2_STATE_SX9300_RESET,
AM_DEVICES_FIREBALL2_STATE_BNO055_RESET,
AM_DEVICES_FIREBALL2_STATE_MSPI_RESET,
AM_DEVICES_FIREBALL2_STATE_MKB1_RESET,
AM_DEVICES_FIREBALL2_STATE_MKB2_RESET,
AM_DEVICES_FIREBALL2_STATE_GP30_RESET,
AM_DEVICES_FIREBALL2_STATE_ALL_RESET, // Reset all devices individually
//
// States for Fireball2
//
AM_DEVICES_FIREBALL2_STATE_SPI_FRAM_PSRAM_1P8,
AM_DEVICES_FIREBALL2_STATE_SPI_PSRAM_FLASH_3P3,
AM_DEVICES_FIREBALL2_STATE_I2C_IOM0,
AM_DEVICES_FIREBALL2_STATE_I2C_IOM1,
AM_DEVICES_FIREBALL2_STATE_I2C_IOM2,
AM_DEVICES_FIREBALL2_STATE_I2C_IOM3,
AM_DEVICES_FIREBALL2_STATE_I2C_IOM4,
AM_DEVICES_FIREBALL2_STATE_I2C_IOM5,
AM_DEVICES_FIREBALL2_STATE_MSPI_FRAM_PSRAM_FLASH_1P8,
AM_DEVICES_FIREBALL2_STATE_MSPI_PSRAM_FLASH_3P3,
AM_DEVICES_FIREBALL2_STATE_SC_8_9_16,
AM_DEVICES_FIREBALL2_STATE_SC_17_32_26,
AM_DEVICES_FIREBALL2_STATE_SC_19_18_46,
AM_DEVICES_FIREBALL2_STATE_SC_31_37_21,
AM_DEVICES_FIREBALL2_STATE_PDM_10_29,
AM_DEVICES_FIREBALL2_STATE_PDM_12_15,
AM_DEVICES_FIREBALL2_STATE_PDM_14_11,
AM_DEVICES_FIREBALL2_STATE_PDM_22_34,
AM_DEVICES_FIREBALL2_STATE_PDM_37_36,
AM_DEVICES_FIREBALL2_STATE_PDM_46_45,
AM_DEVICES_FIREBALL2_STATE_PDM_AMP_IN,
AM_DEVICES_FIREBALL2_STATE_I2S_DAC,
AM_DEVICES_FIREBALL2_STATE_STEPPER,
//
// States for Fireball3.
// Most are the same as for FB2 except for a few new ones.
// However, the ordering is important such that FB2 states should
// map to similar FB3 states by simply adding an offset.
//
// FB3 device reset states
AM_DEVICES_FIREBALL3_STATE_GLOBAL_RESET,
AM_DEVICES_FIREBALL3_STATE_SX9300_RESET,
AM_DEVICES_FIREBALL3_STATE_BNO055_RESET,
AM_DEVICES_FIREBALL3_STATE_MSPI_RESET,
AM_DEVICES_FIREBALL3_STATE_MKB1_RESET,
AM_DEVICES_FIREBALL3_STATE_MKB2_RESET,
AM_DEVICES_FIREBALL3_STATE_GP30_RESET,
AM_DEVICES_FIREBALL3_STATE_ALL_RESET, // Reset all devices individually
AM_DEVICES_FIREBALL3_STATE_SPI_FRAM_PSRAM_1P8,
AM_DEVICES_FIREBALL3_STATE_SPI_PSRAM_FLASH_3P3,
AM_DEVICES_FIREBALL3_STATE_I2C_IOM0,
AM_DEVICES_FIREBALL3_STATE_I2C_IOM1,
AM_DEVICES_FIREBALL3_STATE_I2C_IOM2,
AM_DEVICES_FIREBALL3_STATE_I2C_IOM3,
AM_DEVICES_FIREBALL3_STATE_I2C_IOM4,
AM_DEVICES_FIREBALL3_STATE_I2C_IOM5,
AM_DEVICES_FIREBALL3_STATE_MSPI0_PSRAM_1P8,
AM_DEVICES_FIREBALL3_STATE_MSPI0_PSRAM_3P3,
AM_DEVICES_FIREBALL3_STATE_SC_8_9_16,
AM_DEVICES_FIREBALL3_STATE_SC_17_32_26,
AM_DEVICES_FIREBALL3_STATE_SC_19_18_46,
AM_DEVICES_FIREBALL3_STATE_SC_31_37_21,
AM_DEVICES_FIREBALL3_STATE_PDM_10_29,
AM_DEVICES_FIREBALL3_STATE_PDM_12_15,
AM_DEVICES_FIREBALL3_STATE_PDM_14_11,
AM_DEVICES_FIREBALL3_STATE_PDM_22_34,
AM_DEVICES_FIREBALL3_STATE_PDM_37_36,
AM_DEVICES_FIREBALL3_STATE_PDM_46_45,
AM_DEVICES_FIREBALL3_STATE_PDM_AMP_IN,
AM_DEVICES_FIREBALL3_STATE_I2S_DAC,
AM_DEVICES_FIREBALL3_STATE_STEPPER,
// New states for FB3
AM_DEVICES_FIREBALL3_STATE_MSPI0_FLASH_1P8,
AM_DEVICES_FIREBALL3_STATE_MSPI0_FT812,
AM_DEVICES_FIREBALL3_STATE_MSPI0_DISPLAY,
AM_DEVICES_FIREBALL3_STATE_MSPI1_PSRAM_1P8,
AM_DEVICES_FIREBALL3_STATE_MSPI1_FLASH_1P8,
AM_DEVICES_FIREBALL3_STATE_MSPI1_PSRAM_3P3,
AM_DEVICES_FIREBALL3_STATE_MSPI1_FT812,
AM_DEVICES_FIREBALL3_STATE_MSPI1_DISPLAY,
AM_DEVICES_FIREBALL3_STATE_MSPI2_PSRAM_1P8,
AM_DEVICES_FIREBALL3_STATE_MSPI2_FLASH_1P8,
AM_DEVICES_FIREBALL3_STATE_MSPI2_PSRAM_3P3,
AM_DEVICES_FIREBALL3_STATE_MSPI2_FT812,
AM_DEVICES_FIREBALL3_STATE_MSPI2_DISPLAY,
//
// End of valid states
//
AM_DEVICES_FIREBALL_STATE_INVALID
} am_devices_fireball_control_e;
//
// Define valid first/last states for each board.
//
#define AM_DEVICES_FIREBALL_STATE_FIRST AM_DEVICES_FIREBALL_STATE_ALL_RESET
#define AM_DEVICES_FIREBALL_STATE_LAST AM_DEVICES_FIREBALL_STATE_TWIN_QUAD_CE0_CE1
#define AM_DEVICES_FIREBALL2_STATE_FIRST AM_DEVICES_FIREBALL2_STATE_GLOBAL_RESET
#define AM_DEVICES_FIREBALL2_STATE_LAST AM_DEVICES_FIREBALL2_STATE_STEPPER
#define AM_DEVICES_FIREBALL3_STATE_FIRST AM_DEVICES_FIREBALL3_STATE_GLOBAL_RESET
#define AM_DEVICES_FIREBALL3_STATE_LAST AM_DEVICES_FIREBALL3_STATE_STEPPER
//*****************************************************************************
//
//! @brief Set FIREBALL state.
//!
//! @param eState - Designate which state to put the FIREBALL. The state
//! number indicates which peripherals are muxed in.
//
//*****************************************************************************
extern uint32_t am_devices_fireball_control(am_devices_fireball_control_e eState,
void *pArgs);
#ifdef __cplusplus
}
#endif
#endif // AM_DEVICES_FIREBALL_H
@@ -0,0 +1,555 @@
//*****************************************************************************
//
//! @file am_devices_led.c
//!
//! @brief Functions for controlling an array of LEDs
//!
//! @addtogroup devices External Device Control Library
//! @addtogroup LED SPI Device Control for programmable LEDs.
//! @ingroup devices
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
#include "am_devices_led.h"
//
// Define a somewhat arbitrary maximum number of LEDs. No board is actually
// expected to have this many LEDs, the value is used for parameter validation.
//
#define MAX_LEDS 31
//*****************************************************************************
//
//! @brief Configures the necessary pins for an array of LEDs
//!
//! @param psLED is a pointer to an LED structure.
//!
//! This function configures a GPIO to drive an LED in a low-power way.
//!
//! @return None.
//
//*****************************************************************************
void
am_devices_led_init(am_devices_led_t *psLED)
{
if ( (psLED == NULL) ||
(psLED->ui32GPIONumber >= AM_HAL_GPIO_MAX_PADS) )
{
return;
}
#if AM_APOLLO3_GPIO
//
// Handle Direct Drive Versus 3-State (with pull-up or no buffer).
//
if ( AM_DEVICES_LED_POL_DIRECT_DRIVE_M & psLED->ui32Polarity )
{
//
// Configure the pin as a push-pull GPIO output.
//
am_hal_gpio_pinconfig(psLED->ui32GPIONumber, g_AM_HAL_GPIO_OUTPUT);
//
// Disable the output driver, and set the output value to the LEDs "ON"
// state. Note that for Apollo3 GPIOs in push-pull mode, the output
// enable, normally a tri-state control, instead functions as an enable
// for Fast GPIO. Its state does not matter on previous chips, so for
// normal GPIO usage on Apollo3, it must be disabled.
//
am_hal_gpio_state_write(psLED->ui32GPIONumber, AM_HAL_GPIO_OUTPUT_TRISTATE_DISABLE);
am_hal_gpio_state_write(psLED->ui32GPIONumber,
psLED->ui32Polarity & AM_DEVICES_LED_POL_POLARITY_M ?
AM_HAL_GPIO_OUTPUT_SET : AM_HAL_GPIO_OUTPUT_CLEAR);
}
else
{
//
// Configure the pin as a tri-state GPIO.
//
am_hal_gpio_pinconfig(psLED->ui32GPIONumber, g_AM_HAL_GPIO_TRISTATE);
//
// Disable the output driver, and set the output value to the LEDs "ON"
// state.
//
am_hal_gpio_state_write(psLED->ui32GPIONumber, AM_HAL_GPIO_OUTPUT_TRISTATE_DISABLE);
am_hal_gpio_state_write(psLED->ui32GPIONumber,
psLED->ui32Polarity & AM_DEVICES_LED_POL_POLARITY_M ?
AM_HAL_GPIO_OUTPUT_SET : AM_HAL_GPIO_OUTPUT_CLEAR);
}
#else // AM_APOLLO3_GPIO
//
// Handle Direct Drive Versus 3-State (with pull-up or no buffer).
//
if ( AM_DEVICES_LED_POL_DIRECT_DRIVE_M & psLED->ui32Polarity )
{
//
// Configure the pin as a push-pull GPIO output.
//
am_hal_gpio_pin_config(psLED->ui32GPIONumber, AM_HAL_GPIO_OUTPUT);
//
// Disable the output driver, and set the output value to the LEDs "ON"
// state.
//
am_hal_gpio_out_enable_bit_clear(psLED->ui32GPIONumber);
am_hal_gpio_out_bit_replace(psLED->ui32GPIONumber,
psLED->ui32Polarity &
AM_DEVICES_LED_POL_POLARITY_M);
}
else
{
//
// Configure the pin as a tri-state GPIO.
//
am_hal_gpio_pin_config(psLED->ui32GPIONumber, AM_HAL_GPIO_3STATE);
//
// Disable the output driver, and set the output value to the LEDs "ON"
// state.
//
am_hal_gpio_out_enable_bit_clear(psLED->ui32GPIONumber);
am_hal_gpio_out_bit_replace(psLED->ui32GPIONumber,
psLED->ui32Polarity &
AM_DEVICES_LED_POL_POLARITY_M );
}
#endif // AM_APOLLO3_GPIO
}
//*****************************************************************************
//
//! @brief Disables an array of LEDs
//!
//! @param psLEDs is an array of LED structures.
//! @param ui32NumLEDs is the total number of LEDs in the array.
//!
//! This function disables the GPIOs for an array of LEDs.
//!
//! @return None.
//
//*****************************************************************************
void
am_devices_led_array_disable(am_devices_led_t *psLEDs, uint32_t ui32NumLEDs)
{
if ( (psLEDs == NULL) ||
(ui32NumLEDs > MAX_LEDS) )
{
return;
}
//
// Loop through the list of LEDs, configuring each one individually.
//
for ( uint32_t i = 0; i < ui32NumLEDs; i++ )
{
if ( psLEDs[i].ui32GPIONumber >= AM_HAL_GPIO_MAX_PADS )
{
continue;
}
#if AM_APOLLO3_GPIO
am_hal_gpio_pinconfig((psLEDs + i)->ui32GPIONumber, g_AM_HAL_GPIO_DISABLE);
#else // AM_APOLLO3_GPIO
am_hal_gpio_pin_config((psLEDs + i)->ui32GPIONumber, AM_HAL_GPIO_DISABLE);
#endif // AM_APOLLO3_GPIO
}
}
//*****************************************************************************
//
//! @brief Configures the necessary pins for an array of LEDs
//!
//! @param psLEDs is an array of LED structures.
//! @param ui32NumLEDs is the total number of LEDs in the array.
//!
//! This function configures the GPIOs for an array of LEDs.
//!
//! @return None.
//
//*****************************************************************************
void
am_devices_led_array_init(am_devices_led_t *psLEDs, uint32_t ui32NumLEDs)
{
uint32_t i;
if ( (psLEDs == NULL) ||
(ui32NumLEDs > MAX_LEDS) )
{
return;
}
//
// Loop through the list of LEDs, configuring each one individually.
//
for ( i = 0; i < ui32NumLEDs; i++ )
{
am_devices_led_init(psLEDs + i);
}
}
//*****************************************************************************
//
//! @brief Turns on the requested LED.
//!
//! @param psLEDs is an array of LED structures.
//! @param ui32LEDNum is the LED number for the light to turn on.
//!
//! This function turns on a single LED.
//!
//! @return None.
//
//*****************************************************************************
void
am_devices_led_on(am_devices_led_t *psLEDs, uint32_t ui32LEDNum)
{
if ( (psLEDs == NULL) ||
(ui32LEDNum >= MAX_LEDS) ||
(psLEDs[ui32LEDNum].ui32GPIONumber >= AM_HAL_GPIO_MAX_PADS) )
{
return;
}
#if AM_APOLLO3_GPIO
//
// Handle Direct Drive Versus 3-State (with pull-up or no buffer).
//
if ( AM_DEVICES_LED_POL_DIRECT_DRIVE_M & psLEDs[ui32LEDNum].ui32Polarity )
{
//
// Set the output to the correct state for the LED.
//
am_hal_gpio_state_write(psLEDs[ui32LEDNum].ui32GPIONumber,
psLEDs[ui32LEDNum].ui32Polarity & AM_DEVICES_LED_POL_POLARITY_M ?
AM_HAL_GPIO_OUTPUT_SET : AM_HAL_GPIO_OUTPUT_CLEAR);
}
else
{
//
// Turn on the output driver for the LED.
//
am_hal_gpio_state_write(psLEDs[ui32LEDNum].ui32GPIONumber,
AM_HAL_GPIO_OUTPUT_TRISTATE_ENABLE);
}
#else // AM_APOLLO3_GPIO
//
// Handle Direct Drive Versus 3-State (with pull-up or no buffer).
//
if ( AM_DEVICES_LED_POL_DIRECT_DRIVE_M & psLEDs[ui32LEDNum].ui32Polarity )
{
//
// Set the output to the correct state for the LED.
//
am_hal_gpio_out_bit_replace(psLEDs[ui32LEDNum].ui32GPIONumber,
psLEDs[ui32LEDNum].ui32Polarity &
AM_DEVICES_LED_POL_POLARITY_M );
}
else
{
//
// Turn on the output driver for the LED.
//
am_hal_gpio_out_enable_bit_set(psLEDs[ui32LEDNum].ui32GPIONumber);
}
#endif // AM_APOLLO3_GPIO
}
//*****************************************************************************
//
//! @brief Turns off the requested LED.
//!
//! @param psLEDs is an array of LED structures.
//! @param ui32LEDNum is the LED number for the light to turn off.
//!
//! This function turns off a single LED.
//!
//! @return None.
//
//*****************************************************************************
void
am_devices_led_off(am_devices_led_t *psLEDs, uint32_t ui32LEDNum)
{
if ( (psLEDs == NULL) ||
(ui32LEDNum >= MAX_LEDS) ||
(psLEDs[ui32LEDNum].ui32GPIONumber >= AM_HAL_GPIO_MAX_PADS) )
{
return;
}
#if AM_APOLLO3_GPIO
//
// Handle Direct Drive Versus 3-State (with pull-up or no buffer).
//
if ( AM_DEVICES_LED_POL_DIRECT_DRIVE_M & psLEDs[ui32LEDNum].ui32Polarity )
{
//
// Set the output to the correct state for the LED.
//
am_hal_gpio_state_write(psLEDs[ui32LEDNum].ui32GPIONumber,
psLEDs[ui32LEDNum].ui32Polarity & AM_DEVICES_LED_POL_POLARITY_M ?
AM_HAL_GPIO_OUTPUT_CLEAR : AM_HAL_GPIO_OUTPUT_SET);
}
else
{
//
// Turn off the output driver for the LED.
//
am_hal_gpio_state_write(psLEDs[ui32LEDNum].ui32GPIONumber,
AM_HAL_GPIO_OUTPUT_TRISTATE_DISABLE);
}
#else // AM_APOLLO3_GPIO
//
// Handle Direct Drive Versus 3-State (with pull-up or no buffer).
//
if ( AM_DEVICES_LED_POL_DIRECT_DRIVE_M & psLEDs[ui32LEDNum].ui32Polarity )
{
//
// Set the output to the correct state for the LED.
//
am_hal_gpio_out_bit_replace(psLEDs[ui32LEDNum].ui32GPIONumber,
!(psLEDs[ui32LEDNum].ui32Polarity &
AM_DEVICES_LED_POL_POLARITY_M) );
}
else
{
//
// Turn off the output driver for the LED.
//
am_hal_gpio_out_enable_bit_clear(psLEDs[ui32LEDNum].ui32GPIONumber);
}
#endif // AM_APOLLO3_GPIO
}
//*****************************************************************************
//
//! @brief Toggles the requested LED.
//!
//! @param psLEDs is an array of LED structures.
//! @param ui32LEDNum is the LED number for the light to toggle.
//!
//! This function toggles a single LED.
//!
//! @return None.
//
//*****************************************************************************
void
am_devices_led_toggle(am_devices_led_t *psLEDs, uint32_t ui32LEDNum)
{
if ( (psLEDs == NULL) ||
(ui32LEDNum >= MAX_LEDS) ||
(psLEDs[ui32LEDNum].ui32GPIONumber >= AM_HAL_GPIO_MAX_PADS) )
{
return;
}
#if AM_APOLLO3_GPIO
//
// Handle Direct Drive Versus 3-State (with pull-up or no buffer).
//
if ( AM_DEVICES_LED_POL_DIRECT_DRIVE_M & psLEDs[ui32LEDNum].ui32Polarity )
{
am_hal_gpio_state_write(psLEDs[ui32LEDNum].ui32GPIONumber,
AM_HAL_GPIO_OUTPUT_TOGGLE);
}
else
{
uint32_t ui32Ret, ui32Value;
//
// Check to see if the LED pin is enabled.
//
ui32Ret = am_hal_gpio_state_read(psLEDs[ui32LEDNum].ui32GPIONumber,
AM_HAL_GPIO_ENABLE_READ, &ui32Value);
if ( ui32Ret == AM_HAL_STATUS_SUCCESS )
{
if ( ui32Value )
{
//
// If it was enabled, turn if off.
//
am_hal_gpio_state_write(psLEDs[ui32LEDNum].ui32GPIONumber,
AM_HAL_GPIO_OUTPUT_TRISTATE_DISABLE);
}
else
{
//
// If it was not enabled, turn it on.
//
am_hal_gpio_state_write(psLEDs[ui32LEDNum].ui32GPIONumber,
AM_HAL_GPIO_OUTPUT_TRISTATE_ENABLE);
}
}
}
#else // AM_APOLLO3_GPIO
//
// Handle Direct Drive Versus 3-State (with pull-up or no buffer).
//
if ( AM_DEVICES_LED_POL_DIRECT_DRIVE_M & psLEDs[ui32LEDNum].ui32Polarity )
{
am_hal_gpio_out_bit_toggle(psLEDs[ui32LEDNum].ui32GPIONumber);
}
else
{
//
// Check to see if the LED pin is enabled.
//
if ( am_hal_gpio_out_enable_bit_get(psLEDs[ui32LEDNum].ui32GPIONumber) )
{
//
// If it was enabled, turn if off.
//
am_hal_gpio_out_enable_bit_clear(psLEDs[ui32LEDNum].ui32GPIONumber);
}
else
{
//
// If it was not enabled, turn if on.
//
am_hal_gpio_out_enable_bit_set(psLEDs[ui32LEDNum].ui32GPIONumber);
}
}
#endif // AM_APOLLO3_GPIO
}
//*****************************************************************************
//
//! @brief Gets the state of the requested LED.
//!
//! @param psLEDs is an array of LED structures.
//! @param ui32LEDNum is the LED to check.
//!
//! This function checks the state of a single LED.
//!
//! @return true if the LED is on.
//
//*****************************************************************************
bool
am_devices_led_get(am_devices_led_t *psLEDs, uint32_t ui32LEDNum)
{
if ( (psLEDs == NULL) ||
(ui32LEDNum >= MAX_LEDS) ||
(psLEDs[ui32LEDNum].ui32GPIONumber >= AM_HAL_GPIO_MAX_PADS) )
{
return false; // No error return, so return as off
}
#if AM_APOLLO3_GPIO
uint32_t ui32Ret, ui32Value;
am_hal_gpio_read_type_e eReadType;
eReadType = AM_DEVICES_LED_POL_DIRECT_DRIVE_M & psLEDs[ui32LEDNum].ui32Polarity ?
AM_HAL_GPIO_OUTPUT_READ : AM_HAL_GPIO_ENABLE_READ;
ui32Ret = am_hal_gpio_state_read(psLEDs[ui32LEDNum].ui32GPIONumber,
eReadType, &ui32Value);
if ( ui32Ret == AM_HAL_STATUS_SUCCESS )
{
return (bool)ui32Value;
}
else
{
return false;
}
#else // AM_APOLLO3_GPIO
//
// Handle Direct Drive Versus 3-State (with pull-up or no buffer).
//
if ( AM_DEVICES_LED_POL_DIRECT_DRIVE_M & psLEDs[ui32LEDNum].ui32Polarity )
{
//
// Mask to the GPIO bit position for this GPIO number.
//
uint64_t ui64Mask = ((uint64_t)0x01l) << psLEDs[ui32LEDNum].ui32GPIONumber;
//
// Extract the state of this bit and return it.
//
return !!(am_hal_gpio_out_read() & ui64Mask);
}
else
{
return am_hal_gpio_out_enable_bit_get(psLEDs[ui32LEDNum].ui32GPIONumber);
}
#endif // AM_APOLLO3_GPIO
}
//*****************************************************************************
//
//! @brief Display a binary value using LEDs.
//!
//! @param psLEDs is an array of LED structures.
//! @param ui32NumLEDs is the number of LEDs in the array.
//! @param ui32Value is the value to display on the LEDs.
//!
//! This function displays a value in binary across an array of LEDs.
//!
//! @return true if the LED is on.
//
//*****************************************************************************
void
am_devices_led_array_out(am_devices_led_t *psLEDs, uint32_t ui32NumLEDs,
uint32_t ui32Value)
{
uint32_t i;
for ( i = 0; i < ui32NumLEDs; i++ )
{
if ( ui32Value & (1 << i) )
{
am_devices_led_on(psLEDs, i);
}
else
{
am_devices_led_off(psLEDs, i);
}
}
}
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,114 @@
//*****************************************************************************
//
//! @file am_devices_led.h
//!
//! @brief Functions for controlling an array of LEDs
//!
//! @addtogroup devices External Device Control Library
//! @addtogroup LED SPI Device Control for programmable LEDs.
//! @ingroup devices
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_DEVICES_LED_H
#define AM_DEVICES_LED_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// LED polarity macros
//
//*****************************************************************************
#define AM_DEVICES_LED_POL_POLARITY_M 0x1
#define AM_DEVICES_LED_ON_HIGH 0x1
#define AM_DEVICES_LED_ON_LOW 0x0
//*****************************************************************************
//
// LED direct drive indicator macro
// Or this in with the polarity value to use the GPIO DATA register instead of
// the GPIO DATA ENABLE register to directly drive an LED buffer.
//
//*****************************************************************************
#define AM_DEVICES_LED_POL_DIRECT_DRIVE_M 0x2
//*****************************************************************************
//
// Structure for keeping track of LEDs
//
//*****************************************************************************
typedef struct
{
uint32_t ui32GPIONumber;
uint32_t ui32Polarity;
}
am_devices_led_t;
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern void am_devices_led_init(am_devices_led_t *psLED);
extern void am_devices_led_array_init(am_devices_led_t *psLEDs, uint32_t ui32NumLEDs);
extern void am_devices_led_array_disable(am_devices_led_t *psLEDs, uint32_t ui32NumLEDs);
extern void am_devices_led_on(am_devices_led_t *psLEDs, uint32_t ui32LEDNum);
extern void am_devices_led_off(am_devices_led_t *psLEDs, uint32_t ui32LEDNum);
extern void am_devices_led_toggle(am_devices_led_t *psLEDs, uint32_t ui32LEDNum);
extern bool am_devices_led_get(am_devices_led_t *psLEDs, uint32_t ui32LEDNum);
extern void am_devices_led_array_out(am_devices_led_t *psLEDs, uint32_t ui32NumLEDs,
uint32_t ui32Value);
#ifdef __cplusplus
}
#endif
#endif // AM_DEVICES_LED_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,495 @@
//*****************************************************************************
//
//! @file am_devices_mb85rc256v.c
//!
//! @brief Fujitsu 256K I2C FRAM driver.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include "am_mcu_apollo.h"
#include "am_devices_mb85rc256v.h"
#include "am_bsp.h"
//*****************************************************************************
//
// Global variables.
//
//*****************************************************************************
typedef struct
{
uint32_t ui32Module;
void *pIomHandle;
bool bOccupied;
} am_devices_iom_mb85rc256v_t;
am_devices_iom_mb85rc256v_t gAmMb85rc256v[AM_DEVICES_MB85RC256V_MAX_DEVICE_NUM];
am_hal_iom_config_t g_sIomMb85rc256vCfg =
{
.eInterfaceMode = AM_HAL_IOM_I2C_MODE,
.ui32ClockFreq = AM_HAL_IOM_1MHZ,
.eSpiMode = AM_HAL_IOM_SPI_MODE_0,
.ui32NBTxnBufLength = 0,
.pNBTxnBuf = NULL,
};
//*****************************************************************************
//
// Generic Command Write function.
//
//*****************************************************************************
static uint32_t
am_device_command_write(void *pHandle, uint8_t ui8DevAddr, uint32_t ui32InstrLen,
uint32_t ui32Instr, bool bCont,
uint32_t *pData, uint32_t ui32NumBytes)
{
am_hal_iom_transfer_t Transaction;
//
// Create the transaction.
//
Transaction.ui32InstrLen = ui32InstrLen;
Transaction.ui32Instr = ui32Instr;
Transaction.eDirection = AM_HAL_IOM_TX;
Transaction.ui32NumBytes = ui32NumBytes;
Transaction.pui32TxBuffer = pData;
Transaction.uPeerInfo.ui32I2CDevAddr = ui8DevAddr;
Transaction.bContinue = bCont;
Transaction.ui8RepeatCount = 0;
Transaction.ui32PauseCondition = 0;
Transaction.ui32StatusSetClr = 0;
//
// Execute the transction over IOM.
//
if (am_hal_iom_blocking_transfer(pHandle, &Transaction))
{
return AM_DEVICES_MB85RC256V_STATUS_ERROR;
}
return AM_DEVICES_MB85RC256V_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Generic Command Read function.
//
//*****************************************************************************
static uint32_t
am_device_command_read(void *pHandle, uint8_t ui8DevAddr, uint32_t ui32InstrLen, uint32_t ui32Instr,
bool bCont, uint32_t *pData, uint32_t ui32NumBytes)
{
am_hal_iom_transfer_t Transaction;
//
// Create the transaction.
//
Transaction.ui32InstrLen = ui32InstrLen;
Transaction.ui32Instr = ui32Instr;
Transaction.eDirection = AM_HAL_IOM_RX;
Transaction.ui32NumBytes = ui32NumBytes;
Transaction.pui32RxBuffer = pData;
Transaction.uPeerInfo.ui32I2CDevAddr = ui8DevAddr;
Transaction.bContinue = bCont;
Transaction.ui8RepeatCount = 0;
Transaction.ui32PauseCondition = 0;
Transaction.ui32StatusSetClr = 0;
//
// Execute the transction over IOM.
//
if (am_hal_iom_blocking_transfer(pHandle, &Transaction))
{
return AM_DEVICES_MB85RC256V_STATUS_ERROR;
}
return AM_DEVICES_MB85RC256V_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Initialize the mb85rc256v driver.
//!
//! @param psIOMSettings - IOM device structure describing the target spiflash.
//! @param pDMACtrlBuffer - DMA Transfer Control Buffer.
//!
//! This function should be called before any other am_devices_mb85rc256v
//! functions. It is used to set tell the other functions how to communicate
//! with the external spiflash hardware.
//!
//! @return Status.
//
//*****************************************************************************
uint32_t
am_devices_mb85rc256v_init(uint32_t ui32Module, am_devices_mb85rc256v_config_t *pDevConfig, void **ppHandle, void **ppIomHandle)
{
void *pIomHandle;
am_hal_iom_config_t stIOMMB85RC256VSettings;
uint32_t ui32Index = 0;
// Allocate a vacant device handle
for ( ui32Index = 0; ui32Index < AM_DEVICES_MB85RC256V_MAX_DEVICE_NUM; ui32Index++ )
{
if ( gAmMb85rc256v[ui32Index].bOccupied == false )
{
break;
}
}
if ( ui32Index == AM_DEVICES_MB85RC256V_MAX_DEVICE_NUM )
{
return AM_DEVICES_MB85RC256V_STATUS_ERROR;
}
if ( (ui32Module > AM_REG_IOM_NUM_MODULES) || (pDevConfig == NULL) )
{
return AM_DEVICES_MB85RC256V_STATUS_ERROR;
}
//
// Enable fault detection.
//
#if defined (AM_PART_APOLLO3) || defined (AM_PART_APOLLO3P)
#if AM_APOLLO3_MCUCTRL
am_hal_mcuctrl_control(AM_HAL_MCUCTRL_CONTROL_FAULT_CAPTURE_ENABLE, 0);
#else // AM_APOLLO3_MCUCTRL
am_hal_mcuctrl_fault_capture_enable();
#endif // AM_APOLLO3_MCUCTRL
#endif
stIOMMB85RC256VSettings = g_sIomMb85rc256vCfg;
stIOMMB85RC256VSettings.ui32NBTxnBufLength = pDevConfig->ui32NBTxnBufLength;
stIOMMB85RC256VSettings.pNBTxnBuf = pDevConfig->pNBTxnBuf;
stIOMMB85RC256VSettings.ui32ClockFreq = pDevConfig->ui32ClockFreq;
//
// Initialize the IOM instance.
// Enable power to the IOM instance.
// Configure the IOM for Serial operation during initialization.
// Enable the IOM.
//
if (am_hal_iom_initialize(ui32Module, &pIomHandle) ||
am_hal_iom_power_ctrl(pIomHandle, AM_HAL_SYSCTRL_WAKE, false) ||
am_hal_iom_configure(pIomHandle, &stIOMMB85RC256VSettings) ||
am_hal_iom_enable(pIomHandle))
{
return AM_DEVICES_MB85RC256V_STATUS_ERROR;
}
else
{
//
// Configure the IOM pins.
//
am_bsp_iom_pins_enable(ui32Module, AM_HAL_IOM_I2C_MODE);
gAmMb85rc256v[ui32Index].bOccupied = true;
gAmMb85rc256v[ui32Index].ui32Module = ui32Module;
*ppIomHandle = gAmMb85rc256v[ui32Index].pIomHandle = pIomHandle;
*ppHandle = (void *)&gAmMb85rc256v[ui32Index];
//
// Return the status.
//
return AM_DEVICES_MB85RC256V_STATUS_SUCCESS;
}
}
//*****************************************************************************
//
//! @brief De-Initialize the mb85rc256v driver.
//!
//! @param ui32Module - IOM Module#
//!
//! This function reverses the initialization
//!
//! @return Status.
//
//*****************************************************************************
uint32_t
am_devices_mb85rc256v_term(void *pHandle)
{
am_devices_iom_mb85rc256v_t *pIom = (am_devices_iom_mb85rc256v_t *)pHandle;
if ( pIom->ui32Module > AM_REG_IOM_NUM_MODULES )
{
return AM_DEVICES_MB85RC256V_STATUS_ERROR;
}
//
// Disable the IOM.
//
am_hal_iom_disable(pIom->pIomHandle);
//
// Disable power to and uninitialize the IOM instance.
//
am_hal_iom_power_ctrl(pIom->pIomHandle, AM_HAL_SYSCTRL_DEEPSLEEP, false);
am_hal_iom_uninitialize(pIom->pIomHandle);
// Free this device handle
pIom->bOccupied = false;
//
// Return the status.
//
return AM_DEVICES_MB85RC256V_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Reads the ID of the external flash and returns the value.
//!
//! @param pDeviceID - Pointer to the return buffer for the Device ID.
//!
//! This function reads the device ID register of the external flash, and returns
//! the result as an 32-bit unsigned integer value.
//!
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_mb85rc256v_read_id(void *pHandle, uint32_t *pDeviceID)
{
am_devices_iom_mb85rc256v_t *pIom = (am_devices_iom_mb85rc256v_t *)pHandle;
//
// Send the command sequence to read the Device ID.
//
if (am_device_command_read(pIom->pIomHandle, AM_DEVICES_MB85RC256V_RSVD_SLAVE_ID, 1,
(AM_DEVICES_MB85RC256V_SLAVE_ID << 1),
false, pDeviceID, 3))
{
return AM_DEVICES_MB85RC256V_STATUS_ERROR;
}
//
// Return the status.
//
return AM_DEVICES_MB85RC256V_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Programs the given range of flash addresses.
//!
//! @param ui32DeviceNumber - Device number of the external flash
//! @param pui8TxBuffer - Buffer to write the external flash data from
//! @param ui32WriteAddress - Address to write to in the external flash
//! @param ui32NumBytes - Number of bytes to write to the external flash
//!
//! This function uses the data in the provided pui8TxBuffer and copies it to
//! the external flash at the address given by ui32WriteAddress. It will copy
//! exactly ui32NumBytes of data from the original pui8TxBuffer pointer. The
//! user is responsible for ensuring that they do not overflow the target flash
//! memory or underflow the pui8TxBuffer array
//
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_mb85rc256v_blocking_write(void *pHandle, uint8_t *pui8TxBuffer,
uint32_t ui32WriteAddress,
uint32_t ui32NumBytes)
{
am_devices_iom_mb85rc256v_t *pIom = (am_devices_iom_mb85rc256v_t *)pHandle;
//
// Write the data to the device.
//
if (am_device_command_write(pIom->pIomHandle, AM_DEVICES_MB85RC256V_SLAVE_ID, 2,
(ui32WriteAddress & 0x0000FFFF),
false, (uint32_t *)pui8TxBuffer, ui32NumBytes))
{
return AM_DEVICES_MB85RC256V_STATUS_ERROR;
}
//
// Return the status.
//
return AM_DEVICES_MB85RC256V_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Programs the given range of flash addresses.
//!
//! @param ui32DeviceNumber - Device number of the external flash
//! @param pui8TxBuffer - Buffer to write the external flash data from
//! @param ui32WriteAddress - Address to write to in the external flash
//! @param ui32NumBytes - Number of bytes to write to the external flash
//!
//! This function uses the data in the provided pui8TxBuffer and copies it to
//! the external flash at the address given by ui32WriteAddress. It will copy
//! exactly ui32NumBytes of data from the original pui8TxBuffer pointer. The
//! user is responsible for ensuring that they do not overflow the target flash
//! memory or underflow the pui8TxBuffer array
//
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_mb85rc256v_nonblocking_write(void *pHandle, uint8_t *pui8TxBuffer,
uint32_t ui32WriteAddress,
uint32_t ui32NumBytes,
am_hal_iom_callback_t pfnCallback,
void *pCallbackCtxt)
{
am_hal_iom_transfer_t Transaction;
am_devices_iom_mb85rc256v_t *pIom = (am_devices_iom_mb85rc256v_t *)pHandle;
Transaction.ui8RepeatCount = 0;
Transaction.ui32PauseCondition = 0;
Transaction.ui32StatusSetClr = 0;
Transaction.ui8Priority = 1; // High priority for now.
Transaction.uPeerInfo.ui32I2CDevAddr = AM_DEVICES_MB85RC256V_SLAVE_ID;
Transaction.bContinue = false;
//
// Set up the IOM transaction.
//
Transaction.eDirection = AM_HAL_IOM_TX;
Transaction.ui32InstrLen = 2;
Transaction.ui32Instr = ui32WriteAddress & 0x0000FFFF;
Transaction.ui32NumBytes = ui32NumBytes;
Transaction.pui32TxBuffer = (uint32_t *)pui8TxBuffer;
//
// Add this transaction to the command queue (no callback).
//
if (am_hal_iom_nonblocking_transfer(pIom->pIomHandle, &Transaction, pfnCallback, pCallbackCtxt))
{
return AM_DEVICES_MB85RC256V_STATUS_ERROR;
}
//
// Return the status.
//
return AM_DEVICES_MB85RC256V_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Reads the contents of the fram into a buffer.
//!
//! @param pui8RxBuffer - Buffer to store the received data from the flash
//! @param ui32ReadAddress - Address of desired data in external flash
//! @param ui32NumBytes - Number of bytes to read from external flash
//!
//! This function reads the external flash at the provided address and stores
//! the received data into the provided buffer location. This function will
//! only store ui32NumBytes worth of data.
//
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_mb85rc256v_blocking_read(void *pHandle, uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes)
{
am_devices_iom_mb85rc256v_t *pIom = (am_devices_iom_mb85rc256v_t *)pHandle;
if (am_device_command_read(pIom->pIomHandle, AM_DEVICES_MB85RC256V_SLAVE_ID, 2,
(ui32ReadAddress & 0x0000FFFF),
false, (uint32_t *)pui8RxBuffer, ui32NumBytes))
{
return AM_DEVICES_MB85RC256V_STATUS_ERROR;
}
//
// Return the status.
//
return AM_DEVICES_MB85RC256V_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Reads the contents of the fram into a buffer.
//!
//! @param pui8RxBuffer - Buffer to store the received data from the flash
//! @param ui32ReadAddress - Address of desired data in external flash
//! @param ui32NumBytes - Number of bytes to read from external flash
//!
//! This function reads the external flash at the provided address and stores
//! the received data into the provided buffer location. This function will
//! only store ui32NumBytes worth of data.
//
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_mb85rc256v_nonblocking_read(void *pHandle, uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes,
am_hal_iom_callback_t pfnCallback,
void * pCallbackCtxt)
{
am_hal_iom_transfer_t Transaction;
am_devices_iom_mb85rc256v_t *pIom = (am_devices_iom_mb85rc256v_t *)pHandle;
//
// Set up the IOM transaction.
//
Transaction.ui8Priority = 1; // High priority for now.
Transaction.eDirection = AM_HAL_IOM_RX;
Transaction.ui32InstrLen = 2;
Transaction.ui32Instr = (ui32ReadAddress & 0x0000FFFF);
Transaction.ui32NumBytes = ui32NumBytes;
Transaction.pui32RxBuffer = (uint32_t *)pui8RxBuffer;
Transaction.uPeerInfo.ui32I2CDevAddr = AM_DEVICES_MB85RC256V_SLAVE_ID;
Transaction.ui8RepeatCount = 0;
Transaction.ui32PauseCondition = 0;
Transaction.ui32StatusSetClr = 0;
Transaction.bContinue = false;
//
// Start the transaction.
//
if (am_hal_iom_nonblocking_transfer(pIom->pIomHandle, &Transaction, pfnCallback, pCallbackCtxt))
{
return AM_DEVICES_MB85RC256V_STATUS_ERROR;
}
//
// Return the status.
//
return AM_DEVICES_MB85RC256V_STATUS_SUCCESS;
}
@@ -0,0 +1,120 @@
//*****************************************************************************
//
//! @file am_devices_mb85rc256v.h
//!
//! @brief Fujitsu 256K I2C FRAM driver.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_DEVICES_MB85RC256V_H
#define AM_DEVICES_MB85RC256V_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Global definitions for the commands
//
//*****************************************************************************
#define AM_DEVICES_MB85RC256V_SLAVE_ID 0x50
#define AM_DEVICES_MB85RC256V_RSVD_SLAVE_ID 0x7C
#define AM_DEVICES_MB85RC256V_ID 0x0010A500
#define AM_DEVICES_MB85RC64TA_ID 0x0058A300
//*****************************************************************************
//
// Global type definitions.
//
//*****************************************************************************
typedef enum
{
AM_DEVICES_MB85RC256V_STATUS_SUCCESS,
AM_DEVICES_MB85RC256V_STATUS_ERROR
} am_devices_mb85rc256v_status_t;
typedef struct
{
uint32_t ui32ClockFreq;
uint32_t *pNBTxnBuf;
uint32_t ui32NBTxnBufLength;
} am_devices_mb85rc256v_config_t;
#define AM_DEVICES_MB85RC256V_MAX_DEVICE_NUM 1
//*****************************************************************************
//
// External function definitions.
//
//*****************************************************************************
extern uint32_t am_devices_mb85rc256v_init(uint32_t ui32Module, am_devices_mb85rc256v_config_t *pDevConfig, void **ppHandle, void **ppIomHandle);
extern uint32_t am_devices_mb85rc256v_term(void *pHandle);
extern uint32_t am_devices_mb85rc256v_read_id(void *pHandle, uint32_t *pDeviceID);
extern uint32_t am_devices_mb85rc256v_blocking_write(void *pHandle, uint8_t *ui8TxBuffer,
uint32_t ui32WriteAddress,
uint32_t ui32NumBytes);
extern uint32_t am_devices_mb85rc256v_nonblocking_write(void *pHandle, uint8_t *ui8TxBuffer,
uint32_t ui32WriteAddress,
uint32_t ui32NumBytes,
am_hal_iom_callback_t pfnCallback,
void *pCallbackCtxt);
extern uint32_t am_devices_mb85rc256v_blocking_read(void *pHandle, uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes);
extern uint32_t am_devices_mb85rc256v_nonblocking_read(void *pHandle, uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes,
am_hal_iom_callback_t pfnCallback,
void *pCallbackCtxt);
#ifdef __cplusplus
}
#endif
#endif // AM_DEVICES_MB85RC256V_H
@@ -0,0 +1,909 @@
//*****************************************************************************
//
//! @file am_devices_mb85rs1mt.c
//!
//! @brief Fujitsu 64K SPI FRAM driver.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include "am_mcu_apollo.h"
#include "am_devices_mb85rs1mt.h"
#include "am_bsp.h"
//*****************************************************************************
//
// Global variables.
//
//*****************************************************************************
typedef struct
{
uint32_t ui32Module;
uint32_t ui32CS;
void *pIomHandle;
bool bOccupied;
} am_devices_iom_mb85rs1mt_t;
am_devices_iom_mb85rs1mt_t gAmMb85rs1mt[AM_DEVICES_MB85RS1MT_MAX_DEVICE_NUM];
am_hal_iom_config_t g_sIomMb85rs1mtCfg =
{
.eInterfaceMode = AM_HAL_IOM_SPI_MODE,
.ui32ClockFreq = AM_HAL_IOM_1MHZ,
.eSpiMode = AM_HAL_IOM_SPI_MODE_0,
.ui32NBTxnBufLength = 0,
.pNBTxnBuf = NULL,
};
//*****************************************************************************
//
// Generic Command Write function.
//
//*****************************************************************************
static uint32_t
am_device_command_write(void *pHandle, uint32_t ui32InstrLen, uint32_t ui32Instr,
uint32_t *pData, uint32_t ui32NumBytes)
{
am_hal_iom_transfer_t Transaction;
am_devices_iom_mb85rs1mt_t *pIom = (am_devices_iom_mb85rs1mt_t *)pHandle;
//
// Create the transaction.
//
Transaction.ui32InstrLen = ui32InstrLen;
Transaction.ui32Instr = ui32Instr;
Transaction.eDirection = AM_HAL_IOM_TX;
Transaction.ui32NumBytes = ui32NumBytes;
Transaction.pui32TxBuffer = pData;
Transaction.uPeerInfo.ui32SpiChipSelect = pIom->ui32CS;
Transaction.bContinue = false;
Transaction.ui8RepeatCount = 0;
Transaction.ui32PauseCondition = 0;
Transaction.ui32StatusSetClr = 0;
//
// Execute the transction over IOM.
//
if (am_hal_iom_blocking_transfer(pIom->pIomHandle, &Transaction))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
return AM_DEVICES_MB85RS1MT_STATUS_SUCCESS;
}
static uint32_t
am_device_command_read(void *pHandle, uint32_t ui32InstrLen, uint32_t ui32Instr,
uint32_t *pData, uint32_t ui32NumBytes)
{
am_hal_iom_transfer_t Transaction;
am_devices_iom_mb85rs1mt_t *pIom = (am_devices_iom_mb85rs1mt_t *)pHandle;
//
// Create the transaction.
//
Transaction.ui32InstrLen = ui32InstrLen;
Transaction.ui32Instr = ui32Instr;
Transaction.eDirection = AM_HAL_IOM_RX;
Transaction.ui32NumBytes = ui32NumBytes;
Transaction.pui32RxBuffer = pData;
Transaction.uPeerInfo.ui32SpiChipSelect = pIom->ui32CS;
Transaction.bContinue = false;
Transaction.ui8RepeatCount = 0;
Transaction.ui32PauseCondition = 0;
Transaction.ui32StatusSetClr = 0;
//
// Execute the transction over IOM.
//
if (am_hal_iom_blocking_transfer(pIom->pIomHandle, &Transaction))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
return AM_DEVICES_MB85RS1MT_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Initialize the mb85rs1mt driver.
//!
//! @param ui32Module - IOM Module#
//! @param psIOMSettings - IOM device structure describing the target spiflash.
//!
//! This function should be called before any other am_devices_mb85rs1mt
//! functions. It is used to set tell the other functions how to communicate
//! with the external spiflash hardware.
//!
//! @return Status.
//
//*****************************************************************************
uint32_t
am_devices_mb85rs1mt_init(uint32_t ui32Module, am_devices_mb85rs1mt_config_t *pDevConfig, void **ppHandle, void **ppIomHandle)
{
void *pIomHandle;
am_hal_iom_config_t stIOMMB85RS1MTSettings;
uint32_t g_CS[AM_REG_IOM_NUM_MODULES] =
{
AM_BSP_IOM0_CS_CHNL,
AM_BSP_IOM1_CS_CHNL,
#ifndef APOLLO3_FPGA
AM_BSP_IOM2_CS_CHNL,
AM_BSP_IOM3_CS_CHNL,
AM_BSP_IOM4_CS_CHNL,
AM_BSP_IOM5_CS_CHNL,
#endif
};
uint32_t ui32Index = 0;
// Allocate a vacant device handle
for ( ui32Index = 0; ui32Index < AM_DEVICES_MB85RS1MT_MAX_DEVICE_NUM; ui32Index++ )
{
if ( gAmMb85rs1mt[ui32Index].bOccupied == false )
{
break;
}
}
if ( ui32Index == AM_DEVICES_MB85RS1MT_MAX_DEVICE_NUM )
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
if ( (ui32Module > AM_REG_IOM_NUM_MODULES) || (pDevConfig == NULL) )
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
//
// Configure the IOM pins.
//
am_bsp_iom_pins_enable(ui32Module, AM_HAL_IOM_SPI_MODE);
//
// Enable fault detection.
//
#if AM_APOLLO3_MCUCTRL
am_hal_mcuctrl_control(AM_HAL_MCUCTRL_CONTROL_FAULT_CAPTURE_ENABLE, 0);
#else // AM_APOLLO3_MCUCTRL
am_hal_mcuctrl_fault_capture_enable();
#endif // AM_APOLLO3_MCUCTRL
stIOMMB85RS1MTSettings = g_sIomMb85rs1mtCfg;
stIOMMB85RS1MTSettings.ui32NBTxnBufLength = pDevConfig->ui32NBTxnBufLength;
stIOMMB85RS1MTSettings.pNBTxnBuf = pDevConfig->pNBTxnBuf;
stIOMMB85RS1MTSettings.ui32ClockFreq = pDevConfig->ui32ClockFreq;
//
// Initialize the IOM instance.
// Enable power to the IOM instance.
// Configure the IOM for Serial operation during initialization.
// Enable the IOM.
// HAL Success return is 0
//
if (am_hal_iom_initialize(ui32Module, &pIomHandle) ||
am_hal_iom_power_ctrl(pIomHandle, AM_HAL_SYSCTRL_WAKE, false) ||
am_hal_iom_configure(pIomHandle, &stIOMMB85RS1MTSettings) ||
am_hal_iom_enable(pIomHandle))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
else
{
gAmMb85rs1mt[ui32Index].bOccupied = true;
gAmMb85rs1mt[ui32Index].ui32Module = ui32Module;
gAmMb85rs1mt[ui32Index].ui32CS = g_CS[ui32Module];
*ppIomHandle = gAmMb85rs1mt[ui32Index].pIomHandle = pIomHandle;
*ppHandle = (void *)&gAmMb85rs1mt[ui32Index];
//
// Return the status.
//
return AM_DEVICES_MB85RS1MT_STATUS_SUCCESS;
}
}
//*****************************************************************************
//
//! @brief De-Initialize the mb85rs1mt driver.
//!
//! @param ui32Module - IOM Module#
//!
//! This function reverses the initialization
//!
//! @return Status.
//
//*****************************************************************************
uint32_t
am_devices_mb85rs1mt_term(void *pHandle)
{
am_devices_iom_mb85rs1mt_t *pIom = (am_devices_iom_mb85rs1mt_t *)pHandle;
if ( pIom->ui32Module > AM_REG_IOM_NUM_MODULES )
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
// Disable the pins
am_bsp_iom_pins_disable(pIom->ui32Module, AM_HAL_IOM_SPI_MODE);
//
// Disable the IOM.
//
am_hal_iom_disable(pIom->pIomHandle);
//
// Disable power to and uninitialize the IOM instance.
//
am_hal_iom_power_ctrl(pIom->pIomHandle, AM_HAL_SYSCTRL_DEEPSLEEP, false);
am_hal_iom_uninitialize(pIom->pIomHandle);
// Free this device handle
pIom->bOccupied = false;
//
// Return the status.
//
return AM_DEVICES_MB85RS1MT_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Reads the ID of the external flash and returns the value.
//!
//! @param pDeviceID - Pointer to the return buffer for the Device ID.
//!
//! This function reads the device ID register of the external flash, and returns
//! the result as an 32-bit unsigned integer value.
//!
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_mb85rs1mt_read_id(void *pHandle, uint32_t *pDeviceID)
{
//
// Send the command sequence to read the Device ID.
//
if (am_device_command_read(pHandle, 1, AM_DEVICES_MB85RS1MT_READ_DEVICE_ID, pDeviceID, 4))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
return AM_DEVICES_MB85RS1MT_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Reads the current status of the external flash
//!
//! This function reads the status register of the external flash, and returns
//! the result as an 8-bit unsigned integer value. The processor will block
//! during the data transfer process, but will return as soon as the status
//! register had been read.
//!
//! Macro definitions for interpreting the contents of the status register are
//! included in the header file.
//!
//! @return 8-bit status register contents
//
//*****************************************************************************
uint32_t
am_devices_mb85rs1mt_status_get(void *pHandle, uint32_t *pStatus)
{
//
// Send the command sequence to read the device status.
//
if (am_device_command_read(pHandle, 1, AM_DEVICES_MB85RS1MT_READ_STATUS, pStatus, 1))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
return AM_DEVICES_MB85RS1MT_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Sends a specific command to the device (blocking).
//!
//! ui32Cmd = AM_DEVICES_CMD_WREN
//! AM_DEVICES_CMD_WRDI
//
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_mb85rs1mt_command_send(void *pHandle, uint32_t ui32Cmd)
{
uint32_t Dummy;
if ( ui32Cmd == AM_DEVICES_MB85RS1MT_CMD_WREN )
{
//
// Send the command to enable writing.
//
if (am_device_command_write(pHandle, 1, AM_DEVICES_MB85RS1MT_WRITE_ENABLE, &Dummy, 0))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
}
else if ( ui32Cmd == AM_DEVICES_MB85RS1MT_CMD_WRDI )
{
//
// Send the command to enable writing.
//
if (am_device_command_write(pHandle, 1, AM_DEVICES_MB85RS1MT_WRITE_DISABLE, &Dummy, 0))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
}
else
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
return AM_DEVICES_MB85RS1MT_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Programs the given range of flash addresses.
//!
//! @param ui32DeviceNumber - Device number of the external flash
//! @param pui8TxBuffer - Buffer to write the external flash data from
//! @param ui32WriteAddress - Address to write to in the external flash
//! @param ui32NumBytes - Number of bytes to write to the external flash
//!
//! This function uses the data in the provided pui8TxBuffer and copies it to
//! the external flash at the address given by ui32WriteAddress. It will copy
//! exactly ui32NumBytes of data from the original pui8TxBuffer pointer. The
//! user is responsible for ensuring that they do not overflow the target flash
//! memory or underflow the pui8TxBuffer array
//
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_mb85rs1mt_blocking_write(void *pHandle, uint8_t *pui8TxBuffer,
uint32_t ui32WriteAddress,
uint32_t ui32NumBytes)
{
am_hal_iom_transfer_t Transaction;
uint32_t Dummy;
am_devices_iom_mb85rs1mt_t *pIom = (am_devices_iom_mb85rs1mt_t *)pHandle;
//
// Send the WRITE ENABLE command to enable writing.
//
if (am_device_command_write(pHandle, 1, AM_DEVICES_MB85RS1MT_WRITE_ENABLE, &Dummy, 0))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
Transaction.ui8RepeatCount = 0;
Transaction.ui32PauseCondition = 0;
Transaction.ui32StatusSetClr = 0;
//
// Write the command to the device.
//
Transaction.eDirection = AM_HAL_IOM_TX;
Transaction.ui32InstrLen = 1;
Transaction.ui32Instr = AM_DEVICES_MB85RS1MT_WRITE;
Transaction.ui32NumBytes = 0;
Transaction.pui32TxBuffer = (uint32_t *)pui8TxBuffer;
Transaction.uPeerInfo.ui32SpiChipSelect = pIom->ui32CS;
Transaction.bContinue = true;
//
// Start the transaction.
//
if (am_hal_iom_blocking_transfer(pIom->pIomHandle, &Transaction))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
//
// Write the offset (24 bits) to the device.
//
Transaction.eDirection = AM_HAL_IOM_TX;
Transaction.ui32InstrLen = 3;
Transaction.ui32Instr = ui32WriteAddress & 0x00FFFFFF;
Transaction.ui32NumBytes = ui32NumBytes;
Transaction.pui32TxBuffer = (uint32_t *)pui8TxBuffer;
Transaction.uPeerInfo.ui32SpiChipSelect = pIom->ui32CS;
Transaction.bContinue = false;
//
// Start the transaction.
//
if (am_hal_iom_blocking_transfer(pIom->pIomHandle, &Transaction))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
//
// Send the command to disable writing.
//
if (am_device_command_write(pHandle, 1, AM_DEVICES_MB85RS1MT_WRITE_DISABLE, &Dummy, 0))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
//
// Return the status.
//
return AM_DEVICES_MB85RS1MT_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Programs the given range of flash addresses.
//!
//! @param ui32DeviceNumber - Device number of the external flash
//! @param pui8TxBuffer - Buffer to write the external flash data from
//! @param ui32WriteAddress - Address to write to in the external flash
//! @param ui32NumBytes - Number of bytes to write to the external flash
//!
//! This function uses the data in the provided pui8TxBuffer and copies it to
//! the external flash at the address given by ui32WriteAddress. It will copy
//! exactly ui32NumBytes of data from the original pui8TxBuffer pointer. The
//! user is responsible for ensuring that they do not overflow the target flash
//! memory or underflow the pui8TxBuffer array
//
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_mb85rs1mt_nonblocking_write_adv(void *pHandle, uint8_t *pui8TxBuffer,
uint32_t ui32WriteAddress,
uint32_t ui32NumBytes,
uint32_t ui32PauseCondition,
uint32_t ui32StatusSetClr,
am_hal_iom_callback_t pfnCallback,
void *pCallbackCtxt)
{
am_hal_iom_transfer_t Transaction;
am_devices_iom_mb85rs1mt_t *pIom = (am_devices_iom_mb85rs1mt_t *)pHandle;
//
// Common transaction parameters
//
Transaction.ui8Priority = 1; // High priority for now.
Transaction.uPeerInfo.ui32SpiChipSelect = pIom->ui32CS;
Transaction.ui8RepeatCount = 0;
Transaction.ui32PauseCondition = ui32PauseCondition;
//
// Set up the IOM transaction to send the WREN device command.
//
Transaction.eDirection = AM_HAL_IOM_TX;
Transaction.ui32InstrLen = 1; // Sending 1 offset byte
Transaction.ui32Instr = AM_DEVICES_MB85RS1MT_WRITE_ENABLE;
Transaction.ui32NumBytes = 0; // WREN CMD is sent as the offset
Transaction.pui32TxBuffer = (uint32_t *)pui8TxBuffer; // Not used for this CMD
Transaction.bContinue = false;
Transaction.ui32StatusSetClr = 0;
//
// Start the transaction (no callback).
//
if (am_hal_iom_nonblocking_transfer(pIom->pIomHandle, &Transaction, 0, 0))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
//
// Set up the IOM transaction to write the FRAM command to the device.
// This one needs to keep CE asserted (via continue).
//
Transaction.eDirection = AM_HAL_IOM_TX;
Transaction.ui32InstrLen = 1;
Transaction.ui32Instr = AM_DEVICES_MB85RS1MT_WRITE;
Transaction.ui32NumBytes = 0;
Transaction.pui32TxBuffer = (uint32_t *)pui8TxBuffer;
Transaction.ui32PauseCondition = 0;
Transaction.ui32StatusSetClr = 0;
Transaction.bContinue = true;
//
// Start the transaction (no callback).
//
if (am_hal_iom_nonblocking_transfer(pIom->pIomHandle, &Transaction, 0, 0))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
if (ui32NumBytes)
{
//
// Set up the IOM transaction to write the offset (address) and data.
//
Transaction.eDirection = AM_HAL_IOM_TX;
Transaction.ui32InstrLen = 3;
Transaction.ui32Instr = ui32WriteAddress & 0x00FFFFFF;
Transaction.ui32NumBytes = ui32NumBytes;
Transaction.pui32TxBuffer = (uint32_t *)pui8TxBuffer;
Transaction.bContinue = false;
Transaction.ui32PauseCondition = 0;
// Now set the post processing condition
Transaction.ui32StatusSetClr = ui32StatusSetClr;
//
// Start the transaction
//
if (am_hal_iom_nonblocking_transfer(pIom->pIomHandle, &Transaction, pfnCallback, pCallbackCtxt))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
}
// No Need to issue AM_DEVICES_MB85RS1MT_WRITE_DISABLE, as WEL gets deasserted
// following the WRITE transaction
//
// Return the status.
//
return AM_DEVICES_MB85RS1MT_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Programs the given range of flash addresses.
//!
//! @param ui32DeviceNumber - Device number of the external flash
//! @param pui8TxBuffer - Buffer to write the external flash data from
//! @param ui32WriteAddress - Address to write to in the external flash
//! @param ui32NumBytes - Number of bytes to write to the external flash
//!
//! This function uses the data in the provided pui8TxBuffer and copies it to
//! the external flash at the address given by ui32WriteAddress. It will copy
//! exactly ui32NumBytes of data from the original pui8TxBuffer pointer. The
//! user is responsible for ensuring that they do not overflow the target flash
//! memory or underflow the pui8TxBuffer array
//
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_mb85rs1mt_nonblocking_write(void *pHandle, uint8_t *pui8TxBuffer,
uint32_t ui32WriteAddress,
uint32_t ui32NumBytes,
am_hal_iom_callback_t pfnCallback,
void *pCallbackCtxt)
{
#if 0
am_hal_iom_transfer_t Transaction;
//
// Common transaction parameters
//
Transaction.ui8Priority = 1; // High priority for now.
Transaction.uPeerInfo.ui32SpiChipSelect = g_MB85RS1MTCS;
Transaction.ui8RepeatCount = 0;
Transaction.ui32PauseCondition = 0;
Transaction.ui32StatusSetClr = 0;
#if 0
//
// Set up the IOM transaction to send the WREN device command.
//
Transaction.eDirection = AM_HAL_IOM_TX;
Transaction.ui32InstrLen = 1; // Sending 1 offset byte
Transaction.ui32Instr = AM_DEVICES_MB85RS1MT_WRITE_ENABLE;
Transaction.ui32NumBytes = 0; // WREN CMD is sent as the offset
Transaction.pui32TxBuffer = (uint32_t *)pui8TxBuffer; // Not used for this CMD
Transaction.bContinue = false;
//
// Start the transaction (no callback).
//
if (am_hal_iom_nonblocking_transfer(pHandle, &Transaction, 0, 0))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
#endif
// Do the transaction (no callback).
if (am_devices_mb85rs1mt_nonblocking_write_adv(pui8TxBuffer,
ui32WriteAddress,
ui32NumBytes,
0, 0, 0, 0))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
//
// Set up the IOM transaction to send the WRDI (write disable) device command.
//
Transaction.eDirection = AM_HAL_IOM_TX;
Transaction.ui32InstrLen = 1; // Sending 1 offset byte
Transaction.ui32Instr = AM_DEVICES_MB85RS1MT_WRITE_DISABLE;
Transaction.ui32NumBytes = 0; // WRDI CMD is sent as the offset
Transaction.pui32TxBuffer = (uint32_t *)pui8TxBuffer; // Not used for this CMD
Transaction.bContinue = false;
//
// Start the transaction, sending the callback.
//
if (am_hal_iom_nonblocking_transfer(pHandle, &Transaction, pfnCallback, pCallbackCtxt))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
//
// Return the status.
//
return AM_DEVICES_MB85RS1MT_STATUS_SUCCESS;
#else
return (am_devices_mb85rs1mt_nonblocking_write_adv(pHandle, pui8TxBuffer,
ui32WriteAddress,
ui32NumBytes,
0, 0, pfnCallback, pCallbackCtxt));
#endif
}
//*****************************************************************************
//
//! @brief Reads the contents of the fram into a buffer.
//!
//! @param pui8RxBuffer - Buffer to store the received data from the flash
//! @param ui32ReadAddress - Address of desired data in external flash
//! @param ui32NumBytes - Number of bytes to read from external flash
//!
//! This function reads the external flash at the provided address and stores
//! the received data into the provided buffer location. This function will
//! only store ui32NumBytes worth of data.
//
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_mb85rs1mt_blocking_read(void *pHandle, uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes)
{
am_hal_iom_transfer_t Transaction;
am_devices_iom_mb85rs1mt_t *pIom = (am_devices_iom_mb85rs1mt_t *)pHandle;
Transaction.ui8RepeatCount = 0;
Transaction.ui32PauseCondition = 0;
Transaction.ui32StatusSetClr = 0;
//
// Write the command to the device.
//
Transaction.eDirection = AM_HAL_IOM_RX;
Transaction.ui32InstrLen = 1;
Transaction.ui32Instr = AM_DEVICES_MB85RS1MT_READ;
Transaction.ui32NumBytes = 0;
Transaction.pui32TxBuffer = (uint32_t *)pui8RxBuffer;
Transaction.uPeerInfo.ui32SpiChipSelect = pIom->ui32CS;
Transaction.bContinue = true;
//
// Start the transaction.
//
if (am_hal_iom_blocking_transfer(pIom->pIomHandle, &Transaction))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
//
// Set up the IOM transaction to write to the device with offset address.
//
Transaction.eDirection = AM_HAL_IOM_RX;
Transaction.ui32InstrLen = 3;
Transaction.ui32Instr = ui32ReadAddress & 0x00FFFFFF;
Transaction.ui32NumBytes = ui32NumBytes;
Transaction.pui32RxBuffer = (uint32_t *)pui8RxBuffer;
Transaction.uPeerInfo.ui32SpiChipSelect = pIom->ui32CS;
Transaction.bContinue = false;
//
// Start the transaction.
//
if (am_hal_iom_blocking_transfer(pIom->pIomHandle, &Transaction))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
//
// Return the status.
//
return AM_DEVICES_MB85RS1MT_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Reads the contents of the fram into a buffer.
//!
//! @param pui8RxBuffer - Buffer to store the received data from the flash
//! @param ui32ReadAddress - Address of desired data in external flash
//! @param ui32NumBytes - Number of bytes to read from external flash
//!
//! This function reads the external flash at the provided address and stores
//! the received data into the provided buffer location. This function will
//! only store ui32NumBytes worth of data.
//
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_mb85rs1mt_nonblocking_read(void *pHandle, uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes,
am_hal_iom_callback_t pfnCallback,
void *pCallbackCtxt)
{
am_hal_iom_transfer_t Transaction;
am_devices_iom_mb85rs1mt_t *pIom = (am_devices_iom_mb85rs1mt_t *)pHandle;
Transaction.ui8RepeatCount = 0;
Transaction.ui32PauseCondition = 0;
Transaction.ui32StatusSetClr = 0;
//
// Set up the IOM transaction to write the FRAM command to the device.
// This one needs to keep CE asserted (via continue).
//
Transaction.eDirection = AM_HAL_IOM_RX;
Transaction.ui32InstrLen = 1;
Transaction.ui32Instr = AM_DEVICES_MB85RS1MT_READ;
Transaction.ui32NumBytes = 0;
Transaction.pui32TxBuffer = (uint32_t *)pui8RxBuffer;
Transaction.uPeerInfo.ui32SpiChipSelect = pIom->ui32CS;
Transaction.bContinue = true;
//
// Start the transaction (no callback).
//
if (am_hal_iom_nonblocking_transfer(pIom->pIomHandle, &Transaction, 0, 0))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
//
// Set up the IOM transaction.
//
Transaction.ui8Priority = 1; // High priority for now.
Transaction.eDirection = AM_HAL_IOM_RX;
Transaction.ui32InstrLen = 3;
Transaction.ui32Instr = ui32ReadAddress & 0x00FFFFFF;
Transaction.ui32NumBytes = ui32NumBytes;
Transaction.pui32RxBuffer = (uint32_t *)pui8RxBuffer;
Transaction.uPeerInfo.ui32SpiChipSelect = pIom->ui32CS;
Transaction.bContinue = false;
//
// Start the transaction.
//
if (am_hal_iom_nonblocking_transfer(pIom->pIomHandle, &Transaction, pfnCallback, pCallbackCtxt))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
//
// Return the status.
//
return AM_DEVICES_MB85RS1MT_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Reads the contents of the fram into a buffer.
//!
//! @param pui8RxBuffer - Buffer to store the received data from the flash
//! @param ui32ReadAddress - Address of desired data in external flash
//! @param ui32NumBytes - Number of bytes to read from external flash
//!
//! This function reads the external flash at the provided address and stores
//! the received data into the provided buffer location. This function will
//! only store ui32NumBytes worth of data.
//
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_mb85rs1mt_nonblocking_read_hiprio(void *pHandle, uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes,
am_hal_iom_callback_t pfnCallback,
void *pCallbackCtxt)
{
am_hal_iom_transfer_t Transaction;
am_devices_iom_mb85rs1mt_t *pIom = (am_devices_iom_mb85rs1mt_t *)pHandle;
Transaction.ui8RepeatCount = 0;
Transaction.ui32PauseCondition = 0;
Transaction.ui32StatusSetClr = 0;
//
// Set up the IOM transaction to write the FRAM command to the device.
// This one needs to keep CE asserted (via continue).
//
Transaction.eDirection = AM_HAL_IOM_TX;
Transaction.ui32InstrLen = 1;
Transaction.ui32Instr = AM_DEVICES_MB85RS1MT_READ;
Transaction.ui32NumBytes = 0;
Transaction.pui32TxBuffer = (uint32_t *)pui8RxBuffer;
Transaction.uPeerInfo.ui32SpiChipSelect = pIom->ui32CS;
Transaction.bContinue = true;
//
// Start the transaction (no callback).
//
if (am_hal_iom_highprio_transfer(pIom->pIomHandle, &Transaction, 0, 0))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
//
// Set up the IOM transaction.
//
Transaction.ui8Priority = 1; // High priority for now.
Transaction.eDirection = AM_HAL_IOM_RX;
Transaction.ui32InstrLen = 3;
Transaction.ui32Instr = ui32ReadAddress & 0x00FFFFFF;
Transaction.ui32NumBytes = ui32NumBytes;
Transaction.pui32RxBuffer = (uint32_t *)pui8RxBuffer;
Transaction.uPeerInfo.ui32SpiChipSelect = pIom->ui32CS;
Transaction.bContinue = false;
//
// Start the transaction.
//
if (am_hal_iom_highprio_transfer(pIom->pIomHandle, &Transaction, pfnCallback, pCallbackCtxt))
{
return AM_DEVICES_MB85RS1MT_STATUS_ERROR;
}
//
// Return the status.
//
return AM_DEVICES_MB85RS1MT_STATUS_SUCCESS;
}
@@ -0,0 +1,158 @@
//*****************************************************************************
//
//! @file am_devices_mb85rs1mt.h
//!
//! @brief Fujitsu 64K SPI FRAM driver.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_DEVICES_MB85RS1MT_H
#define AM_DEVICES_MB85RS1MT_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Global definitions for the commands
//
//*****************************************************************************
#define AM_DEVICES_MB85RS1MT_WRITE_ENABLE 0x06
#define AM_DEVICES_MB85RS1MT_WRITE_DISABLE 0x04
#define AM_DEVICES_MB85RS1MT_READ_STATUS 0x05
#define AM_DEVICES_MB85RS1MT_WRITE_STATUS 0x01
#define AM_DEVICES_MB85RS1MT_READ 0x03
#define AM_DEVICES_MB85RS1MT_WRITE 0x02
#define AM_DEVICES_MB85RS1MT_READ_DEVICE_ID 0x9F
//*****************************************************************************
//
// Global definitions for the status register
//
//*****************************************************************************
#define AM_DEVICES_MB85RS1MT_WPEN 0x80 // Write pending status
#define AM_DEVICES_MB85RS1MT_WEL 0x02 // Write enable latch
//*****************************************************************************
//
// Global definitions for the device id.
//
//*****************************************************************************
#define AM_DEVICES_MB85RS1MT_ID 0x03277F04 //0x047F2703
//*****************************************************************************
//
// Global type definitions.
//
//*****************************************************************************
typedef enum
{
AM_DEVICES_MB85RS1MT_STATUS_SUCCESS,
AM_DEVICES_MB85RS1MT_STATUS_ERROR
} am_devices_mb85rs1mt_status_t;
typedef struct
{
uint32_t ui32ClockFreq;
uint32_t *pNBTxnBuf;
uint32_t ui32NBTxnBufLength;
} am_devices_mb85rs1mt_config_t;
#define AM_DEVICES_MB85RS1MT_CMD_WREN AM_DEVICES_MB85RS1MT_WRITE_ENABLE
#define AM_DEVICES_MB85RS1MT_CMD_WRDI AM_DEVICES_MB85RS1MT_WRITE_DISABLE
#define AM_DEVICES_MB85RS1MT_MAX_DEVICE_NUM 1
//*****************************************************************************
//
// External function definitions.
//
//*****************************************************************************
extern uint32_t am_devices_mb85rs1mt_init(uint32_t ui32Module, am_devices_mb85rs1mt_config_t *pDevConfig, void **ppHandle, void **ppIomHandle);
extern uint32_t am_devices_mb85rs1mt_term(void *pHandle);
extern uint32_t am_devices_mb85rs1mt_read_id(void *pHandle, uint32_t *pDeviceID);
extern uint32_t am_devices_mb85rs1mt_status_get(void *pHandle, uint32_t *pStatus);
extern uint32_t am_devices_mb85rs1mt_command_send(void *pHandle, uint32_t ui32Cmd);
extern uint32_t am_devices_mb85rs1mt_blocking_write(void *pHandle, uint8_t *ui8TxBuffer,
uint32_t ui32WriteAddress,
uint32_t ui32NumBytes);
extern uint32_t am_devices_mb85rs1mt_nonblocking_write(void *pHandle, uint8_t *ui8TxBuffer,
uint32_t ui32WriteAddress,
uint32_t ui32NumBytes,
am_hal_iom_callback_t pfnCallback,
void *pCallbackCtxt);
extern uint32_t am_devices_mb85rs1mt_nonblocking_write_adv(void *pHandle, uint8_t *pui8TxBuffer,
uint32_t ui32WriteAddress,
uint32_t ui32NumBytes,
uint32_t ui32PauseCondition,
uint32_t ui32StatusSetClr,
am_hal_iom_callback_t pfnCallback,
void *pCallbackCtxt);
extern uint32_t am_devices_mb85rs1mt_blocking_read(void *pHandle, uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes);
extern uint32_t am_devices_mb85rs1mt_nonblocking_read(void *pHandle, uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes,
am_hal_iom_callback_t pfnCallback,
void *pCallbackCtxt);
extern uint32_t am_devices_mb85rs1mt_nonblocking_read_hiprio(void *pHandle, uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes,
am_hal_iom_callback_t pfnCallback,
void *pCallbackCtxt);
#ifdef __cplusplus
}
#endif
#endif // AM_DEVICES_MB85RS1MT_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,221 @@
//*****************************************************************************
//
//! @file am_devices_mspi_atxp032.h
//!
//! @brief Micron Serial NOR SPI Flash driver.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_DEVICES_MSPI_ATXP032_H
#define AM_DEVICES_MSPI_ATXP032_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Global definitions for flash commands
//
//*****************************************************************************
#define AM_DEVICES_MSPI_ATXP032_WRITE_STATUS 0x01
#define AM_DEVICES_MSPI_ATXP032_PAGE_PROGRAM 0x02
#define AM_DEVICES_MSPI_ATXP032_READ 0x03
#define AM_DEVICES_MSPI_ATXP032_WRITE_DISABLE 0x04
#define AM_DEVICES_MSPI_ATXP032_READ_STATUS 0x05
#define AM_DEVICES_MSPI_ATXP032_WRITE_ENABLE 0x06
#define AM_DEVICES_MSPI_ATXP032_FAST_READ 0x0B
#define AM_DEVICES_MSPI_ATXP032_READ_4B 0x13
#define AM_DEVICES_MSPI_ATXP032_SUBSECTOR_ERASE 0x20
#define AM_DEVICES_MSPI_ATXP032_DUAL_READ 0x3B
#define AM_DEVICES_MSPI_ATXP032_DUAL_IO_READ 0xBB
#define AM_DEVICES_MSPI_ATXP032_WRITE_ENHVOL_CFG 0x61
#define AM_DEVICES_MSPI_ATXP032_RESET_ENABLE 0x66
#define AM_DEVICES_MSPI_ATXP032_QUAD_READ 0x6B
#define AM_DEVICES_MSPI_ATXP032_WRITE_VOL_CFG 0x81
#define AM_DEVICES_MSPI_ATXP032_RESET_MEMORY 0x99
#define AM_DEVICES_MSPI_ATXP032_READ_ID 0x9F
#define AM_DEVICES_MSPI_ATXP032_ENTER_4B 0xB7
#define AM_DEVICES_MSPI_ATXP032_BULK_ERASE 0xC7
#define AM_DEVICES_MSPI_ATXP032_SECTOR_ERASE 0xD8
#define AM_DEVICES_MSPI_ATXP032_EXIT_4B 0xE9
#define AM_DEVICES_MSPI_ATXP032_QUAD_IO_READ 0xEB
#define AM_DEVICES_MSPI_ATXP032_READ_QUAD_4B 0xEC
//*****************************************************************************
//
// Global definitions for the flash status register
//
//*****************************************************************************
#define AM_DEVICES_MSPI_ATXP032_WEL 0x00000002 // Write enable latch
#define AM_DEVICES_MSPI_ATXP032_WIP 0x00000001 // Write in progress
//*****************************************************************************
//
// Device specific identification.
//
//*****************************************************************************
#define AM_DEVICES_MSPI_ATXP032_ID 0x0043A700
#define AM_DEVICES_MSPI_ATXP032_ID_MASK 0x00FFFFFF
//*****************************************************************************
//
// Device specific definitions for flash commands
//
//*****************************************************************************
#define AM_DEVICES_ATXP032_ENTER_QUAD_MODE 0x38
#define AM_DEVICES_ATXP032_UNPROTECT_SECTOR 0x39
#define AM_DEVICES_ATXP032_WRITE_STATUS_CTRL 0x71
#define AM_DEVICES_ATXP032_ENTER_OCTAL_MODE 0xE8
#define AM_DEVICES_ATXP032_RETURN_TO_SPI_MODE 0xFF
//*****************************************************************************
//
// Device specific definitions for the flash size information
//
//*****************************************************************************
#define AM_DEVICES_MSPI_ATXP032_PAGE_SIZE 0x100 //256 bytes, minimum program unit
//#define AM_DEVICES_MSPI_ATXP032_SECTOR_SIZE 0x10000 //64K bytes
#define AM_DEVICES_MSPI_ATXP032_SECTOR_SIZE 0x1000 //4K bytes
#define AM_DEVICES_MSPI_ATXP032_MAX_BLOCKS 256
#define AM_DEVICES_MSPI_ATXP032_MAX_SECTORS 256 // Sectors within 4-byte address range.
//*****************************************************************************
//
// Global definitions for the flash status register
//
//*****************************************************************************
#define AM_DEVICES_ATXP032_RSTE 0x00000010 // Reset enable
#define AM_DEVICES_ATXP032_WEL 0x00000002 // Write enable latch
#define AM_DEVICES_ATXP032_WIP 0x00000001 // Operation in progress
//*****************************************************************************
//
// Global definitions for the MSPI instance to use.
//
//*****************************************************************************
#define AM_DEVICES_MSPI_ATXP032_MSPI_INSTANCE 0
#define AM_DEVICES_MSPI_ATXP032_MAX_DEVICE_NUM 1
//*****************************************************************************
//
// Global type definitions.
//
//*****************************************************************************
typedef enum
{
AM_DEVICES_MSPI_ATXP032_STATUS_SUCCESS,
AM_DEVICES_MSPI_ATXP032_STATUS_ERROR
} am_devices_mspi_atxp032_status_t;
typedef struct
{
am_hal_mspi_device_e eDeviceConfig;
am_hal_mspi_clock_e eClockFreq;
am_hal_mspi_xipmixed_mode_e eMixedMode;
uint32_t *pNBTxnBuf;
uint32_t ui32NBTxnBufLength;
uint32_t ui32ScramblingStartAddr;
uint32_t ui32ScramblingEndAddr;
} am_devices_mspi_atxp032_config_t;
//*****************************************************************************
//
// External function definitions.
//
//*****************************************************************************
extern uint32_t am_devices_mspi_atxp032_init(uint32_t ui32Module,
am_devices_mspi_atxp032_config_t *psMSPISettings,
void **ppHandle, void **ppMspiHandle);
extern uint32_t am_devices_mspi_atxp032_deinit(void *pHandle);
extern uint32_t am_devices_mspi_atxp032_id(void *pHandle);
extern uint32_t am_devices_mspi_atxp032_reset(void *pHandle);
extern uint32_t am_devices_mspi_atxp032_status(void *pHandle, uint32_t *pStatus);
extern uint32_t am_devices_mspi_atxp032_read(void *pHandle, uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes,
bool bWaitForCompletion);
extern uint32_t am_devices_mspi_atxp032_write(void *pHandle, uint8_t *ui8TxBuffer,
uint32_t ui32WriteAddress,
uint32_t ui32NumBytes,
bool bWaitForCompletion);
extern uint32_t am_devices_mspi_atxp032_mass_erase(void *pHandle);
extern uint32_t am_devices_mspi_atxp032_sector_erase(void *pHandle, uint32_t ui32SectorAddress);
extern uint32_t am_devices_mspi_atxp032_enable_xip(void *pHandle);
extern uint32_t am_devices_mspi_atxp032_disable_xip(void *pHandle);
extern uint32_t am_devices_mspi_atxp032_enable_scrambling(void *pHandle);
extern uint32_t am_devices_mspi_atxp032_disable_scrambling(void *pHandle);
extern uint32_t
am_devices_mspi_atxp032_read_adv(void *pHandle, uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes,
uint32_t ui32PauseCondition,
uint32_t ui32StatusSetClr,
am_hal_mspi_callback_t pfnCallback,
void *pCallbackCtxt);
extern uint32_t
am_devices_mspi_atxp032_read_hiprio(void *pHandle, uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes,
bool bWaitForCompletion);
#ifdef __cplusplus
}
#endif
#endif // AM_DEVICES_MSPI_ATXP032_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,205 @@
//*****************************************************************************
//
//! @file am_devices_mspi_psram_aps6404l.h
//!
//! @brief Micron Serial SPI PSRAM driver.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_DEVICES_MSPI_PSRAM_APS6404L_H
#define AM_DEVICES_MSPI_PSRAM_APS6404L_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Global definitions for psram commands
//
//*****************************************************************************
#define AM_DEVICES_MSPI_PSRAM_WRITE 0x02
#define AM_DEVICES_MSPI_PSRAM_READ 0x03
#define AM_DEVICES_MSPI_PSRAM_FAST_READ 0x0B
#define AM_DEVICES_MSPI_PSRAM_QUAD_MODE_ENTER 0x35
#define AM_DEVICES_MSPI_PSRAM_QUAD_WRITE 0x38
#define AM_DEVICES_MSPI_PSRAM_RESET_ENABLE 0x66
#define AM_DEVICES_MSPI_PSRAM_RESET_MEMORY 0x99
#define AM_DEVICES_MSPI_PSRAM_READ_ID 0x9F
#define AM_DEVICES_MSPI_PSRAM_APS6404L_HALF_SLEEP_ENTER 0xC0
#define AM_DEVICES_MSPI_PSRAM_QUAD_READ 0xEB
#define AM_DEVICES_MSPI_PSRAM_QUAD_MODE_EXIT 0xF5
//
// The following definitions are typically specific to a multibit spi psram device.
// They should be tailored
//
//*****************************************************************************
//
// Device specific identification.
//
//*****************************************************************************
#define AM_DEVICES_MSPI_PSRAM_KGD_PASS 0x5D0D
#define AM_DEVICES_MSPI_PSRAM_KGD_FAIL 0x550D
// Page size - limits the bust write/read
#define AM_DEVICES_MSPI_PSRAM_PAGE_SIZE 1024
//#define AM_DEVICES_MSPI_PSRAM_TEST_BLOCK_SIZE 64*1024
#define AM_DEVICES_MSPI_PSRAM_TEST_BLOCK_SIZE 8*1024
// According to APS6404L tCEM restriction, we define maximum bytes for each speed empirically
#define AM_DEVICES_MSPI_PSRAM_48MHZ_MAX_BYTES 128
#define AM_DEVICES_MSPI_PSRAM_24MHZ_MAX_BYTES 64
#define AM_DEVICES_MSPI_PSRAM_16MHZ_MAX_BYTES 32
#define AM_DEVICES_MSPI_PSRAM_12MHZ_MAX_BYTES 16
#define AM_DEVICES_MSPI_PSRAM_8MHZ_MAX_BYTES 8
//*****************************************************************************
//
// Global definitions for the MSPI instance to use.
//
//*****************************************************************************
#define AM_DEVICES_MSPI_PSRAM_MAX_DEVICE_NUM 2
//*****************************************************************************
//
// Global type definitions.
//
//*****************************************************************************
typedef enum
{
AM_DEVICES_MSPI_PSRAM_STATUS_SUCCESS,
AM_DEVICES_MSPI_PSRAM_STATUS_ERROR
} am_devices_mspi_psram_status_t;
typedef struct
{
am_hal_mspi_device_e eDeviceConfig;
am_hal_mspi_clock_e eClockFreq;
am_hal_mspi_xipmixed_mode_e eMixedMode;
uint32_t *pNBTxnBuf;
uint32_t ui32NBTxnBufLength;
uint32_t ui32ScramblingStartAddr;
uint32_t ui32ScramblingEndAddr;
} am_devices_mspi_psram_config_t;
//*****************************************************************************
//
// External function definitions.
//
//*****************************************************************************
extern uint32_t am_devices_mspi_psram_init(uint32_t ui32Module,
am_devices_mspi_psram_config_t *pDevCfg,
void **ppHandle,
void **pMspiHandle);
extern uint32_t am_devices_mspi_psram_deinit(void *pHandle);
extern uint32_t am_devices_mspi_psram_id(void *pHandle);
extern uint32_t am_devices_mspi_psram_reset(void *pHandle);
extern uint32_t am_devices_mspi_psram_read(void *pHandle,
uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes,
bool bWaitForCompletion);
extern uint32_t am_devices_mspi_psram_read_adv(void *pHandle,
uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes,
uint32_t ui32PauseCondition,
uint32_t ui32StatusSetClr,
am_hal_mspi_callback_t pfnCallback,
void *pCallbackCtxt);
extern uint32_t am_devices_mspi_psram_write(void *pHandle,
uint8_t *ui8TxBuffer,
uint32_t ui32WriteAddress,
uint32_t ui32NumBytes,
bool bWaitForCompletion);
extern uint32_t am_devices_mspi_psram_write_adv(void *pHandle,
uint8_t *puiTxBuffer,
uint32_t ui32WriteAddress,
uint32_t ui32NumBytes,
uint32_t ui32PauseCondition,
uint32_t ui32StatusSetClr,
am_hal_mspi_callback_t pfnCallback,
void *pCallbackCtxt);
extern uint32_t am_devices_mspi_psram_enable_xip(void *pHandle);
extern uint32_t am_devices_mspi_psram_disable_xip(void *pHandle);
extern uint32_t am_devices_mspi_psram_enable_scrambling(void *pHandle);
extern uint32_t am_devices_mspi_psram_disable_scrambling(void *pHandle);
extern uint32_t am_devices_mspi_psram_read_hiprio(void *pHandle, uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes,
am_hal_mspi_callback_t pfnCallback,
void *pCallbackCtxt);
extern uint32_t am_devices_mspi_psram_nonblocking_read(void *pHandle, uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes,
am_hal_mspi_callback_t pfnCallback,
void *pCallbackCtxt);
extern uint32_t am_devices_mspi_psram_write_hiprio(void *pHandle, uint8_t *pui8TxBuffer,
uint32_t ui32WriteAddress,
uint32_t ui32NumBytes,
am_hal_mspi_callback_t pfnCallback,
void *pCallbackCtxt);
extern uint32_t am_devices_mspi_psram_nonblocking_write(void *pHandle, uint8_t *pui8TxBuffer,
uint32_t ui32WriteAddress,
uint32_t ui32NumBytes,
am_hal_mspi_callback_t pfnCallback,
void *pCallbackCtxt);
#ifdef __cplusplus
}
#endif
#endif // AM_DEVICES_MSPI_PSRAM_APS6404L_H
@@ -0,0 +1,961 @@
//*****************************************************************************
//
//! @file am_devices_mspi_rm67162.c
//!
//! @brief Generic Raydium TFT display driver.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <string.h>
#include "am_mcu_apollo.h"
#include "am_devices_mspi_rm67162.h"
#include "am_bsp.h"
#include "am_util_delay.h"
#include "am_util.h"
//*****************************************************************************
//
// Global variables.
//
//*****************************************************************************
#define BYTE_NUM_PER_WRITE 65535
//#define BYTE_NUM_PER_WRITE AM_HAL_MSPI_MAX_TRANS_SIZE
#define AM_DEVICES_MSPI_TIMEOUT 1000000
static struct
{
uint32_t row_start;
uint32_t row_end;
uint32_t col_start;
uint32_t col_end;
} gs_display_info;
static am_devices_rm67162_graphic_conf_t g_sGraphic_conf =
{
.bus_mode = AM_DEVICES_RM67162_SPI_WRAM,
.color_mode = AM_DEVICES_RM67162_COLOR_MODE_8BIT,
.scan_mode = AM_DEVICES_RM67162_SCAN_MODE_0,
.max_row = 400, //390,
.max_col = 400, // 390,
.row_offset = 0,
.col_offset = 0 // 6
// .col_offset = 100
};
// Display MSPI configuration
static am_hal_mspi_dev_config_t SerialDisplayMSPICfg =
{
.ui8TurnAround = 1,
.eAddrCfg = AM_HAL_MSPI_ADDR_3_BYTE,
.eInstrCfg = AM_HAL_MSPI_INSTR_1_BYTE,
.ui8ReadInstr = AM_DEVICES_RM67162_MEMORY_READ,
.ui8WriteInstr = AM_DEVICES_RM67162_MEMORY_WRITE_CONTINUE, // AM_DEVICES_RM67162_MEMORY_WRITE_CONTINUE,
.eDeviceConfig = AM_HAL_MSPI_FLASH_SERIAL_CE0,
.ui8WriteLatency = 0,
.eSpiMode = AM_HAL_MSPI_SPI_MODE_0,
.eClockFreq = AM_HAL_MSPI_CLK_48MHZ,
.bEnWriteLatency = false,
.bSendAddr = false,
.bSendInstr = true,
.bSeparateIO = false,
.bTurnaround = false,
.bEmulateDDR = false,
.ui16DMATimeLimit = 0,
.eDMABoundary = AM_HAL_MSPI_BOUNDARY_NONE,
.ui32TCBSize = 0,
.pTCB = 0,
.scramblingStartAddr = 0,
.scramblingEndAddr = 0,
};
typedef struct
{
uint32_t ui32Module;
void *pMspiHandle;
bool bOccupied;
} am_devices_mspi_rm67162_t;
am_devices_mspi_rm67162_t gAmRm67162[AM_DEVICES_MSPI_RM67162_MAX_DEVICE_NUM];
void pfnMSPI_RM67162_Callback(void *pCallbackCtxt, uint32_t status)
{
// Set the DMA complete flag.
*(volatile bool *)pCallbackCtxt = true;
}
//*****************************************************************************
//
// Generic Command Write function.
//
//*****************************************************************************
uint32_t
am_devices_rm67162_command_write(void *pHandle,
uint32_t ui32Instr,
uint8_t *pData,
uint32_t ui32NumBytes)
{
am_hal_mspi_pio_transfer_t Transaction;
am_devices_mspi_rm67162_t *pDisplay = (am_devices_mspi_rm67162_t *)pHandle;
// Create the individual write transaction.
Transaction.ui32NumBytes = ui32NumBytes;
Transaction.bScrambling = false;
Transaction.bDCX = true;
Transaction.eDirection = AM_HAL_MSPI_TX;
Transaction.bSendAddr = false;
Transaction.ui32DeviceAddr = 0;
Transaction.bSendInstr = true;
Transaction.ui16DeviceInstr = ui32Instr;
Transaction.bTurnaround = false;
Transaction.bEnWRLatency = false;
Transaction.bQuadCmd = false;
Transaction.bContinue = false;
Transaction.pui32Buffer = (uint32_t *)pData;
//
// Execute the transction over MSPI.
//
if (am_hal_mspi_blocking_transfer(pDisplay->pMspiHandle, &Transaction, AM_DEVICES_MSPI_TIMEOUT))
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
return AM_DEVICES_RM67162_STATUS_SUCCESS;
}
static uint32_t
am_devices_rm67162_command_read(void *pHandle,
uint32_t ui32Instr,
uint32_t *pData,
uint32_t ui32NumBytes,
bool bTurnaround)
{
am_hal_mspi_pio_transfer_t Transaction;
am_devices_mspi_rm67162_t *pDisplay = (am_devices_mspi_rm67162_t *)pHandle;
// Create the individual write transaction.
Transaction.ui32NumBytes = ui32NumBytes;
Transaction.bScrambling = false;
Transaction.bDCX = true;
Transaction.eDirection = AM_HAL_MSPI_RX;
Transaction.bSendAddr = false;
Transaction.ui32DeviceAddr = 0;
Transaction.bSendInstr = true;
Transaction.ui16DeviceInstr = ui32Instr;
Transaction.bTurnaround = bTurnaround;
Transaction.bEnWRLatency = false;
Transaction.bQuadCmd = false;
Transaction.bContinue = false;
Transaction.pui32Buffer = (uint32_t *)pData;
//
// Execute the transction over MSPI.
//
if (am_hal_mspi_blocking_transfer(pDisplay->pMspiHandle,
&Transaction,
AM_DEVICES_MSPI_TIMEOUT))
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
return AM_DEVICES_RM67162_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Reads the current status of the external display
//!
//! @param ui32DeviceNumber - Device number of the external display
//!
//! This function reads the device ID register of the external display, and returns
//! the result as an 32-bit unsigned integer value.
//!
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_rm67162_reset(void *pHandle)
{
// Hardware Reset
#if 1
am_hal_gpio_state_write(AM_BSP_GPIO_DISPLAY_RESET, AM_HAL_GPIO_OUTPUT_SET);
am_util_delay_ms(20);
am_hal_gpio_state_write(AM_BSP_GPIO_DISPLAY_RESET, AM_HAL_GPIO_OUTPUT_CLEAR);
am_util_delay_ms(20);
am_hal_gpio_state_write(AM_BSP_GPIO_DISPLAY_RESET, AM_HAL_GPIO_OUTPUT_SET);
am_util_delay_ms(20);
#endif
if ( am_devices_rm67162_command_write(pHandle, AM_DEVICES_RM67162_SWRESET, NULL, 0) )
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
am_util_delay_ms(300);
return AM_DEVICES_RM67162_STATUS_SUCCESS;
}
uint32_t
am_devices_rm67162_display_off(void *pHandle)
{
if ( am_devices_rm67162_command_write(pHandle, AM_DEVICES_RM67162_DISPLAY_OFF, NULL, 0) )
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
if ( am_devices_rm67162_command_write(pHandle, AM_DEVICES_RM67162_SLEEP_IN, NULL, 0) )
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
return AM_DEVICES_RM67162_STATUS_SUCCESS;
}
uint32_t
am_devices_rm67162_display_on(void *pHandle)
{
if ( am_devices_rm67162_command_write(pHandle, AM_DEVICES_RM67162_DISPLAY_ON, NULL, 0) )
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
return AM_DEVICES_RM67162_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Programs the given range of flash addresses.
//!
//! @param pui8TxBuffer - Buffer to write the external flash data from
//! @param ui32NumBytes - Number of bytes to write to the external flash
//!
//! This function uses the data in the provided pui8TxBuffer and copies it to
//! the external flash at the address given by ui32WriteAddress. It will copy
//! exactly ui32NumBytes of data from the original pui8TxBuffer pointer. The
//! user is responsible for ensuring that they do not overflow the target flash
//! memory or underflow the pui8TxBuffer array
//
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_rm67162_blocking_write(void *pHandle,
uint8_t *pui8TxBuffer,
uint32_t ui32NumBytes)
{
am_hal_mspi_pio_transfer_t Transaction;
am_devices_mspi_rm67162_t *pDisplay = (am_devices_mspi_rm67162_t *)pHandle;
// Create the individual write transaction.
Transaction.ui32NumBytes = 0;
Transaction.bScrambling = false;
Transaction.bDCX = true;
Transaction.eDirection = AM_HAL_MSPI_TX;
Transaction.bSendAddr = false;
Transaction.ui32DeviceAddr = 0;
Transaction.bSendInstr = true;
Transaction.ui16DeviceInstr = AM_DEVICES_RM67162_MEMORY_WRITE;
Transaction.bTurnaround = false;
Transaction.bEnWRLatency = false;
Transaction.bQuadCmd = false;
Transaction.bContinue = true;
Transaction.pui32Buffer = NULL;
//
// Execute the transction over MSPI.
//
if (am_hal_mspi_blocking_transfer(pDisplay->pMspiHandle, &Transaction, AM_DEVICES_MSPI_TIMEOUT))
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
while (ui32NumBytes)
{
// Create the individual write transaction.
Transaction.ui32NumBytes = (ui32NumBytes > BYTE_NUM_PER_WRITE) ? BYTE_NUM_PER_WRITE : ui32NumBytes;
Transaction.bScrambling = false;
Transaction.bDCX = false;
Transaction.eDirection = AM_HAL_MSPI_TX;
Transaction.bSendAddr = false;
Transaction.ui32DeviceAddr = 0;
Transaction.bSendInstr = false;
Transaction.ui16DeviceInstr = 0;
Transaction.bTurnaround = false;
Transaction.bEnWRLatency = false;
Transaction.bQuadCmd = false;
Transaction.bContinue = (ui32NumBytes > BYTE_NUM_PER_WRITE) ? true : false;
Transaction.pui32Buffer = (uint32_t *)pui8TxBuffer;
//
// Execute the transction over MSPI.
//
if (am_hal_mspi_blocking_transfer(pDisplay->pMspiHandle, &Transaction, AM_DEVICES_MSPI_TIMEOUT))
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
ui32NumBytes -= Transaction.ui32NumBytes;
pui8TxBuffer += Transaction.ui32NumBytes;
}
return AM_DEVICES_RM67162_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Reads the contents of the fram into a buffer.
//!
//! @param pui8RxBuffer - Buffer to store the received data from the flash
//! @param ui32ReadAddress - Address of desired data in external flash
//! @param ui32NumBytes - Number of bytes to read from external flash
//!
//! This function reads the external flash at the provided address and stores
//! the received data into the provided buffer location. This function will
//! only store ui32NumBytes worth of data.
//
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_rm67162_blocking_read(void *pHandle,
uint8_t *pui8RxBuffer,
uint32_t ui32NumBytes)
{
am_hal_mspi_pio_transfer_t Transaction;
am_devices_mspi_rm67162_t *pDisplay = (am_devices_mspi_rm67162_t *)pHandle;
// Create the individual write transaction.
Transaction.ui32NumBytes = 0;
Transaction.bScrambling = false;
Transaction.bDCX = true;
Transaction.eDirection = AM_HAL_MSPI_RX;
Transaction.bSendAddr = false;
Transaction.ui32DeviceAddr = 0;
Transaction.bSendInstr = true;
Transaction.ui16DeviceInstr = AM_DEVICES_RM67162_MEMORY_READ;
Transaction.bTurnaround = false;
Transaction.bEnWRLatency = false;
Transaction.bQuadCmd = false;
Transaction.bContinue = true;
Transaction.pui32Buffer = NULL;
while (ui32NumBytes)
{
// Create the individual write transaction.
Transaction.ui32NumBytes = (ui32NumBytes > BYTE_NUM_PER_WRITE) ? BYTE_NUM_PER_WRITE : ui32NumBytes;
Transaction.bScrambling = false;
Transaction.bDCX = false;
Transaction.eDirection = AM_HAL_MSPI_RX;
Transaction.bSendAddr = false;
Transaction.ui32DeviceAddr = 0;
Transaction.bSendInstr = false;
Transaction.ui16DeviceInstr = 0;
Transaction.bTurnaround = false;
Transaction.bEnWRLatency = false;
Transaction.bQuadCmd = false;
Transaction.bContinue = (ui32NumBytes > BYTE_NUM_PER_WRITE) ? true : false;
Transaction.pui32Buffer = (uint32_t *)pui8RxBuffer;
//
// Execute the transction over MSPI.
//
if (am_hal_mspi_blocking_transfer(pDisplay->pMspiHandle,
&Transaction,
AM_DEVICES_MSPI_TIMEOUT))
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
ui32NumBytes -= Transaction.ui32NumBytes;
pui8RxBuffer += Transaction.ui32NumBytes;
}
return AM_DEVICES_RM67162_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Programs the given range of display addresses.
//!
//! @param ui32Module - MSPI Instance
//! @param pui8TxBuffer - Buffer to write the data from
//! @param ui32NumBytes - Number of bytes to write to the display memory
//! @param bWaitForCompletion - Waits for CQ/DMA to complete before return.
//!
//! This function uses the data in the provided pui8TxBuffer and copies it to
//! the external flash at the address given by ui32WriteAddress. It will copy
//! exactly ui32NumBytes of data from the original pui8TxBuffer pointer. The
//! user is responsible for ensuring that they do not overflow the target flash
//! memory or underflow the pui8TxBuffer array
//
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_rm67162_nonblocking_write(void *pHandle,
uint8_t *pui8TxBuffer,
uint32_t ui32NumBytes,
bool bWaitForCompletion)
{
am_hal_mspi_dma_transfer_t Transaction;
volatile bool bDMAComplete = false;
am_devices_mspi_rm67162_t *pDisplay = (am_devices_mspi_rm67162_t *)pHandle;
//
// Enable DCX for DMA Transactions.
//
if (am_hal_mspi_control(pDisplay->pMspiHandle, AM_HAL_MSPI_REQ_DCX_EN, 0))
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
//
// Create the transaction.
//
Transaction.ui8Priority = 1;
Transaction.eDirection = AM_HAL_MSPI_TX;
Transaction.ui32TransferCount = ui32NumBytes;
Transaction.ui32DeviceAddress = 0;
Transaction.ui32SRAMAddress = (uint32_t)pui8TxBuffer;
Transaction.ui32PauseCondition = 0;
Transaction.ui32StatusSetClr = 0;
//
// Execute the transction over MSPI.
//
if (am_hal_mspi_nonblocking_transfer(pDisplay->pMspiHandle,
&Transaction,
AM_HAL_MSPI_TRANS_DMA,
pfnMSPI_RM67162_Callback,
(void *)&bDMAComplete))
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
if (bWaitForCompletion)
{
// Wait for DMA Complete or Timeout
for (uint32_t i = 0; i < AM_DEVICES_MSPI_TIMEOUT; i++)
{
if (bDMAComplete)
{
break;
}
//
// Call the BOOTROM cycle function to delay for about 1 microsecond.
//
am_hal_flash_delay( FLASH_CYCLES_US(1) );
}
// Check the status.
if (!bDMAComplete)
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
}
return AM_DEVICES_RM67162_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Programs the given range of display addresses.
//!
//! @param ui32Module - MSPI Instance
//! @param pui8TxBuffer - Buffer to write the data from
//! @param ui32NumBytes - Number of bytes to write to the display memory
//! @param ui32PauseCondition - CQ Pause condition before execution.
//! @param ui32StatusSetClr - CQ Set/Clear condition after execution.
//! @param pfnCallback - Callback function after execution.
//! @param pCallbackCtxt - Callback context after execution.
//!
//! This function uses the data in the provided pui8TxBuffer and copies it to
//! the external display the address given by ui32WriteAddress. It will copy
//! exactly ui32NumBytes of data from the original pui8TxBuffer pointer. The
//! user is responsible for ensuring that they do not overflow the target display
//! memory or underflow the pui8TxBuffer array
//
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_rm67162_nonblocking_write_adv(void *pHandle,
uint8_t *pui8TxBuffer,
uint32_t ui32NumBytes,
uint32_t ui32PauseCondition,
uint32_t ui32StatusSetClr,
am_hal_mspi_callback_t pfnCallback,
void *pCallbackCtxt)
{
am_hal_mspi_dma_transfer_t Transaction;
am_devices_mspi_rm67162_t *pDisplay = (am_devices_mspi_rm67162_t *)pHandle;
//
// Create the transaction.
//
Transaction.ui8Priority = 1;
Transaction.eDirection = AM_HAL_MSPI_TX;
Transaction.ui32TransferCount = ui32NumBytes;
Transaction.ui32DeviceAddress = 0;
Transaction.ui32SRAMAddress = (uint32_t)pui8TxBuffer;
Transaction.ui32PauseCondition = ui32PauseCondition;
Transaction.ui32StatusSetClr = ui32StatusSetClr;
// am_hal_gpio_state_write(AM_BSP_GPIO_IOM0_DCX, AM_HAL_GPIO_OUTPUT_CLEAR);
//
// Execute the transction over IOM.
//
if (am_hal_mspi_nonblocking_transfer(pDisplay->pMspiHandle,
&Transaction,
AM_HAL_MSPI_TRANS_DMA,
pfnCallback,
pCallbackCtxt))
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
return AM_DEVICES_RM67162_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Reads the contents of the display into a buffer.
//!
//! @param ui32Module - MSPI Instance
//! @param pui8RxBuffer - Buffer to store the received data from the flash
//! @param ui32NumBytes - Number of bytes to read from external flash
//! @param bWaitForCompletion - Waits for CQ/DMA to complete before return.
//!
//! This function reads the external display at the provided address and stores
//! the received data into the provided buffer location. This function will
//! only store ui32NumBytes worth of data.
//
//! @return 32-bit status
//
//*****************************************************************************
uint32_t
am_devices_rm67162_nonblocking_read(void *pHandle,
uint8_t *pui8RxBuffer,
uint32_t ui32NumBytes,
bool bWaitForCompletion)
{
am_hal_mspi_dma_transfer_t Transaction;
volatile bool bDMAComplete = false;
am_devices_mspi_rm67162_t *pDisplay = (am_devices_mspi_rm67162_t *)pHandle;
//
// Create the transaction.
//
Transaction.ui8Priority = 1;
Transaction.eDirection = AM_HAL_MSPI_RX;
Transaction.ui32TransferCount = ui32NumBytes;
Transaction.ui32DeviceAddress = 0;
Transaction.ui32SRAMAddress = (uint32_t)pui8RxBuffer;
Transaction.ui32PauseCondition = 0;
Transaction.ui32StatusSetClr = 0;
//
// Execute the transction over MSPI.
//
if (am_hal_mspi_nonblocking_transfer(pDisplay->pMspiHandle,
&Transaction,
AM_HAL_MSPI_TRANS_DMA,
pfnMSPI_RM67162_Callback,
(void *)&bDMAComplete))
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
if (bWaitForCompletion)
{
// Wait for DMA Complete or Timeout
for (uint32_t i = 0; i < AM_DEVICES_MSPI_TIMEOUT; i++)
{
if (bDMAComplete)
{
break;
}
//
// Call the BOOTROM cycle function to delay for about 1 microsecond.
//
am_hal_flash_delay( FLASH_CYCLES_US(1) );
}
// Check the status.
if (!bDMAComplete)
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
}
return AM_DEVICES_RM67162_STATUS_SUCCESS;
}
static uint32_t
am_devices_set_row_col(void *pHandle, am_devices_rm67162_graphic_conf_t *psGraphic_conf)
{
uint8_t data[10] = {0};
gs_display_info.row_start = psGraphic_conf->row_offset;
gs_display_info.row_end = psGraphic_conf->max_row + psGraphic_conf->row_offset - 1;
gs_display_info.col_start = psGraphic_conf->col_offset;
gs_display_info.col_end = psGraphic_conf->max_col + psGraphic_conf->col_offset - 1;
/* set column start address */
data[0] = (gs_display_info.col_start / 256);
data[1] = (gs_display_info.col_start % 256);
data[2] = (gs_display_info.col_end / 256);
data[3] = (gs_display_info.col_end % 256);
if (am_devices_rm67162_command_write(pHandle, AM_DEVICES_RM67162_COLUMN_ADDR_SETTING, data, 4))//Column
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
/* set row start address */
data[0] = (gs_display_info.row_start / 256);
data[1] = (gs_display_info.row_start % 256);
data[2] = (gs_display_info.row_end / 256);
data[3] = (gs_display_info.row_end % 256);
if (am_devices_rm67162_command_write(pHandle, AM_DEVICES_RM67162_ROW_ADDR_SETTING, data, 4))//raw
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
return AM_DEVICES_RM67162_STATUS_SUCCESS;
}
static uint32_t
am_devices_lcm_init(void *pHandle, am_devices_rm67162_graphic_conf_t *psGraphic_conf)
{
uint8_t data[10] = {0};
/* Tearing effect line ON */
data[0] = 0x0;
if (am_devices_rm67162_command_write(pHandle, AM_DEVICES_RM67162_TEARING_EFFECT_LINE_ON, data, 1))
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
data[0] = psGraphic_conf->bus_mode;
if (am_devices_rm67162_command_write(pHandle, AM_DEVICES_RM67162_SET_DSPI_MODE, data, 1))
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
data[0] = psGraphic_conf->color_mode ;
if (am_devices_rm67162_command_write(pHandle, AM_DEVICES_RM67162_DATA_FORMAT_SEL, data, 1))
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
data[0] = psGraphic_conf->scan_mode;
if (am_devices_rm67162_command_write(pHandle, AM_DEVICES_RM67162_SCAN_MODE, data, 1))
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
data[0] = 0x20;
if (am_devices_rm67162_command_write(pHandle, AM_DEVICES_RM67162_SET_WRITE_DISPLAY_CTRL, data, 1))
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
//
// Set row/col start/end addresses.
//
am_devices_set_row_col(pHandle, psGraphic_conf);
/* set tear scan-line */
data[0] = 0x00;
data[1] = 0x28; // 0xf0
if ( am_devices_rm67162_command_write(pHandle, AM_DEVICES_RM67162_SET_TEAR_SCANLINE, data, 2) )
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
if ( am_devices_rm67162_command_write(pHandle, AM_DEVICES_RM67162_SLEEP_OUT, NULL, 0) )
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
am_util_delay_ms(130);
if ( am_devices_rm67162_command_write(pHandle, AM_DEVICES_RM67162_DISPLAY_ON, NULL, 0) )
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
am_util_delay_ms(200);
// am_hal_gpio_state_write(AM_BSP_GPIO_DISPLAY_BL, AM_HAL_GPIO_OUTPUT_CLEAR);
am_util_stdio_printf("AM_BSP_GPIO_DISPLAY_BL set on \n");
return AM_DEVICES_RM67162_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Initialize the rm67162 driver.
//!
//! @param ui32Module - MSPI module ID.
//! @param psMSPISettings - MSPI device structure describing the target spiflash.
//! @param ppMspiHandle - MSPI handler.
//!
//! This function should be called before any other am_devices_rm67162
//! functions. It is used to set tell the other functions how to communicate
//! with the TFT display hardware.
//!
//! @return Status.
//
//*****************************************************************************
uint32_t
am_devices_mspi_rm67162_init(uint32_t ui32Module,
am_devices_mspi_rm67162_config_t *psMSPISettings,
void **ppHandle,
void **ppMspiHandle)
{
uint32_t ui32Status;
uint32_t ui32DeviceID;
uint32_t ui32Index = 0;
am_hal_mspi_dev_config_t mspiDevCfg;
void *pMspiHandle;
if ((ui32Module > AM_REG_MSPI_NUM_MODULES) || (psMSPISettings == NULL))
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
// Allocate a vacant device handle
for ( ui32Index = 0; ui32Index < AM_DEVICES_MSPI_RM67162_MAX_DEVICE_NUM; ui32Index++ )
{
if ( gAmRm67162[ui32Index].bOccupied == false )
{
break;
}
}
if ( ui32Index == AM_DEVICES_MSPI_RM67162_MAX_DEVICE_NUM )
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
//
// Re-Configure the MSPI for the requested operation mode.
//
mspiDevCfg = SerialDisplayMSPICfg;
mspiDevCfg.eClockFreq = psMSPISettings->eClockFreq;
//mspiDevCfg.eDeviceConfig = psMSPISettings->eDeviceConfig;
mspiDevCfg.ui32TCBSize = psMSPISettings->ui32NBTxnBufLength;
mspiDevCfg.pTCB = psMSPISettings->pNBTxnBuf;
mspiDevCfg.scramblingStartAddr = psMSPISettings->ui32ScramblingStartAddr;
mspiDevCfg.scramblingEndAddr = psMSPISettings->ui32ScramblingEndAddr;
mspiDevCfg.eXipMixedMode = psMSPISettings->eMixedMode;
//
// Configure the MSPI pins.
//
am_bsp_mspi_pins_enable(ui32Module, mspiDevCfg.eDeviceConfig);
//
// Initialize the MSPI instance.
// Enable power to the MSPI instance.
// Configure the MSPI for Serial operation during initialization.
// Enable the MSPI.
// HAL Success return is 0
//
if ( am_hal_mspi_initialize(ui32Module, &pMspiHandle) ||
am_hal_mspi_power_control(pMspiHandle, AM_HAL_SYSCTRL_WAKE, false) ||
am_hal_mspi_device_configure(pMspiHandle, &mspiDevCfg) ||
am_hal_mspi_enable(pMspiHandle) )
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
else
{
//
// Enable DCX for DMA Transactions.
//
if ( am_hal_mspi_control(pMspiHandle, AM_HAL_MSPI_REQ_DCX_EN, 0) )
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
//
// Enable MSPI interrupts.
//
ui32Status = am_hal_mspi_interrupt_clear(pMspiHandle, AM_HAL_MSPI_INT_CQUPD | AM_HAL_MSPI_INT_ERR );
if (AM_HAL_STATUS_SUCCESS != ui32Status)
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
ui32Status = am_hal_mspi_interrupt_enable(pMspiHandle, AM_HAL_MSPI_INT_CQUPD | AM_HAL_MSPI_INT_ERR );
if (AM_HAL_STATUS_SUCCESS != ui32Status)
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
gAmRm67162[ui32Index].pMspiHandle = pMspiHandle;
gAmRm67162[ui32Index].ui32Module = ui32Module;
*ppMspiHandle = pMspiHandle;
*ppHandle = (void *)&gAmRm67162[ui32Index];
//
// Read the Device ID.
//
am_devices_rm67162_read_id((void*)&gAmRm67162[ui32Index], &ui32DeviceID);
am_util_stdio_printf("RM67167 Device ID = %6X\n", (ui32DeviceID & 0x00FFFFFF));
//
// Device specific TFT display initialization.
//
am_util_delay_ms(500);
am_devices_rm67162_reset((void*)&gAmRm67162[ui32Index]);
ui32Status = am_devices_lcm_init((void*)&gAmRm67162[ui32Index], &g_sGraphic_conf);
if (AM_DEVICES_RM67162_STATUS_SUCCESS != ui32Status)
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
gAmRm67162[ui32Index].bOccupied = true;
//am_hal_gpio_state_write(AM_BSP_GPIO_DISPLAY_BL, AM_HAL_GPIO_OUTPUT_SET);
//
// Return the status.
//
return AM_DEVICES_RM67162_STATUS_SUCCESS;
}
}
uint32_t
am_devices_mspi_rm67162_row_col_reset(void *pHandle)
{
uint32_t ui32Status = am_devices_set_row_col(pHandle, &g_sGraphic_conf);
if (AM_DEVICES_RM67162_STATUS_SUCCESS != ui32Status)
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
return AM_DEVICES_RM67162_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief De-Initialize the rm67162 driver.
//!
//! @param ui32Module - MSPI Module#
//!
//! This function reverses the initialization
//!
//! @return Status.
//
//*****************************************************************************
uint32_t
am_devices_rm67162_term(void *pHandle)
{
am_devices_mspi_rm67162_t *pDisplay = (am_devices_mspi_rm67162_t *)pHandle;
if ( pDisplay->ui32Module > AM_REG_IOM_NUM_MODULES )
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
// am_hal_gpio_interrupt_clear(AM_HAL_GPIO_MASKBIT(pGpioIntMask, AM_BSP_GPIO_DISPLAY_TE));
// am_hal_gpio_interrupt_disable(AM_HAL_GPIO_MASKBIT(pGpioIntMask, AM_BSP_GPIO_DISPLAY_TE));
// NVIC_DisableIRQ(GPIO_IRQn);
// Disable the pins
// am_bsp_iom_display_pins_disable(AM_BSP_4_WIRES_SPI_MODE);
//
// Disable the MSPI.
//
am_hal_mspi_disable(pDisplay->pMspiHandle);
//
// Disable power to and uninitialize the MSPI instance.
//
am_hal_mspi_power_control(pDisplay->pMspiHandle, AM_HAL_SYSCTRL_DEEPSLEEP, false);
am_hal_mspi_deinitialize(pDisplay->pMspiHandle);
// Free this device handle
pDisplay->bOccupied = false;
//
// Return the status.
//
return AM_DEVICES_RM67162_STATUS_SUCCESS;
}
uint32_t
am_devices_rm67162_read_id(void *pHandle, uint32_t *pdata)
{
if (am_devices_rm67162_command_read(pHandle, AM_DEVICES_RM67162_READ_ID, pdata, 3, true))
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
return AM_DEVICES_RM67162_STATUS_SUCCESS;
}
uint32_t
am_devices_mspi_rm67162_set_transfer_window(void *pHandle, uint32_t startRow, uint32_t startCol, uint32_t endRow, uint32_t endCol)
{
uint8_t data[4] = {0};
/* set column start address */
data[0] = (startCol / 256);
data[1] = (startCol % 256);
data[2] = (endCol / 256);
data[3] = (endCol % 256);
if (am_devices_rm67162_command_write(pHandle, AM_DEVICES_RM67162_COLUMN_ADDR_SETTING, data, 4))//Column
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
/* set row start address */
data[0] = (startRow / 256);
data[1] = (startRow % 256);
data[2] = (endRow / 256);
data[3] = (endRow % 256);
if (am_devices_rm67162_command_write(pHandle, AM_DEVICES_RM67162_ROW_ADDR_SETTING, data, 4))//raw
{
return AM_DEVICES_RM67162_STATUS_ERROR;
}
return AM_DEVICES_RM67162_STATUS_SUCCESS;
}
@@ -0,0 +1,200 @@
//*****************************************************************************
//
//! @file am_devices_rm67162.c
//!
//! @brief Generic Raydium TFT display driver.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_DEVICES_RM67162_H
#define AM_DEVICES_RM67162_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Display Dimensions
//
//*****************************************************************************
#define AM_DEVICES_RM67162_NUM_ROWS 400
#define AM_DEVICES_RM67162_NUM_COLUMNS 400
#define AM_DEVICES_RM67162_PIXEL_SIZE 1
//*****************************************************************************
//
// Global definitions for the commands
//
//*****************************************************************************
#define AM_DEVICES_RM67162_SWRESET 0x01
#define AM_DEVICES_RM67162_READ_ID 0x04
#define AM_DEVICES_RM67162_RD_PXL_FORMAT 0x0C
#define AM_DEVICES_RM67162_SLEEP_IN 0x10
#define AM_DEVICES_RM67162_SLEEP_OUT 0x11
#define AM_DEVICES_RM67162_INVERSION_ON 0x21
#define AM_DEVICES_RM67162_DISPLAY_OFF 0x28
#define AM_DEVICES_RM67162_DISPLAY_ON 0x29
#define AM_DEVICES_RM67162_COLUMN_ADDR_SETTING 0x2A
#define AM_DEVICES_RM67162_ROW_ADDR_SETTING 0x2B
#define AM_DEVICES_RM67162_MEMORY_WRITE 0x2C
#define AM_DEVICES_RM67162_MEMORY_READ 0x2E
#define AM_DEVICES_RM67162_TEARING_EFFECT_LINE_ON 0x35
#define AM_DEVICES_RM67162_SCAN_MODE 0x36
#define AM_DEVICES_RM67162_HIGH_POWER_MODE_ON 0x38
#define AM_DEVICES_RM67162_LOW_POWER_MODE_ON 0x39
#define AM_DEVICES_RM67162_DATA_FORMAT_SEL 0x3A
#define AM_DEVICES_RM67162_MEMORY_WRITE_CONTINUE 0x3C
#define AM_DEVICES_RM67162_MEMORY_READ_CONTINUE 0x3E
#define AM_DEVICES_RM67162_SET_TEAR_SCANLINE 0x44
#define AM_DEVICES_RM67162_SET_WRITE_DISPLAY_CTRL 0x53
#define AM_DEVICES_RM67162_DUTY_SETTING 0xB0
#define AM_DEVICES_RM67162_FRAME_RATE_CTRL 0xB2
#define AM_DEVICES_RM67162_UPDATE_PERIOD_GATE_EQ_CTRL 0xB4
#define AM_DEVICES_RM67162_DESTRESS_PERIOD_GATE_EQ_CTRL 0xB5
#define AM_DEVICES_RM67162_PANEL_SETTING 0xB8
#define AM_DEVICES_RM67162_SOURCE_SETTING 0xB9
#define AM_DEVICES_RM67162_GATE_VOL_CTRL 0xC0
#define AM_DEVICES_RM67162_SET_DSPI_MODE 0xC4
#define AM_DEVICES_RM67162_OSC_ENABLE 0xC7
#define AM_DEVICES_RM67162_VCOMH_VOL_CTRL 0xCB
#define AM_DEVICES_RM67162_BOOSTER_ENABLE 0xD1
#define AM_DEVICES_RM67162_4SPI_INPUT_DATA_SEL 0xE4
#define AM_DEVICES_RM67162_MTP_LOAD_CTRL 0xEB
//*****************************************************************************
//
// Global type definitions.
//
//*****************************************************************************
typedef enum
{
AM_DEVICES_RM67162_STATUS_SUCCESS,
AM_DEVICES_RM67162_STATUS_ERROR
} am_devices_rm67162_status_t;
#define AM_DEVICES_RM67162_SPI_WRAM 0x80
#define AM_DEVICES_RM67162_DSPI_WRAM 0x81
#define AM_DEVICES_RM67162_COLOR_MODE_8BIT 0x72
#define AM_DEVICES_RM67162_COLOR_MODE_3BIT 0x71
#define AM_DEVICES_RM67162_COLOR_MODE_16BIT 0x75
#define AM_DEVICES_RM67162_COLOR_MODE_24BIT 0x77
#define AM_DEVICES_RM67162_SCAN_MODE_0 0x40
#define AM_DEVICES_RM67162_SCAN_MODE_90 0x70
#define AM_DEVICES_RM67162_SCAN_MODE_180 0x10
#define AM_DEVICES_RM67162_SCAN_MODE_270 0x00
typedef struct
{
uint8_t bus_mode;
uint8_t color_mode;
uint8_t scan_mode;
uint32_t max_row;
uint32_t max_col;
uint32_t row_offset;
uint32_t col_offset;
} am_devices_rm67162_graphic_conf_t;
typedef struct
{
am_hal_mspi_device_e eDeviceConfig;
am_hal_mspi_clock_e eClockFreq;
am_hal_mspi_xipmixed_mode_e eMixedMode;
uint32_t *pNBTxnBuf;
uint32_t ui32NBTxnBufLength;
uint32_t ui32ScramblingStartAddr;
uint32_t ui32ScramblingEndAddr;
} am_devices_mspi_rm67162_config_t;
#define AM_DEVICES_MSPI_RM67162_MAX_DEVICE_NUM 1
//*****************************************************************************
//
// External function definitions.
//
//*****************************************************************************
extern uint32_t am_devices_rm67162_reset(void *pHandle);
extern uint32_t am_devices_rm67162_display_off(void *pHandle);
extern uint32_t am_devices_rm67162_display_on(void *pHandle);
extern uint32_t am_devices_rm67162_blocking_write(void *pHandle,
uint8_t *pui8TxBuffer,
uint32_t ui32NumBytes);
extern uint32_t am_devices_rm67162_blocking_read(void *pHandle,
uint8_t *pui8RxBuffer,
uint32_t ui32NumBytes);
extern uint32_t am_devices_rm67162_nonblocking_write(void *pHandle,
uint8_t *pui8TxBuffer,
uint32_t ui32NumBytes,
bool bWaitForCompletion);
extern uint32_t am_devices_rm67162_nonblocking_write_adv(void *pHandle,
uint8_t *pui8TxBuffer,
uint32_t ui32NumBytes,
uint32_t ui32PauseCondition,
uint32_t ui32StatusSetClr,
am_hal_mspi_callback_t pfnCallback,
void *pCallbackCtxt);
extern uint32_t am_devices_rm67162_nonblocking_read(void *pHandle,
uint8_t *pui8RxBuffer,
uint32_t ui32NumBytes,
bool bWaitForCompletion);
extern uint32_t am_devices_rm67162_read_id(void *pHandle,
uint32_t *pdata);
extern uint32_t am_devices_mspi_rm67162_init(uint32_t ui32Module, am_devices_mspi_rm67162_config_t *psMSPISettings, void **ppHandle, void **ppMspiHandle);
extern uint32_t am_devices_rm67162_term(void *pHandle);
extern uint32_t am_devices_rm67162_command_write(void *pHandle,
uint32_t ui32Instr,
uint8_t *pData,
uint32_t ui32NumBytes);
// extern uint32_t am_devices_mspi_rm67162_row_col_reset(uint32_t ui32Module);
extern uint32_t am_devices_mspi_rm67162_set_transfer_window(void *pHandle, uint32_t startRow, uint32_t startCol, uint32_t endRow, uint32_t endCol);
#ifdef __cplusplus
}
#endif
#endif // AM_DEVICES_RM67162_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,235 @@
//*****************************************************************************
//
//! @file am_devices_mspi_s25fs064s.h
//!
//! @brief Micron Serial NOR SPI Flash driver.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_DEVICES_MSPI_S25FS064S_H
#define AM_DEVICES_MSPI_S25FS064S_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Global definitions for s25fs064s commands
//
//*****************************************************************************
#define AM_DEVICES_MSPI_S25FS064S_WRITE_STATUS 0x01
#define AM_DEVICES_MSPI_S25FS064S_PAGE_PROGRAM 0x02
#define AM_DEVICES_MSPI_S25FS064S_READ 0x03
#define AM_DEVICES_MSPI_S25FS064S_WRITE_DISABLE 0x04
#define AM_DEVICES_MSPI_S25FS064S_READ_STATUS 0x05
#define AM_DEVICES_MSPI_S25FS064S_WRITE_ENABLE 0x06
#define AM_DEVICES_MSPI_S25FS064S_FAST_READ 0x0B
#define AM_DEVICES_MSPI_S25FS064S_READ_4B 0x13
#define AM_DEVICES_MSPI_S25FS064S_SUBSECTOR_ERASE 0x20
#define AM_DEVICES_MSPI_S25FS064S_DUAL_READ 0x3B
#define AM_DEVICES_MSPI_S25FS064S_DUAL_IO_READ 0xBB
#define AM_DEVICES_MSPI_S25FS064S_WRITE_ENHVOL_CFG 0x61
#define AM_DEVICES_MSPI_S25FS064S_RESET_ENABLE 0x66
#define AM_DEVICES_MSPI_S25FS064S_QUAD_READ 0x6B
#define AM_DEVICES_MSPI_S25FS064S_WRITE_VOL_CFG 0x81
#define AM_DEVICES_MSPI_S25FS064S_RESET_MEMORY 0x99
#define AM_DEVICES_MSPI_S25FS064S_READ_ID 0x9F
#define AM_DEVICES_MSPI_S25FS064S_ENTER_4B 0xB7
#define AM_DEVICES_MSPI_S25FS064S_BULK_ERASE 0xC7
#define AM_DEVICES_MSPI_S25FS064S_SECTOR_ERASE 0xD8
#define AM_DEVICES_MSPI_S25FS064S_EXIT_4B 0xE9
#define AM_DEVICES_MSPI_S25FS064S_QUAD_IO_READ 0xEB
#define AM_DEVICES_MSPI_S25FS064S_READ_QUAD_4B 0xEC
//*****************************************************************************
//
// Global definitions for the s25fs064s status register
//
//*****************************************************************************
#define AM_DEVICES_MSPI_S25FS064S_WEL 0x00000002 // Write enable latch
#define AM_DEVICES_MSPI_S25FS064S_WIP 0x00000001 // Write in progress
//*****************************************************************************
//
// Device specific identification.
//
//*****************************************************************************
#define AM_DEVICES_MSPI_S25FS064S_ID 0x00170201
#define AM_DEVICES_MSPI_S25FS064S_ID_MASK 0x00FFFFFF
//*****************************************************************************
//
// Device specific definitions for s25fs064s commands
//
//*****************************************************************************
#define AM_DEVICES_MSPI_S25FS064S_READ_STATUS2 0x07
#define AM_DEVICES_MSPI_S25FS064S_WRITE_ANY_REG 0x71
#define AM_DEVICES_MSPI_S25FS064S_EVAL_ERASE_STATUS 0xD0
//*****************************************************************************
//
// Device specific definitions for the Configuration register(s)
//
//*****************************************************************************
#define AM_DEVICES_MSPI_S25FS064S_QUAD_MODE (0x02)
#define AM_DEVICES_MSPI_S25FS064S_DUAL_MODE (0x00)
#define AM_DEVICES_MSPI_S25FS064S_SERIAL_MODE (0x00)
#define AM_DEVICES_MSPI_S25FS064S_CR1V (0x00020080)
#define AM_DEVICES_MSPI_S25FS064S_CR1V_VALUE(n) (((uint32_t)(n) << 24) & 0xFF000000)
#define AM_DEVICES_MSPI_S25FS064S_CR2V (0x00030080)
#define AM_DEVICES_MSPI_S25FS064S_CR2V_VALUE(n) (((uint32_t)(n) << 24) & 0xFF000000)
#define AM_DEVICES_MSPI_S25FS064S_ADDR_QUAD_EXT_DELAY (2)
#define AM_DEVICES_MSPI_S25FS064S_ADDR_DUAL_EXT_DELAY (4)
#define AM_DEVICES_MSPI_S25FS064S_CR3V (0x00040080)
#define AM_DEVICES_MSPI_S25FS064S_CR4V (0x00050080)
#define AM_DEVICES_MSPI_S25FS064S_CR3V_VALUE (((uint32_t)(0x08) << 24) & 0xFF000000)
#define AM_DEVICES_MSPI_S25FS064S_CR4V_VALUE (((uint32_t)(0x10) << 24) & 0xFF000000)
#define AM_DEVICES_MSPI_S25FS064S_ERASE_SUCCESS (0x04)
//*****************************************************************************
//
// Device specific definitions for the s25fs064s size information
//
//*****************************************************************************
#define AM_DEVICES_MSPI_S25FS064S_PAGE_SIZE 0x100 //256 bytes, minimum program unit
#define AM_DEVICES_MSPI_S25FS064S_SUBSECTOR_SIZE 0x1000 //4K bytes
#define AM_DEVICES_MSPI_S25FS064S_SECTOR_SIZE 0x10000 //64K bytes.
#define AM_DEVICES_MSPI_S25FS064S_MAX_SECTORS 128 // Sectors within 3-byte address range.
//*****************************************************************************
//
// Global definitions for the MSPI instance to use.
//
//*****************************************************************************
#define AM_DEVICES_MSPI_S25FS064S_MSPI_INSTANCE 0
#define AM_DEVICES_MSPI_S25FS064S_MAX_DEVICE_NUM 1
//*****************************************************************************
//
// Global type definitions.
//
//*****************************************************************************
typedef enum
{
AM_DEVICES_MSPI_S25FS064S_STATUS_SUCCESS,
AM_DEVICES_MSPI_S25FS064S_STATUS_ERROR
} am_devices_mspi_s25fs064s_status_t;
typedef struct
{
am_hal_mspi_device_e eDeviceConfig;
am_hal_mspi_clock_e eClockFreq;
am_hal_mspi_xipmixed_mode_e eMixedMode;
uint32_t *pNBTxnBuf;
uint32_t ui32NBTxnBufLength;
uint32_t ui32ScramblingStartAddr;
uint32_t ui32ScramblingEndAddr;
} am_devices_mspi_s25fs064s_config_t;
//*****************************************************************************
//
// External function definitions.
//
//*****************************************************************************
extern uint32_t am_devices_mspi_s25fs064s_init(uint32_t ui32Module,
am_devices_mspi_s25fs064s_config_t *psMSPISettings,
void **ppHandle, void **ppMspiHandle);
extern uint32_t am_devices_mspi_s25fs064s_deinit(void *pHandle);
extern uint32_t am_devices_mspi_s25fs064s_id(void *pHandle);
extern uint32_t am_devices_mspi_s25fs064s_reset(void *pHandle);
extern uint32_t am_devices_mspi_s25fs064s_status(void *pHandle, uint32_t *pStatus);
extern uint32_t am_devices_mspi_s25fs064s_read(void *pHandle, uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes,
bool bWaitForCompletion);
extern uint32_t am_devices_mspi_s25fs064s_write(void *pHandle, uint8_t *ui8TxBuffer,
uint32_t ui32WriteAddress,
uint32_t ui32NumBytes,
bool bWaitForCompletion);
extern uint32_t am_devices_mspi_s25fs064s_mass_erase(void *pHandle);
extern uint32_t am_devices_mspi_s25fs064s_sector_erase(void *pHandle, uint32_t ui32SectorAddress);
extern uint32_t am_devices_mspi_s25fs064s_enable_xip(void *pHandle);
extern uint32_t am_devices_mspi_s25fs064s_disable_xip(void *pHandle);
extern uint32_t am_devices_mspi_s25fs064s_enable_scrambling(void *pHandle);
extern uint32_t am_devices_mspi_s25fs064s_disable_scrambling(void *pHandle);
extern uint32_t
am_devices_mspi_s25fs064s_read_adv(void *pHandle, uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes,
uint32_t ui32PauseCondition,
uint32_t ui32StatusSetClr,
am_hal_mspi_callback_t pfnCallback,
void *pCallbackCtxt);
extern am_devices_mspi_s25fs064s_config_t
am_devices_mspi_s25fs064s_mode_switch(void *pHandle,
am_devices_mspi_s25fs064s_config_t *pMSPISettings);
extern uint32_t
am_devices_mspi_s25fs064s_read_hiprio(void *pHandle, uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes,
bool bWaitForCompletion);
#ifdef __cplusplus
}
#endif
#endif // AM_DEVICES_MSPI_S25FS064S_H
@@ -0,0 +1,437 @@
//*****************************************************************************
//
//! @file am_devices_spiflash.c
//!
//! @brief Generic spiflash driver.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include "am_mcu_apollo.h"
#include "am_devices_spiflash.h"
//*****************************************************************************
//
// Global variables.
//
//*****************************************************************************
am_devices_spiflash_t *g_psIOMSettings;
//*****************************************************************************
//
//! @brief Initialize the spiflash driver.
//!
//! @param psIOMSettings - IOM device structure describing the target spiflash.
//! @param pfnWriteFunc - Function to use for spi writes.
//! @param pfnReadFunc - Function to use for spi reads.
//!
//! This function should be called before any other am_devices_spiflash
//! functions. It is used to set tell the other functions how to communicate
//! with the external spiflash hardware.
//!
//! The \e pfnWriteFunc and \e pfnReadFunc variables may be used to provide
//! alternate implementations of SPI write and read functions respectively. If
//! they are left set to 0, the default functions am_hal_iom_spi_write() and
//! am_hal_iom_spi_read() will be used.
//!
//! @return None.
//
//*****************************************************************************
void
am_devices_spiflash_init(am_devices_spiflash_t *psIOMSettings)
{
//
// Initialize the IOM settings for the spiflash.
//
g_psIOMSettings = psIOMSettings;
}
//*****************************************************************************
//
//! @brief Reads the current status of the external flash
//!
//! @param ui32DeviceNumber - Device number of the external flash
//!
//! This function reads the status register of the external flash, and returns
//! the result as an 8-bit unsigned integer value. The processor will block
//! during the data transfer process, but will return as soon as the status
//! register had been read.
//!
//! Macro definitions for interpreting the contents of the status register are
//! included in the header file.
//!
//! @return 8-bit status register contents
//
//*****************************************************************************
uint8_t
am_devices_spiflash_status(void)
{
am_hal_iom_buffer(1) psResponse;
//
// Send the command and read the response.
//
am_hal_iom_spi_read(g_psIOMSettings->ui32IOMModule,
g_psIOMSettings->ui32ChipSelect,
psResponse.words, 1,
AM_HAL_IOM_OFFSET(AM_DEVICES_SPIFLASH_RDRSR));
//
// Return the status read from the external flash.
//
return psResponse.bytes[0];
}
//*****************************************************************************
//
//! @brief Reads the ID register for the external flash
//!
//! @param ui32DeviceNumber - Device number of the external flash
//!
//! This function reads the ID register of the external flash, and returns the
//! result as a 32-bit unsigned integer value. The processor will block during
//! the data transfer process, but will return as soon as the ID register had
//! been read. The ID contents for this flash only contains 24 bits of data, so
//! the result will be stored in the lower 24 bits of the return value.
//!
//! @return 32-bit ID register contents
//
//*****************************************************************************
uint32_t
am_devices_spiflash_id(void)
{
am_hal_iom_buffer(3) psResponse;
//
// Send a command to read the ID register in the external flash.
//
am_hal_iom_spi_read(g_psIOMSettings->ui32IOMModule,
g_psIOMSettings->ui32ChipSelect,
psResponse.words, 3,
AM_HAL_IOM_OFFSET(AM_DEVICES_SPIFLASH_RDID));
//
// Return the ID
//
return psResponse.words[0] & 0x00FFFFFF;
}
//*****************************************************************************
//
//! @brief Reads the contents of the external flash into a buffer.
//!
//! @param ui32DeviceNumber - Device number of the external flash
//! @param pui8RxBuffer - Buffer to store the received data from the flash
//! @param ui32ReadAddress - Address of desired data in external flash
//! @param ui32NumBytes - Number of bytes to read from external flash
//!
//! This function reads the external flash at the provided address and stores
//! the received data into the provided buffer location. This function will
//! only store ui32NumBytes worth of data.
//
//*****************************************************************************
void
am_devices_spiflash_read(uint8_t *pui8RxBuffer, uint32_t ui32ReadAddress,
uint32_t ui32NumBytes)
{
uint32_t i, ui32BytesRemaining, ui32TransferSize, ui32CurrentReadAddress;
uint8_t *pui8Dest;
uint32_t pui32WriteBuffer[1];
uint8_t *pui8WritePtr;
uint32_t pui32ReadBuffer[16];
uint8_t *pui8ReadPtr;
pui8WritePtr = (uint8_t *)(&pui32WriteBuffer);
pui8ReadPtr = (uint8_t *)(&pui32ReadBuffer);
//
// Set the total number of bytes,and the starting transfer destination.
//
ui32BytesRemaining = ui32NumBytes;
pui8Dest = pui8RxBuffer;
ui32CurrentReadAddress = ui32ReadAddress;
while ( ui32BytesRemaining )
{
//
// Set the transfer size to either 64, or the number of remaining
// bytes, whichever is smaller.
//
ui32TransferSize = ui32BytesRemaining > 64 ? 64 : ui32BytesRemaining;
pui8WritePtr[0] = AM_DEVICES_SPIFLASH_READ;
pui8WritePtr[1] = (ui32CurrentReadAddress & 0x00FF0000) >> 16;
pui8WritePtr[2] = (ui32CurrentReadAddress & 0x0000FF00) >> 8;
pui8WritePtr[3] = ui32CurrentReadAddress & 0x000000FF;
//
// Send the read command.
//
am_hal_iom_spi_write(g_psIOMSettings->ui32IOMModule,
g_psIOMSettings->ui32ChipSelect,
pui32WriteBuffer, 4,
AM_HAL_IOM_CS_LOW | AM_HAL_IOM_RAW);
am_hal_iom_spi_read(g_psIOMSettings->ui32IOMModule,
g_psIOMSettings->ui32ChipSelect, pui32ReadBuffer,
ui32TransferSize, AM_HAL_IOM_RAW);
//
// Copy the received bytes over to the RxBuffer
//
for ( i = 0; i < ui32TransferSize; i++ )
{
pui8Dest[i] = pui8ReadPtr[i];
}
//
// Update the number of bytes remaining and the destination.
//
ui32BytesRemaining -= ui32TransferSize;
pui8Dest += ui32TransferSize;
ui32CurrentReadAddress += ui32TransferSize;
}
}
//*****************************************************************************
//
//! @brief Programs the given range of flash addresses.
//!
//! @param ui32DeviceNumber - Device number of the external flash
//! @param pui8TxBuffer - Buffer to write the external flash data from
//! @param ui32WriteAddress - Address to write to in the external flash
//! @param ui32NumBytes - Number of bytes to write to the external flash
//!
//! This function uses the data in the provided pui8TxBuffer and copies it to
//! the external flash at the address given by ui32WriteAddress. It will copy
//! exactly ui32NumBytes of data from the original pui8TxBuffer pointer. The
//! user is responsible for ensuring that they do not overflow the target flash
//! memory or underflow the pui8TxBuffer array
//
//*****************************************************************************
void
am_devices_spiflash_write(uint8_t *pui8TxBuffer, uint32_t ui32WriteAddress,
uint32_t ui32NumBytes)
{
uint32_t i;
uint32_t ui32DestAddress;
uint32_t ui32BytesRemaining;
uint32_t ui32TransferSize;
uint8_t *pui8Source;
am_hal_iom_buffer(1) psEnableCommand;
am_hal_iom_buffer(64) psWriteCommand;
//
// Prepare the command for write-enable.
//
psEnableCommand.bytes[0] = AM_DEVICES_SPIFLASH_WREN;
//
// Set the total number of bytes, and the starting transfer destination.
//
ui32BytesRemaining = ui32NumBytes;
pui8Source = pui8TxBuffer;
ui32DestAddress = ui32WriteAddress;
while ( ui32BytesRemaining )
{
//
// Set up a write command to hit the beginning of the next "chunk" of
// flash.
//
psWriteCommand.bytes[0] = AM_DEVICES_SPIFLASH_PP;
psWriteCommand.bytes[1] = (ui32DestAddress & 0x00FF0000) >> 16;
psWriteCommand.bytes[2] = (ui32DestAddress & 0x0000FF00) >> 8;
psWriteCommand.bytes[3] = ui32DestAddress & 0x000000FF;
//
// Set the transfer size to either 32, or the number of remaining
// bytes, whichever is smaller.
//
ui32TransferSize = ui32BytesRemaining > 32 ? 32 : ui32BytesRemaining;
//
// Fill the rest of the command buffer with the data that we actually
// want to write to flash.
//
for ( i = 0; i < ui32TransferSize; i++ )
{
psWriteCommand.bytes[4 + i] = pui8Source[i];
}
//
// Send the write-enable command to prepare the external flash for
// program operations, and wait for the write-enable latch to be set in
// the status register.
//
am_hal_iom_spi_write(g_psIOMSettings->ui32IOMModule,
g_psIOMSettings->ui32ChipSelect,
psEnableCommand.words,
1, AM_HAL_IOM_RAW);
while ( !(am_devices_spiflash_status() & AM_DEVICES_SPIFLASH_WEL) );
//
// Send the write command.
//
am_hal_iom_spi_write(g_psIOMSettings->ui32IOMModule,
g_psIOMSettings->ui32ChipSelect,
psWriteCommand.words,
(ui32TransferSize + 4), AM_HAL_IOM_RAW);
//
// Wait for status to indicate that the write is no longer in progress.
//
while ( am_devices_spiflash_status() & AM_DEVICES_SPIFLASH_WIP );
//
// Update the number of bytes remaining, as well as the source and
// destination pointers
//
ui32BytesRemaining -= ui32TransferSize;
pui8Source += ui32TransferSize;
ui32DestAddress += ui32TransferSize;
}
return;
}
//*****************************************************************************
//
//! @brief Erases the entire contents of the external flash
//!
//! @param ui32DeviceNumber - Device number of the external flash
//!
//! This function uses the "Bulk Erase" instruction to erase the entire
//! contents of the external flash.
//
//*****************************************************************************
void
am_devices_spiflash_mass_erase(void)
{
am_hal_iom_buffer(1) psCommand;
//
// Send the write-enable command to prepare the external flash for program
// operations.
//
psCommand.bytes[0] = AM_DEVICES_SPIFLASH_WREN;
am_hal_iom_spi_write(g_psIOMSettings->ui32IOMModule,
g_psIOMSettings->ui32ChipSelect,
psCommand.words, 1, AM_HAL_IOM_RAW);
//
// Wait for the write enable latch status bit.
//
while ( !(am_devices_spiflash_status() & AM_DEVICES_SPIFLASH_WEL) );
//
// Send the bulk erase command.
//
psCommand.bytes[0] = AM_DEVICES_SPIFLASH_BE;
am_hal_iom_spi_write(g_psIOMSettings->ui32IOMModule,
g_psIOMSettings->ui32ChipSelect,
psCommand.words, 1, AM_HAL_IOM_RAW);
//
// Wait for status to indicate that the write is no longer in progress.
//
while ( am_devices_spiflash_status() & AM_DEVICES_SPIFLASH_WIP );
return;
}
//*****************************************************************************
//
//! @brief Erases the contents of a single sector of flash
//!
//! @param ui32DeviceNumber - Device number of the external flash
//! @param ui32SectorAddress - Address to erase in the external flash
//!
//! This function erases a single sector of the external flash as specified by
//! ui32EraseAddress. The entire sector where ui32EraseAddress will
//! be erased.
//
//*****************************************************************************
void
am_devices_spiflash_sector_erase(uint32_t ui32SectorAddress)
{
am_hal_iom_buffer(4) psCommand;
//
// Send the write-enable command to prepare the external flash for program
// operations.
//
psCommand.bytes[0] = AM_DEVICES_SPIFLASH_WREN;
am_hal_iom_spi_write(g_psIOMSettings->ui32IOMModule,
g_psIOMSettings->ui32ChipSelect,
psCommand.words, 1, AM_HAL_IOM_RAW);
//
// Wait for the write enable latch status bit.
//
while ( !(am_devices_spiflash_status() & AM_DEVICES_SPIFLASH_WEL) );
//
// Prepare the sector erase command, followed by the three-byte external
// flash address.
//
psCommand.bytes[0] = AM_DEVICES_SPIFLASH_SE;
psCommand.bytes[1] = (ui32SectorAddress & 0x00FF0000) >> 16;
psCommand.bytes[2] = (ui32SectorAddress & 0x0000FF00) >> 8;
psCommand.bytes[3] = ui32SectorAddress & 0x000000FF;
//
// Send the command to erase the desired sector.
//
am_hal_iom_spi_write(g_psIOMSettings->ui32IOMModule,
g_psIOMSettings->ui32ChipSelect,
psCommand.words, 4, AM_HAL_IOM_RAW);
//
// Wait for status to indicate that the write is no longer in progress.
//
while ( am_devices_spiflash_status() & AM_DEVICES_SPIFLASH_WIP );
return;
}
@@ -0,0 +1,151 @@
//*****************************************************************************
//
//! @file am_devices_spiflash.h
//!
//! @brief Generic spiflash driver.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_DEVICES_SPIFLASH_H
#define AM_DEVICES_SPIFLASH_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Global definitions for flash commands
//
//*****************************************************************************
#define AM_DEVICES_SPIFLASH_WREN 0x06 // Write enable
#define AM_DEVICES_SPIFLASH_WRDI 0x04 // Write disable
#define AM_DEVICES_SPIFLASH_RDID 0x9E // Read Identification
#define AM_DEVICES_SPIFLASH_RDRSR 0x05 // Read status register
#define AM_DEVICES_SPIFLASH_WRSR 0x01 // Write status register
#define AM_DEVICES_SPIFLASH_READ 0x03 // Read data bytes
#define AM_DEVICES_SPIFLASH_PP 0x02 // Page program
#define AM_DEVICES_SPIFLASH_SE 0xD8 // Sector Erase
#define AM_DEVICES_SPIFLASH_BE 0xC7 // Bulk Erase
//*****************************************************************************
//
// Global definitions for the flash status register
//
//*****************************************************************************
#define AM_DEVICES_SPIFLASH_WEL 0x02 // Write enable latch
#define AM_DEVICES_SPIFLASH_WIP 0x01 // Write in progress
//*****************************************************************************
//
// Global definitions for the flash size information
//
//*****************************************************************************
#define AM_DEVICES_SPIFLASH_PAGE_SIZE 0x100 //256 bytes, minimum program unit
#define AM_DEVICES_SPIFLASH_SUBSECTOR_SIZE 0x1000 //4096 bytes
#define AM_DEVICES_SPIFLASH_SECTOR_SIZE 0x10000 //65536 bytes
//*****************************************************************************
//
// Function pointers for SPI write and read.
//
//*****************************************************************************
typedef bool (*am_devices_spiflash_write_t)(uint32_t ui32Module,
uint32_t ui32ChipSelect,
uint32_t *pui32Data,
uint32_t ui32NumBytes,
uint32_t ui32Options);
typedef bool (*am_devices_spiflash_read_t)(uint32_t ui32Module,
uint32_t ui32ChipSelect,
uint32_t *pui32Data,
uint32_t ui32NumBytes,
uint32_t ui32Options);
//*****************************************************************************
//
// Device structure used for communication.
//
//*****************************************************************************
typedef struct
{
//
// Module number to use for IOM access.
//
uint32_t ui32IOMModule;
//
// Chip Select number to use for IOM access.
//
uint32_t ui32ChipSelect;
}
am_devices_spiflash_t;
//*****************************************************************************
//
// External function definitions.
//
//*****************************************************************************
extern void am_devices_spiflash_init(am_devices_spiflash_t *psIOMSettings);
extern uint8_t am_devices_spiflash_status(void);
extern uint32_t am_devices_spiflash_id(void);
extern void am_devices_spiflash_read(uint8_t *pui8RxBuffer,
uint32_t ui32ReadAddress,
uint32_t ui32NumBytes);
extern void am_devices_spiflash_write(uint8_t *ui8TxBuffer,
uint32_t ui32WriteAddress,
uint32_t ui32NumBytes);
extern void am_devices_spiflash_mass_erase(void);
extern void am_devices_spiflash_sector_erase(uint32_t ui32SectorAddress);
#ifdef __cplusplus
}
#endif
#endif // AM_DEVICES_SPIFLASH_H