add NXP Imx RT1052 support

add NXP RT1052 support
This commit is contained in:
supowang
2020-01-08 19:55:20 +08:00
parent 72481955e2
commit e7457d9714
232 changed files with 367079 additions and 0 deletions

View File

@@ -0,0 +1,321 @@
/*
* Copyright (c) 2015-2016 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Driver_CAN.h"
#define ARM_CAN_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1,0) // CAN driver version
// Driver Version
static const ARM_DRIVER_VERSION can_driver_version = { ARM_CAN_API_VERSION, ARM_CAN_DRV_VERSION };
// Driver Capabilities
static const ARM_CAN_CAPABILITIES can_driver_capabilities = {
32U, // Number of CAN Objects available
1U, // Supports reentrant calls to ARM_CAN_MessageSend, ARM_CAN_MessageRead, ARM_CAN_ObjectConfigure and abort message sending used by ARM_CAN_Control.
0U, // Does not support CAN with Flexible Data-rate mode (CAN_FD)
0U, // Does not support restricted operation mode
1U, // Supports bus monitoring mode
1U, // Supports internal loopback mode
1U, // Supports external loopback mode
};
// Object Capabilities
static const ARM_CAN_OBJ_CAPABILITIES can_object_capabilities = {
1U, // Object supports transmission
1U, // Object supports reception
0U, // Object does not support RTR reception and automatic Data transmission
0U, // Object does not support RTR transmission and automatic Data reception
1U, // Object allows assignment of multiple filters to it
1U, // Object supports exact identifier filtering
0U, // Object does not support range identifier filtering
1U, // Object supports mask identifier filtering
3U // Object can buffer 3 messages
};
static uint8_t can_driver_powered = 0U;
static uint8_t can_driver_initialized = 0U;
static ARM_CAN_SignalUnitEvent_t CAN_SignalUnitEvent = NULL;
static ARM_CAN_SignalObjectEvent_t CAN_SignalObjectEvent = NULL;
//
// Functions
//
static ARM_DRIVER_VERSION CAN_GetVersion (void) {
// Return driver version
return can_driver_version;
}
static ARM_CAN_CAPABILITIES CAN_GetCapabilities (void) {
// Return driver capabilities
return can_driver_capabilities;
}
static int32_t CAN_Initialize (ARM_CAN_SignalUnitEvent_t cb_unit_event,
ARM_CAN_SignalObjectEvent_t cb_object_event) {
if (can_driver_initialized != 0U) { return ARM_DRIVER_OK; }
CAN_SignalUnitEvent = cb_unit_event;
CAN_SignalObjectEvent = cb_object_event;
// Add code for pin, memory, RTX objects initialization
// ..
can_driver_initialized = 1U;
return ARM_DRIVER_OK;
}
static int32_t CAN_Uninitialize (void) {
// Add code for pin, memory, RTX objects de-initialization
// ..
can_driver_initialized = 0U;
return ARM_DRIVER_OK;
}
static int32_t CAN_PowerControl (ARM_POWER_STATE state) {
switch (state) {
case ARM_POWER_OFF:
can_driver_powered = 0U;
// Add code to disable interrupts and put peripheral into reset mode,
// and if possible disable clock
// ..
case ARM_POWER_FULL:
if (can_driver_initialized == 0U) { return ARM_DRIVER_ERROR; }
if (can_driver_powered != 0U) { return ARM_DRIVER_OK; }
// Add code to enable clocks, reset variables enable interrupts
// and put peripheral into operational
// ..
can_driver_powered = 1U;
break;
default:
// Other states are not supported
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
return ARM_DRIVER_OK;
}
uint32_t CAN_GetClock (void) {
// Add code to return peripheral clock frequency
// ..
}
static int32_t CAN_SetBitrate (ARM_CAN_BITRATE_SELECT select, uint32_t bitrate, uint32_t bit_segments) {
if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
// Add code to setup peripheral parameters to generate specified bitrate
// with specified bit segments
// ..
return ARM_DRIVER_OK;
}
static int32_t CAN_SetMode (ARM_CAN_MODE mode) {
if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
switch (mode) {
case ARM_CAN_MODE_INITIALIZATION:
// Add code to put peripheral into initialization mode
// ..
break;
case ARM_CAN_MODE_NORMAL:
// Add code to put peripheral into normal operation mode
// ..
break;
case ARM_CAN_MODE_RESTRICTED:
// Add code to put peripheral into restricted operation mode
// ..
break;
case ARM_CAN_MODE_MONITOR:
// Add code to put peripheral into bus monitoring mode
// ..
break;
case ARM_CAN_MODE_LOOPBACK_INTERNAL:
// Add code to put peripheral into internal loopback mode
// ..
break;
case ARM_CAN_MODE_LOOPBACK_EXTERNAL:
// Add code to put peripheral into external loopback mode
// ..
break;
default:
// Handle unknown mode code
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
return ARM_DRIVER_OK;
}
ARM_CAN_OBJ_CAPABILITIES CAN_ObjectGetCapabilities (uint32_t obj_idx) {
// Return object capabilities
return can_object_capabilities;
}
static int32_t CAN_ObjectSetFilter (uint32_t obj_idx, ARM_CAN_FILTER_OPERATION operation, uint32_t id, uint32_t arg) {
if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
switch (operation) {
case ARM_CAN_FILTER_ID_EXACT_ADD:
// Add code to setup peripheral to receive messages with specified exact ID
break;
case ARM_CAN_FILTER_ID_MASKABLE_ADD:
// Add code to setup peripheral to receive messages with specified maskable ID
break;
case ARM_CAN_FILTER_ID_RANGE_ADD:
// Add code to setup peripheral to receive messages within specified range of IDs
break;
case ARM_CAN_FILTER_ID_EXACT_REMOVE:
// Add code to remove specified exact ID from being received by peripheral
break;
case ARM_CAN_FILTER_ID_MASKABLE_REMOVE:
// Add code to remove specified maskable ID from being received by peripheral
break;
case ARM_CAN_FILTER_ID_RANGE_REMOVE:
// Add code to remove specified range of IDs from being received by peripheral
break;
default:
// Handle unknown operation code
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
return ARM_DRIVER_OK;
}
static int32_t CAN_ObjectConfigure (uint32_t obj_idx, ARM_CAN_OBJ_CONFIG obj_cfg) {
if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
switch (obj_cfg) {
case ARM_CAN_OBJ_INACTIVE:
// Deactivate object
// ..
break;
case ARM_CAN_OBJ_RX_RTR_TX_DATA:
// Setup object to automatically return data when RTR with it's ID is received
// ..
break;
case ARM_CAN_OBJ_TX_RTR_RX_DATA:
// Setup object to send RTR and receive data response
// ..
break;
case ARM_CAN_OBJ_TX:
// Setup object to be used for sending messages
// ..
break;
case ARM_CAN_OBJ_RX:
// Setup object to be used for receiving messages
// ..
break;
default:
// Handle unknown object configuration code
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
return ARM_DRIVER_OK;
}
static int32_t CAN_MessageSend (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, const uint8_t *data, uint8_t size) {
if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
// Add code to send requested message
// ..
return ((int32_t)size);
}
static int32_t CAN_MessageRead (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, uint8_t *data, uint8_t size) {
if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
// Add code to read previously received message
// (reception was started when object was configured for reception)
// ..
return ((int32_t)size);
}
static int32_t CAN_Control (uint32_t control, uint32_t arg) {
if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
switch (control & ARM_CAN_CONTROL_Msk) {
case ARM_CAN_ABORT_MESSAGE_SEND:
// Add code to abort message pending to be sent
// ..
break;
case ARM_CAN_SET_FD_MODE:
// Add code to enable Flexible Data-rate mode
// ..
break;
case ARM_CAN_SET_TRANSCEIVER_DELAY:
// Add code to set transceiver delay
// ..
break;
default:
// Handle unknown control code
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
return ARM_DRIVER_OK;
}
static ARM_CAN_STATUS CAN_GetStatus (void) {
// Add code to return device bus and error status
// ..
}
// IRQ handlers
// Add interrupt routines to handle transmission, reception, error and status interrupts
// ..
// CAN driver functions structure
ARM_DRIVER_CAN Driver_CAN = {
CAN_GetVersion,
CAN_GetCapabilities,
CAN_Initialize,
CAN_Uninitialize,
CAN_PowerControl,
CAN_GetClock,
CAN_SetBitrate,
CAN_SetMode,
CAN_ObjectGetCapabilities,
CAN_ObjectSetFilter,
CAN_ObjectConfigure,
CAN_MessageSend,
CAN_MessageRead,
CAN_Control,
CAN_GetStatus
};

View File

@@ -0,0 +1,228 @@
/*
* Copyright (c) 2013-2016 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Driver_ETH_MAC.h"
#define ARM_ETH_MAC_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 0) /* driver version */
/* Driver Version */
static const ARM_DRIVER_VERSION DriverVersion = {
ARM_ETH_MAC_API_VERSION,
ARM_ETH_MAC_DRV_VERSION
};
/* Driver Capabilities */
static const ARM_ETH_MAC_CAPABILITIES DriverCapabilities = {
0, /* 1 = IPv4 header checksum verified on receive */
0, /* 1 = IPv6 checksum verification supported on receive */
0, /* 1 = UDP payload checksum verified on receive */
0, /* 1 = TCP payload checksum verified on receive */
0, /* 1 = ICMP payload checksum verified on receive */
0, /* 1 = IPv4 header checksum generated on transmit */
0, /* 1 = IPv6 checksum generation supported on transmit */
0, /* 1 = UDP payload checksum generated on transmit */
0, /* 1 = TCP payload checksum generated on transmit */
0, /* 1 = ICMP payload checksum generated on transmit */
0, /* Ethernet Media Interface type */
0, /* 1 = driver provides initial valid MAC address */
0, /* 1 = callback event \ref ARM_ETH_MAC_EVENT_RX_FRAME generated */
0, /* 1 = callback event \ref ARM_ETH_MAC_EVENT_TX_FRAME generated */
0, /* 1 = wakeup event \ref ARM_ETH_MAC_EVENT_WAKEUP generated */
0 /* 1 = Precision Timer supported */
};
//
// Functions
//
ARM_DRIVER_VERSION ARM_ETH_MAC_GetVersion(void)
{
}
ARM_ETH_MAC_CAPABILITIES ARM_ETH_MAC_GetCapabilities(void)
{
}
int32_t ARM_ETH_MAC_Initialize(ARM_ETH_MAC_SignalEvent_t cb_event)
{
}
int32_t ARM_ETH_MAC_Uninitialize(void)
{
}
int32_t ARM_ETH_MAC_PowerControl(ARM_POWER_STATE state)
{
switch (state)
{
case ARM_POWER_OFF:
break;
case ARM_POWER_LOW:
break;
case ARM_POWER_FULL:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
int32_t ARM_ETH_MAC_GetMacAddress(ARM_ETH_MAC_ADDR *ptr_addr)
{
}
int32_t ARM_ETH_MAC_SetMacAddress(const ARM_ETH_MAC_ADDR *ptr_addr)
{
}
int32_t ARM_ETH_MAC_SetAddressFilter(const ARM_ETH_MAC_ADDR *ptr_addr, uint32_t num_addr)
{
}
int32_t ARM_ETH_MAC_SendFrame(const uint8_t *frame, uint32_t len, uint32_t flags)
{
}
int32_t ARM_ETH_MAC_ReadFrame(uint8_t *frame, uint32_t len)
{
}
uint32_t ARM_ETH_MAC_GetRxFrameSize(void)
{
}
int32_t ARM_ETH_MAC_GetRxFrameTime(ARM_ETH_MAC_TIME *time)
{
}
int32_t ARM_ETH_MAC_GetTxFrameTime(ARM_ETH_MAC_TIME *time)
{
}
int32_t ARM_ETH_MAC_Control(uint32_t control, uint32_t arg)
{
switch (control)
{
case ARM_ETH_MAC_CONFIGURE:
switch (arg & ARM_ETH_MAC_SPEED_Msk)
{
case ARM_ETH_MAC_SPEED_10M:
break;
case ARM_ETH_SPEED_100M:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
switch (arg & ARM_ETH_MAC_DUPLEX_Msk)
{
case ARM_ETH_MAC_DUPLEX_FULL:
break;
}
if (arg & ARM_ETH_MAC_LOOPBACK)
{
}
if ((arg & ARM_ETH_MAC_CHECKSUM_OFFLOAD_RX) ||
(arg & ARM_ETH_MAC_CHECKSUM_OFFLOAD_TX))
{
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
if (!(arg & ARM_ETH_MAC_ADDRESS_BROADCAST))
{
}
if (arg & ARM_ETH_MAC_ADDRESS_MULTICAST)
{
}
if (arg & ARM_ETH_MAC_ADDRESS_ALL)
{
}
break;
case ARM_ETH_MAC_CONTROL_TX:
break;
case ARM_ETH_MAC_CONTROL_RX:
break;
case ARM_ETH_MAC_FLUSH:
if (arg & ARM_ETH_MAC_FLUSH_RX)
{
}
if (arg & ARM_ETH_MAC_FLUSH_TX)
{
}
break;
case ARM_ETH_MAC_SLEEP:
break;
case ARM_ETH_MAC_VLAN_FILTER:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
int32_t ARM_ETH_MAC_ControlTimer(uint32_t control, ARM_ETH_MAC_TIME *time)
{
}
int32_t ARM_ETH_MAC_PHY_Read(uint8_t phy_addr, uint8_t reg_addr, uint16_t *data)
{
}
int32_t ARM_ETH_MAC_PHY_Write(uint8_t phy_addr, uint8_t reg_addr, uint16_t data)
{
}
void ARM_ETH_MAC_SignalEvent(uint32_t event)
{
}
// End ETH MAC Interface
ARM_DRIVER_ETH_MAC Driver_ETH_MAC =
{
ARM_ETH_MAC_GetVersion,
ARM_ETH_MAC_GetCapabilities,
ARM_ETH_MAC_Initialize,
ARM_ETH_MAC_Uninitialize,
ARM_ETH_MAC_PowerControl,
ARM_ETH_MAC_GetMacAddress,
ARM_ETH_MAC_SetMacAddress,
ARM_ETH_MAC_SetAddressFilter,
ARM_ETH_MAC_SendFrame,
ARM_ETH_MAC_ReadFrame,
ARM_ETH_MAC_GetRxFrameSize,
ARM_ETH_MAC_GetRxFrameTime,
ARM_ETH_MAC_GetTxFrameTime,
ARM_ETH_MAC_ControlTimer,
ARM_ETH_MAC_Control,
ARM_ETH_MAC_PHY_Read,
ARM_ETH_MAC_PHY_Write
};

View File

@@ -0,0 +1,127 @@
/*
* Copyright (c) 2013-2016 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Driver_ETH_PHY.h"
#define ARM_ETH_PHY_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 0) /* driver version */
/* Driver Version */
static const ARM_DRIVER_VERSION DriverVersion = {
ARM_ETH_PHY_API_VERSION,
ARM_ETH_PHY_DRV_VERSION
};
//
// Functions
//
ARM_DRIVER_VERSION ARM_ETH_PHY_GetVersion(void)
{
}
int32_t ARM_ETH_PHY_Initialize(ARM_ETH_PHY_Read_t fn_read, ARM_ETH_PHY_Write_t fn_write)
{
}
int32_t ARM_ETH_PHY_Uninitialize(void)
{
}
int32_t ARM_ETH_PHY_PowerControl(ARM_POWER_STATE state)
{
switch (state)
{
case ARM_POWER_OFF:
break;
case ARM_POWER_LOW:
break;
case ARM_POWER_FULL:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
int32_t ARM_ETH_PHY_SetInterface(uint32_t interface)
{
switch (interface)
{
case ARM_ETH_INTERFACE_MII:
break;
case ARM_ETH_INTERFACE_RMII:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
int32_t ARM_ETH_PHY_SetMode(uint32_t mode)
{
switch (mode & ARM_ETH_PHY_SPEED_Msk)
{
case ARM_ETH_PHY_SPEED_10M:
break;
case ARM_ETH_PHY_SPEED_100M:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
switch (mode & ARM_ETH_PHY_DUPLEX_Msk)
{
case ARM_ETH_PHY_DUPLEX_HALF:
break;
case ARM_ETH_PHY_DUPLEX_FULL:
break;
}
if (mode & ARM_ETH_PHY_AUTO_NEGOTIATE)
{
}
if (mode & ARM_ETH_PHY_LOOPBACK)
{
}
if (mode & ARM_ETH_PHY_ISOLATE)
{
}
}
ARM_ETH_LINK_STATE ARM_ETH_PHY_GetLinkState(void)
{
}
ARM_ETH_LINK_INFO ARM_ETH_PHY_GetLinkInfo(void)
{
}
ARM_DRIVER_ETH_PHY ARM_Driver_ETH_PHY_(ETH_PHY_NUM) =
{
ARM_ETH_PHY_GetVersion,
ARM_ETH_PHY_Initialize,
ARM_ETH_PHY_Uninitialize,
ARM_ETH_PHY_PowerControl,
ARM_ETH_PHY_SetInterface,
ARM_ETH_PHY_SetMode,
ARM_ETH_PHY_GetLinkState,
ARM_ETH_PHY_GetLinkInfo,
};

View File

@@ -0,0 +1,137 @@
/*
* Copyright (c) 2013-2016 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Driver_Flash.h"
#define ARM_FLASH_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0) /* driver version */
/* Sector Information */
#ifdef FLASH_SECTORS
static ARM_FLASH_SECTOR FLASH_SECTOR_INFO[FLASH_SECTOR_COUNT] = {
FLASH_SECTORS
};
#else
#define FLASH_SECTOR_INFO NULL
#endif
/* Flash Information */
static ARM_FLASH_INFO FlashInfo = {
0, /* FLASH_SECTOR_INFO */
0, /* FLASH_SECTOR_COUNT */
0, /* FLASH_SECTOR_SIZE */
0, /* FLASH_PAGE_SIZE */
0, /* FLASH_PROGRAM_UNIT */
0 /* FLASH_ERASED_VALUE */
};
/* Flash Status */
static ARM_FLASH_STATUS FlashStatus;
/* Driver Version */
static const ARM_DRIVER_VERSION DriverVersion = {
ARM_FLASH_API_VERSION,
ARM_FLASH_DRV_VERSION
};
/* Driver Capabilities */
static const ARM_FLASH_CAPABILITIES DriverCapabilities = {
0, /* event_ready */
0, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */
0 /* erase_chip */
};
//
// Functions
//
ARM_DRIVER_VERSION ARM_Flash_GetVersion(void)
{
}
ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities(void)
{
}
int32_t ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)
{
}
int32_t ARM_Flash_Uninitialize(void)
{
}
int32_t ARM_Flash_PowerControl(ARM_POWER_STATE state)
{
switch (state)
{
case ARM_POWER_OFF:
break;
case ARM_POWER_LOW:
break;
case ARM_POWER_FULL:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
int32_t ARM_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt)
{
}
int32_t ARM_Flash_ProgramData(uint32_t addr, const void *data, uint32_t cnt)
{
}
int32_t ARM_Flash_EraseSector(uint32_t addr)
{
}
int32_t ARM_Flash_EraseChip(void)
{
}
ARM_FLASH_STATUS ARM_Flash_GetStatus(void)
{
}
ARM_FLASH_INFO * ARM_Flash_GetInfo(void)
{
}
void ARM_Flash_SignalEvent(uint32_t event)
{
}
// End Flash Interface
ARM_DRIVER_FLASH Driver_FLASH = {
ARM_Flash_GetVersion,
ARM_Flash_GetCapabilities,
ARM_Flash_Initialize,
ARM_Flash_Uninitialize,
ARM_Flash_PowerControl,
ARM_Flash_ReadData,
ARM_Flash_ProgramData,
ARM_Flash_EraseSector,
ARM_Flash_EraseChip,
ARM_Flash_GetStatus,
ARM_Flash_GetInfo
};

View File

@@ -0,0 +1,148 @@
/*
* Copyright (c) 2013-2016 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Driver_I2C.h"
#define ARM_I2C_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 0) /* driver version */
/* Driver Version */
static const ARM_DRIVER_VERSION DriverVersion = {
ARM_I2C_API_VERSION,
ARM_I2C_DRV_VERSION
};
/* Driver Capabilities */
static const ARM_I2C_CAPABILITIES DriverCapabilities = {
0 /* supports 10-bit addressing */
};
//
// Functions
//
ARM_DRIVER_VERSION ARM_I2C_GetVersion(void)
{
}
ARM_I2C_CAPABILITIES ARM_I2C_GetCapabilities(void)
{
}
int32_t ARM_I2C_Initialize(ARM_I2C_SignalEvent_t cb_event)
{
}
int32_t ARM_I2C_Uninitialize(void)
{
}
int32_t ARM_I2C_PowerControl(ARM_POWER_STATE state)
{
switch (state)
{
case ARM_POWER_OFF:
break;
case ARM_POWER_LOW:
break;
case ARM_POWER_FULL:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
int32_t ARM_I2C_MasterTransmit(uint32_t addr, const uint8_t *data, uint32_t num, bool xfer_pending)
{
}
int32_t ARM_I2C_MasterReceive(uint32_t addr, uint8_t *data, uint32_t num, bool xfer_pending)
{
}
int32_t ARM_I2C_SlaveTransmit(const uint8_t *data, uint32_t num)
{
}
int32_t ARM_I2C_SlaveReceive(uint8_t *data, uint32_t num)
{
}
int32_t ARM_I2C_GetDataCount(void)
{
}
int32_t ARM_I2C_Control(uint32_t control, uint32_t arg)
{
switch (control)
{
case ARM_I2C_OWN_ADDRESS:
break;
case ARM_I2C_BUS_SPEED:
switch (arg)
{
case ARM_I2C_BUS_SPEED_STANDARD:
break;
case ARM_I2C_BUS_SPEED_FAST:
break;
case ARM_I2C_BUS_SPEED_FAST_PLUS:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
break;
case ARM_I2C_BUS_CLEAR:
break;
case ARM_I2C_ABORT_TRANSFER:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
ARM_I2C_STATUS ARM_I2C_GetStatus(void)
{
}
void ARM_I2C_SignalEvent(uint32_t event)
{
// function body
}
// End I2C Interface
ARM_DRIVER_I2C Driver_I2C = {
ARM_I2C_GetVersion,
ARM_I2C_GetCapabilities,
ARM_I2C_Initialize,
ARM_I2C_Uninitialize,
ARM_I2C_PowerControl,
ARM_I2C_MasterTransmit,
ARM_I2C_MasterReceive,
ARM_I2C_SlaveTransmit,
ARM_I2C_SlaveReceive,
ARM_I2C_GetDataCount,
ARM_I2C_Control,
ARM_I2C_GetStatus
};

View File

@@ -0,0 +1,219 @@
/*
* Copyright (c) 2013-2016 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Driver_MCI.h"
#define ARM_MCI_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 0) /* driver version */
/* Driver Version */
static const ARM_DRIVER_VERSION DriverVersion = {
ARM_MCI_API_VERSION,
ARM_MCI_DRV_VERSION
};
/* Driver Capabilities */
static const ARM_MCI_CAPABILITIES DriverCapabilities = {
0, /* cd_state */
0, /* cd_event */
0, /* vdd */
0, /* vdd_1v8 */
0, /* vccq */
0, /* vccq_1v8 */
0, /* vccq_1v2 */
1, /* data_width_4 */
1, /* data_width_8 */
0, /* data_width_4_ddr */
0, /* data_width_8_ddr */
0, /* high_speed */
0, /* uhs_signaling */
0, /* uhs_tuning */
0, /* uhs_sdr50 */
0, /* uhs_sdr104 */
0, /* uhs_ddr50 */
0, /* uhs_driver_type_a */
0, /* uhs_driver_type_c */
0, /* uhs_driver_type_d */
1, /* sdio_interrupt */
1, /* read_wait */
0, /* suspend_resume */
0, /* mmc_interrupt */
0, /* mmc_boot */
0, /* ccs */
0 /* ccs_timeout */
};
//
// Functions
//
ARM_DRIVER_VERSION ARM_MCI_GetVersion(void)
{
}
ARM_MCI_CAPABILITIES ARM_MCI_GetCapabilities(void)
{
}
int32_t ARM_MCI_Initialize(ARM_MCI_SignalEvent_t cb_event)
{
}
int32_t ARM_MCI_Uninitialize(void)
{
}
int32_t ARM_MCI_PowerControl(ARM_POWER_STATE state)
{
switch (state)
{
case ARM_POWER_OFF:
break;
case ARM_POWER_LOW:
break;
case ARM_POWER_FULL:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
int32_t ARM_MCI_CardPower(uint32_t voltage)
{
switch (voltage & ARM_MCI_POWER_VDD_Msk)
{
case ARM_MCI_POWER_VDD_OFF:
return ARM_DRIVER_OK;
case ARM_MCI_POWER_VDD_3V3:
return ARM_DRIVER_OK;
default:
break;
}
}
int32_t ARM_MCI_ReadCD(void)
{
}
int32_t ARM_MCI_ReadWP(void)
{
}
int32_t ARM_MCI_SendCommand(uint32_t cmd, uint32_t arg, uint32_t flags, uint32_t *response)
{
}
int32_t ARM_MCI_SetupTransfer(uint8_t *data, uint32_t block_count, uint32_t block_size, uint32_t mode)
{
}
int32_t ARM_MCI_AbortTransfer(void)
{
}
int32_t ARM_MCI_Control(uint32_t control, uint32_t arg)
{
switch (control)
{
case ARM_MCI_BUS_SPEED:
break;
case ARM_MCI_BUS_SPEED_MODE:
break;
case ARM_MCI_BUS_CMD_MODE:
/* Implement external pull-up control to support MMC cards in open-drain mode */
/* Default mode is push-pull and is configured in Driver_MCI0.Initialize() */
if (arg == ARM_MCI_BUS_CMD_PUSH_PULL)
{
/* Configure external circuit to work in push-pull mode */
}
else if (arg == ARM_MCI_BUS_CMD_OPEN_DRAIN)
{
/* Configure external circuit to work in open-drain mode */
}
else
{
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
break;
case ARM_MCI_BUS_DATA_WIDTH:
switch (arg)
{
case ARM_MCI_BUS_DATA_WIDTH_1:
break;
case ARM_MCI_BUS_DATA_WIDTH_4:
break;
case ARM_MCI_BUS_DATA_WIDTH_8:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
break;
case ARM_MCI_CONTROL_RESET:
break;
case ARM_MCI_CONTROL_CLOCK_IDLE:
break;
case ARM_MCI_DATA_TIMEOUT:
break;
case ARM_MCI_MONITOR_SDIO_INTERRUPT:
break;
case ARM_MCI_CONTROL_READ_WAIT:
break;
case ARM_MCI_DRIVER_STRENGTH:
default: return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
ARM_MCI_STATUS ARM_MCI_GetStatus(void)
{
}
void ARM_MCI_SignalEvent(uint32_t event)
{
// function body
}
// End MCI Interface
ARM_DRIVER_MCI Driver_MCI = {
ARM_MCI_GetVersion,
ARM_MCI_GetCapabilities,
ARM_MCI_Initialize,
ARM_MCI_Uninitialize,
ARM_MCI_PowerControl,
ARM_MCI_CardPower,
ARM_MCI_ReadCD,
ARM_MCI_ReadWP,
ARM_MCI_SendCommand,
ARM_MCI_SetupTransfer,
ARM_MCI_AbortTransfer,
ARM_MCI_Control,
ARM_MCI_GetStatus
};

View File

@@ -0,0 +1,125 @@
/*
* Copyright (c) 2013-2016 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Driver_SAI.h"
#define ARM_SAI_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0) /* driver version */
/* Driver Version */
static const ARM_DRIVER_VERSION DriverVersion = {
ARM_SAI_API_VERSION,
ARM_SAI_DRV_VERSION
};
/* Driver Capabilities */
static const ARM_SAI_CAPABILITIES DriverCapabilities = {
1, /* supports asynchronous Transmit/Receive */
0, /* supports synchronous Transmit/Receive */
0, /* supports user defined Protocol */
1, /* supports I2S Protocol */
0, /* supports MSB/LSB justified Protocol */
0, /* supports PCM short/long frame Protocol */
0, /* supports AC'97 Protocol */
0, /* supports Mono mode */
0, /* supports Companding */
0, /* supports MCLK (Master Clock) pin */
0 /* supports Frame error event: \ref ARM_SAI_EVENT_FRAME_ERROR */
};
//
// Functions
//
ARM_DRIVER_VERSION ARM_SAI_GetVersion (void)
{
}
ARM_SAI_CAPABILITIES ARM_SAI_GetCapabilities (void)
{
}
int32_t ARM_SAI_Initialize (ARM_SAI_SignalEvent_t cb_event)
{
}
int32_t ARM_SAI_Uninitialize (void)
{
}
int32_t ARM_SAI_PowerControl (ARM_POWER_STATE state)
{
switch (state)
{
case ARM_POWER_OFF:
break;
case ARM_POWER_LOW:
break;
case ARM_POWER_FULL:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
int32_t ARM_SAI_Send (const void *data, uint32_t num)
{
}
int32_t ARM_SAI_Receive (void *data, uint32_t num)
{
}
uint32_t ARM_SAI_GetTxCount (void)
{
}
uint32_t ARM_SAI_GetRxCount (void)
{
}
int32_t ARM_SAI_Control (uint32_t control, uint32_t arg1, uint32_t arg2)
{
}
ARM_SAI_STATUS ARM_SAI_GetStatus (void)
{
}
void ARM_SAI_SignalEvent(uint32_t event)
{
// function body
}
// End SAI Interface
ARM_DRIVER_SAI Driver_SAI = {
ARM_SAI_GetVersion,
ARM_SAI_GetCapabilities,
ARM_SAI_Initialize,
ARM_SAI_Uninitialize,
ARM_SAI_PowerControl,
ARM_SAI_Send,
ARM_SAI_Receive,
ARM_SAI_GetTxCount,
ARM_SAI_GetRxCount,
ARM_SAI_Control,
ARM_SAI_GetStatus
};

View File

@@ -0,0 +1,151 @@
/*
* Copyright (c) 2013-2016 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Driver_SPI.h"
#define ARM_SPI_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 0) /* driver version */
/* Driver Version */
static const ARM_DRIVER_VERSION DriverVersion = {
ARM_SPI_API_VERSION,
ARM_SPI_DRV_VERSION
};
/* Driver Capabilities */
static const ARM_SPI_CAPABILITIES DriverCapabilities = {
1, /* Simplex Mode (Master and Slave) */
1, /* TI Synchronous Serial Interface */
1, /* Microwire Interface */
0 /* Signal Mode Fault event: \ref ARM_SPI_EVENT_MODE_FAULT */
};
//
// Functions
//
ARM_DRIVER_VERSION ARM_SPI_GetVersion(void)
{
}
ARM_SPI_CAPABILITIES ARM_SPI_GetCapabilities(void)
{
}
int32_t ARM_SPI_Initialize(ARM_SPI_SignalEvent_t cb_event)
{
}
int32_t ARM_SPI_Uninitialize(void)
{
}
int32_t ARM_SPI_PowerControl(ARM_POWER_STATE state)
{
switch (state)
{
case ARM_POWER_OFF:
break;
case ARM_POWER_LOW:
break;
case ARM_POWER_FULL:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
int32_t ARM_SPI_Send(const void *data, uint32_t num)
{
}
int32_t ARM_SPI_Receive(void *data, uint32_t num)
{
}
int32_t ARM_SPI_Transfer(const void *data_out, void *data_in, uint32_t num)
{
}
uint32_t ARM_SPI_GetDataCount(void)
{
}
int32_t ARM_SPI_Control(uint32_t control, uint32_t arg)
{
switch (control & ARM_SPI_CONTROL_Msk)
{
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
case ARM_SPI_MODE_INACTIVE: // SPI Inactive
return ARM_DRIVER_OK;
case ARM_SPI_MODE_MASTER: // SPI Master (Output on MOSI, Input on MISO); arg = Bus Speed in bps
break;
case ARM_SPI_MODE_SLAVE: // SPI Slave (Output on MISO, Input on MOSI)
break;
case ARM_SPI_MODE_MASTER_SIMPLEX: // SPI Master (Output/Input on MOSI); arg = Bus Speed in bps
case ARM_SPI_MODE_SLAVE_SIMPLEX: // SPI Slave (Output/Input on MISO)
return ARM_SPI_ERROR_MODE;
case ARM_SPI_SET_BUS_SPEED: // Set Bus Speed in bps; arg = value
break;
case ARM_SPI_GET_BUS_SPEED: // Get Bus Speed in bps
break;
case ARM_SPI_SET_DEFAULT_TX_VALUE: // Set default Transmit value; arg = value
break;
case ARM_SPI_CONTROL_SS: // Control Slave Select; arg = 0:inactive, 1:active
break;
case ARM_SPI_ABORT_TRANSFER: // Abort current data transfer
break;
}
}
ARM_SPI_STATUS ARM_SPI_GetStatus(void)
{
}
void ARM_SPI_SignalEvent(uint32_t event)
{
// function body
}
// End SPI Interface
ARM_DRIVER_SPI Driver_SPI = {
ARM_SPI_GetVersion,
ARM_SPI_GetCapabilities,
ARM_SPI_Initialize,
ARM_SPI_Uninitialize,
ARM_SPI_PowerControl,
ARM_SPI_Send,
ARM_SPI_Receive,
ARM_SPI_Transfer,
ARM_SPI_GetDataCount,
ARM_SPI_Control,
ARM_SPI_GetStatus
};

View File

@@ -0,0 +1,115 @@
/*
* Copyright (c) 2013-2016 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Driver_Storage.h"
#define ARM_STORAGE_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0) /* driver version */
/* Driver Version */
static const ARM_DRIVER_VERSION DriverVersion = {
ARM_STORAGE_API_VERSION,
ARM_STORAGE_DRV_VERSION
};
/* Driver Capabilities */
static const ARM_STORAGE_CAPABILITIES DriverCapabilities = {
1, /* Asynchronous Mode */
1, /* Supports EraseAll operation */
0 /* Reserved */
};
//
// Functions
//
ARM_DRIVER_VERSION ARM_Storage_GetVersion (void) {
}
ARM_STORAGE_CAPABILITIES ARM_Storage_GetCapabilities (void) {
}
int32_t ARM_Storage_Initialize (ARM_Storage_Callback_t callback) {
}
int32_t ARM_Storage_Uninitialize (void) {
}
int32_t ARM_Storage_PowerControl (ARM_POWER_STATE state)
{
switch (state)
{
case ARM_POWER_OFF:
break;
case ARM_POWER_LOW:
break;
case ARM_POWER_FULL:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
int32_t ARM_Storage_ReadData (uint64_t addr, void *data, uint32_t size) {
}
int32_t ARM_Storage_ProgramData (uint64_t addr, const void *data, uint32_t size) {
}
int32_t ARM_Storage_Erase (uint64_t addr, uint32_t size) {
}
int32_t ARM_Storage_EraseAll (void) {
}
ARM_STORAGE_STATUS ARM_Storage_GetStatus (void) {
}
int32_t ARM_Storage_GetInfo (ARM_STORAGE_INFO *info) {
}
uint32_t ARM_Storage_ResolveAddress(uint64_t addr) {
}
int32_t ARM_Storage_GetNextBlock(const ARM_STORAGE_BLOCK* prev_block, ARM_STORAGE_BLOCK *next_block) {
}
int32_t ARM_Storage_GetBlock(uint64_t addr, ARM_STORAGE_BLOCK *block) {
}
// End Storage Interface
ARM_DRIVER_STORAGE Driver_STORAGE = {
ARM_Storage_GetVersion,
ARM_Storage_GetCapabilities,
ARM_Storage_Initialize,
ARM_Storage_Uninitialize,
ARM_Storage_PowerControl,
ARM_Storage_ReadData,
ARM_Storage_ProgramData,
ARM_Storage_Erase,
ARM_Storage_EraseAll,
ARM_Storage_GetStatus,
ARM_Storage_GetInfo,
ARM_Storage_ResolveAddress,
ARM_Storage_GetNextBlock,
ARM_Storage_GetBlock
};

View File

@@ -0,0 +1,150 @@
/*
* Copyright (c) 2013-2016 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Driver_USART.h"
#define ARM_USART_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 0) /* driver version */
/* Driver Version */
static const ARM_DRIVER_VERSION DriverVersion = {
ARM_USART_API_VERSION,
ARM_USART_DRV_VERSION
};
/* Driver Capabilities */
static const ARM_USART_CAPABILITIES DriverCapabilities = {
1, /* supports UART (Asynchronous) mode */
0, /* supports Synchronous Master mode */
0, /* supports Synchronous Slave mode */
0, /* supports UART Single-wire mode */
0, /* supports UART IrDA mode */
0, /* supports UART Smart Card mode */
0, /* Smart Card Clock generator available */
0, /* RTS Flow Control available */
0, /* CTS Flow Control available */
0, /* Transmit completed event: \ref ARM_USART_EVENT_TX_COMPLETE */
0, /* Signal receive character timeout event: \ref ARM_USART_EVENT_RX_TIMEOUT */
0, /* RTS Line: 0=not available, 1=available */
0, /* CTS Line: 0=not available, 1=available */
0, /* DTR Line: 0=not available, 1=available */
0, /* DSR Line: 0=not available, 1=available */
0, /* DCD Line: 0=not available, 1=available */
0, /* RI Line: 0=not available, 1=available */
0, /* Signal CTS change event: \ref ARM_USART_EVENT_CTS */
0, /* Signal DSR change event: \ref ARM_USART_EVENT_DSR */
0, /* Signal DCD change event: \ref ARM_USART_EVENT_DCD */
0 /* Signal RI change event: \ref ARM_USART_EVENT_RI */
};
//
// Functions
//
ARM_DRIVER_VERSION ARM_USART_GetVersion(void)
{
}
ARM_USART_CAPABILITIES ARM_USART_GetCapabilities(void)
{
}
int32_t ARM_USART_Initialize(ARM_USART_SignalEvent_t cb_event)
{
}
int32_t ARM_USART_Uninitialize(void)
{
}
int32_t ARM_USART_PowerControl(ARM_POWER_STATE state)
{
switch (state)
{
case ARM_POWER_OFF:
break;
case ARM_POWER_LOW:
break;
case ARM_POWER_FULL:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
int32_t ARM_USART_Send(const void *data, uint32_t num)
{
}
int32_t ARM_USART_Receive(void *data, uint32_t num)
{
}
int32_t ARM_USART_Transfer(const void *data_out, void *data_in, uint32_t num)
{
}
uint32_t ARM_USART_GetTxCount(void)
{
}
uint32_t ARM_USART_GetRxCount(void)
{
}
int32_t ARM_USART_Control(uint32_t control, uint32_t arg)
{
}
ARM_USART_STATUS ARM_USART_GetStatus(void)
{
}
int32_t ARM_USART_SetModemControl(ARM_USART_MODEM_CONTROL control)
{
}
ARM_USART_MODEM_STATUS ARM_USART_GetModemStatus(void)
{
}
void ARM_USART_SignalEvent(uint32_t event)
{
// function body
}
// End USART Interface
ARM_DRIVER_USART Driver_USART = {
ARM_USART_GetVersion,
ARM_USART_GetCapabilities,
ARM_USART_Initialize,
ARM_USART_Uninitialize,
ARM_USART_PowerControl,
ARM_USART_Send,
ARM_USART_Receive,
ARM_USART_Transfer,
ARM_USART_GetTxCount,
ARM_USART_GetRxCount,
ARM_USART_Control,
ARM_USART_GetStatus,
ARM_USART_SetModemControl,
ARM_USART_GetModemStatus
};

View File

@@ -0,0 +1,161 @@
/*
* Copyright (c) 2013-2016 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Driver_USBD.h"
#define ARM_USBD_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 0) /* driver version */
/* Driver Version */
static const ARM_DRIVER_VERSION usbd_driver_version = {
ARM_USBD_API_VERSION,
ARM_USBD_DRV_VERSION
};
/* Driver Capabilities */
static const ARM_USBD_CAPABILITIES usbd_driver_capabilities = {
0, /* vbus_detection */
0, /* event_vbus_on */
0 /* event_vbus_off */
};
//
// Functions
//
ARM_DRIVER_VERSION ARM_USBD_GetVersion(void)
{
}
ARM_USBD_CAPABILITIES ARM_USBD_GetCapabilities(void)
{
}
int32_t ARM_USBD_Initialize(ARM_USBD_SignalDeviceEvent_t cb_device_event,
ARM_USBD_SignalEndpointEvent_t cb_endpoint_event)
{
}
int32_t ARM_USBD_Uninitialize(void)
{
}
int32_t ARM_USBD_PowerControl(ARM_POWER_STATE state)
{
switch (state)
{
case ARM_POWER_OFF:
break;
case ARM_POWER_LOW:
break;
case ARM_POWER_FULL:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
int32_t ARM_USBD_DeviceConnect(void)
{
}
int32_t ARM_USBD_DeviceDisconnect(void)
{
}
ARM_USBD_STATE ARM_USBD_DeviceGetState(void)
{
}
int32_t ARM_USBD_DeviceRemoteWakeup(void)
{
}
int32_t ARM_USBD_DeviceSetAddress(uint8_t dev_addr)
{
}
int32_t ARM_USBD_ReadSetupPacket(uint8_t *setup)
{
}
int32_t ARM_USBD_EndpointConfigure(uint8_t ep_addr,
uint8_t ep_type,
uint16_t ep_max_packet_size)
{
}
int32_t ARM_USBD_EndpointUnconfigure(uint8_t ep_addr)
{
}
int32_t ARM_USBD_EndpointStall(uint8_t ep_addr, bool stall)
{
}
int32_t ARM_USBD_EndpointTransfer(uint8_t ep_addr, uint8_t *data, uint32_t num)
{
}
uint32_t ARM_USBD_EndpointTransferGetResult(uint8_t ep_addr)
{
}
int32_t ARM_USBD_EndpointTransferAbort(uint8_t ep_addr)
{
}
uint16_t ARM_USBD_GetFrameNumber(void)
{
}
void ARM_USBD_SignalDeviceEvent(uint32_t event)
{
// function body
}
void ARM_USBD_SignalEndpointEvent(uint8_t ep_addr, uint32_t ep_event)
{
// function body
}
// End USBD Interface
ARM_DRIVER_USBD Driver_USBD =
{
ARM_USBD_GetVersion,
ARM_USBD_GetCapabilities,
ARM_USBD_Initialize,
ARM_USBD_Uninitialize,
ARM_USBD_PowerControl,
ARM_USBD_DeviceConnect,
ARM_USBD_DeviceDisconnect,
ARM_USBD_DeviceGetState,
ARM_USBD_DeviceRemoteWakeup,
ARM_USBD_DeviceSetAddress,
ARM_USBD_ReadSetupPacket,
ARM_USBD_EndpointConfigure,
ARM_USBD_EndpointUnconfigure,
ARM_USBD_EndpointStall,
ARM_USBD_EndpointTransfer,
ARM_USBD_EndpointTransferGetResult,
ARM_USBD_EndpointTransferAbort,
ARM_USBD_GetFrameNumber
};

View File

@@ -0,0 +1,225 @@
/*
* Copyright (c) 2013-2016 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Driver_USBH.h"
/* USB Host Driver */
#define ARM_USBH_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 0) /* driver version */
/* Driver Version */
static const ARM_DRIVER_VERSION usbh_driver_version = {
ARM_USBH_API_VERSION,
ARM_USBH_DRV_VERSION
};
/* Driver Capabilities */
static const ARM_USBH_CAPABILITIES usbd_driver_capabilities = {
0x0001, /* Root HUB available Ports Mask */
0, /* Automatic SPLIT packet handling */
0, /* Signal Connect event */
0, /* Signal Disconnect event */
0 /* Signal Overcurrent event */
};
//
// Functions
//
ARM_DRIVER_VERSION ARM_USBH_GetVersion(void)
{
}
ARM_USBH_CAPABILITIES ARM_USBH_GetCapabilities(void)
{
}
int32_t ARM_USBH_Initialize(ARM_USBH_SignalPortEvent_t cb_port_event,
ARM_USBH_SignalEndpointEvent_t cb_endpoint_event)
{
}
int32_t ARM_USBH_Uninitialize(void)
{
}
int32_t ARM_USBH_PowerControl(ARM_POWER_STATE state)
{
switch (state)
{
case ARM_POWER_OFF:
break;
case ARM_POWER_LOW:
break;
case ARM_POWER_FULL:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
int32_t ARM_USBH_PortVbusOnOff(uint8_t port, bool vbus)
{
}
int32_t ARM_USBH_PortReset(uint8_t port)
{
}
int32_t ARM_USBH_PortSuspend(uint8_t port)
{
}
int32_t ARM_USBH_PortResume(uint8_t port)
{
}
ARM_USBH_PORT_STATE ARM_USBH_PortGetState(uint8_t port)
{
}
ARM_USBH_EP_HANDLE ARM_USBH_EndpointCreate(uint8_t dev_addr,
uint8_t dev_speed,
uint8_t hub_addr,
uint8_t hub_port,
uint8_t ep_addr,
uint8_t ep_type,
uint16_t ep_max_packet_size,
uint8_t ep_interval)
{
}
int32_t ARM_USBH_EndpointModify(ARM_USBH_EP_HANDLE ep_hndl,
uint8_t dev_addr,
uint8_t dev_speed,
uint8_t hub_addr,
uint8_t hub_port,
uint16_t ep_max_packet_size)
{
}
int32_t ARM_USBH_EndpointDelete(ARM_USBH_EP_HANDLE ep_hndl)
{
}
int32_t ARM_USBH_EndpointReset(ARM_USBH_EP_HANDLE ep_hndl)
{
}
int32_t ARM_USBH_EndpointTransfer(ARM_USBH_EP_HANDLE ep_hndl,
uint32_t packet,
uint8_t *data,
uint32_t num)
{
}
uint32_t ARM_USBH_EndpointTransferGetResult(ARM_USBH_EP_HANDLE ep_hndl)
{
}
int32_t ARM_USBH_EndpointTransferAbort(ARM_USBH_EP_HANDLE ep_hndl)
{
}
uint16_t ARM_USBH_GetFrameNumber(void)
{
}
void ARM_USBH_SignalPortEvent(uint8_t port, uint32_t event)
{
// function body
}
void ARM_USBH_SignalEndpointEvent(ARM_USBH_EP_HANDLE ep_hndl, uint32_t event)
{
// function body
}
/* USB Host HCI (OHCI/EHCI) Driver */
/* Driver Version */
static const ARM_DRIVER_VERSION usbh_hci_driver_version = {
ARM_USBH_API_VERSION,
ARM_USBH_DRV_VERSION
};
/* Driver Capabilities */
static const ARM_USBH_HCI_CAPABILITIES usbh_hci_driver_capabilities = {
0x0001 /* Root HUB available Ports Mask */
};
//
// Functions
//
ARM_DRIVER_VERSION ARM_USBH_HCI_GetVersion(void)
{
}
ARM_USBH_HCI_CAPABILITIES ARM_USBH_HCI_GetCapabilities(void)
{
}
int32_t ARM_USBH_HCI_Initialize(ARM_USBH_HCI_Interrupt_t cb_interrupt)
{
}
int32_t ARM_USBH_HCI_Uninitialize(void)
{
}
int32_t ARM_USBH_HCI_PowerControl(ARM_POWER_STATE state)
{
switch (state)
{
case ARM_POWER_OFF:
break;
case ARM_POWER_LOW:
break;
case ARM_POWER_FULL:
break;
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
}
int32_t ARM_USBH_HCI_PortVbusOnOff(uint8_t port, bool vbus)
{
}
void ARM_USBH_HCI_Interrupt(void)
{
// function body
}
// End USBH Interface
ARM_DRIVER_USBH_HCI Driver_USBH_HCI = {
ARM_USBH_HCI_GetVersion,
ARM_USBH_HCI_GetCapabilities,
ARM_USBH_HCI_Initialize,
ARM_USBH_HCI_Uninitialize,
ARM_USBH_HCI_PowerControl,
ARM_USBH_HCI_PortVbusOnOff
};

View File

@@ -0,0 +1,377 @@
/*
* Copyright (c) 2015-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Date: 2. Feb 2017
* $Revision: V1.1
*
* Project: CAN (Controller Area Network) Driver definitions
*/
/* History:
* Version 1.1
* ARM_CAN_STATUS made volatile
* Version 1.0
* Initial release
*/
#ifndef DRIVER_CAN_H_
#define DRIVER_CAN_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include "Driver_Common.h"
#define ARM_CAN_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1,1) /* API version */
/****** CAN Bitrate selection codes *****/
typedef enum _ARM_CAN_BITRATE_SELECT {
ARM_CAN_BITRATE_NOMINAL, ///< Select nominal (flexible data-rate arbitration) bitrate
ARM_CAN_BITRATE_FD_DATA ///< Select flexible data-rate data bitrate
} ARM_CAN_BITRATE_SELECT;
/****** CAN Bit Propagation Segment codes (PROP_SEG) *****/
#define ARM_CAN_BIT_PROP_SEG_Pos 0UL ///< bits 7..0
#define ARM_CAN_BIT_PROP_SEG_Msk (0xFFUL << ARM_CAN_BIT_PROP_SEG_Pos)
#define ARM_CAN_BIT_PROP_SEG(x) (((x) << ARM_CAN_BIT_PROP_SEG_Pos) & ARM_CAN_BIT_PROP_SEG_Msk)
/****** CAN Bit Phase Buffer Segment 1 (PHASE_SEG1) codes *****/
#define ARM_CAN_BIT_PHASE_SEG1_Pos 8UL ///< bits 15..8
#define ARM_CAN_BIT_PHASE_SEG1_Msk (0xFFUL << ARM_CAN_BIT_PHASE_SEG1_Pos)
#define ARM_CAN_BIT_PHASE_SEG1(x) (((x) << ARM_CAN_BIT_PHASE_SEG1_Pos) & ARM_CAN_BIT_PHASE_SEG1_Msk)
/****** CAN Bit Phase Buffer Segment 2 (PHASE_SEG2) codes *****/
#define ARM_CAN_BIT_PHASE_SEG2_Pos 16UL ///< bits 23..16
#define ARM_CAN_BIT_PHASE_SEG2_Msk (0xFFUL << ARM_CAN_BIT_PHASE_SEG2_Pos)
#define ARM_CAN_BIT_PHASE_SEG2(x) (((x) << ARM_CAN_BIT_PHASE_SEG2_Pos) & ARM_CAN_BIT_PHASE_SEG2_Msk)
/****** CAN Bit (Re)Synchronization Jump Width Segment (SJW) *****/
#define ARM_CAN_BIT_SJW_Pos 24UL ///< bits 28..24
#define ARM_CAN_BIT_SJW_Msk (0x1FUL << ARM_CAN_BIT_SJW_Pos)
#define ARM_CAN_BIT_SJW(x) (((x) << ARM_CAN_BIT_SJW_Pos) & ARM_CAN_BIT_SJW_Msk)
/****** CAN Mode codes *****/
typedef enum _ARM_CAN_MODE {
ARM_CAN_MODE_INITIALIZATION, ///< Initialization mode
ARM_CAN_MODE_NORMAL, ///< Normal operation mode
ARM_CAN_MODE_RESTRICTED, ///< Restricted operation mode
ARM_CAN_MODE_MONITOR, ///< Bus monitoring mode
ARM_CAN_MODE_LOOPBACK_INTERNAL, ///< Loopback internal mode
ARM_CAN_MODE_LOOPBACK_EXTERNAL ///< Loopback external mode
} ARM_CAN_MODE;
/****** CAN Filter Operation codes *****/
typedef enum _ARM_CAN_FILTER_OPERATION {
ARM_CAN_FILTER_ID_EXACT_ADD, ///< Add exact id filter
ARM_CAN_FILTER_ID_EXACT_REMOVE, ///< Remove exact id filter
ARM_CAN_FILTER_ID_RANGE_ADD, ///< Add range id filter
ARM_CAN_FILTER_ID_RANGE_REMOVE, ///< Remove range id filter
ARM_CAN_FILTER_ID_MASKABLE_ADD, ///< Add maskable id filter
ARM_CAN_FILTER_ID_MASKABLE_REMOVE ///< Remove maskable id filter
} ARM_CAN_FILTER_OPERATION;
/****** CAN Object Configuration codes *****/
typedef enum _ARM_CAN_OBJ_CONFIG {
ARM_CAN_OBJ_INACTIVE, ///< CAN object inactive
ARM_CAN_OBJ_TX, ///< CAN transmit object
ARM_CAN_OBJ_RX, ///< CAN receive object
ARM_CAN_OBJ_RX_RTR_TX_DATA, ///< CAN object that on RTR reception automatically transmits Data Frame
ARM_CAN_OBJ_TX_RTR_RX_DATA ///< CAN object that transmits RTR and automatically receives Data Frame
} ARM_CAN_OBJ_CONFIG;
/**
\brief CAN Object Capabilities
*/
typedef struct _ARM_CAN_OBJ_CAPABILITIES {
uint32_t tx : 1; ///< Object supports transmission
uint32_t rx : 1; ///< Object supports reception
uint32_t rx_rtr_tx_data : 1; ///< Object supports RTR reception and automatic Data Frame transmission
uint32_t tx_rtr_rx_data : 1; ///< Object supports RTR transmission and automatic Data Frame reception
uint32_t multiple_filters : 1; ///< Object allows assignment of multiple filters to it
uint32_t exact_filtering : 1; ///< Object supports exact identifier filtering
uint32_t range_filtering : 1; ///< Object supports range identifier filtering
uint32_t mask_filtering : 1; ///< Object supports mask identifier filtering
uint32_t message_depth : 8; ///< Number of messages buffers (FIFO) for that object
uint32_t reserved : 16; ///< Reserved (must be zero)
} ARM_CAN_OBJ_CAPABILITIES;
/****** CAN Control Function Operation codes *****/
#define ARM_CAN_CONTROL_Pos 0UL
#define ARM_CAN_CONTROL_Msk (0xFFUL << ARM_CAN_CONTROL_Pos)
#define ARM_CAN_SET_FD_MODE (1UL << ARM_CAN_CONTROL_Pos) ///< Set FD operation mode; arg: 0 = disable, 1 = enable
#define ARM_CAN_ABORT_MESSAGE_SEND (2UL << ARM_CAN_CONTROL_Pos) ///< Abort sending of CAN message; arg = object
#define ARM_CAN_CONTROL_RETRANSMISSION (3UL << ARM_CAN_CONTROL_Pos) ///< Enable/disable automatic retransmission; arg: 0 = disable, 1 = enable (default state)
#define ARM_CAN_SET_TRANSCEIVER_DELAY (4UL << ARM_CAN_CONTROL_Pos) ///< Set transceiver delay; arg = delay in time quanta
/****** CAN ID Frame Format codes *****/
#define ARM_CAN_ID_IDE_Pos 31UL
#define ARM_CAN_ID_IDE_Msk (1UL << ARM_CAN_ID_IDE_Pos)
/****** CAN Identifier encoding *****/
#define ARM_CAN_STANDARD_ID(id) (id & 0x000007FFUL) ///< CAN identifier in standard format (11-bits)
#define ARM_CAN_EXTENDED_ID(id) ((id & 0x1FFFFFFFUL) | ARM_CAN_ID_IDE_Msk)///< CAN identifier in extended format (29-bits)
/**
\brief CAN Message Information
*/
typedef struct _ARM_CAN_MSG_INFO {
uint32_t id; ///< CAN identifier with frame format specifier (bit 31)
uint32_t rtr : 1; ///< Remote transmission request frame
uint32_t edl : 1; ///< Flexible data-rate format extended data length
uint32_t brs : 1; ///< Flexible data-rate format with bitrate switch
uint32_t esi : 1; ///< Flexible data-rate format error state indicator
uint32_t dlc : 4; ///< Data length code
uint32_t reserved : 24;
} ARM_CAN_MSG_INFO;
/****** CAN specific error code *****/
#define ARM_CAN_INVALID_BITRATE_SELECT (ARM_DRIVER_ERROR_SPECIFIC - 1) ///< Bitrate selection not supported
#define ARM_CAN_INVALID_BITRATE (ARM_DRIVER_ERROR_SPECIFIC - 2) ///< Requested bitrate not supported
#define ARM_CAN_INVALID_BIT_PROP_SEG (ARM_DRIVER_ERROR_SPECIFIC - 3) ///< Propagation segment value not supported
#define ARM_CAN_INVALID_BIT_PHASE_SEG1 (ARM_DRIVER_ERROR_SPECIFIC - 4) ///< Phase segment 1 value not supported
#define ARM_CAN_INVALID_BIT_PHASE_SEG2 (ARM_DRIVER_ERROR_SPECIFIC - 5) ///< Phase segment 2 value not supported
#define ARM_CAN_INVALID_BIT_SJW (ARM_DRIVER_ERROR_SPECIFIC - 6) ///< SJW value not supported
#define ARM_CAN_NO_MESSAGE_AVAILABLE (ARM_DRIVER_ERROR_SPECIFIC - 7) ///< Message is not available
/****** CAN Status codes *****/
#define ARM_CAN_UNIT_STATE_INACTIVE (0U) ///< Unit state: Not active on bus (initialize or error bus off)
#define ARM_CAN_UNIT_STATE_ACTIVE (1U) ///< Unit state: Active on bus (can generate active error frame)
#define ARM_CAN_UNIT_STATE_PASSIVE (2U) ///< Unit state: Error passive (can not generate active error frame)
#define ARM_CAN_LEC_NO_ERROR (0U) ///< Last error code: No error
#define ARM_CAN_LEC_BIT_ERROR (1U) ///< Last error code: Bit error
#define ARM_CAN_LEC_STUFF_ERROR (2U) ///< Last error code: Bit stuffing error
#define ARM_CAN_LEC_CRC_ERROR (3U) ///< Last error code: CRC error
#define ARM_CAN_LEC_FORM_ERROR (4U) ///< Last error code: Illegal fixed-form bit
#define ARM_CAN_LEC_ACK_ERROR (5U) ///< Last error code: Acknowledgment error
/**
\brief CAN Status
*/
typedef volatile struct _ARM_CAN_STATUS {
uint32_t unit_state : 4; ///< Unit bus state
uint32_t last_error_code : 4; ///< Last error code
uint32_t tx_error_count : 8; ///< Transmitter error count
uint32_t rx_error_count : 8; ///< Receiver error count
uint32_t reserved : 8;
} ARM_CAN_STATUS;
/****** CAN Unit Event *****/
#define ARM_CAN_EVENT_UNIT_ACTIVE (1U) ///< Unit entered Error Active state
#define ARM_CAN_EVENT_UNIT_WARNING (2U) ///< Unit entered Error Warning state (one or both error counters >= 96)
#define ARM_CAN_EVENT_UNIT_PASSIVE (3U) ///< Unit entered Error Passive state
#define ARM_CAN_EVENT_UNIT_BUS_OFF (4U) ///< Unit entered bus off state
/****** CAN Send/Receive Event *****/
#define ARM_CAN_EVENT_SEND_COMPLETE (1UL << 0) ///< Send complete
#define ARM_CAN_EVENT_RECEIVE (1UL << 1) ///< Message received
#define ARM_CAN_EVENT_RECEIVE_OVERRUN (1UL << 2) ///< Received message overrun
// Function documentation
/**
\fn ARM_DRIVER_VERSION ARM_CAN_GetVersion (void)
\brief Get driver version.
\return \ref ARM_DRIVER_VERSION
\fn ARM_CAN_CAPABILITIES ARM_CAN_GetCapabilities (void)
\brief Get driver capabilities.
\return \ref ARM_CAN_CAPABILITIES
\fn int32_t ARM_CAN_Initialize (ARM_CAN_SignalUnitEvent_t cb_unit_event,
ARM_CAN_SignalObjectEvent_t cb_object_event)
\brief Initialize CAN interface and register signal (callback) functions.
\param[in] cb_unit_event Pointer to \ref ARM_CAN_SignalUnitEvent callback function
\param[in] cb_object_event Pointer to \ref ARM_CAN_SignalObjectEvent callback function
\return \ref execution_status
\fn int32_t ARM_CAN_Uninitialize (void)
\brief De-initialize CAN interface.
\return \ref execution_status
\fn int32_t ARM_CAN_PowerControl (ARM_POWER_STATE state)
\brief Control CAN interface power.
\param[in] state Power state
- \ref ARM_POWER_OFF : power off: no operation possible
- \ref ARM_POWER_LOW : low power mode: retain state, detect and signal wake-up events
- \ref ARM_POWER_FULL : power on: full operation at maximum performance
\return \ref execution_status
\fn uint32_t ARM_CAN_GetClock (void)
\brief Retrieve CAN base clock frequency.
\return base clock frequency
\fn int32_t ARM_CAN_SetBitrate (ARM_CAN_BITRATE_SELECT select, uint32_t bitrate, uint32_t bit_segments)
\brief Set bitrate for CAN interface.
\param[in] select Bitrate selection
- \ref ARM_CAN_BITRATE_NOMINAL : nominal (flexible data-rate arbitration) bitrate
- \ref ARM_CAN_BITRATE_FD_DATA : flexible data-rate data bitrate
\param[in] bitrate Bitrate
\param[in] bit_segments Bit segments settings
- \ref ARM_CAN_BIT_PROP_SEG(x) : number of time quanta for propagation time segment
- \ref ARM_CAN_BIT_PHASE_SEG1(x) : number of time quanta for phase buffer segment 1
- \ref ARM_CAN_BIT_PHASE_SEG2(x) : number of time quanta for phase buffer Segment 2
- \ref ARM_CAN_BIT_SJW(x) : number of time quanta for (re-)synchronization jump width
\return \ref execution_status
\fn int32_t ARM_CAN_SetMode (ARM_CAN_MODE mode)
\brief Set operating mode for CAN interface.
\param[in] mode Operating mode
- \ref ARM_CAN_MODE_INITIALIZATION : initialization mode
- \ref ARM_CAN_MODE_NORMAL : normal operation mode
- \ref ARM_CAN_MODE_RESTRICTED : restricted operation mode
- \ref ARM_CAN_MODE_MONITOR : bus monitoring mode
- \ref ARM_CAN_MODE_LOOPBACK_INTERNAL : loopback internal mode
- \ref ARM_CAN_MODE_LOOPBACK_EXTERNAL : loopback external mode
\return \ref execution_status
\fn ARM_CAN_OBJ_CAPABILITIES ARM_CAN_ObjectGetCapabilities (uint32_t obj_idx)
\brief Retrieve capabilities of an object.
\param[in] obj_idx Object index
\return \ref ARM_CAN_OBJ_CAPABILITIES
\fn int32_t ARM_CAN_ObjectSetFilter (uint32_t obj_idx, ARM_CAN_FILTER_OPERATION operation, uint32_t id, uint32_t arg)
\brief Add or remove filter for message reception.
\param[in] obj_idx Object index of object that filter should be or is assigned to
\param[in] operation Operation on filter
- \ref ARM_CAN_FILTER_ID_EXACT_ADD : add exact id filter
- \ref ARM_CAN_FILTER_ID_EXACT_REMOVE : remove exact id filter
- \ref ARM_CAN_FILTER_ID_RANGE_ADD : add range id filter
- \ref ARM_CAN_FILTER_ID_RANGE_REMOVE : remove range id filter
- \ref ARM_CAN_FILTER_ID_MASKABLE_ADD : add maskable id filter
- \ref ARM_CAN_FILTER_ID_MASKABLE_REMOVE : remove maskable id filter
\param[in] id ID or start of ID range (depending on filter type)
\param[in] arg Mask or end of ID range (depending on filter type)
\return \ref execution_status
\fn int32_t ARM_CAN_ObjectConfigure (uint32_t obj_idx, ARM_CAN_OBJ_CONFIG obj_cfg)
\brief Configure object.
\param[in] obj_idx Object index
\param[in] obj_cfg Object configuration state
- \ref ARM_CAN_OBJ_INACTIVE : deactivate object
- \ref ARM_CAN_OBJ_RX : configure object for reception
- \ref ARM_CAN_OBJ_TX : configure object for transmission
- \ref ARM_CAN_OBJ_RX_RTR_TX_DATA : configure object that on RTR reception automatically transmits Data Frame
- \ref ARM_CAN_OBJ_TX_RTR_RX_DATA : configure object that transmits RTR and automatically receives Data Frame
\return \ref execution_status
\fn int32_t ARM_CAN_MessageSend (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, const uint8_t *data, uint8_t size)
\brief Send message on CAN bus.
\param[in] obj_idx Object index
\param[in] msg_info Pointer to CAN message information
\param[in] data Pointer to data buffer
\param[in] size Number of data bytes to send
\return value >= 0 number of data bytes accepted to send
\return value < 0 \ref execution_status
\fn int32_t ARM_CAN_MessageRead (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, uint8_t *data, uint8_t size)
\brief Read message received on CAN bus.
\param[in] obj_idx Object index
\param[out] msg_info Pointer to read CAN message information
\param[out] data Pointer to data buffer for read data
\param[in] size Maximum number of data bytes to read
\return value >= 0 number of data bytes read
\return value < 0 \ref execution_status
\fn int32_t ARM_CAN_Control (uint32_t control, uint32_t arg)
\brief Control CAN interface.
\param[in] control Operation
- \ref ARM_CAN_SET_FD_MODE : set FD operation mode
- \ref ARM_CAN_ABORT_MESSAGE_SEND : abort sending of CAN message
- \ref ARM_CAN_CONTROL_RETRANSMISSION : enable/disable automatic retransmission
- \ref ARM_CAN_SET_TRANSCEIVER_DELAY : set transceiver delay
\param[in] arg Argument of operation
\return \ref execution_status
\fn ARM_CAN_STATUS ARM_CAN_GetStatus (void)
\brief Get CAN status.
\return CAN status \ref ARM_CAN_STATUS
\fn void ARM_CAN_SignalUnitEvent (uint32_t event)
\brief Signal CAN unit event.
\param[in] event \ref CAN_unit_events
\return none
\fn void ARM_CAN_SignalObjectEvent (uint32_t obj_idx, uint32_t event)
\brief Signal CAN object event.
\param[in] obj_idx Object index
\param[in] event \ref CAN_events
\return none
*/
typedef void (*ARM_CAN_SignalUnitEvent_t) (uint32_t event); ///< Pointer to \ref ARM_CAN_SignalUnitEvent : Signal CAN Unit Event.
typedef void (*ARM_CAN_SignalObjectEvent_t) (uint32_t obj_idx, uint32_t event); ///< Pointer to \ref ARM_CAN_SignalObjectEvent : Signal CAN Object Event.
/**
\brief CAN Device Driver Capabilities.
*/
typedef struct _ARM_CAN_CAPABILITIES {
uint32_t num_objects : 8; ///< Number of \ref can_objects available
uint32_t reentrant_operation : 1; ///< Support for reentrant calls to \ref ARM_CAN_MessageSend, \ref ARM_CAN_MessageRead, \ref ARM_CAN_ObjectConfigure and abort message sending used by \ref ARM_CAN_Control
uint32_t fd_mode : 1; ///< Support for CAN with flexible data-rate mode (CAN_FD) (set by \ref ARM_CAN_Control)
uint32_t restricted_mode : 1; ///< Support for restricted operation mode (set by \ref ARM_CAN_SetMode)
uint32_t monitor_mode : 1; ///< Support for bus monitoring mode (set by \ref ARM_CAN_SetMode)
uint32_t internal_loopback : 1; ///< Support for internal loopback mode (set by \ref ARM_CAN_SetMode)
uint32_t external_loopback : 1; ///< Support for external loopback mode (set by \ref ARM_CAN_SetMode)
uint32_t reserved : 18; ///< Reserved (must be zero)
} ARM_CAN_CAPABILITIES;
/**
\brief Access structure of the CAN Driver.
*/
typedef struct _ARM_DRIVER_CAN {
ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_CAN_GetVersion : Get driver version.
ARM_CAN_CAPABILITIES (*GetCapabilities) (void); ///< Pointer to \ref ARM_CAN_GetCapabilities : Get driver capabilities.
int32_t (*Initialize) (ARM_CAN_SignalUnitEvent_t cb_unit_event,
ARM_CAN_SignalObjectEvent_t cb_object_event); ///< Pointer to \ref ARM_CAN_Initialize : Initialize CAN interface.
int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_CAN_Uninitialize : De-initialize CAN interface.
int32_t (*PowerControl) (ARM_POWER_STATE state); ///< Pointer to \ref ARM_CAN_PowerControl : Control CAN interface power.
uint32_t (*GetClock) (void); ///< Pointer to \ref ARM_CAN_GetClock : Retrieve CAN base clock frequency.
int32_t (*SetBitrate) (ARM_CAN_BITRATE_SELECT select,
uint32_t bitrate,
uint32_t bit_segments); ///< Pointer to \ref ARM_CAN_SetBitrate : Set bitrate for CAN interface.
int32_t (*SetMode) (ARM_CAN_MODE mode); ///< Pointer to \ref ARM_CAN_SetMode : Set operating mode for CAN interface.
ARM_CAN_OBJ_CAPABILITIES (*ObjectGetCapabilities) (uint32_t obj_idx); ///< Pointer to \ref ARM_CAN_ObjectGetCapabilities : Retrieve capabilities of an object.
int32_t (*ObjectSetFilter) (uint32_t obj_idx,
ARM_CAN_FILTER_OPERATION operation,
uint32_t id,
uint32_t arg); ///< Pointer to \ref ARM_CAN_ObjectSetFilter : Add or remove filter for message reception.
int32_t (*ObjectConfigure) (uint32_t obj_idx,
ARM_CAN_OBJ_CONFIG obj_cfg); ///< Pointer to \ref ARM_CAN_ObjectConfigure : Configure object.
int32_t (*MessageSend) (uint32_t obj_idx,
ARM_CAN_MSG_INFO *msg_info,
const uint8_t *data,
uint8_t size); ///< Pointer to \ref ARM_CAN_MessageSend : Send message on CAN bus.
int32_t (*MessageRead) (uint32_t obj_idx,
ARM_CAN_MSG_INFO *msg_info,
uint8_t *data,
uint8_t size); ///< Pointer to \ref ARM_CAN_MessageRead : Read message received on CAN bus.
int32_t (*Control) (uint32_t control,
uint32_t arg); ///< Pointer to \ref ARM_CAN_Control : Control CAN interface.
ARM_CAN_STATUS (*GetStatus) (void); ///< Pointer to \ref ARM_CAN_GetStatus : Get CAN status.
} const ARM_DRIVER_CAN;
#ifdef __cplusplus
}
#endif
#endif /* DRIVER_CAN_H_ */

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Date: 2. Feb 2017
* $Revision: V2.0
*
* Project: Common Driver definitions
*/
/* History:
* Version 2.0
* Changed prefix ARM_DRV -> ARM_DRIVER
* Added General return codes definitions
* Version 1.10
* Namespace prefix ARM_ added
* Version 1.00
* Initial release
*/
#ifndef DRIVER_COMMON_H_
#define DRIVER_COMMON_H_
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#define ARM_DRIVER_VERSION_MAJOR_MINOR(major,minor) (((major) << 8) | (minor))
/**
\brief Driver Version
*/
typedef struct _ARM_DRIVER_VERSION {
uint16_t api; ///< API version
uint16_t drv; ///< Driver version
} ARM_DRIVER_VERSION;
/* General return codes */
#define ARM_DRIVER_OK 0 ///< Operation succeeded
#define ARM_DRIVER_ERROR -1 ///< Unspecified error
#define ARM_DRIVER_ERROR_BUSY -2 ///< Driver is busy
#define ARM_DRIVER_ERROR_TIMEOUT -3 ///< Timeout occurred
#define ARM_DRIVER_ERROR_UNSUPPORTED -4 ///< Operation not supported
#define ARM_DRIVER_ERROR_PARAMETER -5 ///< Parameter error
#define ARM_DRIVER_ERROR_SPECIFIC -6 ///< Start of driver specific errors
/**
\brief General power states
*/
typedef enum _ARM_POWER_STATE {
ARM_POWER_OFF, ///< Power off: no operation possible
ARM_POWER_LOW, ///< Low Power mode: retain state, detect and signal wake-up events
ARM_POWER_FULL ///< Power on: full operation at maximum performance
} ARM_POWER_STATE;
#endif /* DRIVER_COMMON_H_ */

View File

@@ -0,0 +1,85 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Date: 2. Feb 2017
* $Revision: V2.1
*
* Project: Ethernet PHY and MAC Driver common definitions
*/
/* History:
* Version 2.1
* ARM_ETH_LINK_INFO made volatile
* Version 2.0
* Removed ARM_ETH_STATUS enumerator
* Removed ARM_ETH_MODE enumerator
* Version 1.10
* Namespace prefix ARM_ added
* Version 1.00
* Initial release
*/
#ifndef DRIVER_ETH_H_
#define DRIVER_ETH_H_
#include "Driver_Common.h"
/**
\brief Ethernet Media Interface type
*/
#define ARM_ETH_INTERFACE_MII (0) ///< Media Independent Interface (MII)
#define ARM_ETH_INTERFACE_RMII (1) ///< Reduced Media Independent Interface (RMII)
#define ARM_ETH_INTERFACE_SMII (2) ///< Serial Media Independent Interface (SMII)
/**
\brief Ethernet link speed
*/
#define ARM_ETH_SPEED_10M (0) ///< 10 Mbps link speed
#define ARM_ETH_SPEED_100M (1) ///< 100 Mbps link speed
#define ARM_ETH_SPEED_1G (2) ///< 1 Gpbs link speed
/**
\brief Ethernet duplex mode
*/
#define ARM_ETH_DUPLEX_HALF (0) ///< Half duplex link
#define ARM_ETH_DUPLEX_FULL (1) ///< Full duplex link
/**
\brief Ethernet link state
*/
typedef enum _ARM_ETH_LINK_STATE {
ARM_ETH_LINK_DOWN, ///< Link is down
ARM_ETH_LINK_UP ///< Link is up
} ARM_ETH_LINK_STATE;
/**
\brief Ethernet link information
*/
typedef volatile struct _ARM_ETH_LINK_INFO {
uint32_t speed : 2; ///< Link speed: 0= 10 MBit, 1= 100 MBit, 2= 1 GBit
uint32_t duplex : 1; ///< Duplex mode: 0= Half, 1= Full
uint32_t reserved : 29;
} ARM_ETH_LINK_INFO;
/**
\brief Ethernet MAC Address
*/
typedef struct _ARM_ETH_MAC_ADDR {
uint8_t b[6]; ///< MAC Address (6 bytes), MSB first
} ARM_ETH_MAC_ADDR;
#endif /* DRIVER_ETH_H_ */

View File

@@ -0,0 +1,308 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Date: 2. Feb 2017
* $Revision: V2.1
*
* Project: Ethernet MAC (Media Access Control) Driver definitions
*/
/* History:
* Version 2.1
* Added ARM_ETH_MAC_SLEEP Control
* Version 2.0
* Changed MAC Address handling:
* moved from ARM_ETH_MAC_Initialize
* to new functions ARM_ETH_MAC_GetMacAddress and ARM_ETH_MAC_SetMacAddress
* Replaced ARM_ETH_MAC_SetMulticastAddr function with ARM_ETH_MAC_SetAddressFilter
* Extended ARM_ETH_MAC_SendFrame function with flags
* Added ARM_ETH_MAC_Control function:
* more control options (Broadcast, Multicast, Checksum offload, VLAN, ...)
* replaces ARM_ETH_MAC_SetMode
* replaces ARM_ETH_MAC_EnableTx, ARM_ETH_MAC_EnableRx
* Added optional event on transmitted frame
* Added support for PTP (Precision Time Protocol) through new functions:
* ARM_ETH_MAC_ControlTimer
* ARM_ETH_MAC_GetRxFrameTime
* ARM_ETH_MAC_GetTxFrameTime
* Changed prefix ARM_DRV -> ARM_DRIVER
* Changed return values of some functions to int32_t
* Version 1.10
* Name space prefix ARM_ added
* Version 1.01
* Renamed capabilities items for checksum offload
* Version 1.00
* Initial release
*/
#ifndef DRIVER_ETH_MAC_H_
#define DRIVER_ETH_MAC_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include "Driver_ETH.h"
#define ARM_ETH_MAC_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,1) /* API version */
#define _ARM_Driver_ETH_MAC_(n) Driver_ETH_MAC##n
#define ARM_Driver_ETH_MAC_(n) _ARM_Driver_ETH_MAC_(n)
/****** Ethernet MAC Control Codes *****/
#define ARM_ETH_MAC_CONFIGURE (0x01) ///< Configure MAC; arg = configuration
#define ARM_ETH_MAC_CONTROL_TX (0x02) ///< Transmitter; arg: 0=disabled (default), 1=enabled
#define ARM_ETH_MAC_CONTROL_RX (0x03) ///< Receiver; arg: 0=disabled (default), 1=enabled
#define ARM_ETH_MAC_FLUSH (0x04) ///< Flush buffer; arg = ARM_ETH_MAC_FLUSH_...
#define ARM_ETH_MAC_SLEEP (0x05) ///< Sleep mode; arg: 1=enter and wait for Magic packet, 0=exit
#define ARM_ETH_MAC_VLAN_FILTER (0x06) ///< VLAN Filter for received frames; arg15..0: VLAN Tag; arg16: optional ARM_ETH_MAC_VLAN_FILTER_ID_ONLY; 0=disabled (default)
/*----- Ethernet MAC Configuration -----*/
#define ARM_ETH_MAC_SPEED_Pos 0
#define ARM_ETH_MAC_SPEED_Msk (3UL << ARM_ETH_MAC_SPEED_Pos)
#define ARM_ETH_MAC_SPEED_10M (ARM_ETH_SPEED_10M << ARM_ETH_MAC_SPEED_Pos) ///< 10 Mbps link speed
#define ARM_ETH_MAC_SPEED_100M (ARM_ETH_SPEED_100M << ARM_ETH_MAC_SPEED_Pos) ///< 100 Mbps link speed
#define ARM_ETH_MAC_SPEED_1G (ARM_ETH_SPEED_1G << ARM_ETH_MAC_SPEED_Pos) ///< 1 Gpbs link speed
#define ARM_ETH_MAC_DUPLEX_Pos 2
#define ARM_ETH_MAC_DUPLEX_Msk (1UL << ARM_ETH_MAC_DUPLEX_Pos)
#define ARM_ETH_MAC_DUPLEX_HALF (ARM_ETH_DUPLEX_HALF << ARM_ETH_MAC_DUPLEX_Pos) ///< Half duplex link
#define ARM_ETH_MAC_DUPLEX_FULL (ARM_ETH_DUPLEX_FULL << ARM_ETH_MAC_DUPLEX_Pos) ///< Full duplex link
#define ARM_ETH_MAC_LOOPBACK (1UL << 4) ///< Loop-back test mode
#define ARM_ETH_MAC_CHECKSUM_OFFLOAD_RX (1UL << 5) ///< Receiver Checksum offload
#define ARM_ETH_MAC_CHECKSUM_OFFLOAD_TX (1UL << 6) ///< Transmitter Checksum offload
#define ARM_ETH_MAC_ADDRESS_BROADCAST (1UL << 7) ///< Accept frames with Broadcast address
#define ARM_ETH_MAC_ADDRESS_MULTICAST (1UL << 8) ///< Accept frames with any Multicast address
#define ARM_ETH_MAC_ADDRESS_ALL (1UL << 9) ///< Accept frames with any address (Promiscuous Mode)
/*----- Ethernet MAC Flush Flags -----*/
#define ARM_ETH_MAC_FLUSH_RX (1UL << 0) ///< Flush Receive buffer
#define ARM_ETH_MAC_FLUSH_TX (1UL << 1) ///< Flush Transmit buffer
/*----- Ethernet MAC VLAN Filter Flag -----*/
#define ARM_ETH_MAC_VLAN_FILTER_ID_ONLY (1UL << 16) ///< Compare only the VLAN Identifier (12-bit)
/****** Ethernet MAC Frame Transmit Flags *****/
#define ARM_ETH_MAC_TX_FRAME_FRAGMENT (1UL << 0) ///< Indicate frame fragment
#define ARM_ETH_MAC_TX_FRAME_EVENT (1UL << 1) ///< Generate event when frame is transmitted
#define ARM_ETH_MAC_TX_FRAME_TIMESTAMP (1UL << 2) ///< Capture frame time stamp
/****** Ethernet MAC Timer Control Codes *****/
#define ARM_ETH_MAC_TIMER_GET_TIME (0x01) ///< Get current time
#define ARM_ETH_MAC_TIMER_SET_TIME (0x02) ///< Set new time
#define ARM_ETH_MAC_TIMER_INC_TIME (0x03) ///< Increment current time
#define ARM_ETH_MAC_TIMER_DEC_TIME (0x04) ///< Decrement current time
#define ARM_ETH_MAC_TIMER_SET_ALARM (0x05) ///< Set alarm time
#define ARM_ETH_MAC_TIMER_ADJUST_CLOCK (0x06) ///< Adjust clock frequency; time->ns: correction factor * 2^31
/**
\brief Ethernet MAC Time
*/
typedef struct _ARM_ETH_MAC_TIME {
uint32_t ns; ///< Nano seconds
uint32_t sec; ///< Seconds
} ARM_ETH_MAC_TIME;
/****** Ethernet MAC Event *****/
#define ARM_ETH_MAC_EVENT_RX_FRAME (1UL << 0) ///< Frame Received
#define ARM_ETH_MAC_EVENT_TX_FRAME (1UL << 1) ///< Frame Transmitted
#define ARM_ETH_MAC_EVENT_WAKEUP (1UL << 2) ///< Wake-up (on Magic Packet)
#define ARM_ETH_MAC_EVENT_TIMER_ALARM (1UL << 3) ///< Timer Alarm
// Function documentation
/**
\fn ARM_DRIVER_VERSION ARM_ETH_MAC_GetVersion (void)
\brief Get driver version.
\return \ref ARM_DRIVER_VERSION
*/
/**
\fn ARM_ETH_MAC_CAPABILITIES ARM_ETH_MAC_GetCapabilities (void)
\brief Get driver capabilities.
\return \ref ARM_ETH_MAC_CAPABILITIES
*/
/**
\fn int32_t ARM_ETH_MAC_Initialize (ARM_ETH_MAC_SignalEvent_t cb_event)
\brief Initialize Ethernet MAC Device.
\param[in] cb_event Pointer to \ref ARM_ETH_MAC_SignalEvent
\return \ref execution_status
*/
/**
\fn int32_t ARM_ETH_MAC_Uninitialize (void)
\brief De-initialize Ethernet MAC Device.
\return \ref execution_status
*/
/**
\fn int32_t ARM_ETH_MAC_PowerControl (ARM_POWER_STATE state)
\brief Control Ethernet MAC Device Power.
\param[in] state Power state
\return \ref execution_status
*/
/**
\fn int32_t ARM_ETH_MAC_GetMacAddress (ARM_ETH_MAC_ADDR *ptr_addr)
\brief Get Ethernet MAC Address.
\param[in] ptr_addr Pointer to address
\return \ref execution_status
*/
/**
\fn int32_t ARM_ETH_MAC_SetMacAddress (const ARM_ETH_MAC_ADDR *ptr_addr)
\brief Set Ethernet MAC Address.
\param[in] ptr_addr Pointer to address
\return \ref execution_status
*/
/**
\fn int32_t ARM_ETH_MAC_SetAddressFilter (const ARM_ETH_MAC_ADDR *ptr_addr,
uint32_t num_addr)
\brief Configure Address Filter.
\param[in] ptr_addr Pointer to addresses
\param[in] num_addr Number of addresses to configure
\return \ref execution_status
*/
/**
\fn int32_t ARM_ETH_MAC_SendFrame (const uint8_t *frame, uint32_t len, uint32_t flags)
\brief Send Ethernet frame.
\param[in] frame Pointer to frame buffer with data to send
\param[in] len Frame buffer length in bytes
\param[in] flags Frame transmit flags (see ARM_ETH_MAC_TX_FRAME_...)
\return \ref execution_status
*/
/**
\fn int32_t ARM_ETH_MAC_ReadFrame (uint8_t *frame, uint32_t len)
\brief Read data of received Ethernet frame.
\param[in] frame Pointer to frame buffer for data to read into
\param[in] len Frame buffer length in bytes
\return number of data bytes read or execution status
- value >= 0: number of data bytes read
- value < 0: error occurred, value is execution status as defined with \ref execution_status
*/
/**
\fn uint32_t ARM_ETH_MAC_GetRxFrameSize (void)
\brief Get size of received Ethernet frame.
\return number of bytes in received frame
*/
/**
\fn int32_t ARM_ETH_MAC_GetRxFrameTime (ARM_ETH_MAC_TIME *time)
\brief Get time of received Ethernet frame.
\param[in] time Pointer to time structure for data to read into
\return \ref execution_status
*/
/**
\fn int32_t ARM_ETH_MAC_GetTxFrameTime (ARM_ETH_MAC_TIME *time)
\brief Get time of transmitted Ethernet frame.
\param[in] time Pointer to time structure for data to read into
\return \ref execution_status
*/
/**
\fn int32_t ARM_ETH_MAC_Control (uint32_t control, uint32_t arg)
\brief Control Ethernet Interface.
\param[in] control Operation
\param[in] arg Argument of operation (optional)
\return \ref execution_status
*/
/**
\fn int32_t ARM_ETH_MAC_ControlTimer (uint32_t control, ARM_ETH_MAC_TIME *time)
\brief Control Precision Timer.
\param[in] control Operation
\param[in] time Pointer to time structure
\return \ref execution_status
*/
/**
\fn int32_t ARM_ETH_MAC_PHY_Read (uint8_t phy_addr, uint8_t reg_addr, uint16_t *data)
\brief Read Ethernet PHY Register through Management Interface.
\param[in] phy_addr 5-bit device address
\param[in] reg_addr 5-bit register address
\param[out] data Pointer where the result is written to
\return \ref execution_status
*/
/**
\fn int32_t ARM_ETH_MAC_PHY_Write (uint8_t phy_addr, uint8_t reg_addr, uint16_t data)
\brief Write Ethernet PHY Register through Management Interface.
\param[in] phy_addr 5-bit device address
\param[in] reg_addr 5-bit register address
\param[in] data 16-bit data to write
\return \ref execution_status
*/
/**
\fn void ARM_ETH_MAC_SignalEvent (uint32_t event)
\brief Callback function that signals a Ethernet Event.
\param[in] event event notification mask
\return none
*/
typedef void (*ARM_ETH_MAC_SignalEvent_t) (uint32_t event); ///< Pointer to \ref ARM_ETH_MAC_SignalEvent : Signal Ethernet Event.
/**
\brief Ethernet MAC Capabilities
*/
typedef struct _ARM_ETH_MAC_CAPABILITIES {
uint32_t checksum_offload_rx_ip4 : 1; ///< 1 = IPv4 header checksum verified on receive
uint32_t checksum_offload_rx_ip6 : 1; ///< 1 = IPv6 checksum verification supported on receive
uint32_t checksum_offload_rx_udp : 1; ///< 1 = UDP payload checksum verified on receive
uint32_t checksum_offload_rx_tcp : 1; ///< 1 = TCP payload checksum verified on receive
uint32_t checksum_offload_rx_icmp : 1; ///< 1 = ICMP payload checksum verified on receive
uint32_t checksum_offload_tx_ip4 : 1; ///< 1 = IPv4 header checksum generated on transmit
uint32_t checksum_offload_tx_ip6 : 1; ///< 1 = IPv6 checksum generation supported on transmit
uint32_t checksum_offload_tx_udp : 1; ///< 1 = UDP payload checksum generated on transmit
uint32_t checksum_offload_tx_tcp : 1; ///< 1 = TCP payload checksum generated on transmit
uint32_t checksum_offload_tx_icmp : 1; ///< 1 = ICMP payload checksum generated on transmit
uint32_t media_interface : 2; ///< Ethernet Media Interface type
uint32_t mac_address : 1; ///< 1 = driver provides initial valid MAC address
uint32_t event_rx_frame : 1; ///< 1 = callback event \ref ARM_ETH_MAC_EVENT_RX_FRAME generated
uint32_t event_tx_frame : 1; ///< 1 = callback event \ref ARM_ETH_MAC_EVENT_TX_FRAME generated
uint32_t event_wakeup : 1; ///< 1 = wakeup event \ref ARM_ETH_MAC_EVENT_WAKEUP generated
uint32_t precision_timer : 1; ///< 1 = Precision Timer supported
uint32_t reserved : 15; ///< Reserved (must be zero)
} ARM_ETH_MAC_CAPABILITIES;
/**
\brief Access structure of the Ethernet MAC Driver
*/
typedef struct _ARM_DRIVER_ETH_MAC {
ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_ETH_MAC_GetVersion : Get driver version.
ARM_ETH_MAC_CAPABILITIES (*GetCapabilities) (void); ///< Pointer to \ref ARM_ETH_MAC_GetCapabilities : Get driver capabilities.
int32_t (*Initialize) (ARM_ETH_MAC_SignalEvent_t cb_event); ///< Pointer to \ref ARM_ETH_MAC_Initialize : Initialize Ethernet MAC Device.
int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_ETH_MAC_Uninitialize : De-initialize Ethernet MAC Device.
int32_t (*PowerControl) (ARM_POWER_STATE state); ///< Pointer to \ref ARM_ETH_MAC_PowerControl : Control Ethernet MAC Device Power.
int32_t (*GetMacAddress) ( ARM_ETH_MAC_ADDR *ptr_addr); ///< Pointer to \ref ARM_ETH_MAC_GetMacAddress : Get Ethernet MAC Address.
int32_t (*SetMacAddress) (const ARM_ETH_MAC_ADDR *ptr_addr); ///< Pointer to \ref ARM_ETH_MAC_SetMacAddress : Set Ethernet MAC Address.
int32_t (*SetAddressFilter)(const ARM_ETH_MAC_ADDR *ptr_addr, uint32_t num_addr); ///< Pointer to \ref ARM_ETH_MAC_SetAddressFilter : Configure Address Filter.
int32_t (*SendFrame) (const uint8_t *frame, uint32_t len, uint32_t flags); ///< Pointer to \ref ARM_ETH_MAC_SendFrame : Send Ethernet frame.
int32_t (*ReadFrame) ( uint8_t *frame, uint32_t len); ///< Pointer to \ref ARM_ETH_MAC_ReadFrame : Read data of received Ethernet frame.
uint32_t (*GetRxFrameSize) (void); ///< Pointer to \ref ARM_ETH_MAC_GetRxFrameSize : Get size of received Ethernet frame.
int32_t (*GetRxFrameTime) (ARM_ETH_MAC_TIME *time); ///< Pointer to \ref ARM_ETH_MAC_GetRxFrameTime : Get time of received Ethernet frame.
int32_t (*GetTxFrameTime) (ARM_ETH_MAC_TIME *time); ///< Pointer to \ref ARM_ETH_MAC_GetTxFrameTime : Get time of transmitted Ethernet frame.
int32_t (*ControlTimer) (uint32_t control, ARM_ETH_MAC_TIME *time); ///< Pointer to \ref ARM_ETH_MAC_ControlTimer : Control Precision Timer.
int32_t (*Control) (uint32_t control, uint32_t arg); ///< Pointer to \ref ARM_ETH_MAC_Control : Control Ethernet Interface.
int32_t (*PHY_Read) (uint8_t phy_addr, uint8_t reg_addr, uint16_t *data); ///< Pointer to \ref ARM_ETH_MAC_PHY_Read : Read Ethernet PHY Register through Management Interface.
int32_t (*PHY_Write) (uint8_t phy_addr, uint8_t reg_addr, uint16_t data); ///< Pointer to \ref ARM_ETH_MAC_PHY_Write : Write Ethernet PHY Register through Management Interface.
} const ARM_DRIVER_ETH_MAC;
#ifdef __cplusplus
}
#endif
#endif /* DRIVER_ETH_MAC_H_ */

View File

@@ -0,0 +1,141 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Date: 2. Feb 2017
* $Revision: V2.1
*
* Project: Ethernet PHY (Physical Transceiver) Driver definitions
*/
/* History:
* Version 2.1
* ARM_ETH_LINK_INFO made volatile
* Version 2.0
* changed parameter "mode" in function ARM_ETH_PHY_SetMode
* Changed prefix ARM_DRV -> ARM_DRIVER
* Changed return values of some functions to int32_t
* Version 1.10
* Namespace prefix ARM_ added
* Version 1.00
* Initial release
*/
#ifndef DRIVER_ETH_PHY_H_
#define DRIVER_ETH_PHY_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include "Driver_ETH.h"
#define ARM_ETH_PHY_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,1) /* API version */
#define _ARM_Driver_ETH_PHY_(n) Driver_ETH_PHY##n
#define ARM_Driver_ETH_PHY_(n) _ARM_Driver_ETH_PHY_(n)
/****** Ethernet PHY Mode *****/
#define ARM_ETH_PHY_SPEED_Pos 0
#define ARM_ETH_PHY_SPEED_Msk (3UL << ARM_ETH_PHY_SPEED_Pos)
#define ARM_ETH_PHY_SPEED_10M (ARM_ETH_SPEED_10M << ARM_ETH_PHY_SPEED_Pos) ///< 10 Mbps link speed
#define ARM_ETH_PHY_SPEED_100M (ARM_ETH_SPEED_100M << ARM_ETH_PHY_SPEED_Pos) ///< 100 Mbps link speed
#define ARM_ETH_PHY_SPEED_1G (ARM_ETH_SPEED_1G << ARM_ETH_PHY_SPEED_Pos) ///< 1 Gpbs link speed
#define ARM_ETH_PHY_DUPLEX_Pos 2
#define ARM_ETH_PHY_DUPLEX_Msk (1UL << ARM_ETH_PHY_DUPLEX_Pos)
#define ARM_ETH_PHY_DUPLEX_HALF (ARM_ETH_DUPLEX_HALF << ARM_ETH_PHY_DUPLEX_Pos) ///< Half duplex link
#define ARM_ETH_PHY_DUPLEX_FULL (ARM_ETH_DUPLEX_FULL << ARM_ETH_PHY_DUPLEX_Pos) ///< Full duplex link
#define ARM_ETH_PHY_AUTO_NEGOTIATE (1UL << 3) ///< Auto Negotiation mode
#define ARM_ETH_PHY_LOOPBACK (1UL << 4) ///< Loop-back test mode
#define ARM_ETH_PHY_ISOLATE (1UL << 5) ///< Isolate PHY from MII/RMII interface
// Function documentation
/**
\fn ARM_DRIVER_VERSION ARM_ETH_PHY_GetVersion (void)
\brief Get driver version.
\return \ref ARM_DRIVER_VERSION
*/
/**
\fn int32_t ARM_ETH_PHY_Initialize (ARM_ETH_PHY_Read_t fn_read,
ARM_ETH_PHY_Write_t fn_write)
\brief Initialize Ethernet PHY Device.
\param[in] fn_read Pointer to \ref ARM_ETH_MAC_PHY_Read
\param[in] fn_write Pointer to \ref ARM_ETH_MAC_PHY_Write
\return \ref execution_status
*/
/**
\fn int32_t ARM_ETH_PHY_Uninitialize (void)
\brief De-initialize Ethernet PHY Device.
\return \ref execution_status
*/
/**
\fn int32_t ARM_ETH_PHY_PowerControl (ARM_POWER_STATE state)
\brief Control Ethernet PHY Device Power.
\param[in] state Power state
\return \ref execution_status
*/
/**
\fn int32_t ARM_ETH_PHY_SetInterface (uint32_t interface)
\brief Set Ethernet Media Interface.
\param[in] interface Media Interface type
\return \ref execution_status
*/
/**
\fn int32_t ARM_ETH_PHY_SetMode (uint32_t mode)
\brief Set Ethernet PHY Device Operation mode.
\param[in] mode Operation Mode
\return \ref execution_status
*/
/**
\fn ARM_ETH_LINK_STATE ARM_ETH_PHY_GetLinkState (void)
\brief Get Ethernet PHY Device Link state.
\return current link status \ref ARM_ETH_LINK_STATE
*/
/**
\fn ARM_ETH_LINK_INFO ARM_ETH_PHY_GetLinkInfo (void)
\brief Get Ethernet PHY Device Link information.
\return current link parameters \ref ARM_ETH_LINK_INFO
*/
typedef int32_t (*ARM_ETH_PHY_Read_t) (uint8_t phy_addr, uint8_t reg_addr, uint16_t *data); ///< Pointer to \ref ARM_ETH_MAC_PHY_Read : Read Ethernet PHY Register.
typedef int32_t (*ARM_ETH_PHY_Write_t) (uint8_t phy_addr, uint8_t reg_addr, uint16_t data); ///< Pointer to \ref ARM_ETH_MAC_PHY_Write : Write Ethernet PHY Register.
/**
\brief Access structure of the Ethernet PHY Driver
*/
typedef struct _ARM_DRIVER_ETH_PHY {
ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_ETH_PHY_GetVersion : Get driver version.
int32_t (*Initialize) (ARM_ETH_PHY_Read_t fn_read,
ARM_ETH_PHY_Write_t fn_write); ///< Pointer to \ref ARM_ETH_PHY_Initialize : Initialize PHY Device.
int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_ETH_PHY_Uninitialize : De-initialize PHY Device.
int32_t (*PowerControl) (ARM_POWER_STATE state); ///< Pointer to \ref ARM_ETH_PHY_PowerControl : Control PHY Device Power.
int32_t (*SetInterface) (uint32_t interface); ///< Pointer to \ref ARM_ETH_PHY_SetInterface : Set Ethernet Media Interface.
int32_t (*SetMode) (uint32_t mode); ///< Pointer to \ref ARM_ETH_PHY_SetMode : Set Ethernet PHY Device Operation mode.
ARM_ETH_LINK_STATE (*GetLinkState) (void); ///< Pointer to \ref ARM_ETH_PHY_GetLinkState : Get Ethernet PHY Device Link state.
ARM_ETH_LINK_INFO (*GetLinkInfo) (void); ///< Pointer to \ref ARM_ETH_PHY_GetLinkInfo : Get Ethernet PHY Device Link information.
} const ARM_DRIVER_ETH_PHY;
#ifdef __cplusplus
}
#endif
#endif /* DRIVER_ETH_PHY_H_ */

View File

@@ -0,0 +1,204 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Date: 2. Feb 2017
* $Revision: V2.1
*
* Project: Flash Driver definitions
*/
/* History:
* Version 2.1
* ARM_FLASH_STATUS made volatile
* Version 2.0
* Renamed driver NOR -> Flash (more generic)
* Non-blocking operation
* Added Events, Status and Capabilities
* Linked Flash information (GetInfo)
* Version 1.11
* Changed prefix ARM_DRV -> ARM_DRIVER
* Version 1.10
* Namespace prefix ARM_ added
* Version 1.00
* Initial release
*/
#ifndef DRIVER_FLASH_H_
#define DRIVER_FLASH_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include "Driver_Common.h"
#define ARM_FLASH_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,1) /* API version */
#define _ARM_Driver_Flash_(n) Driver_Flash##n
#define ARM_Driver_Flash_(n) _ARM_Driver_Flash_(n)
#define ARM_FLASH_SECTOR_INFO(addr,size) { (addr), (addr)+(size)-1 }
/**
\brief Flash Sector information
*/
typedef struct _ARM_FLASH_SECTOR {
uint32_t start; ///< Sector Start address
uint32_t end; ///< Sector End address (start+size-1)
} const ARM_FLASH_SECTOR;
/**
\brief Flash information
*/
typedef struct _ARM_FLASH_INFO {
ARM_FLASH_SECTOR *sector_info; ///< Sector layout information (NULL=Uniform sectors)
uint32_t sector_count; ///< Number of sectors
uint32_t sector_size; ///< Uniform sector size in bytes (0=sector_info used)
uint32_t page_size; ///< Optimal programming page size in bytes
uint32_t program_unit; ///< Smallest programmable unit in bytes
uint8_t erased_value; ///< Contents of erased memory (usually 0xFF)
} const ARM_FLASH_INFO;
/**
\brief Flash Status
*/
typedef volatile struct _ARM_FLASH_STATUS {
uint32_t busy : 1; ///< Flash busy flag
uint32_t error : 1; ///< Read/Program/Erase error flag (cleared on start of next operation)
uint32_t reserved : 30;
} ARM_FLASH_STATUS;
/****** Flash Event *****/
#define ARM_FLASH_EVENT_READY (1UL << 0) ///< Flash Ready
#define ARM_FLASH_EVENT_ERROR (1UL << 1) ///< Read/Program/Erase Error
// Function documentation
/**
\fn ARM_DRIVER_VERSION ARM_Flash_GetVersion (void)
\brief Get driver version.
\return \ref ARM_DRIVER_VERSION
*/
/**
\fn ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities (void)
\brief Get driver capabilities.
\return \ref ARM_FLASH_CAPABILITIES
*/
/**
\fn int32_t ARM_Flash_Initialize (ARM_Flash_SignalEvent_t cb_event)
\brief Initialize the Flash Interface.
\param[in] cb_event Pointer to \ref ARM_Flash_SignalEvent
\return \ref execution_status
*/
/**
\fn int32_t ARM_Flash_Uninitialize (void)
\brief De-initialize the Flash Interface.
\return \ref execution_status
*/
/**
\fn int32_t ARM_Flash_PowerControl (ARM_POWER_STATE state)
\brief Control the Flash interface power.
\param[in] state Power state
\return \ref execution_status
*/
/**
\fn int32_t ARM_Flash_ReadData (uint32_t addr, void *data, uint32_t cnt)
\brief Read data from Flash.
\param[in] addr Data address.
\param[out] data Pointer to a buffer storing the data read from Flash.
\param[in] cnt Number of data items to read.
\return number of data items read or \ref execution_status
*/
/**
\fn int32_t ARM_Flash_ProgramData (uint32_t addr, const void *data, uint32_t cnt)
\brief Program data to Flash.
\param[in] addr Data address.
\param[in] data Pointer to a buffer containing the data to be programmed to Flash.
\param[in] cnt Number of data items to program.
\return number of data items programmed or \ref execution_status
*/
/**
\fn int32_t ARM_Flash_EraseSector (uint32_t addr)
\brief Erase Flash Sector.
\param[in] addr Sector address
\return \ref execution_status
*/
/**
\fn int32_t ARM_Flash_EraseChip (void)
\brief Erase complete Flash.
Optional function for faster full chip erase.
\return \ref execution_status
*/
/**
\fn ARM_FLASH_STATUS ARM_Flash_GetStatus (void)
\brief Get Flash status.
\return Flash status \ref ARM_FLASH_STATUS
*/
/**
\fn ARM_FLASH_INFO * ARM_Flash_GetInfo (void)
\brief Get Flash information.
\return Pointer to Flash information \ref ARM_FLASH_INFO
*/
/**
\fn void ARM_Flash_SignalEvent (uint32_t event)
\brief Signal Flash event.
\param[in] event Event notification mask
\return none
*/
typedef void (*ARM_Flash_SignalEvent_t) (uint32_t event); ///< Pointer to \ref ARM_Flash_SignalEvent : Signal Flash Event.
/**
\brief Flash Driver Capabilities.
*/
typedef struct _ARM_FLASH_CAPABILITIES {
uint32_t event_ready : 1; ///< Signal Flash Ready event
uint32_t data_width : 2; ///< Data width: 0=8-bit, 1=16-bit, 2=32-bit
uint32_t erase_chip : 1; ///< Supports EraseChip operation
uint32_t reserved : 28; ///< Reserved (must be zero)
} ARM_FLASH_CAPABILITIES;
/**
\brief Access structure of the Flash Driver
*/
typedef struct _ARM_DRIVER_FLASH {
ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_Flash_GetVersion : Get driver version.
ARM_FLASH_CAPABILITIES (*GetCapabilities)(void); ///< Pointer to \ref ARM_Flash_GetCapabilities : Get driver capabilities.
int32_t (*Initialize) (ARM_Flash_SignalEvent_t cb_event); ///< Pointer to \ref ARM_Flash_Initialize : Initialize Flash Interface.
int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_Flash_Uninitialize : De-initialize Flash Interface.
int32_t (*PowerControl) (ARM_POWER_STATE state); ///< Pointer to \ref ARM_Flash_PowerControl : Control Flash Interface Power.
int32_t (*ReadData) (uint32_t addr, void *data, uint32_t cnt); ///< Pointer to \ref ARM_Flash_ReadData : Read data from Flash.
int32_t (*ProgramData) (uint32_t addr, const void *data, uint32_t cnt); ///< Pointer to \ref ARM_Flash_ProgramData : Program data to Flash.
int32_t (*EraseSector) (uint32_t addr); ///< Pointer to \ref ARM_Flash_EraseSector : Erase Flash Sector.
int32_t (*EraseChip) (void); ///< Pointer to \ref ARM_Flash_EraseChip : Erase complete Flash.
ARM_FLASH_STATUS (*GetStatus) (void); ///< Pointer to \ref ARM_Flash_GetStatus : Get Flash status.
ARM_FLASH_INFO * (*GetInfo) (void); ///< Pointer to \ref ARM_Flash_GetInfo : Get Flash information.
} const ARM_DRIVER_FLASH;
#ifdef __cplusplus
}
#endif
#endif /* DRIVER_FLASH_H_ */

View File

@@ -0,0 +1,217 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Date: 2. Feb 2017
* $Revision: V2.3
*
* Project: I2C (Inter-Integrated Circuit) Driver definitions
*/
/* History:
* Version 2.3
* ARM_I2C_STATUS made volatile
* Version 2.2
* Removed function ARM_I2C_MasterTransfer in order to simplify drivers
* and added back parameter "xfer_pending" to functions
* ARM_I2C_MasterTransmit and ARM_I2C_MasterReceive
* Version 2.1
* Added function ARM_I2C_MasterTransfer and removed parameter "xfer_pending"
* from functions ARM_I2C_MasterTransmit and ARM_I2C_MasterReceive
* Added function ARM_I2C_GetDataCount
* Removed flag "address_nack" from ARM_I2C_STATUS
* Replaced events ARM_I2C_EVENT_MASTER_DONE and ARM_I2C_EVENT_SLAVE_DONE
* with event ARM_I2C_EVENT_TRANSFER_DONE
* Added event ARM_I2C_EVENT_TRANSFER_INCOMPLETE
* Removed parameter "arg" from function ARM_I2C_SignalEvent
* Version 2.0
* New simplified driver:
* complexity moved to upper layer (especially data handling)
* more unified API for different communication interfaces
* Added:
* Slave Mode
* Changed prefix ARM_DRV -> ARM_DRIVER
* Version 1.10
* Namespace prefix ARM_ added
* Version 1.00
* Initial release
*/
#ifndef DRIVER_I2C_H_
#define DRIVER_I2C_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include "Driver_Common.h"
#define ARM_I2C_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,3) /* API version */
/****** I2C Control Codes *****/
#define ARM_I2C_OWN_ADDRESS (0x01) ///< Set Own Slave Address; arg = address
#define ARM_I2C_BUS_SPEED (0x02) ///< Set Bus Speed; arg = speed
#define ARM_I2C_BUS_CLEAR (0x03) ///< Execute Bus clear: send nine clock pulses
#define ARM_I2C_ABORT_TRANSFER (0x04) ///< Abort Master/Slave Transmit/Receive
/*----- I2C Bus Speed -----*/
#define ARM_I2C_BUS_SPEED_STANDARD (0x01) ///< Standard Speed (100kHz)
#define ARM_I2C_BUS_SPEED_FAST (0x02) ///< Fast Speed (400kHz)
#define ARM_I2C_BUS_SPEED_FAST_PLUS (0x03) ///< Fast+ Speed ( 1MHz)
#define ARM_I2C_BUS_SPEED_HIGH (0x04) ///< High Speed (3.4MHz)
/****** I2C Address Flags *****/
#define ARM_I2C_ADDRESS_10BIT (0x0400) ///< 10-bit address flag
#define ARM_I2C_ADDRESS_GC (0x8000) ///< General Call flag
/**
\brief I2C Status
*/
typedef volatile struct _ARM_I2C_STATUS {
uint32_t busy : 1; ///< Busy flag
uint32_t mode : 1; ///< Mode: 0=Slave, 1=Master
uint32_t direction : 1; ///< Direction: 0=Transmitter, 1=Receiver
uint32_t general_call : 1; ///< General Call indication (cleared on start of next Slave operation)
uint32_t arbitration_lost : 1; ///< Master lost arbitration (cleared on start of next Master operation)
uint32_t bus_error : 1; ///< Bus error detected (cleared on start of next Master/Slave operation)
uint32_t reserved : 26;
} ARM_I2C_STATUS;
/****** I2C Event *****/
#define ARM_I2C_EVENT_TRANSFER_DONE (1UL << 0) ///< Master/Slave Transmit/Receive finished
#define ARM_I2C_EVENT_TRANSFER_INCOMPLETE (1UL << 1) ///< Master/Slave Transmit/Receive incomplete transfer
#define ARM_I2C_EVENT_SLAVE_TRANSMIT (1UL << 2) ///< Slave Transmit operation requested
#define ARM_I2C_EVENT_SLAVE_RECEIVE (1UL << 3) ///< Slave Receive operation requested
#define ARM_I2C_EVENT_ADDRESS_NACK (1UL << 4) ///< Address not acknowledged from Slave
#define ARM_I2C_EVENT_GENERAL_CALL (1UL << 5) ///< General Call indication
#define ARM_I2C_EVENT_ARBITRATION_LOST (1UL << 6) ///< Master lost arbitration
#define ARM_I2C_EVENT_BUS_ERROR (1UL << 7) ///< Bus error detected (START/STOP at illegal position)
#define ARM_I2C_EVENT_BUS_CLEAR (1UL << 8) ///< Bus clear finished
// Function documentation
/**
\fn ARM_DRIVER_VERSION ARM_I2C_GetVersion (void)
\brief Get driver version.
\return \ref ARM_DRIVER_VERSION
\fn ARM_I2C_CAPABILITIES ARM_I2C_GetCapabilities (void)
\brief Get driver capabilities.
\return \ref ARM_I2C_CAPABILITIES
\fn int32_t ARM_I2C_Initialize (ARM_I2C_SignalEvent_t cb_event)
\brief Initialize I2C Interface.
\param[in] cb_event Pointer to \ref ARM_I2C_SignalEvent
\return \ref execution_status
\fn int32_t ARM_I2C_Uninitialize (void)
\brief De-initialize I2C Interface.
\return \ref execution_status
\fn int32_t ARM_I2C_PowerControl (ARM_POWER_STATE state)
\brief Control I2C Interface Power.
\param[in] state Power state
\return \ref execution_status
\fn int32_t ARM_I2C_MasterTransmit (uint32_t addr, const uint8_t *data, uint32_t num, bool xfer_pending)
\brief Start transmitting data as I2C Master.
\param[in] addr Slave address (7-bit or 10-bit)
\param[in] data Pointer to buffer with data to transmit to I2C Slave
\param[in] num Number of data bytes to transmit
\param[in] xfer_pending Transfer operation is pending - Stop condition will not be generated
\return \ref execution_status
\fn int32_t ARM_I2C_MasterReceive (uint32_t addr, uint8_t *data, uint32_t num, bool xfer_pending)
\brief Start receiving data as I2C Master.
\param[in] addr Slave address (7-bit or 10-bit)
\param[out] data Pointer to buffer for data to receive from I2C Slave
\param[in] num Number of data bytes to receive
\param[in] xfer_pending Transfer operation is pending - Stop condition will not be generated
\return \ref execution_status
\fn int32_t ARM_I2C_SlaveTransmit (const uint8_t *data, uint32_t num)
\brief Start transmitting data as I2C Slave.
\param[in] data Pointer to buffer with data to transmit to I2C Master
\param[in] num Number of data bytes to transmit
\return \ref execution_status
\fn int32_t ARM_I2C_SlaveReceive (uint8_t *data, uint32_t num)
\brief Start receiving data as I2C Slave.
\param[out] data Pointer to buffer for data to receive from I2C Master
\param[in] num Number of data bytes to receive
\return \ref execution_status
\fn int32_t ARM_I2C_GetDataCount (void)
\brief Get transferred data count.
\return number of data bytes transferred; -1 when Slave is not addressed by Master
\fn int32_t ARM_I2C_Control (uint32_t control, uint32_t arg)
\brief Control I2C Interface.
\param[in] control Operation
\param[in] arg Argument of operation (optional)
\return \ref execution_status
\fn ARM_I2C_STATUS ARM_I2C_GetStatus (void)
\brief Get I2C status.
\return I2C status \ref ARM_I2C_STATUS
\fn void ARM_I2C_SignalEvent (uint32_t event)
\brief Signal I2C Events.
\param[in] event \ref I2C_events notification mask
*/
typedef void (*ARM_I2C_SignalEvent_t) (uint32_t event); ///< Pointer to \ref ARM_I2C_SignalEvent : Signal I2C Event.
/**
\brief I2C Driver Capabilities.
*/
typedef struct _ARM_I2C_CAPABILITIES {
uint32_t address_10_bit : 1; ///< supports 10-bit addressing
uint32_t reserved : 31; ///< Reserved (must be zero)
} ARM_I2C_CAPABILITIES;
/**
\brief Access structure of the I2C Driver.
*/
typedef struct _ARM_DRIVER_I2C {
ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_I2C_GetVersion : Get driver version.
ARM_I2C_CAPABILITIES (*GetCapabilities)(void); ///< Pointer to \ref ARM_I2C_GetCapabilities : Get driver capabilities.
int32_t (*Initialize) (ARM_I2C_SignalEvent_t cb_event); ///< Pointer to \ref ARM_I2C_Initialize : Initialize I2C Interface.
int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_I2C_Uninitialize : De-initialize I2C Interface.
int32_t (*PowerControl) (ARM_POWER_STATE state); ///< Pointer to \ref ARM_I2C_PowerControl : Control I2C Interface Power.
int32_t (*MasterTransmit) (uint32_t addr, const uint8_t *data, uint32_t num, bool xfer_pending); ///< Pointer to \ref ARM_I2C_MasterTransmit : Start transmitting data as I2C Master.
int32_t (*MasterReceive) (uint32_t addr, uint8_t *data, uint32_t num, bool xfer_pending); ///< Pointer to \ref ARM_I2C_MasterReceive : Start receiving data as I2C Master.
int32_t (*SlaveTransmit) ( const uint8_t *data, uint32_t num); ///< Pointer to \ref ARM_I2C_SlaveTransmit : Start transmitting data as I2C Slave.
int32_t (*SlaveReceive) ( uint8_t *data, uint32_t num); ///< Pointer to \ref ARM_I2C_SlaveReceive : Start receiving data as I2C Slave.
int32_t (*GetDataCount) (void); ///< Pointer to \ref ARM_I2C_GetDataCount : Get transferred data count.
int32_t (*Control) (uint32_t control, uint32_t arg); ///< Pointer to \ref ARM_I2C_Control : Control I2C Interface.
ARM_I2C_STATUS (*GetStatus) (void); ///< Pointer to \ref ARM_I2C_GetStatus : Get I2C status.
} const ARM_DRIVER_I2C;
#ifdef __cplusplus
}
#endif
#endif /* DRIVER_I2C_H_ */

View File

@@ -0,0 +1,360 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Date: 2. Feb 2017
* $Revision: V2.3
*
* Project: MCI (Memory Card Interface) Driver definitions
*/
/* History:
* Version 2.3
* ARM_MCI_STATUS made volatile
* Version 2.2
* Added timeout and error flags to ARM_MCI_STATUS
* Added support for controlling optional RST_n pin (eMMC)
* Removed explicit Clock Control (ARM_MCI_CONTROL_CLOCK)
* Removed event ARM_MCI_EVENT_BOOT_ACK_TIMEOUT
* Version 2.1
* Decoupled SPI mode from MCI driver
* Replaced function ARM_MCI_CardSwitchRead with ARM_MCI_ReadCD and ARM_MCI_ReadWP
* Version 2.0
* Added support for:
* SD UHS-I (Ultra High Speed)
* SD I/O Interrupt
* Read Wait (SD I/O)
* Suspend/Resume (SD I/O)
* MMC Interrupt
* MMC Boot
* Stream Data transfer (MMC)
* VCCQ Power Supply Control (eMMC)
* Command Completion Signal (CCS) for CE-ATA
* Added ARM_MCI_Control function
* Added ARM_MCI_GetStatus function
* Removed ARM_MCI_BusMode, ARM_MCI_BusDataWidth, ARM_MCI_BusSingaling functions
* (replaced by ARM_MCI_Control)
* Changed ARM_MCI_CardPower function (voltage parameter)
* Changed ARM_MCI_SendCommnad function (flags parameter)
* Changed ARM_MCI_SetupTransfer function (mode parameter)
* Removed ARM_MCI_ReadTransfer and ARM_MCI_WriteTransfer functions
* Changed prefix ARM_DRV -> ARM_DRIVER
* Changed return values of some functions to int32_t
* Version 1.10
* Namespace prefix ARM_ added
* Version 1.00
* Initial release
*/
#ifndef DRIVER_MCI_H_
#define DRIVER_MCI_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include "Driver_Common.h"
#define ARM_MCI_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,3) /* API version */
/****** MCI Send Command Flags *****/
#define ARM_MCI_RESPONSE_Pos 0
#define ARM_MCI_RESPONSE_Msk (3UL << ARM_MCI_RESPONSE_Pos)
#define ARM_MCI_RESPONSE_NONE (0UL << ARM_MCI_RESPONSE_Pos) ///< No response expected (default)
#define ARM_MCI_RESPONSE_SHORT (1UL << ARM_MCI_RESPONSE_Pos) ///< Short response (48-bit)
#define ARM_MCI_RESPONSE_SHORT_BUSY (2UL << ARM_MCI_RESPONSE_Pos) ///< Short response with busy signal (48-bit)
#define ARM_MCI_RESPONSE_LONG (3UL << ARM_MCI_RESPONSE_Pos) ///< Long response (136-bit)
#define ARM_MCI_RESPONSE_INDEX (1UL << 2) ///< Check command index in response
#define ARM_MCI_RESPONSE_CRC (1UL << 3) ///< Check CRC in response
#define ARM_MCI_WAIT_BUSY (1UL << 4) ///< Wait until busy before sending the command
#define ARM_MCI_TRANSFER_DATA (1UL << 5) ///< Activate Data transfer
#define ARM_MCI_CARD_INITIALIZE (1UL << 6) ///< Execute Memory Card initialization sequence
#define ARM_MCI_INTERRUPT_COMMAND (1UL << 7) ///< Send Interrupt command (CMD40 - MMC only)
#define ARM_MCI_INTERRUPT_RESPONSE (1UL << 8) ///< Send Interrupt response (CMD40 - MMC only)
#define ARM_MCI_BOOT_OPERATION (1UL << 9) ///< Execute Boot operation (MMC only)
#define ARM_MCI_BOOT_ALTERNATIVE (1UL << 10) ///< Execute Alternative Boot operation (MMC only)
#define ARM_MCI_BOOT_ACK (1UL << 11) ///< Expect Boot Acknowledge (MMC only)
#define ARM_MCI_CCSD (1UL << 12) ///< Send Command Completion Signal Disable (CCSD) for CE-ATA device
#define ARM_MCI_CCS (1UL << 13) ///< Expect Command Completion Signal (CCS) for CE-ATA device
/****** MCI Setup Transfer Mode *****/
#define ARM_MCI_TRANSFER_READ (0UL << 0) ///< Data Read Transfer (from MCI)
#define ARM_MCI_TRANSFER_WRITE (1UL << 0) ///< Data Write Transfer (to MCI)
#define ARM_MCI_TRANSFER_BLOCK (0UL << 1) ///< Block Data transfer (default)
#define ARM_MCI_TRANSFER_STREAM (1UL << 1) ///< Stream Data transfer (MMC only)
/****** MCI Control Codes *****/
#define ARM_MCI_BUS_SPEED (0x01) ///< Set Bus Speed; arg = requested speed in bits/s; returns configured speed in bits/s
#define ARM_MCI_BUS_SPEED_MODE (0x02) ///< Set Bus Speed Mode as specified with arg
#define ARM_MCI_BUS_CMD_MODE (0x03) ///< Set CMD Line Mode as specified with arg
#define ARM_MCI_BUS_DATA_WIDTH (0x04) ///< Set Bus Data Width as specified with arg
#define ARM_MCI_DRIVER_STRENGTH (0x05) ///< Set SD UHS-I Driver Strength as specified with arg
#define ARM_MCI_CONTROL_RESET (0x06) ///< Control optional RST_n Pin (eMMC); arg: 0=inactive, 1=active
#define ARM_MCI_CONTROL_CLOCK_IDLE (0x07) ///< Control Clock generation on CLK Pin when idle; arg: 0=disabled, 1=enabled
#define ARM_MCI_UHS_TUNING_OPERATION (0x08) ///< Sampling clock Tuning operation (SD UHS-I); arg: 0=reset, 1=execute
#define ARM_MCI_UHS_TUNING_RESULT (0x09) ///< Sampling clock Tuning result (SD UHS-I); returns: 0=done, 1=in progress, -1=error
#define ARM_MCI_DATA_TIMEOUT (0x0A) ///< Set Data timeout; arg = timeout in bus cycles
#define ARM_MCI_CSS_TIMEOUT (0x0B) ///< Set Command Completion Signal (CCS) timeout; arg = timeout in bus cycles
#define ARM_MCI_MONITOR_SDIO_INTERRUPT (0x0C) ///< Monitor SD I/O interrupt: arg: 0=disabled, 1=enabled
#define ARM_MCI_CONTROL_READ_WAIT (0x0D) ///< Control Read/Wait for SD I/O; arg: 0=disabled, 1=enabled
#define ARM_MCI_SUSPEND_TRANSFER (0x0E) ///< Suspend Data transfer (SD I/O); returns number of remaining bytes to transfer
#define ARM_MCI_RESUME_TRANSFER (0x0F) ///< Resume Data transfer (SD I/O)
/*----- MCI Bus Speed Mode -----*/
#define ARM_MCI_BUS_DEFAULT_SPEED (0x00) ///< SD/MMC: Default Speed mode up to 25/26MHz
#define ARM_MCI_BUS_HIGH_SPEED (0x01) ///< SD/MMC: High Speed mode up to 50/52MHz
#define ARM_MCI_BUS_UHS_SDR12 (0x02) ///< SD: SDR12 (Single Data Rate) up to 25MHz, 12.5MB/s: UHS-I (Ultra High Speed) 1.8V signaling
#define ARM_MCI_BUS_UHS_SDR25 (0x03) ///< SD: SDR25 (Single Data Rate) up to 50MHz, 25 MB/s: UHS-I (Ultra High Speed) 1.8V signaling
#define ARM_MCI_BUS_UHS_SDR50 (0x04) ///< SD: SDR50 (Single Data Rate) up to 100MHz, 50 MB/s: UHS-I (Ultra High Speed) 1.8V signaling
#define ARM_MCI_BUS_UHS_SDR104 (0x05) ///< SD: SDR104 (Single Data Rate) up to 208MHz, 104 MB/s: UHS-I (Ultra High Speed) 1.8V signaling
#define ARM_MCI_BUS_UHS_DDR50 (0x06) ///< SD: DDR50 (Dual Data Rate) up to 50MHz, 50 MB/s: UHS-I (Ultra High Speed) 1.8V signaling
/*----- MCI CMD Line Mode -----*/
#define ARM_MCI_BUS_CMD_PUSH_PULL (0x00) ///< Push-Pull CMD line (default)
#define ARM_MCI_BUS_CMD_OPEN_DRAIN (0x01) ///< Open Drain CMD line (MMC only)
/*----- MCI Bus Data Width -----*/
#define ARM_MCI_BUS_DATA_WIDTH_1 (0x00) ///< Bus data width: 1 bit (default)
#define ARM_MCI_BUS_DATA_WIDTH_4 (0x01) ///< Bus data width: 4 bits
#define ARM_MCI_BUS_DATA_WIDTH_8 (0x02) ///< Bus data width: 8 bits
#define ARM_MCI_BUS_DATA_WIDTH_4_DDR (0x03) ///< Bus data width: 4 bits, DDR (Dual Data Rate) - MMC only
#define ARM_MCI_BUS_DATA_WIDTH_8_DDR (0x04) ///< Bus data width: 8 bits, DDR (Dual Data Rate) - MMC only
/*----- MCI Driver Strength -----*/
#define ARM_MCI_DRIVER_TYPE_A (0x01) ///< SD UHS-I Driver Type A
#define ARM_MCI_DRIVER_TYPE_B (0x00) ///< SD UHS-I Driver Type B (default)
#define ARM_MCI_DRIVER_TYPE_C (0x02) ///< SD UHS-I Driver Type C
#define ARM_MCI_DRIVER_TYPE_D (0x03) ///< SD UHS-I Driver Type D
/****** MCI Card Power *****/
#define ARM_MCI_POWER_VDD_Pos 0
#define ARM_MCI_POWER_VDD_Msk (0x0FUL << ARM_MCI_POWER_VDD_Pos)
#define ARM_MCI_POWER_VDD_OFF (0x01UL << ARM_MCI_POWER_VDD_Pos) ///< VDD (VCC) turned off
#define ARM_MCI_POWER_VDD_3V3 (0x02UL << ARM_MCI_POWER_VDD_Pos) ///< VDD (VCC) = 3.3V
#define ARM_MCI_POWER_VDD_1V8 (0x03UL << ARM_MCI_POWER_VDD_Pos) ///< VDD (VCC) = 1.8V
#define ARM_MCI_POWER_VCCQ_Pos 4
#define ARM_MCI_POWER_VCCQ_Msk (0x0FUL << ARM_MCI_POWER_VCCQ_Pos)
#define ARM_MCI_POWER_VCCQ_OFF (0x01UL << ARM_MCI_POWER_VCCQ_Pos) ///< eMMC VCCQ turned off
#define ARM_MCI_POWER_VCCQ_3V3 (0x02UL << ARM_MCI_POWER_VCCQ_Pos) ///< eMMC VCCQ = 3.3V
#define ARM_MCI_POWER_VCCQ_1V8 (0x03UL << ARM_MCI_POWER_VCCQ_Pos) ///< eMMC VCCQ = 1.8V
#define ARM_MCI_POWER_VCCQ_1V2 (0x04UL << ARM_MCI_POWER_VCCQ_Pos) ///< eMMC VCCQ = 1.2V
/**
\brief MCI Status
*/
typedef volatile struct _ARM_MCI_STATUS {
uint32_t command_active : 1; ///< Command active flag
uint32_t command_timeout : 1; ///< Command timeout flag (cleared on start of next command)
uint32_t command_error : 1; ///< Command error flag (cleared on start of next command)
uint32_t transfer_active : 1; ///< Transfer active flag
uint32_t transfer_timeout : 1; ///< Transfer timeout flag (cleared on start of next command)
uint32_t transfer_error : 1; ///< Transfer error flag (cleared on start of next command)
uint32_t sdio_interrupt : 1; ///< SD I/O Interrupt flag (cleared on start of monitoring)
uint32_t ccs : 1; ///< CCS flag (cleared on start of next command)
uint32_t reserved : 24;
} ARM_MCI_STATUS;
/****** MCI Card Event *****/
#define ARM_MCI_EVENT_CARD_INSERTED (1UL << 0) ///< Memory Card inserted
#define ARM_MCI_EVENT_CARD_REMOVED (1UL << 1) ///< Memory Card removed
#define ARM_MCI_EVENT_COMMAND_COMPLETE (1UL << 2) ///< Command completed
#define ARM_MCI_EVENT_COMMAND_TIMEOUT (1UL << 3) ///< Command timeout
#define ARM_MCI_EVENT_COMMAND_ERROR (1UL << 4) ///< Command response error (CRC error or invalid response)
#define ARM_MCI_EVENT_TRANSFER_COMPLETE (1UL << 5) ///< Data transfer completed
#define ARM_MCI_EVENT_TRANSFER_TIMEOUT (1UL << 6) ///< Data transfer timeout
#define ARM_MCI_EVENT_TRANSFER_ERROR (1UL << 7) ///< Data transfer CRC failed
#define ARM_MCI_EVENT_SDIO_INTERRUPT (1UL << 8) ///< SD I/O Interrupt
#define ARM_MCI_EVENT_CCS (1UL << 9) ///< Command Completion Signal (CCS)
#define ARM_MCI_EVENT_CCS_TIMEOUT (1UL << 10) ///< Command Completion Signal (CCS) Timeout
// Function documentation
/**
\fn ARM_DRIVER_VERSION ARM_MCI_GetVersion (void)
\brief Get driver version.
\return \ref ARM_DRIVER_VERSION
*/
/**
\fn ARM_MCI_CAPABILITIES ARM_MCI_GetCapabilities (void)
\brief Get driver capabilities.
\return \ref ARM_MCI_CAPABILITIES
*/
/**
\fn int32_t ARM_MCI_Initialize (ARM_MCI_SignalEvent_t cb_event)
\brief Initialize the Memory Card Interface
\param[in] cb_event Pointer to \ref ARM_MCI_SignalEvent
\return \ref execution_status
*/
/**
\fn int32_t ARM_MCI_Uninitialize (void)
\brief De-initialize Memory Card Interface.
\return \ref execution_status
*/
/**
\fn int32_t ARM_MCI_PowerControl (ARM_POWER_STATE state)
\brief Control Memory Card Interface Power.
\param[in] state Power state \ref ARM_POWER_STATE
\return \ref execution_status
*/
/**
\fn int32_t ARM_MCI_CardPower (uint32_t voltage)
\brief Set Memory Card Power supply voltage.
\param[in] voltage Memory Card Power supply voltage
\return \ref execution_status
*/
/**
\fn int32_t ARM_MCI_ReadCD (void)
\brief Read Card Detect (CD) state.
\return 1:card detected, 0:card not detected, or error
*/
/**
\fn int32_t ARM_MCI_ReadWP (void)
\brief Read Write Protect (WP) state.
\return 1:write protected, 0:not write protected, or error
*/
/**
\fn int32_t ARM_MCI_SendCommand (uint32_t cmd,
uint32_t arg,
uint32_t flags,
uint32_t *response)
\brief Send Command to card and get the response.
\param[in] cmd Memory Card command
\param[in] arg Command argument
\param[in] flags Command flags
\param[out] response Pointer to buffer for response
\return \ref execution_status
*/
/**
\fn int32_t ARM_MCI_SetupTransfer (uint8_t *data,
uint32_t block_count,
uint32_t block_size,
uint32_t mode)
\brief Setup read or write transfer operation.
\param[in,out] data Pointer to data block(s) to be written or read
\param[in] block_count Number of blocks
\param[in] block_size Size of a block in bytes
\param[in] mode Transfer mode
\return \ref execution_status
*/
/**
\fn int32_t ARM_MCI_AbortTransfer (void)
\brief Abort current read/write data transfer.
\return \ref execution_status
*/
/**
\fn int32_t ARM_MCI_Control (uint32_t control, uint32_t arg)
\brief Control MCI Interface.
\param[in] control Operation
\param[in] arg Argument of operation (optional)
\return \ref execution_status
*/
/**
\fn ARM_MCI_STATUS ARM_MCI_GetStatus (void)
\brief Get MCI status.
\return MCI status \ref ARM_MCI_STATUS
*/
/**
\fn void ARM_MCI_SignalEvent (uint32_t event)
\brief Callback function that signals a MCI Card Event.
\param[in] event \ref mci_event_gr
\return none
*/
typedef void (*ARM_MCI_SignalEvent_t) (uint32_t event); ///< Pointer to \ref ARM_MCI_SignalEvent : Signal MCI Card Event.
/**
\brief MCI Driver Capabilities.
*/
typedef struct _ARM_MCI_CAPABILITIES {
uint32_t cd_state : 1; ///< Card Detect State available
uint32_t cd_event : 1; ///< Signal Card Detect change event
uint32_t wp_state : 1; ///< Write Protect State available
uint32_t vdd : 1; ///< Supports VDD Card Power Supply Control
uint32_t vdd_1v8 : 1; ///< Supports 1.8 VDD Card Power Supply
uint32_t vccq : 1; ///< Supports VCCQ Card Power Supply Control (eMMC)
uint32_t vccq_1v8 : 1; ///< Supports 1.8 VCCQ Card Power Supply (eMMC)
uint32_t vccq_1v2 : 1; ///< Supports 1.2 VCCQ Card Power Supply (eMMC)
uint32_t data_width_4 : 1; ///< Supports 4-bit data
uint32_t data_width_8 : 1; ///< Supports 8-bit data
uint32_t data_width_4_ddr : 1; ///< Supports 4-bit data, DDR (Dual Data Rate) - MMC only
uint32_t data_width_8_ddr : 1; ///< Supports 8-bit data, DDR (Dual Data Rate) - MMC only
uint32_t high_speed : 1; ///< Supports SD/MMC High Speed Mode
uint32_t uhs_signaling : 1; ///< Supports SD UHS-I (Ultra High Speed) 1.8V signaling
uint32_t uhs_tuning : 1; ///< Supports SD UHS-I tuning
uint32_t uhs_sdr50 : 1; ///< Supports SD UHS-I SDR50 (Single Data Rate) up to 50MB/s
uint32_t uhs_sdr104 : 1; ///< Supports SD UHS-I SDR104 (Single Data Rate) up to 104MB/s
uint32_t uhs_ddr50 : 1; ///< Supports SD UHS-I DDR50 (Dual Data Rate) up to 50MB/s
uint32_t uhs_driver_type_a : 1; ///< Supports SD UHS-I Driver Type A
uint32_t uhs_driver_type_c : 1; ///< Supports SD UHS-I Driver Type C
uint32_t uhs_driver_type_d : 1; ///< Supports SD UHS-I Driver Type D
uint32_t sdio_interrupt : 1; ///< Supports SD I/O Interrupt
uint32_t read_wait : 1; ///< Supports Read Wait (SD I/O)
uint32_t suspend_resume : 1; ///< Supports Suspend/Resume (SD I/O)
uint32_t mmc_interrupt : 1; ///< Supports MMC Interrupt
uint32_t mmc_boot : 1; ///< Supports MMC Boot
uint32_t rst_n : 1; ///< Supports RST_n Pin Control (eMMC)
uint32_t ccs : 1; ///< Supports Command Completion Signal (CCS) for CE-ATA
uint32_t ccs_timeout : 1; ///< Supports Command Completion Signal (CCS) timeout for CE-ATA
uint32_t reserved : 3; ///< Reserved (must be zero)
} ARM_MCI_CAPABILITIES;
/**
\brief Access structure of the MCI Driver.
*/
typedef struct _ARM_DRIVER_MCI {
ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_MCI_GetVersion : Get driver version.
ARM_MCI_CAPABILITIES (*GetCapabilities)(void); ///< Pointer to \ref ARM_MCI_GetCapabilities : Get driver capabilities.
int32_t (*Initialize) (ARM_MCI_SignalEvent_t cb_event); ///< Pointer to \ref ARM_MCI_Initialize : Initialize MCI Interface.
int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_MCI_Uninitialize : De-initialize MCI Interface.
int32_t (*PowerControl) (ARM_POWER_STATE state); ///< Pointer to \ref ARM_MCI_PowerControl : Control MCI Interface Power.
int32_t (*CardPower) (uint32_t voltage); ///< Pointer to \ref ARM_MCI_CardPower : Set card power supply voltage.
int32_t (*ReadCD) (void); ///< Pointer to \ref ARM_MCI_ReadCD : Read Card Detect (CD) state.
int32_t (*ReadWP) (void); ///< Pointer to \ref ARM_MCI_ReadWP : Read Write Protect (WP) state.
int32_t (*SendCommand) (uint32_t cmd,
uint32_t arg,
uint32_t flags,
uint32_t *response); ///< Pointer to \ref ARM_MCI_SendCommand : Send Command to card and get the response.
int32_t (*SetupTransfer) (uint8_t *data,
uint32_t block_count,
uint32_t block_size,
uint32_t mode); ///< Pointer to \ref ARM_MCI_SetupTransfer : Setup data transfer operation.
int32_t (*AbortTransfer) (void); ///< Pointer to \ref ARM_MCI_AbortTransfer : Abort current data transfer.
int32_t (*Control) (uint32_t control, uint32_t arg); ///< Pointer to \ref ARM_MCI_Control : Control MCI Interface.
ARM_MCI_STATUS (*GetStatus) (void); ///< Pointer to \ref ARM_MCI_GetStatus : Get MCI status.
} const ARM_DRIVER_MCI;
#ifdef __cplusplus
}
#endif
#endif /* DRIVER_MCI_H_ */

View File

@@ -0,0 +1,413 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Date: 2. Feb 2017
* $Revision: V2.2
*
* Project: NAND Flash Driver definitions
*/
/* History:
* Version 2.2
* ARM_NAND_STATUS made volatile
* Version 2.1
* Updated ARM_NAND_ECC_INFO structure and ARM_NAND_ECC_xxx definitions
* Version 2.0
* New simplified driver:
* complexity moved to upper layer (command agnostic)
* Added support for:
* NV-DDR & NV-DDR2 Interface (ONFI specification)
* VCC, VCCQ and VPP Power Supply Control
* WP (Write Protect) Control
* Version 1.11
* Changed prefix ARM_DRV -> ARM_DRIVER
* Version 1.10
* Namespace prefix ARM_ added
* Version 1.00
* Initial release
*/
#ifndef DRIVER_NAND_H_
#define DRIVER_NAND_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include "Driver_Common.h"
#define ARM_NAND_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,2) /* API version */
/****** NAND Device Power *****/
#define ARM_NAND_POWER_VCC_Pos 0
#define ARM_NAND_POWER_VCC_Msk (0x07UL << ARM_NAND_POWER_VCC_Pos)
#define ARM_NAND_POWER_VCC_OFF (0x01UL << ARM_NAND_POWER_VCC_Pos) ///< VCC Power off
#define ARM_NAND_POWER_VCC_3V3 (0x02UL << ARM_NAND_POWER_VCC_Pos) ///< VCC = 3.3V
#define ARM_NAND_POWER_VCC_1V8 (0x03UL << ARM_NAND_POWER_VCC_Pos) ///< VCC = 1.8V
#define ARM_NAND_POWER_VCCQ_Pos 3
#define ARM_NAND_POWER_VCCQ_Msk (0x07UL << ARM_NAND_POWER_VCCQ_Pos)
#define ARM_NAND_POWER_VCCQ_OFF (0x01UL << ARM_NAND_POWER_VCCQ_Pos) ///< VCCQ I/O Power off
#define ARM_NAND_POWER_VCCQ_3V3 (0x02UL << ARM_NAND_POWER_VCCQ_Pos) ///< VCCQ = 3.3V
#define ARM_NAND_POWER_VCCQ_1V8 (0x03UL << ARM_NAND_POWER_VCCQ_Pos) ///< VCCQ = 1.8V
#define ARM_NAND_POWER_VPP_OFF (1UL << 6) ///< VPP off
#define ARM_NAND_POWER_VPP_ON (1Ul << 7) ///< VPP on
/****** NAND Control Codes *****/
#define ARM_NAND_BUS_MODE (0x01) ///< Set Bus Mode as specified with arg
#define ARM_NAND_BUS_DATA_WIDTH (0x02) ///< Set Bus Data Width as specified with arg
#define ARM_NAND_DRIVER_STRENGTH (0x03) ///< Set Driver Strength as specified with arg
#define ARM_NAND_DEVICE_READY_EVENT (0x04) ///< Generate \ref ARM_NAND_EVENT_DEVICE_READY; arg: 0=disabled (default), 1=enabled
#define ARM_NAND_DRIVER_READY_EVENT (0x05) ///< Generate \ref ARM_NAND_EVENT_DRIVER_READY; arg: 0=disabled (default), 1=enabled
/*----- NAND Bus Mode (ONFI - Open NAND Flash Interface) -----*/
#define ARM_NAND_BUS_INTERFACE_Pos 4
#define ARM_NAND_BUS_INTERFACE_Msk (0x03UL << ARM_NAND_BUS_INTERFACE_Pos)
#define ARM_NAND_BUS_SDR (0x00UL << ARM_NAND_BUS_INTERFACE_Pos) ///< Data Interface: SDR (Single Data Rate) - Traditional interface (default)
#define ARM_NAND_BUS_DDR (0x01UL << ARM_NAND_BUS_INTERFACE_Pos) ///< Data Interface: NV-DDR (Double Data Rate)
#define ARM_NAND_BUS_DDR2 (0x02UL << ARM_NAND_BUS_INTERFACE_Pos) ///< Data Interface: NV-DDR2 (Double Data Rate)
#define ARM_NAND_BUS_TIMING_MODE_Pos 0
#define ARM_NAND_BUS_TIMING_MODE_Msk (0x0FUL << ARM_NAND_BUS_TIMING_MODE_Pos)
#define ARM_NAND_BUS_TIMING_MODE_0 (0x00UL << ARM_NAND_BUS_TIMING_MODE_Pos) ///< Timing Mode 0 (default)
#define ARM_NAND_BUS_TIMING_MODE_1 (0x01UL << ARM_NAND_BUS_TIMING_MODE_Pos) ///< Timing Mode 1
#define ARM_NAND_BUS_TIMING_MODE_2 (0x02UL << ARM_NAND_BUS_TIMING_MODE_Pos) ///< Timing Mode 2
#define ARM_NAND_BUS_TIMING_MODE_3 (0x03UL << ARM_NAND_BUS_TIMING_MODE_Pos) ///< Timing Mode 3
#define ARM_NAND_BUS_TIMING_MODE_4 (0x04UL << ARM_NAND_BUS_TIMING_MODE_Pos) ///< Timing Mode 4 (SDR EDO capable)
#define ARM_NAND_BUS_TIMING_MODE_5 (0x05UL << ARM_NAND_BUS_TIMING_MODE_Pos) ///< Timing Mode 5 (SDR EDO capable)
#define ARM_NAND_BUS_TIMING_MODE_6 (0x06UL << ARM_NAND_BUS_TIMING_MODE_Pos) ///< Timing Mode 6 (NV-DDR2 only)
#define ARM_NAND_BUS_TIMING_MODE_7 (0x07UL << ARM_NAND_BUS_TIMING_MODE_Pos) ///< Timing Mode 7 (NV-DDR2 only)
#define ARM_NAND_BUS_DDR2_DO_WCYC_Pos 8
#define ARM_NAND_BUS_DDR2_DO_WCYC_Msk (0x0FUL << ARM_NAND_BUS_DDR2_DO_WCYC_Pos)
#define ARM_NAND_BUS_DDR2_DO_WCYC_0 (0x00UL << ARM_NAND_BUS_DDR2_DO_WCYC_Pos) ///< DDR2 Data Output Warm-up cycles: 0 (default)
#define ARM_NAND_BUS_DDR2_DO_WCYC_1 (0x01UL << ARM_NAND_BUS_DDR2_DO_WCYC_Pos) ///< DDR2 Data Output Warm-up cycles: 1
#define ARM_NAND_BUS_DDR2_DO_WCYC_2 (0x02UL << ARM_NAND_BUS_DDR2_DO_WCYC_Pos) ///< DDR2 Data Output Warm-up cycles: 2
#define ARM_NAND_BUS_DDR2_DO_WCYC_4 (0x03UL << ARM_NAND_BUS_DDR2_DO_WCYC_Pos) ///< DDR2 Data Output Warm-up cycles: 4
#define ARM_NAND_BUS_DDR2_DI_WCYC_Pos 12
#define ARM_NAND_BUS_DDR2_DI_WCYC_Msk (0x0FUL << ARM_NAND_BUS_DDR2_DI_WCYC_Pos)
#define ARM_NAND_BUS_DDR2_DI_WCYC_0 (0x00UL << ARM_NAND_BUS_DDR2_DI_WCYC_Pos) ///< DDR2 Data Input Warm-up cycles: 0 (default)
#define ARM_NAND_BUS_DDR2_DI_WCYC_1 (0x01UL << ARM_NAND_BUS_DDR2_DI_WCYC_Pos) ///< DDR2 Data Input Warm-up cycles: 1
#define ARM_NAND_BUS_DDR2_DI_WCYC_2 (0x02UL << ARM_NAND_BUS_DDR2_DI_WCYC_Pos) ///< DDR2 Data Input Warm-up cycles: 2
#define ARM_NAND_BUS_DDR2_DI_WCYC_4 (0x03UL << ARM_NAND_BUS_DDR2_DI_WCYC_Pos) ///< DDR2 Data Input Warm-up cycles: 4
#define ARM_NAND_BUS_DDR2_VEN (1UL << 16) ///< DDR2 Enable external VREFQ as reference
#define ARM_NAND_BUS_DDR2_CMPD (1UL << 17) ///< DDR2 Enable complementary DQS (DQS_c) signal
#define ARM_NAND_BUS_DDR2_CMPR (1UL << 18) ///< DDR2 Enable complementary RE_n (RE_c) signal
/*----- NAND Data Bus Width -----*/
#define ARM_NAND_BUS_DATA_WIDTH_8 (0x00) ///< Bus Data Width: 8 bit (default)
#define ARM_NAND_BUS_DATA_WIDTH_16 (0x01) ///< Bus Data Width: 16 bit
/*----- NAND Driver Strength (ONFI - Open NAND Flash Interface) -----*/
#define ARM_NAND_DRIVER_STRENGTH_18 (0x00) ///< Driver Strength 2.0x = 18 Ohms
#define ARM_NAND_DRIVER_STRENGTH_25 (0x01) ///< Driver Strength 1.4x = 25 Ohms
#define ARM_NAND_DRIVER_STRENGTH_35 (0x02) ///< Driver Strength 1.0x = 35 Ohms (default)
#define ARM_NAND_DRIVER_STRENGTH_50 (0x03) ///< Driver Strength 0.7x = 50 Ohms
/****** NAND ECC for Read/Write Data Mode and Sequence Execution Code *****/
#define ARM_NAND_ECC_INDEX_Pos 0
#define ARM_NAND_ECC_INDEX_Msk (0xFFUL << ARM_NAND_ECC_INDEX_Pos)
#define ARM_NAND_ECC(n) ((n) & ARM_NAND_ECC_INDEX_Msk) ///< Select ECC
#define ARM_NAND_ECC0 (1UL << 8) ///< Use ECC0 of selected ECC
#define ARM_NAND_ECC1 (1UL << 9) ///< Use ECC1 of selected ECC
/****** NAND Flag for Read/Write Data Mode and Sequence Execution Code *****/
#define ARM_NAND_DRIVER_DONE_EVENT (1UL << 16) ///< Generate \ref ARM_NAND_EVENT_DRIVER_DONE
/****** NAND Sequence Execution Code *****/
#define ARM_NAND_CODE_SEND_CMD1 (1UL << 17) ///< Send Command 1
#define ARM_NAND_CODE_SEND_ADDR_COL1 (1UL << 18) ///< Send Column Address 1
#define ARM_NAND_CODE_SEND_ADDR_COL2 (1UL << 19) ///< Send Column Address 2
#define ARM_NAND_CODE_SEND_ADDR_ROW1 (1UL << 20) ///< Send Row Address 1
#define ARM_NAND_CODE_SEND_ADDR_ROW2 (1UL << 21) ///< Send Row Address 2
#define ARM_NAND_CODE_SEND_ADDR_ROW3 (1UL << 22) ///< Send Row Address 3
#define ARM_NAND_CODE_INC_ADDR_ROW (1UL << 23) ///< Auto-increment Row Address
#define ARM_NAND_CODE_WRITE_DATA (1UL << 24) ///< Write Data
#define ARM_NAND_CODE_SEND_CMD2 (1UL << 25) ///< Send Command 2
#define ARM_NAND_CODE_WAIT_BUSY (1UL << 26) ///< Wait while R/Bn busy
#define ARM_NAND_CODE_READ_DATA (1UL << 27) ///< Read Data
#define ARM_NAND_CODE_SEND_CMD3 (1UL << 28) ///< Send Command 3
#define ARM_NAND_CODE_READ_STATUS (1UL << 29) ///< Read Status byte and check FAIL bit (bit 0)
/*----- NAND Sequence Execution Code: Command -----*/
#define ARM_NAND_CODE_CMD1_Pos 0
#define ARM_NAND_CODE_CMD1_Msk (0xFFUL << ARM_NAND_CODE_CMD1_Pos)
#define ARM_NAND_CODE_CMD2_Pos 8
#define ARM_NAND_CODE_CMD2_Msk (0xFFUL << ARM_NAND_CODE_CMD2_Pos)
#define ARM_NAND_CODE_CMD3_Pos 16
#define ARM_NAND_CODE_CMD3_Msk (0xFFUL << ARM_NAND_CODE_CMD3_Pos)
/*----- NAND Sequence Execution Code: Column Address -----*/
#define ARM_NAND_CODE_ADDR_COL1_Pos 0
#define ARM_NAND_CODE_ADDR_COL1_Msk (0xFFUL << ARM_NAND_CODE_ADDR_COL1_Pos)
#define ARM_NAND_CODE_ADDR_COL2_Pos 8
#define ARM_NAND_CODE_ADDR_COL2_Msk (0xFFUL << ARM_NAND_CODE_ADDR_COL2_Pos)
/*----- NAND Sequence Execution Code: Row Address -----*/
#define ARM_NAND_CODE_ADDR_ROW1_Pos 0
#define ARM_NAND_CODE_ADDR_ROW1_Msk (0xFFUL << ARM_NAND_CODE_ADDR_ROW1_Pos)
#define ARM_NAND_CODE_ADDR_ROW2_Pos 8
#define ARM_NAND_CODE_ADDR_ROW2_Msk (0xFFUL << ARM_NAND_CODE_ADDR_ROW2_Pos)
#define ARM_NAND_CODE_ADDR_ROW3_Pos 16
#define ARM_NAND_CODE_ADDR_ROW3_Msk (0xFFUL << ARM_NAND_CODE_ADDR_ROW3_Pos)
/****** NAND specific error codes *****/
#define ARM_NAND_ERROR_ECC (ARM_DRIVER_ERROR_SPECIFIC - 1) ///< ECC generation/correction failed
/**
\brief NAND ECC (Error Correction Code) Information
*/
typedef struct _ARM_NAND_ECC_INFO {
uint32_t type : 2; ///< Type: 1=ECC0 over Data, 2=ECC0 over Data+Spare, 3=ECC0 over Data and ECC1 over Spare
uint32_t page_layout : 1; ///< Page layout: 0=|Data0|Spare0|...|DataN-1|SpareN-1|, 1=|Data0|...|DataN-1|Spare0|...|SpareN-1|
uint32_t page_count : 3; ///< Number of virtual pages: N = 2 ^ page_count
uint32_t page_size : 4; ///< Virtual Page size (Data+Spare): 0=512+16, 1=1k+32, 2=2k+64, 3=4k+128, 4=8k+256, 8=512+28, 9=1k+56, 10=2k+112, 11=4k+224, 12=8k+448
uint32_t reserved : 14; ///< Reserved (must be zero)
uint32_t correctable_bits : 8; ///< Number of correctable bits (based on 512 byte codeword size)
uint16_t codeword_size [2]; ///< Number of bytes over which ECC is calculated
uint16_t ecc_size [2]; ///< ECC size in bytes (rounded up)
uint16_t ecc_offset [2]; ///< ECC offset in bytes (where ECC starts in Spare area)
} ARM_NAND_ECC_INFO;
/**
\brief NAND Status
*/
typedef volatile struct _ARM_NAND_STATUS {
uint32_t busy : 1; ///< Driver busy flag
uint32_t ecc_error : 1; ///< ECC error detected (cleared on next Read/WriteData or ExecuteSequence)
uint32_t reserved : 30;
} ARM_NAND_STATUS;
/****** NAND Event *****/
#define ARM_NAND_EVENT_DEVICE_READY (1UL << 0) ///< Device Ready: R/Bn rising edge
#define ARM_NAND_EVENT_DRIVER_READY (1UL << 1) ///< Driver Ready
#define ARM_NAND_EVENT_DRIVER_DONE (1UL << 2) ///< Driver operation done
#define ARM_NAND_EVENT_ECC_ERROR (1UL << 3) ///< ECC could not correct data
// Function documentation
/**
\fn ARM_DRIVER_VERSION ARM_NAND_GetVersion (void)
\brief Get driver version.
\return \ref ARM_DRIVER_VERSION
*/
/**
\fn ARM_NAND_CAPABILITIES ARM_NAND_GetCapabilities (void)
\brief Get driver capabilities.
\return \ref ARM_NAND_CAPABILITIES
*/
/**
\fn int32_t ARM_NAND_Initialize (ARM_NAND_SignalEvent_t cb_event)
\brief Initialize the NAND Interface.
\param[in] cb_event Pointer to \ref ARM_NAND_SignalEvent
\return \ref execution_status
*/
/**
\fn int32_t ARM_NAND_Uninitialize (void)
\brief De-initialize the NAND Interface.
\return \ref execution_status
*/
/**
\fn int32_t ARM_NAND_PowerControl (ARM_POWER_STATE state)
\brief Control the NAND interface power.
\param[in] state Power state
\return \ref execution_status
*/
/**
\fn int32_t ARM_NAND_DevicePower (uint32_t voltage)
\brief Set device power supply voltage.
\param[in] voltage NAND Device supply voltage
\return \ref execution_status
*/
/**
\fn int32_t ARM_NAND_WriteProtect (uint32_t dev_num, bool enable)
\brief Control WPn (Write Protect).
\param[in] dev_num Device number
\param[in] enable
- \b false Write Protect off
- \b true Write Protect on
\return \ref execution_status
*/
/**
\fn int32_t ARM_NAND_ChipEnable (uint32_t dev_num, bool enable)
\brief Control CEn (Chip Enable).
\param[in] dev_num Device number
\param[in] enable
- \b false Chip Enable off
- \b true Chip Enable on
\return \ref execution_status
*/
/**
\fn int32_t ARM_NAND_GetDeviceBusy (uint32_t dev_num)
\brief Get Device Busy pin state.
\param[in] dev_num Device number
\return 1=busy, 0=not busy, or error
*/
/**
\fn int32_t ARM_NAND_SendCommand (uint32_t dev_num, uint8_t cmd)
\brief Send command to NAND device.
\param[in] dev_num Device number
\param[in] cmd Command
\return \ref execution_status
*/
/**
\fn int32_t ARM_NAND_SendAddress (uint32_t dev_num, uint8_t addr)
\brief Send address to NAND device.
\param[in] dev_num Device number
\param[in] addr Address
\return \ref execution_status
*/
/**
\fn int32_t ARM_NAND_ReadData (uint32_t dev_num, void *data, uint32_t cnt, uint32_t mode)
\brief Read data from NAND device.
\param[in] dev_num Device number
\param[out] data Pointer to buffer for data to read from NAND device
\param[in] cnt Number of data items to read
\param[in] mode Operation mode
\return number of data items read or \ref execution_status
*/
/**
\fn int32_t ARM_NAND_WriteData (uint32_t dev_num, const void *data, uint32_t cnt, uint32_t mode)
\brief Write data to NAND device.
\param[in] dev_num Device number
\param[out] data Pointer to buffer with data to write to NAND device
\param[in] cnt Number of data items to write
\param[in] mode Operation mode
\return number of data items written or \ref execution_status
*/
/**
\fn int32_t ARM_NAND_ExecuteSequence (uint32_t dev_num, uint32_t code, uint32_t cmd,
uint32_t addr_col, uint32_t addr_row,
void *data, uint32_t data_cnt,
uint8_t *status, uint32_t *count)
\brief Execute sequence of operations.
\param[in] dev_num Device number
\param[in] code Sequence code
\param[in] cmd Command(s)
\param[in] addr_col Column address
\param[in] addr_row Row address
\param[in,out] data Pointer to data to be written or read
\param[in] data_cnt Number of data items in one iteration
\param[out] status Pointer to status read
\param[in,out] count Number of iterations
\return \ref execution_status
*/
/**
\fn int32_t ARM_NAND_AbortSequence (uint32_t dev_num)
\brief Abort sequence execution.
\param[in] dev_num Device number
\return \ref execution_status
*/
/**
\fn int32_t ARM_NAND_Control (uint32_t dev_num, uint32_t control, uint32_t arg)
\brief Control NAND Interface.
\param[in] dev_num Device number
\param[in] control Operation
\param[in] arg Argument of operation
\return \ref execution_status
*/
/**
\fn ARM_NAND_STATUS ARM_NAND_GetStatus (uint32_t dev_num)
\brief Get NAND status.
\param[in] dev_num Device number
\return NAND status \ref ARM_NAND_STATUS
*/
/**
\fn int32_t ARM_NAND_InquireECC (int32_t index, ARM_NAND_ECC_INFO *info)
\brief Inquire about available ECC.
\param[in] index Device number
\param[out] info Pointer to ECC information \ref ARM_NAND_ECC_INFO retrieved
\return \ref execution_status
*/
/**
\fn void ARM_NAND_SignalEvent (uint32_t dev_num, uint32_t event)
\brief Signal NAND event.
\param[in] dev_num Device number
\param[in] event Event notification mask
\return none
*/
typedef void (*ARM_NAND_SignalEvent_t) (uint32_t dev_num, uint32_t event); ///< Pointer to \ref ARM_NAND_SignalEvent : Signal NAND Event.
/**
\brief NAND Driver Capabilities.
*/
typedef struct _ARM_NAND_CAPABILITIES {
uint32_t event_device_ready : 1; ///< Signal Device Ready event (R/Bn rising edge)
uint32_t reentrant_operation : 1; ///< Supports re-entrant operation (SendCommand/Address, Read/WriteData)
uint32_t sequence_operation : 1; ///< Supports Sequence operation (ExecuteSequence, AbortSequence)
uint32_t vcc : 1; ///< Supports VCC Power Supply Control
uint32_t vcc_1v8 : 1; ///< Supports 1.8 VCC Power Supply
uint32_t vccq : 1; ///< Supports VCCQ I/O Power Supply Control
uint32_t vccq_1v8 : 1; ///< Supports 1.8 VCCQ I/O Power Supply
uint32_t vpp : 1; ///< Supports VPP High Voltage Power Supply Control
uint32_t wp : 1; ///< Supports WPn (Write Protect) Control
uint32_t ce_lines : 4; ///< Number of CEn (Chip Enable) lines: ce_lines + 1
uint32_t ce_manual : 1; ///< Supports manual CEn (Chip Enable) Control
uint32_t rb_monitor : 1; ///< Supports R/Bn (Ready/Busy) Monitoring
uint32_t data_width_16 : 1; ///< Supports 16-bit data
uint32_t ddr : 1; ///< Supports NV-DDR Data Interface (ONFI)
uint32_t ddr2 : 1; ///< Supports NV-DDR2 Data Interface (ONFI)
uint32_t sdr_timing_mode : 3; ///< Fastest (highest) SDR Timing Mode supported (ONFI)
uint32_t ddr_timing_mode : 3; ///< Fastest (highest) NV_DDR Timing Mode supported (ONFI)
uint32_t ddr2_timing_mode : 3; ///< Fastest (highest) NV_DDR2 Timing Mode supported (ONFI)
uint32_t driver_strength_18 : 1; ///< Supports Driver Strength 2.0x = 18 Ohms
uint32_t driver_strength_25 : 1; ///< Supports Driver Strength 1.4x = 25 Ohms
uint32_t driver_strength_50 : 1; ///< Supports Driver Strength 0.7x = 50 Ohms
uint32_t reserved : 2; ///< Reserved (must be zero)
} ARM_NAND_CAPABILITIES;
/**
\brief Access structure of the NAND Driver.
*/
typedef struct _ARM_DRIVER_NAND {
ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_NAND_GetVersion : Get driver version.
ARM_NAND_CAPABILITIES (*GetCapabilities)(void); ///< Pointer to \ref ARM_NAND_GetCapabilities : Get driver capabilities.
int32_t (*Initialize) (ARM_NAND_SignalEvent_t cb_event); ///< Pointer to \ref ARM_NAND_Initialize : Initialize NAND Interface.
int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_NAND_Uninitialize : De-initialize NAND Interface.
int32_t (*PowerControl) (ARM_POWER_STATE state); ///< Pointer to \ref ARM_NAND_PowerControl : Control NAND Interface Power.
int32_t (*DevicePower) (uint32_t voltage); ///< Pointer to \ref ARM_NAND_DevicePower : Set device power supply voltage.
int32_t (*WriteProtect) (uint32_t dev_num, bool enable); ///< Pointer to \ref ARM_NAND_WriteProtect : Control WPn (Write Protect).
int32_t (*ChipEnable) (uint32_t dev_num, bool enable); ///< Pointer to \ref ARM_NAND_ChipEnable : Control CEn (Chip Enable).
int32_t (*GetDeviceBusy) (uint32_t dev_num); ///< Pointer to \ref ARM_NAND_GetDeviceBusy : Get Device Busy pin state.
int32_t (*SendCommand) (uint32_t dev_num, uint8_t cmd); ///< Pointer to \ref ARM_NAND_SendCommand : Send command to NAND device.
int32_t (*SendAddress) (uint32_t dev_num, uint8_t addr); ///< Pointer to \ref ARM_NAND_SendAddress : Send address to NAND device.
int32_t (*ReadData) (uint32_t dev_num, void *data, uint32_t cnt, uint32_t mode); ///< Pointer to \ref ARM_NAND_ReadData : Read data from NAND device.
int32_t (*WriteData) (uint32_t dev_num, const void *data, uint32_t cnt, uint32_t mode); ///< Pointer to \ref ARM_NAND_WriteData : Write data to NAND device.
int32_t (*ExecuteSequence)(uint32_t dev_num, uint32_t code, uint32_t cmd,
uint32_t addr_col, uint32_t addr_row,
void *data, uint32_t data_cnt,
uint8_t *status, uint32_t *count); ///< Pointer to \ref ARM_NAND_ExecuteSequence : Execute sequence of operations.
int32_t (*AbortSequence) (uint32_t dev_num); ///< Pointer to \ref ARM_NAND_AbortSequence : Abort sequence execution.
int32_t (*Control) (uint32_t dev_num, uint32_t control, uint32_t arg); ///< Pointer to \ref ARM_NAND_Control : Control NAND Interface.
ARM_NAND_STATUS (*GetStatus) (uint32_t dev_num); ///< Pointer to \ref ARM_NAND_GetStatus : Get NAND status.
int32_t (*InquireECC) ( int32_t index, ARM_NAND_ECC_INFO *info); ///< Pointer to \ref ARM_NAND_InquireECC : Inquire about available ECC.
} const ARM_DRIVER_NAND;
#ifdef __cplusplus
}
#endif
#endif /* DRIVER_NAND_H_ */

View File

@@ -0,0 +1,308 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Date: 2. Feb 2017
* $Revision: V1.1
*
* Project: SAI (Serial Audio Interface) Driver definitions
*/
/* History:
* Version 1.1
* ARM_SAI_STATUS made volatile
* Version 1.0
* Initial release
*/
#ifndef DRIVER_SAI_H_
#define DRIVER_SAI_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include "Driver_Common.h"
#define ARM_SAI_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1,1) /* API version */
/****** SAI Control Codes *****/
#define ARM_SAI_CONTROL_Msk (0xFFU)
#define ARM_SAI_CONFIGURE_TX (0x01U) ///< Configure Transmitter; arg1 and arg2 provide additional configuration
#define ARM_SAI_CONFIGURE_RX (0x02U) ///< Configure Receiver; arg1 and arg2 provide additional configuration
#define ARM_SAI_CONTROL_TX (0x03U) ///< Control Transmitter; arg1.0: 0=disable (default), 1=enable; arg1.1: mute
#define ARM_SAI_CONTROL_RX (0x04U) ///< Control Receiver; arg1.0: 0=disable (default), 1=enable
#define ARM_SAI_MASK_SLOTS_TX (0x05U) ///< Mask Transmitter slots; arg1 = mask (bit: 0=active, 1=inactive); all configured slots are active by default
#define ARM_SAI_MASK_SLOTS_RX (0x06U) ///< Mask Receiver slots; arg1 = mask (bit: 0=active, 1=inactive); all configured slots are active by default
#define ARM_SAI_ABORT_SEND (0x07U) ///< Abort \ref ARM_SAI_Send
#define ARM_SAI_ABORT_RECEIVE (0x08U) ///< Abort \ref ARM_SAI_Receive
/*----- SAI Control Codes: Configuration Parameters: Mode -----*/
#define ARM_SAI_MODE_Pos 8
#define ARM_SAI_MODE_Msk (1U << ARM_SAI_MODE_Pos)
#define ARM_SAI_MODE_MASTER (1U << ARM_SAI_MODE_Pos) ///< Master Mode
#define ARM_SAI_MODE_SLAVE (0U << ARM_SAI_MODE_Pos) ///< Slave Mode (default)
/*----- SAI Control Codes: Configuration Parameters: Synchronization -----*/
#define ARM_SAI_SYNCHRONIZATION_Pos 9
#define ARM_SAI_SYNCHRONIZATION_Msk (1U << ARM_SAI_SYNCHRONIZATION_Pos)
#define ARM_SAI_ASYNCHRONOUS (0U << ARM_SAI_SYNCHRONIZATION_Pos) ///< Asynchronous (default)
#define ARM_SAI_SYNCHRONOUS (1U << ARM_SAI_SYNCHRONIZATION_Pos) ///< Synchronous
/*----- SAI Control Codes: Configuration Parameters: Protocol -----*/
#define ARM_SAI_PROTOCOL_Pos 10
#define ARM_SAI_PROTOCOL_Msk (7U << ARM_SAI_PROTOCOL_Pos)
#define ARM_SAI_PROTOCOL_USER (0U << ARM_SAI_PROTOCOL_Pos) ///< User defined (default)
#define ARM_SAI_PROTOCOL_I2S (1U << ARM_SAI_PROTOCOL_Pos) ///< I2S
#define ARM_SAI_PROTOCOL_MSB_JUSTIFIED (2U << ARM_SAI_PROTOCOL_Pos) ///< MSB (left) justified
#define ARM_SAI_PROTOCOL_LSB_JUSTIFIED (3U << ARM_SAI_PROTOCOL_Pos) ///< LSB (right) justified
#define ARM_SAI_PROTOCOL_PCM_SHORT (4U << ARM_SAI_PROTOCOL_Pos) ///< PCM with short frame
#define ARM_SAI_PROTOCOL_PCM_LONG (5U << ARM_SAI_PROTOCOL_Pos) ///< PCM with long frame
#define ARM_SAI_PROTOCOL_AC97 (6U << ARM_SAI_PROTOCOL_Pos) ///< AC'97
/*----- SAI Control Codes: Configuration Parameters: Data Size -----*/
#define ARM_SAI_DATA_SIZE_Pos 13
#define ARM_SAI_DATA_SIZE_Msk (0x1FU << ARM_SAI_DATA_SIZE_Pos)
#define ARM_SAI_DATA_SIZE(n) ((((n)-1)&0x1FU) << ARM_SAI_DATA_SIZE_Pos) ///< Data size in bits (8..32)
/*----- SAI Control Codes: Configuration Parameters: Bit Order -----*/
#define ARM_SAI_BIT_ORDER_Pos 18
#define ARM_SAI_BIT_ORDER_Msk (1U << ARM_SAI_BIT_ORDER_Pos)
#define ARM_SAI_MSB_FIRST (0U << ARM_SAI_BIT_ORDER_Pos) ///< Data is transferred with MSB first (default)
#define ARM_SAI_LSB_FIRST (1U << ARM_SAI_BIT_ORDER_Pos) ///< Data is transferred with LSB first; User Protocol only (ignored otherwise)
/*----- SAI Control Codes: Configuration Parameters: Mono Mode -----*/
#define ARM_SAI_MONO_MODE (1U << 19) ///< Mono Mode (only for I2S, MSB/LSB justified)
/*----- SAI Control Codes:Configuration Parameters: Companding -----*/
#define ARM_SAI_COMPANDING_Pos 20
#define ARM_SAI_COMPANDING_Msk (3U << ARM_SAI_COMPANDING_Pos)
#define ARM_SAI_COMPANDING_NONE (0U << ARM_SAI_COMPANDING_Pos) ///< No compading (default)
#define ARM_SAI_COMPANDING_A_LAW (2U << ARM_SAI_COMPANDING_Pos) ///< A-Law companding
#define ARM_SAI_COMPANDING_U_LAW (3U << ARM_SAI_COMPANDING_Pos) ///< u-Law companding
/*----- SAI Control Codes: Configuration Parameters: Clock Polarity -----*/
#define ARM_SAI_CLOCK_POLARITY_Pos 23
#define ARM_SAI_CLOCK_POLARITY_Msk (1U << ARM_SAI_CLOCK_POLARITY_Pos)
#define ARM_SAI_CLOCK_POLARITY_0 (0U << ARM_SAI_CLOCK_POLARITY_Pos) ///< Drive on falling edge, Capture on rising edge (default)
#define ARM_SAI_CLOCK_POLARITY_1 (1U << ARM_SAI_CLOCK_POLARITY_Pos) ///< Drive on rising edge, Capture on falling edge
/*----- SAI Control Codes: Configuration Parameters: Master Clock Pin -----*/
#define ARM_SAI_MCLK_PIN_Pos 24
#define ARM_SAI_MCLK_PIN_Msk (3U << ARM_SAI_MCLK_PIN_Pos)
#define ARM_SAI_MCLK_PIN_INACTIVE (0U << ARM_SAI_MCLK_PIN_Pos) ///< MCLK not used (default)
#define ARM_SAI_MCLK_PIN_OUTPUT (1U << ARM_SAI_MCLK_PIN_Pos) ///< MCLK is output (Master only)
#define ARM_SAI_MCLK_PIN_INPUT (2U << ARM_SAI_MCLK_PIN_Pos) ///< MCLK is input (Master only)
/****** SAI Configuration (arg1) *****/
/*----- SAI Configuration (arg1): Frame Length -----*/
#define ARM_SAI_FRAME_LENGTH_Pos 0
#define ARM_SAI_FRAME_LENGTH_Msk (0x3FFU << ARM_SAI_FRAME_LENGTH_Pos)
#define ARM_SAI_FRAME_LENGTH(n) ((((n)-1)&0x3FFU) << ARM_SAI_FRAME_LENGTH_Pos) ///< Frame length in bits (8..1024); default depends on protocol and data
/*----- SAI Configuration (arg1): Frame Sync Width -----*/
#define ARM_SAI_FRAME_SYNC_WIDTH_Pos 10
#define ARM_SAI_FRAME_SYNC_WIDTH_Msk (0xFFU << ARM_SAI_FRAME_SYNC_WIDTH_Pos)
#define ARM_SAI_FRAME_SYNC_WIDTH(n) ((((n)-1)&0xFFU) << ARM_SAI_FRAME_SYNC_WIDTH_Pos) ///< Frame Sync width in bits (1..256); default=1; User Protocol only (ignored otherwise)
/*----- SAI Configuration (arg1): Frame Sync Polarity -----*/
#define ARM_SAI_FRAME_SYNC_POLARITY_Pos 18
#define ARM_SAI_FRAME_SYNC_POLARITY_Msk (1U << ARM_SAI_FRAME_SYNC_POLARITY_Pos)
#define ARM_SAI_FRAME_SYNC_POLARITY_HIGH (0U << ARM_SAI_FRAME_SYNC_POLARITY_Pos) ///< Frame Sync is active high (default); User Protocol only (ignored otherwise)
#define ARM_SAI_FRAME_SYNC_POLARITY_LOW (1U << ARM_SAI_FRAME_SYNC_POLARITY_Pos) ///< Frame Sync is active low; User Protocol only (ignored otherwise)
/*----- SAI Configuration (arg1): Frame Sync Early -----*/
#define ARM_SAI_FRAME_SYNC_EARLY (1U << 19) ///< Frame Sync one bit before the first bit of the frame; User Protocol only (ignored otherwise)
/*----- SAI Configuration (arg1): Slot Count -----*/
#define ARM_SAI_SLOT_COUNT_Pos 20
#define ARM_SAI_SLOT_COUNT_Msk (0x1FU << ARM_SAI_SLOT_COUNT_Pos)
#define ARM_SAI_SLOT_COUNT(n) ((((n)-1)&0x1FU) << ARM_SAI_SLOT_COUNT_Pos) ///< Number of slots in frame (1..32); default=1; User Protocol only (ignored otherwise)
/*----- SAI Configuration (arg1): Slot Size -----*/
#define ARM_SAI_SLOT_SIZE_Pos 25
#define ARM_SAI_SLOT_SIZE_Msk (3U << ARM_SAI_SLOT_SIZE_Pos)
#define ARM_SAI_SLOT_SIZE_DEFAULT (0U << ARM_SAI_SLOT_SIZE_Pos) ///< Slot size is equal to data size (default)
#define ARM_SAI_SLOT_SIZE_16 (1U << ARM_SAI_SLOT_SIZE_Pos) ///< Slot size = 16 bits; User Protocol only (ignored otherwise)
#define ARM_SAI_SLOT_SIZE_32 (3U << ARM_SAI_SLOT_SIZE_Pos) ///< Slot size = 32 bits; User Protocol only (ignored otherwise)
/*----- SAI Configuration (arg1): Slot Offset -----*/
#define ARM_SAI_SLOT_OFFSET_Pos 27
#define ARM_SAI_SLOT_OFFSET_Msk (0x1FU << ARM_SAI_SLOT_OFFSET_Pos)
#define ARM_SAI_SLOT_OFFSET(n) (((n)&0x1FU) << ARM_SAI_SLOT_OFFSET_Pos) ///< Offset of first data bit in slot (0..31); default=0; User Protocol only (ignored otherwise)
/****** SAI Configuration (arg2) *****/
/*----- SAI Control Codes: Configuration Parameters: Audio Frequency (Master only) -----*/
#define ARM_SAI_AUDIO_FREQ_Msk (0x0FFFFFU) ///< Audio frequency mask
/*----- SAI Control Codes: Configuration Parameters: Master Clock Prescaler (Master only and MCLK Pin) -----*/
#define ARM_SAI_MCLK_PRESCALER_Pos 20
#define ARM_SAI_MCLK_PRESCALER_Msk (0xFFFU << ARM_SAI_MCLK_PRESCALER_Pos)
#define ARM_SAI_MCLK_PRESCALER(n) ((((n)-1)&0xFFFU) << ARM_SAI_MCLK_PRESCALER_Pos) ///< MCLK prescaler; Audio_frequency = MCLK/n; n = 1..4096 (default=1)
/****** SAI specific error codes *****/
#define ARM_SAI_ERROR_SYNCHRONIZATION (ARM_DRIVER_ERROR_SPECIFIC - 1) ///< Specified Synchronization not supported
#define ARM_SAI_ERROR_PROTOCOL (ARM_DRIVER_ERROR_SPECIFIC - 2) ///< Specified Protocol not supported
#define ARM_SAI_ERROR_DATA_SIZE (ARM_DRIVER_ERROR_SPECIFIC - 3) ///< Specified Data size not supported
#define ARM_SAI_ERROR_BIT_ORDER (ARM_DRIVER_ERROR_SPECIFIC - 4) ///< Specified Bit order not supported
#define ARM_SAI_ERROR_MONO_MODE (ARM_DRIVER_ERROR_SPECIFIC - 5) ///< Specified Mono mode not supported
#define ARM_SAI_ERROR_COMPANDING (ARM_DRIVER_ERROR_SPECIFIC - 6) ///< Specified Companding not supported
#define ARM_SAI_ERROR_CLOCK_POLARITY (ARM_DRIVER_ERROR_SPECIFIC - 7) ///< Specified Clock polarity not supported
#define ARM_SAI_ERROR_AUDIO_FREQ (ARM_DRIVER_ERROR_SPECIFIC - 8) ///< Specified Audio frequency not supported
#define ARM_SAI_ERROR_MCLK_PIN (ARM_DRIVER_ERROR_SPECIFIC - 9) ///< Specified MCLK Pin setting not supported
#define ARM_SAI_ERROR_MCLK_PRESCALER (ARM_DRIVER_ERROR_SPECIFIC - 10) ///< Specified MCLK Prescaler not supported
#define ARM_SAI_ERROR_FRAME_LENGHT (ARM_DRIVER_ERROR_SPECIFIC - 11) ///< Specified Frame length not supported
#define ARM_SAI_ERROR_FRAME_SYNC_WIDTH (ARM_DRIVER_ERROR_SPECIFIC - 12) ///< Specified Frame Sync width not supported
#define ARM_SAI_ERROR_FRAME_SYNC_POLARITY (ARM_DRIVER_ERROR_SPECIFIC - 13) ///< Specified Frame Sync polarity not supported
#define ARM_SAI_ERROR_FRAME_SYNC_EARLY (ARM_DRIVER_ERROR_SPECIFIC - 14) ///< Specified Frame Sync early not supported
#define ARM_SAI_ERROR_SLOT_COUNT (ARM_DRIVER_ERROR_SPECIFIC - 15) ///< Specified Slot count not supported
#define ARM_SAI_ERROR_SLOT_SIZE (ARM_DRIVER_ERROR_SPECIFIC - 16) ///< Specified Slot size not supported
#define ARM_SAI_ERROR_SLOT_OFFESET (ARM_DRIVER_ERROR_SPECIFIC - 17) ///< Specified Slot offset not supported
/**
\brief SAI Status
*/
typedef volatile struct _ARM_SAI_STATUS {
uint32_t tx_busy : 1; ///< Transmitter busy flag
uint32_t rx_busy : 1; ///< Receiver busy flag
uint32_t tx_underflow : 1; ///< Transmit data underflow detected (cleared on start of next send operation)
uint32_t rx_overflow : 1; ///< Receive data overflow detected (cleared on start of next receive operation)
uint32_t frame_error : 1; ///< Sync Frame error detected (cleared on start of next send/receive operation)
uint32_t reserved : 27;
} ARM_SAI_STATUS;
/****** SAI Event *****/
#define ARM_SAI_EVENT_SEND_COMPLETE (1U << 0) ///< Send completed
#define ARM_SAI_EVENT_RECEIVE_COMPLETE (1U << 1) ///< Receive completed
#define ARM_SAI_EVENT_TX_UNDERFLOW (1U << 2) ///< Transmit data not available
#define ARM_SAI_EVENT_RX_OVERFLOW (1U << 3) ///< Receive data overflow
#define ARM_SAI_EVENT_FRAME_ERROR (1U << 4) ///< Sync Frame error in Slave mode (optional)
// Function documentation
/**
\fn ARM_DRIVER_VERSION ARM_SAI_GetVersion (void)
\brief Get driver version.
\return \ref ARM_DRIVER_VERSION
\fn ARM_SAI_CAPABILITIES ARM_SAI_GetCapabilities (void)
\brief Get driver capabilities.
\return \ref ARM_SAI_CAPABILITIES
\fn int32_t ARM_SAI_Initialize (ARM_SAI_SignalEvent_t cb_event)
\brief Initialize SAI Interface.
\param[in] cb_event Pointer to \ref ARM_SAI_SignalEvent
\return \ref execution_status
\fn int32_t ARM_SAI_Uninitialize (void)
\brief De-initialize SAI Interface.
\return \ref execution_status
\fn int32_t ARM_SAI_PowerControl (ARM_POWER_STATE state)
\brief Control SAI Interface Power.
\param[in] state Power state
\return \ref execution_status
\fn int32_t ARM_SAI_Send (const void *data, uint32_t num)
\brief Start sending data to SAI transmitter.
\param[in] data Pointer to buffer with data to send to SAI transmitter
\param[in] num Number of data items to send
\return \ref execution_status
\fn int32_t ARM_SAI_Receive (void *data, uint32_t num)
\brief Start receiving data from SAI receiver.
\param[out] data Pointer to buffer for data to receive from SAI receiver
\param[in] num Number of data items to receive
\return \ref execution_status
\fn uint32_t ARM_SAI_GetTxCount (void)
\brief Get transmitted data count.
\return number of data items transmitted
\fn uint32_t ARM_SAI_GetRxCount (void)
\brief Get received data count.
\return number of data items received
\fn int32_t ARM_SAI_Control (uint32_t control, uint32_t arg1, uint32_t arg2)
\brief Control SAI Interface.
\param[in] control Operation
\param[in] arg1 Argument 1 of operation (optional)
\param[in] arg2 Argument 2 of operation (optional)
\return common \ref execution_status and driver specific \ref sai_execution_status
\fn ARM_SAI_STATUS ARM_SAI_GetStatus (void)
\brief Get SAI status.
\return SAI status \ref ARM_SAI_STATUS
\fn void ARM_SAI_SignalEvent (uint32_t event)
\brief Signal SAI Events.
\param[in] event \ref SAI_events notification mask
\return none
*/
typedef void (*ARM_SAI_SignalEvent_t) (uint32_t event); ///< Pointer to \ref ARM_SAI_SignalEvent : Signal SAI Event.
/**
\brief SAI Driver Capabilities.
*/
typedef struct _ARM_SAI_CAPABILITIES {
uint32_t asynchronous : 1; ///< supports asynchronous Transmit/Receive
uint32_t synchronous : 1; ///< supports synchronous Transmit/Receive
uint32_t protocol_user : 1; ///< supports user defined Protocol
uint32_t protocol_i2s : 1; ///< supports I2S Protocol
uint32_t protocol_justified : 1; ///< supports MSB/LSB justified Protocol
uint32_t protocol_pcm : 1; ///< supports PCM short/long frame Protocol
uint32_t protocol_ac97 : 1; ///< supports AC'97 Protocol
uint32_t mono_mode : 1; ///< supports Mono mode
uint32_t companding : 1; ///< supports Companding
uint32_t mclk_pin : 1; ///< supports MCLK (Master Clock) pin
uint32_t event_frame_error : 1; ///< supports Frame error event: \ref ARM_SAI_EVENT_FRAME_ERROR
uint32_t reserved : 21; ///< Reserved (must be zero)
} ARM_SAI_CAPABILITIES;
/**
\brief Access structure of the SAI Driver.
*/
typedef struct _ARM_DRIVER_SAI {
ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_SAI_GetVersion : Get driver version.
ARM_SAI_CAPABILITIES (*GetCapabilities) (void); ///< Pointer to \ref ARM_SAI_GetCapabilities : Get driver capabilities.
int32_t (*Initialize) (ARM_SAI_SignalEvent_t cb_event); ///< Pointer to \ref ARM_SAI_Initialize : Initialize SAI Interface.
int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_SAI_Uninitialize : De-initialize SAI Interface.
int32_t (*PowerControl) (ARM_POWER_STATE state); ///< Pointer to \ref ARM_SAI_PowerControl : Control SAI Interface Power.
int32_t (*Send) (const void *data, uint32_t num); ///< Pointer to \ref ARM_SAI_Send : Start sending data to SAI Interface.
int32_t (*Receive) ( void *data, uint32_t num); ///< Pointer to \ref ARM_SAI_Receive : Start receiving data from SAI Interface.
uint32_t (*GetTxCount) (void); ///< Pointer to \ref ARM_SAI_GetTxCount : Get transmitted data count.
uint32_t (*GetRxCount) (void); ///< Pointer to \ref ARM_SAI_GetRxCount : Get received data count.
int32_t (*Control) (uint32_t control, uint32_t arg1, uint32_t arg2); ///< Pointer to \ref ARM_SAI_Control : Control SAI Interface.
ARM_SAI_STATUS (*GetStatus) (void); ///< Pointer to \ref ARM_SAI_GetStatus : Get SAI status.
} const ARM_DRIVER_SAI;
#ifdef __cplusplus
}
#endif
#endif /* DRIVER_SAI_H_ */

View File

@@ -0,0 +1,247 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Date: 2. Feb 2017
* $Revision: V2.2
*
* Project: SPI (Serial Peripheral Interface) Driver definitions
*/
/* History:
* Version 2.2
* ARM_SPI_STATUS made volatile
* Version 2.1
* Renamed status flag "tx_rx_busy" to "busy"
* Version 2.0
* New simplified driver:
* complexity moved to upper layer (especially data handling)
* more unified API for different communication interfaces
* Added:
* Slave Mode
* Half-duplex Modes
* Configurable number of data bits
* Support for TI Mode and Microwire
* Changed prefix ARM_DRV -> ARM_DRIVER
* Version 1.10
* Namespace prefix ARM_ added
* Version 1.01
* Added "send_done_event" to Capabilities
* Version 1.00
* Initial release
*/
#ifndef DRIVER_SPI_H_
#define DRIVER_SPI_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include "Driver_Common.h"
#define ARM_SPI_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,2) /* API version */
/****** SPI Control Codes *****/
#define ARM_SPI_CONTROL_Pos 0
#define ARM_SPI_CONTROL_Msk (0xFFUL << ARM_SPI_CONTROL_Pos)
/*----- SPI Control Codes: Mode -----*/
#define ARM_SPI_MODE_INACTIVE (0x00UL << ARM_SPI_CONTROL_Pos) ///< SPI Inactive
#define ARM_SPI_MODE_MASTER (0x01UL << ARM_SPI_CONTROL_Pos) ///< SPI Master (Output on MOSI, Input on MISO); arg = Bus Speed in bps
#define ARM_SPI_MODE_SLAVE (0x02UL << ARM_SPI_CONTROL_Pos) ///< SPI Slave (Output on MISO, Input on MOSI)
#define ARM_SPI_MODE_MASTER_SIMPLEX (0x03UL << ARM_SPI_CONTROL_Pos) ///< SPI Master (Output/Input on MOSI); arg = Bus Speed in bps
#define ARM_SPI_MODE_SLAVE_SIMPLEX (0x04UL << ARM_SPI_CONTROL_Pos) ///< SPI Slave (Output/Input on MISO)
/*----- SPI Control Codes: Mode Parameters: Frame Format -----*/
#define ARM_SPI_FRAME_FORMAT_Pos 8
#define ARM_SPI_FRAME_FORMAT_Msk (7UL << ARM_SPI_FRAME_FORMAT_Pos)
#define ARM_SPI_CPOL0_CPHA0 (0UL << ARM_SPI_FRAME_FORMAT_Pos) ///< Clock Polarity 0, Clock Phase 0 (default)
#define ARM_SPI_CPOL0_CPHA1 (1UL << ARM_SPI_FRAME_FORMAT_Pos) ///< Clock Polarity 0, Clock Phase 1
#define ARM_SPI_CPOL1_CPHA0 (2UL << ARM_SPI_FRAME_FORMAT_Pos) ///< Clock Polarity 1, Clock Phase 0
#define ARM_SPI_CPOL1_CPHA1 (3UL << ARM_SPI_FRAME_FORMAT_Pos) ///< Clock Polarity 1, Clock Phase 1
#define ARM_SPI_TI_SSI (4UL << ARM_SPI_FRAME_FORMAT_Pos) ///< Texas Instruments Frame Format
#define ARM_SPI_MICROWIRE (5UL << ARM_SPI_FRAME_FORMAT_Pos) ///< National Microwire Frame Format
/*----- SPI Control Codes: Mode Parameters: Data Bits -----*/
#define ARM_SPI_DATA_BITS_Pos 12
#define ARM_SPI_DATA_BITS_Msk (0x3FUL << ARM_SPI_DATA_BITS_Pos)
#define ARM_SPI_DATA_BITS(n) (((n) & 0x3F) << ARM_SPI_DATA_BITS_Pos) ///< Number of Data bits
/*----- SPI Control Codes: Mode Parameters: Bit Order -----*/
#define ARM_SPI_BIT_ORDER_Pos 18
#define ARM_SPI_BIT_ORDER_Msk (1UL << ARM_SPI_BIT_ORDER_Pos)
#define ARM_SPI_MSB_LSB (0UL << ARM_SPI_BIT_ORDER_Pos) ///< SPI Bit order from MSB to LSB (default)
#define ARM_SPI_LSB_MSB (1UL << ARM_SPI_BIT_ORDER_Pos) ///< SPI Bit order from LSB to MSB
/*----- SPI Control Codes: Mode Parameters: Slave Select Mode -----*/
#define ARM_SPI_SS_MASTER_MODE_Pos 19
#define ARM_SPI_SS_MASTER_MODE_Msk (3UL << ARM_SPI_SS_MASTER_MODE_Pos)
#define ARM_SPI_SS_MASTER_UNUSED (0UL << ARM_SPI_SS_MASTER_MODE_Pos) ///< SPI Slave Select when Master: Not used (default)
#define ARM_SPI_SS_MASTER_SW (1UL << ARM_SPI_SS_MASTER_MODE_Pos) ///< SPI Slave Select when Master: Software controlled
#define ARM_SPI_SS_MASTER_HW_OUTPUT (2UL << ARM_SPI_SS_MASTER_MODE_Pos) ///< SPI Slave Select when Master: Hardware controlled Output
#define ARM_SPI_SS_MASTER_HW_INPUT (3UL << ARM_SPI_SS_MASTER_MODE_Pos) ///< SPI Slave Select when Master: Hardware monitored Input
#define ARM_SPI_SS_SLAVE_MODE_Pos 21
#define ARM_SPI_SS_SLAVE_MODE_Msk (1UL << ARM_SPI_SS_SLAVE_MODE_Pos)
#define ARM_SPI_SS_SLAVE_HW (0UL << ARM_SPI_SS_SLAVE_MODE_Pos) ///< SPI Slave Select when Slave: Hardware monitored (default)
#define ARM_SPI_SS_SLAVE_SW (1UL << ARM_SPI_SS_SLAVE_MODE_Pos) ///< SPI Slave Select when Slave: Software controlled
/*----- SPI Control Codes: Miscellaneous Controls -----*/
#define ARM_SPI_SET_BUS_SPEED (0x10UL << ARM_SPI_CONTROL_Pos) ///< Set Bus Speed in bps; arg = value
#define ARM_SPI_GET_BUS_SPEED (0x11UL << ARM_SPI_CONTROL_Pos) ///< Get Bus Speed in bps
#define ARM_SPI_SET_DEFAULT_TX_VALUE (0x12UL << ARM_SPI_CONTROL_Pos) ///< Set default Transmit value; arg = value
#define ARM_SPI_CONTROL_SS (0x13UL << ARM_SPI_CONTROL_Pos) ///< Control Slave Select; arg: 0=inactive, 1=active
#define ARM_SPI_ABORT_TRANSFER (0x14UL << ARM_SPI_CONTROL_Pos) ///< Abort current data transfer
/****** SPI Slave Select Signal definitions *****/
#define ARM_SPI_SS_INACTIVE 0 ///< SPI Slave Select Signal Inactive
#define ARM_SPI_SS_ACTIVE 1 ///< SPI Slave Select Signal Active
/****** SPI specific error codes *****/
#define ARM_SPI_ERROR_MODE (ARM_DRIVER_ERROR_SPECIFIC - 1) ///< Specified Mode not supported
#define ARM_SPI_ERROR_FRAME_FORMAT (ARM_DRIVER_ERROR_SPECIFIC - 2) ///< Specified Frame Format not supported
#define ARM_SPI_ERROR_DATA_BITS (ARM_DRIVER_ERROR_SPECIFIC - 3) ///< Specified number of Data bits not supported
#define ARM_SPI_ERROR_BIT_ORDER (ARM_DRIVER_ERROR_SPECIFIC - 4) ///< Specified Bit order not supported
#define ARM_SPI_ERROR_SS_MODE (ARM_DRIVER_ERROR_SPECIFIC - 5) ///< Specified Slave Select Mode not supported
/**
\brief SPI Status
*/
typedef volatile struct _ARM_SPI_STATUS {
uint32_t busy : 1; ///< Transmitter/Receiver busy flag
uint32_t data_lost : 1; ///< Data lost: Receive overflow / Transmit underflow (cleared on start of transfer operation)
uint32_t mode_fault : 1; ///< Mode fault detected; optional (cleared on start of transfer operation)
uint32_t reserved : 29;
} ARM_SPI_STATUS;
/****** SPI Event *****/
#define ARM_SPI_EVENT_TRANSFER_COMPLETE (1UL << 0) ///< Data Transfer completed
#define ARM_SPI_EVENT_DATA_LOST (1UL << 1) ///< Data lost: Receive overflow / Transmit underflow
#define ARM_SPI_EVENT_MODE_FAULT (1UL << 2) ///< Master Mode Fault (SS deactivated when Master)
// Function documentation
/**
\fn ARM_DRIVER_VERSION ARM_SPI_GetVersion (void)
\brief Get driver version.
\return \ref ARM_DRIVER_VERSION
\fn ARM_SPI_CAPABILITIES ARM_SPI_GetCapabilities (void)
\brief Get driver capabilities.
\return \ref ARM_SPI_CAPABILITIES
\fn int32_t ARM_SPI_Initialize (ARM_SPI_SignalEvent_t cb_event)
\brief Initialize SPI Interface.
\param[in] cb_event Pointer to \ref ARM_SPI_SignalEvent
\return \ref execution_status
\fn int32_t ARM_SPI_Uninitialize (void)
\brief De-initialize SPI Interface.
\return \ref execution_status
\fn int32_t ARM_SPI_PowerControl (ARM_POWER_STATE state)
\brief Control SPI Interface Power.
\param[in] state Power state
\return \ref execution_status
\fn int32_t ARM_SPI_Send (const void *data, uint32_t num)
\brief Start sending data to SPI transmitter.
\param[in] data Pointer to buffer with data to send to SPI transmitter
\param[in] num Number of data items to send
\return \ref execution_status
\fn int32_t ARM_SPI_Receive (void *data, uint32_t num)
\brief Start receiving data from SPI receiver.
\param[out] data Pointer to buffer for data to receive from SPI receiver
\param[in] num Number of data items to receive
\return \ref execution_status
\fn int32_t ARM_SPI_Transfer (const void *data_out,
void *data_in,
uint32_t num)
\brief Start sending/receiving data to/from SPI transmitter/receiver.
\param[in] data_out Pointer to buffer with data to send to SPI transmitter
\param[out] data_in Pointer to buffer for data to receive from SPI receiver
\param[in] num Number of data items to transfer
\return \ref execution_status
\fn uint32_t ARM_SPI_GetDataCount (void)
\brief Get transferred data count.
\return number of data items transferred
\fn int32_t ARM_SPI_Control (uint32_t control, uint32_t arg)
\brief Control SPI Interface.
\param[in] control Operation
\param[in] arg Argument of operation (optional)
\return common \ref execution_status and driver specific \ref spi_execution_status
\fn ARM_SPI_STATUS ARM_SPI_GetStatus (void)
\brief Get SPI status.
\return SPI status \ref ARM_SPI_STATUS
\fn void ARM_SPI_SignalEvent (uint32_t event)
\brief Signal SPI Events.
\param[in] event \ref SPI_events notification mask
\return none
*/
typedef void (*ARM_SPI_SignalEvent_t) (uint32_t event); ///< Pointer to \ref ARM_SPI_SignalEvent : Signal SPI Event.
/**
\brief SPI Driver Capabilities.
*/
typedef struct _ARM_SPI_CAPABILITIES {
uint32_t simplex : 1; ///< supports Simplex Mode (Master and Slave)
uint32_t ti_ssi : 1; ///< supports TI Synchronous Serial Interface
uint32_t microwire : 1; ///< supports Microwire Interface
uint32_t event_mode_fault : 1; ///< Signal Mode Fault event: \ref ARM_SPI_EVENT_MODE_FAULT
uint32_t reserved : 28; ///< Reserved (must be zero)
} ARM_SPI_CAPABILITIES;
/**
\brief Access structure of the SPI Driver.
*/
typedef struct _ARM_DRIVER_SPI {
ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_SPI_GetVersion : Get driver version.
ARM_SPI_CAPABILITIES (*GetCapabilities) (void); ///< Pointer to \ref ARM_SPI_GetCapabilities : Get driver capabilities.
int32_t (*Initialize) (ARM_SPI_SignalEvent_t cb_event); ///< Pointer to \ref ARM_SPI_Initialize : Initialize SPI Interface.
int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_SPI_Uninitialize : De-initialize SPI Interface.
int32_t (*PowerControl) (ARM_POWER_STATE state); ///< Pointer to \ref ARM_SPI_PowerControl : Control SPI Interface Power.
int32_t (*Send) (const void *data, uint32_t num); ///< Pointer to \ref ARM_SPI_Send : Start sending data to SPI Interface.
int32_t (*Receive) ( void *data, uint32_t num); ///< Pointer to \ref ARM_SPI_Receive : Start receiving data from SPI Interface.
int32_t (*Transfer) (const void *data_out,
void *data_in,
uint32_t num); ///< Pointer to \ref ARM_SPI_Transfer : Start sending/receiving data to/from SPI.
uint32_t (*GetDataCount) (void); ///< Pointer to \ref ARM_SPI_GetDataCount : Get transferred data count.
int32_t (*Control) (uint32_t control, uint32_t arg); ///< Pointer to \ref ARM_SPI_Control : Control SPI Interface.
ARM_SPI_STATUS (*GetStatus) (void); ///< Pointer to \ref ARM_SPI_GetStatus : Get SPI status.
} const ARM_DRIVER_SPI;
#ifdef __cplusplus
}
#endif
#endif /* DRIVER_SPI_H_ */

View File

@@ -0,0 +1,341 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Date: 2. Feb 2017
* $Revision: V2.3
*
* Project: USART (Universal Synchronous Asynchronous Receiver Transmitter)
* Driver definitions
*/
/* History:
* Version 2.3
* ARM_USART_STATUS and ARM_USART_MODEM_STATUS made volatile
* Version 2.2
* Corrected ARM_USART_CPOL_Pos and ARM_USART_CPHA_Pos definitions
* Version 2.1
* Removed optional argument parameter from Signal Event
* Version 2.0
* New simplified driver:
* complexity moved to upper layer (especially data handling)
* more unified API for different communication interfaces
* renamed driver UART -> USART (Asynchronous & Synchronous)
* Added modes:
* Synchronous
* Single-wire
* IrDA
* Smart Card
* Changed prefix ARM_DRV -> ARM_DRIVER
* Version 1.10
* Namespace prefix ARM_ added
* Version 1.01
* Added events:
* ARM_UART_EVENT_TX_EMPTY, ARM_UART_EVENT_RX_TIMEOUT
* ARM_UART_EVENT_TX_THRESHOLD, ARM_UART_EVENT_RX_THRESHOLD
* Added functions: SetTxThreshold, SetRxThreshold
* Added "rx_timeout_event" to capabilities
* Version 1.00
* Initial release
*/
#ifndef DRIVER_USART_H_
#define DRIVER_USART_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include "Driver_Common.h"
#define ARM_USART_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,3) /* API version */
/****** USART Control Codes *****/
#define ARM_USART_CONTROL_Pos 0
#define ARM_USART_CONTROL_Msk (0xFFUL << ARM_USART_CONTROL_Pos)
/*----- USART Control Codes: Mode -----*/
#define ARM_USART_MODE_ASYNCHRONOUS (0x01UL << ARM_USART_CONTROL_Pos) ///< UART (Asynchronous); arg = Baudrate
#define ARM_USART_MODE_SYNCHRONOUS_MASTER (0x02UL << ARM_USART_CONTROL_Pos) ///< Synchronous Master (generates clock signal); arg = Baudrate
#define ARM_USART_MODE_SYNCHRONOUS_SLAVE (0x03UL << ARM_USART_CONTROL_Pos) ///< Synchronous Slave (external clock signal)
#define ARM_USART_MODE_SINGLE_WIRE (0x04UL << ARM_USART_CONTROL_Pos) ///< UART Single-wire (half-duplex); arg = Baudrate
#define ARM_USART_MODE_IRDA (0x05UL << ARM_USART_CONTROL_Pos) ///< UART IrDA; arg = Baudrate
#define ARM_USART_MODE_SMART_CARD (0x06UL << ARM_USART_CONTROL_Pos) ///< UART Smart Card; arg = Baudrate
/*----- USART Control Codes: Mode Parameters: Data Bits -----*/
#define ARM_USART_DATA_BITS_Pos 8
#define ARM_USART_DATA_BITS_Msk (7UL << ARM_USART_DATA_BITS_Pos)
#define ARM_USART_DATA_BITS_5 (5UL << ARM_USART_DATA_BITS_Pos) ///< 5 Data bits
#define ARM_USART_DATA_BITS_6 (6UL << ARM_USART_DATA_BITS_Pos) ///< 6 Data bit
#define ARM_USART_DATA_BITS_7 (7UL << ARM_USART_DATA_BITS_Pos) ///< 7 Data bits
#define ARM_USART_DATA_BITS_8 (0UL << ARM_USART_DATA_BITS_Pos) ///< 8 Data bits (default)
#define ARM_USART_DATA_BITS_9 (1UL << ARM_USART_DATA_BITS_Pos) ///< 9 Data bits
/*----- USART Control Codes: Mode Parameters: Parity -----*/
#define ARM_USART_PARITY_Pos 12
#define ARM_USART_PARITY_Msk (3UL << ARM_USART_PARITY_Pos)
#define ARM_USART_PARITY_NONE (0UL << ARM_USART_PARITY_Pos) ///< No Parity (default)
#define ARM_USART_PARITY_EVEN (1UL << ARM_USART_PARITY_Pos) ///< Even Parity
#define ARM_USART_PARITY_ODD (2UL << ARM_USART_PARITY_Pos) ///< Odd Parity
/*----- USART Control Codes: Mode Parameters: Stop Bits -----*/
#define ARM_USART_STOP_BITS_Pos 14
#define ARM_USART_STOP_BITS_Msk (3UL << ARM_USART_STOP_BITS_Pos)
#define ARM_USART_STOP_BITS_1 (0UL << ARM_USART_STOP_BITS_Pos) ///< 1 Stop bit (default)
#define ARM_USART_STOP_BITS_2 (1UL << ARM_USART_STOP_BITS_Pos) ///< 2 Stop bits
#define ARM_USART_STOP_BITS_1_5 (2UL << ARM_USART_STOP_BITS_Pos) ///< 1.5 Stop bits
#define ARM_USART_STOP_BITS_0_5 (3UL << ARM_USART_STOP_BITS_Pos) ///< 0.5 Stop bits
/*----- USART Control Codes: Mode Parameters: Flow Control -----*/
#define ARM_USART_FLOW_CONTROL_Pos 16
#define ARM_USART_FLOW_CONTROL_Msk (3UL << ARM_USART_FLOW_CONTROL_Pos)
#define ARM_USART_FLOW_CONTROL_NONE (0UL << ARM_USART_FLOW_CONTROL_Pos) ///< No Flow Control (default)
#define ARM_USART_FLOW_CONTROL_RTS (1UL << ARM_USART_FLOW_CONTROL_Pos) ///< RTS Flow Control
#define ARM_USART_FLOW_CONTROL_CTS (2UL << ARM_USART_FLOW_CONTROL_Pos) ///< CTS Flow Control
#define ARM_USART_FLOW_CONTROL_RTS_CTS (3UL << ARM_USART_FLOW_CONTROL_Pos) ///< RTS/CTS Flow Control
/*----- USART Control Codes: Mode Parameters: Clock Polarity (Synchronous mode) -----*/
#define ARM_USART_CPOL_Pos 18
#define ARM_USART_CPOL_Msk (1UL << ARM_USART_CPOL_Pos)
#define ARM_USART_CPOL0 (0UL << ARM_USART_CPOL_Pos) ///< CPOL = 0 (default)
#define ARM_USART_CPOL1 (1UL << ARM_USART_CPOL_Pos) ///< CPOL = 1
/*----- USART Control Codes: Mode Parameters: Clock Phase (Synchronous mode) -----*/
#define ARM_USART_CPHA_Pos 19
#define ARM_USART_CPHA_Msk (1UL << ARM_USART_CPHA_Pos)
#define ARM_USART_CPHA0 (0UL << ARM_USART_CPHA_Pos) ///< CPHA = 0 (default)
#define ARM_USART_CPHA1 (1UL << ARM_USART_CPHA_Pos) ///< CPHA = 1
/*----- USART Control Codes: Miscellaneous Controls -----*/
#define ARM_USART_SET_DEFAULT_TX_VALUE (0x10UL << ARM_USART_CONTROL_Pos) ///< Set default Transmit value (Synchronous Receive only); arg = value
#define ARM_USART_SET_IRDA_PULSE (0x11UL << ARM_USART_CONTROL_Pos) ///< Set IrDA Pulse in ns; arg: 0=3/16 of bit period
#define ARM_USART_SET_SMART_CARD_GUARD_TIME (0x12UL << ARM_USART_CONTROL_Pos) ///< Set Smart Card Guard Time; arg = number of bit periods
#define ARM_USART_SET_SMART_CARD_CLOCK (0x13UL << ARM_USART_CONTROL_Pos) ///< Set Smart Card Clock in Hz; arg: 0=Clock not generated
#define ARM_USART_CONTROL_SMART_CARD_NACK (0x14UL << ARM_USART_CONTROL_Pos) ///< Smart Card NACK generation; arg: 0=disabled, 1=enabled
#define ARM_USART_CONTROL_TX (0x15UL << ARM_USART_CONTROL_Pos) ///< Transmitter; arg: 0=disabled, 1=enabled
#define ARM_USART_CONTROL_RX (0x16UL << ARM_USART_CONTROL_Pos) ///< Receiver; arg: 0=disabled, 1=enabled
#define ARM_USART_CONTROL_BREAK (0x17UL << ARM_USART_CONTROL_Pos) ///< Continuous Break transmission; arg: 0=disabled, 1=enabled
#define ARM_USART_ABORT_SEND (0x18UL << ARM_USART_CONTROL_Pos) ///< Abort \ref ARM_USART_Send
#define ARM_USART_ABORT_RECEIVE (0x19UL << ARM_USART_CONTROL_Pos) ///< Abort \ref ARM_USART_Receive
#define ARM_USART_ABORT_TRANSFER (0x1AUL << ARM_USART_CONTROL_Pos) ///< Abort \ref ARM_USART_Transfer
/****** USART specific error codes *****/
#define ARM_USART_ERROR_MODE (ARM_DRIVER_ERROR_SPECIFIC - 1) ///< Specified Mode not supported
#define ARM_USART_ERROR_BAUDRATE (ARM_DRIVER_ERROR_SPECIFIC - 2) ///< Specified baudrate not supported
#define ARM_USART_ERROR_DATA_BITS (ARM_DRIVER_ERROR_SPECIFIC - 3) ///< Specified number of Data bits not supported
#define ARM_USART_ERROR_PARITY (ARM_DRIVER_ERROR_SPECIFIC - 4) ///< Specified Parity not supported
#define ARM_USART_ERROR_STOP_BITS (ARM_DRIVER_ERROR_SPECIFIC - 5) ///< Specified number of Stop bits not supported
#define ARM_USART_ERROR_FLOW_CONTROL (ARM_DRIVER_ERROR_SPECIFIC - 6) ///< Specified Flow Control not supported
#define ARM_USART_ERROR_CPOL (ARM_DRIVER_ERROR_SPECIFIC - 7) ///< Specified Clock Polarity not supported
#define ARM_USART_ERROR_CPHA (ARM_DRIVER_ERROR_SPECIFIC - 8) ///< Specified Clock Phase not supported
/**
\brief USART Status
*/
typedef volatile struct _ARM_USART_STATUS {
uint32_t tx_busy : 1; ///< Transmitter busy flag
uint32_t rx_busy : 1; ///< Receiver busy flag
uint32_t tx_underflow : 1; ///< Transmit data underflow detected (cleared on start of next send operation)
uint32_t rx_overflow : 1; ///< Receive data overflow detected (cleared on start of next receive operation)
uint32_t rx_break : 1; ///< Break detected on receive (cleared on start of next receive operation)
uint32_t rx_framing_error : 1; ///< Framing error detected on receive (cleared on start of next receive operation)
uint32_t rx_parity_error : 1; ///< Parity error detected on receive (cleared on start of next receive operation)
uint32_t reserved : 25;
} ARM_USART_STATUS;
/**
\brief USART Modem Control
*/
typedef enum _ARM_USART_MODEM_CONTROL {
ARM_USART_RTS_CLEAR, ///< Deactivate RTS
ARM_USART_RTS_SET, ///< Activate RTS
ARM_USART_DTR_CLEAR, ///< Deactivate DTR
ARM_USART_DTR_SET ///< Activate DTR
} ARM_USART_MODEM_CONTROL;
/**
\brief USART Modem Status
*/
typedef volatile struct _ARM_USART_MODEM_STATUS {
uint32_t cts : 1; ///< CTS state: 1=Active, 0=Inactive
uint32_t dsr : 1; ///< DSR state: 1=Active, 0=Inactive
uint32_t dcd : 1; ///< DCD state: 1=Active, 0=Inactive
uint32_t ri : 1; ///< RI state: 1=Active, 0=Inactive
uint32_t reserved : 28;
} ARM_USART_MODEM_STATUS;
/****** USART Event *****/
#define ARM_USART_EVENT_SEND_COMPLETE (1UL << 0) ///< Send completed; however USART may still transmit data
#define ARM_USART_EVENT_RECEIVE_COMPLETE (1UL << 1) ///< Receive completed
#define ARM_USART_EVENT_TRANSFER_COMPLETE (1UL << 2) ///< Transfer completed
#define ARM_USART_EVENT_TX_COMPLETE (1UL << 3) ///< Transmit completed (optional)
#define ARM_USART_EVENT_TX_UNDERFLOW (1UL << 4) ///< Transmit data not available (Synchronous Slave)
#define ARM_USART_EVENT_RX_OVERFLOW (1UL << 5) ///< Receive data overflow
#define ARM_USART_EVENT_RX_TIMEOUT (1UL << 6) ///< Receive character timeout (optional)
#define ARM_USART_EVENT_RX_BREAK (1UL << 7) ///< Break detected on receive
#define ARM_USART_EVENT_RX_FRAMING_ERROR (1UL << 8) ///< Framing error detected on receive
#define ARM_USART_EVENT_RX_PARITY_ERROR (1UL << 9) ///< Parity error detected on receive
#define ARM_USART_EVENT_CTS (1UL << 10) ///< CTS state changed (optional)
#define ARM_USART_EVENT_DSR (1UL << 11) ///< DSR state changed (optional)
#define ARM_USART_EVENT_DCD (1UL << 12) ///< DCD state changed (optional)
#define ARM_USART_EVENT_RI (1UL << 13) ///< RI state changed (optional)
// Function documentation
/**
\fn ARM_DRIVER_VERSION ARM_USART_GetVersion (void)
\brief Get driver version.
\return \ref ARM_DRIVER_VERSION
\fn ARM_USART_CAPABILITIES ARM_USART_GetCapabilities (void)
\brief Get driver capabilities
\return \ref ARM_USART_CAPABILITIES
\fn int32_t ARM_USART_Initialize (ARM_USART_SignalEvent_t cb_event)
\brief Initialize USART Interface.
\param[in] cb_event Pointer to \ref ARM_USART_SignalEvent
\return \ref execution_status
\fn int32_t ARM_USART_Uninitialize (void)
\brief De-initialize USART Interface.
\return \ref execution_status
\fn int32_t ARM_USART_PowerControl (ARM_POWER_STATE state)
\brief Control USART Interface Power.
\param[in] state Power state
\return \ref execution_status
\fn int32_t ARM_USART_Send (const void *data, uint32_t num)
\brief Start sending data to USART transmitter.
\param[in] data Pointer to buffer with data to send to USART transmitter
\param[in] num Number of data items to send
\return \ref execution_status
\fn int32_t ARM_USART_Receive (void *data, uint32_t num)
\brief Start receiving data from USART receiver.
\param[out] data Pointer to buffer for data to receive from USART receiver
\param[in] num Number of data items to receive
\return \ref execution_status
\fn int32_t ARM_USART_Transfer (const void *data_out,
void *data_in,
uint32_t num)
\brief Start sending/receiving data to/from USART transmitter/receiver.
\param[in] data_out Pointer to buffer with data to send to USART transmitter
\param[out] data_in Pointer to buffer for data to receive from USART receiver
\param[in] num Number of data items to transfer
\return \ref execution_status
\fn uint32_t ARM_USART_GetTxCount (void)
\brief Get transmitted data count.
\return number of data items transmitted
\fn uint32_t ARM_USART_GetRxCount (void)
\brief Get received data count.
\return number of data items received
\fn int32_t ARM_USART_Control (uint32_t control, uint32_t arg)
\brief Control USART Interface.
\param[in] control Operation
\param[in] arg Argument of operation (optional)
\return common \ref execution_status and driver specific \ref usart_execution_status
\fn ARM_USART_STATUS ARM_USART_GetStatus (void)
\brief Get USART status.
\return USART status \ref ARM_USART_STATUS
\fn int32_t ARM_USART_SetModemControl (ARM_USART_MODEM_CONTROL control)
\brief Set USART Modem Control line state.
\param[in] control \ref ARM_USART_MODEM_CONTROL
\return \ref execution_status
\fn ARM_USART_MODEM_STATUS ARM_USART_GetModemStatus (void)
\brief Get USART Modem Status lines state.
\return modem status \ref ARM_USART_MODEM_STATUS
\fn void ARM_USART_SignalEvent (uint32_t event)
\brief Signal USART Events.
\param[in] event \ref USART_events notification mask
\return none
*/
typedef void (*ARM_USART_SignalEvent_t) (uint32_t event); ///< Pointer to \ref ARM_USART_SignalEvent : Signal USART Event.
/**
\brief USART Device Driver Capabilities.
*/
typedef struct _ARM_USART_CAPABILITIES {
uint32_t asynchronous : 1; ///< supports UART (Asynchronous) mode
uint32_t synchronous_master : 1; ///< supports Synchronous Master mode
uint32_t synchronous_slave : 1; ///< supports Synchronous Slave mode
uint32_t single_wire : 1; ///< supports UART Single-wire mode
uint32_t irda : 1; ///< supports UART IrDA mode
uint32_t smart_card : 1; ///< supports UART Smart Card mode
uint32_t smart_card_clock : 1; ///< Smart Card Clock generator available
uint32_t flow_control_rts : 1; ///< RTS Flow Control available
uint32_t flow_control_cts : 1; ///< CTS Flow Control available
uint32_t event_tx_complete : 1; ///< Transmit completed event: \ref ARM_USART_EVENT_TX_COMPLETE
uint32_t event_rx_timeout : 1; ///< Signal receive character timeout event: \ref ARM_USART_EVENT_RX_TIMEOUT
uint32_t rts : 1; ///< RTS Line: 0=not available, 1=available
uint32_t cts : 1; ///< CTS Line: 0=not available, 1=available
uint32_t dtr : 1; ///< DTR Line: 0=not available, 1=available
uint32_t dsr : 1; ///< DSR Line: 0=not available, 1=available
uint32_t dcd : 1; ///< DCD Line: 0=not available, 1=available
uint32_t ri : 1; ///< RI Line: 0=not available, 1=available
uint32_t event_cts : 1; ///< Signal CTS change event: \ref ARM_USART_EVENT_CTS
uint32_t event_dsr : 1; ///< Signal DSR change event: \ref ARM_USART_EVENT_DSR
uint32_t event_dcd : 1; ///< Signal DCD change event: \ref ARM_USART_EVENT_DCD
uint32_t event_ri : 1; ///< Signal RI change event: \ref ARM_USART_EVENT_RI
uint32_t reserved : 11; ///< Reserved (must be zero)
} ARM_USART_CAPABILITIES;
/**
\brief Access structure of the USART Driver.
*/
typedef struct _ARM_DRIVER_USART {
ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_USART_GetVersion : Get driver version.
ARM_USART_CAPABILITIES (*GetCapabilities) (void); ///< Pointer to \ref ARM_USART_GetCapabilities : Get driver capabilities.
int32_t (*Initialize) (ARM_USART_SignalEvent_t cb_event); ///< Pointer to \ref ARM_USART_Initialize : Initialize USART Interface.
int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_USART_Uninitialize : De-initialize USART Interface.
int32_t (*PowerControl) (ARM_POWER_STATE state); ///< Pointer to \ref ARM_USART_PowerControl : Control USART Interface Power.
int32_t (*Send) (const void *data, uint32_t num); ///< Pointer to \ref ARM_USART_Send : Start sending data to USART transmitter.
int32_t (*Receive) ( void *data, uint32_t num); ///< Pointer to \ref ARM_USART_Receive : Start receiving data from USART receiver.
int32_t (*Transfer) (const void *data_out,
void *data_in,
uint32_t num); ///< Pointer to \ref ARM_USART_Transfer : Start sending/receiving data to/from USART.
uint32_t (*GetTxCount) (void); ///< Pointer to \ref ARM_USART_GetTxCount : Get transmitted data count.
uint32_t (*GetRxCount) (void); ///< Pointer to \ref ARM_USART_GetRxCount : Get received data count.
int32_t (*Control) (uint32_t control, uint32_t arg); ///< Pointer to \ref ARM_USART_Control : Control USART Interface.
ARM_USART_STATUS (*GetStatus) (void); ///< Pointer to \ref ARM_USART_GetStatus : Get USART status.
int32_t (*SetModemControl) (ARM_USART_MODEM_CONTROL control); ///< Pointer to \ref ARM_USART_SetModemControl : Set USART Modem Control line state.
ARM_USART_MODEM_STATUS (*GetModemStatus) (void); ///< Pointer to \ref ARM_USART_GetModemStatus : Get USART Modem Status lines state.
} const ARM_DRIVER_USART;
#ifdef __cplusplus
}
#endif
#endif /* DRIVER_USART_H_ */

View File

@@ -0,0 +1,92 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Date: 2. Feb 2017
* $Revision: V2.0
*
* Project: USB Driver common definitions
*/
/* History:
* Version 2.0
* Version 1.10
* Namespace prefix ARM_ added
* Version 1.01
* Added PID Types
* Version 1.00
* Initial release
*/
#ifndef DRIVER_USB_H_
#define DRIVER_USB_H_
#include "Driver_Common.h"
/* USB Role */
#define ARM_USB_ROLE_NONE (0)
#define ARM_USB_ROLE_HOST (1)
#define ARM_USB_ROLE_DEVICE (2)
/* USB Pins */
#define ARM_USB_PIN_DP (1 << 0) ///< USB D+ pin
#define ARM_USB_PIN_DM (1 << 1) ///< USB D- pin
#define ARM_USB_PIN_VBUS (1 << 2) ///< USB VBUS pin
#define ARM_USB_PIN_OC (1 << 3) ///< USB OverCurrent pin
#define ARM_USB_PIN_ID (1 << 4) ///< USB ID pin
/* USB Speed */
#define ARM_USB_SPEED_LOW (0) ///< Low-speed USB
#define ARM_USB_SPEED_FULL (1) ///< Full-speed USB
#define ARM_USB_SPEED_HIGH (2) ///< High-speed USB
/* USB PID Types */
#define ARM_USB_PID_OUT (1)
#define ARM_USB_PID_IN (9)
#define ARM_USB_PID_SOF (5)
#define ARM_USB_PID_SETUP (13)
#define ARM_USB_PID_DATA0 (3)
#define ARM_USB_PID_DATA1 (11)
#define ARM_USB_PID_DATA2 (7)
#define ARM_USB_PID_MDATA (15)
#define ARM_USB_PID_ACK (2)
#define ARM_USB_PID_NAK (10)
#define ARM_USB_PID_STALL (14)
#define ARM_USB_PID_NYET (6)
#define ARM_USB_PID_PRE (12)
#define ARM_USB_PID_ERR (12)
#define ARM_USB_PID_SPLIT (8)
#define ARM_USB_PID_PING (4)
#define ARM_USB_PID_RESERVED (0)
/* USB Endpoint Address (bEndpointAddress) */
#define ARM_USB_ENDPOINT_NUMBER_MASK (0x0F)
#define ARM_USB_ENDPOINT_DIRECTION_MASK (0x80)
/* USB Endpoint Type */
#define ARM_USB_ENDPOINT_CONTROL (0) ///< Control Endpoint
#define ARM_USB_ENDPOINT_ISOCHRONOUS (1) ///< Isochronous Endpoint
#define ARM_USB_ENDPOINT_BULK (2) ///< Bulk Endpoint
#define ARM_USB_ENDPOINT_INTERRUPT (3) ///< Interrupt Endpoint
/* USB Endpoint Maximum Packet Size (wMaxPacketSize) */
#define ARM_USB_ENDPOINT_MAX_PACKET_SIZE_MASK (0x07FF)
#define ARM_USB_ENDPOINT_MICROFRAME_TRANSACTIONS_MASK (0x1800)
#define ARM_USB_ENDPOINT_MICROFRAME_TRANSACTIONS_1 (0x0000)
#define ARM_USB_ENDPOINT_MICROFRAME_TRANSACTIONS_2 (0x0800)
#define ARM_USB_ENDPOINT_MICROFRAME_TRANSACTIONS_3 (0x1000)
#endif /* DRIVER_USB_H_ */

View File

@@ -0,0 +1,273 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Date: 2. Feb 2017
* $Revision: V2.2
*
* Project: USB Device Driver definitions
*/
/* History:
* Version 2.2
* ARM_USBD_STATE made volatile
* Version 2.1
* Added ARM_USBD_ReadSetupPacket function
* Version 2.0
* Removed ARM_USBD_DeviceConfigure function
* Removed ARM_USBD_SET_ADDRESS_STAGE parameter from ARM_USBD_DeviceSetAddress function
* Removed ARM_USBD_EndpointReadStart function
* Replaced ARM_USBD_EndpointRead and ARM_USBD_EndpointWrite functions with ARM_USBD_EndpointTransfer
* Added ARM_USBD_EndpointTransferGetResult function
* Renamed ARM_USBD_EndpointAbort function to ARM_USBD_EndpointTransferAbort
* Changed prefix ARM_DRV -> ARM_DRIVER
* Changed return values of some functions to int32_t
* Version 1.10
* Namespace prefix ARM_ added
* Version 1.00
* Initial release
*/
#ifndef DRIVER_USBD_H_
#define DRIVER_USBD_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include "Driver_USB.h"
#define ARM_USBD_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,2) /* API version */
/**
\brief USB Device State
*/
typedef volatile struct _ARM_USBD_STATE {
uint32_t vbus : 1; ///< USB Device VBUS flag
uint32_t speed : 2; ///< USB Device speed setting (ARM_USB_SPEED_xxx)
uint32_t active : 1; ///< USB Device active flag
uint32_t reserved : 28;
} ARM_USBD_STATE;
/****** USB Device Event *****/
#define ARM_USBD_EVENT_VBUS_ON (1UL << 0) ///< USB Device VBUS On
#define ARM_USBD_EVENT_VBUS_OFF (1UL << 1) ///< USB Device VBUS Off
#define ARM_USBD_EVENT_RESET (1UL << 2) ///< USB Reset occurred
#define ARM_USBD_EVENT_HIGH_SPEED (1UL << 3) ///< USB switch to High Speed occurred
#define ARM_USBD_EVENT_SUSPEND (1UL << 4) ///< USB Suspend occurred
#define ARM_USBD_EVENT_RESUME (1UL << 5) ///< USB Resume occurred
/****** USB Endpoint Event *****/
#define ARM_USBD_EVENT_SETUP (1UL << 0) ///< SETUP Packet
#define ARM_USBD_EVENT_OUT (1UL << 1) ///< OUT Packet(s)
#define ARM_USBD_EVENT_IN (1UL << 2) ///< IN Packet(s)
#ifndef __DOXYGEN_MW__ // exclude from middleware documentation
// Function documentation
/**
\fn ARM_DRIVER_VERSION ARM_USBD_GetVersion (void)
\brief Get driver version.
\return \ref ARM_DRIVER_VERSION
*/
/**
\fn ARM_USBD_CAPABILITIES ARM_USBD_GetCapabilities (void)
\brief Get driver capabilities.
\return \ref ARM_USBD_CAPABILITIES
*/
/**
\fn int32_t ARM_USBD_Initialize (ARM_USBD_SignalDeviceEvent_t cb_device_event,
ARM_USBD_SignalEndpointEvent_t cb_endpoint_event)
\brief Initialize USB Device Interface.
\param[in] cb_device_event Pointer to \ref ARM_USBD_SignalDeviceEvent
\param[in] cb_endpoint_event Pointer to \ref ARM_USBD_SignalEndpointEvent
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBD_Uninitialize (void)
\brief De-initialize USB Device Interface.
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBD_PowerControl (ARM_POWER_STATE state)
\brief Control USB Device Interface Power.
\param[in] state Power state
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBD_DeviceConnect (void)
\brief Connect USB Device.
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBD_DeviceDisconnect (void)
\brief Disconnect USB Device.
\return \ref execution_status
*/
/**
\fn ARM_USBD_STATE ARM_USBD_DeviceGetState (void)
\brief Get current USB Device State.
\return Device State \ref ARM_USBD_STATE
*/
/**
\fn int32_t ARM_USBD_DeviceRemoteWakeup (void)
\brief Trigger USB Remote Wakeup.
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBD_DeviceSetAddress (uint8_t dev_addr)
\brief Set USB Device Address.
\param[in] dev_addr Device Address
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBD_ReadSetupPacket (uint8_t *setup)
\brief Read setup packet received over Control Endpoint.
\param[out] setup Pointer to buffer for setup packet
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBD_EndpointConfigure (uint8_t ep_addr,
uint8_t ep_type,
uint16_t ep_max_packet_size)
\brief Configure USB Endpoint.
\param[in] ep_addr Endpoint Address
- ep_addr.0..3: Address
- ep_addr.7: Direction
\param[in] ep_type Endpoint Type (ARM_USB_ENDPOINT_xxx)
\param[in] ep_max_packet_size Endpoint Maximum Packet Size
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBD_EndpointUnconfigure (uint8_t ep_addr)
\brief Unconfigure USB Endpoint.
\param[in] ep_addr Endpoint Address
- ep_addr.0..3: Address
- ep_addr.7: Direction
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBD_EndpointStall (uint8_t ep_addr, bool stall)
\brief Set/Clear Stall for USB Endpoint.
\param[in] ep_addr Endpoint Address
- ep_addr.0..3: Address
- ep_addr.7: Direction
\param[in] stall Operation
- \b false Clear
- \b true Set
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBD_EndpointTransfer (uint8_t ep_addr, uint8_t *data, uint32_t num)
\brief Read data from or Write data to USB Endpoint.
\param[in] ep_addr Endpoint Address
- ep_addr.0..3: Address
- ep_addr.7: Direction
\param[out] data Pointer to buffer for data to read or with data to write
\param[in] num Number of data bytes to transfer
\return \ref execution_status
*/
/**
\fn uint32_t ARM_USBD_EndpointTransferGetResult (uint8_t ep_addr)
\brief Get result of USB Endpoint transfer.
\param[in] ep_addr Endpoint Address
- ep_addr.0..3: Address
- ep_addr.7: Direction
\return number of successfully transferred data bytes
*/
/**
\fn int32_t ARM_USBD_EndpointTransferAbort (uint8_t ep_addr)
\brief Abort current USB Endpoint transfer.
\param[in] ep_addr Endpoint Address
- ep_addr.0..3: Address
- ep_addr.7: Direction
\return \ref execution_status
*/
/**
\fn uint16_t ARM_USBD_GetFrameNumber (void)
\brief Get current USB Frame Number.
\return Frame Number
*/
/**
\fn void ARM_USBD_SignalDeviceEvent (uint32_t event)
\brief Signal USB Device Event.
\param[in] event \ref USBD_dev_events
\return none
*/
/**
\fn void ARM_USBD_SignalEndpointEvent (uint8_t ep_addr, uint32_t event)
\brief Signal USB Endpoint Event.
\param[in] ep_addr Endpoint Address
- ep_addr.0..3: Address
- ep_addr.7: Direction
\param[in] event \ref USBD_ep_events
\return none
*/
typedef void (*ARM_USBD_SignalDeviceEvent_t) (uint32_t event); ///< Pointer to \ref ARM_USBD_SignalDeviceEvent : Signal USB Device Event.
typedef void (*ARM_USBD_SignalEndpointEvent_t) (uint8_t ep_addr, uint32_t event); ///< Pointer to \ref ARM_USBD_SignalEndpointEvent : Signal USB Endpoint Event.
/**
\brief USB Device Driver Capabilities.
*/
typedef struct _ARM_USBD_CAPABILITIES {
uint32_t vbus_detection : 1; ///< VBUS detection
uint32_t event_vbus_on : 1; ///< Signal VBUS On event
uint32_t event_vbus_off : 1; ///< Signal VBUS Off event
uint32_t reserved : 29; ///< Reserved (must be zero)
} ARM_USBD_CAPABILITIES;
/**
\brief Access structure of the USB Device Driver.
*/
typedef struct _ARM_DRIVER_USBD {
ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_USBD_GetVersion : Get driver version.
ARM_USBD_CAPABILITIES (*GetCapabilities) (void); ///< Pointer to \ref ARM_USBD_GetCapabilities : Get driver capabilities.
int32_t (*Initialize) (ARM_USBD_SignalDeviceEvent_t cb_device_event,
ARM_USBD_SignalEndpointEvent_t cb_endpoint_event); ///< Pointer to \ref ARM_USBD_Initialize : Initialize USB Device Interface.
int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_USBD_Uninitialize : De-initialize USB Device Interface.
int32_t (*PowerControl) (ARM_POWER_STATE state); ///< Pointer to \ref ARM_USBD_PowerControl : Control USB Device Interface Power.
int32_t (*DeviceConnect) (void); ///< Pointer to \ref ARM_USBD_DeviceConnect : Connect USB Device.
int32_t (*DeviceDisconnect) (void); ///< Pointer to \ref ARM_USBD_DeviceDisconnect : Disconnect USB Device.
ARM_USBD_STATE (*DeviceGetState) (void); ///< Pointer to \ref ARM_USBD_DeviceGetState : Get current USB Device State.
int32_t (*DeviceRemoteWakeup) (void); ///< Pointer to \ref ARM_USBD_DeviceRemoteWakeup : Trigger USB Remote Wakeup.
int32_t (*DeviceSetAddress) (uint8_t dev_addr); ///< Pointer to \ref ARM_USBD_DeviceSetAddress : Set USB Device Address.
int32_t (*ReadSetupPacket) (uint8_t *setup); ///< Pointer to \ref ARM_USBD_ReadSetupPacket : Read setup packet received over Control Endpoint.
int32_t (*EndpointConfigure) (uint8_t ep_addr,
uint8_t ep_type,
uint16_t ep_max_packet_size); ///< Pointer to \ref ARM_USBD_EndpointConfigure : Configure USB Endpoint.
int32_t (*EndpointUnconfigure) (uint8_t ep_addr); ///< Pointer to \ref ARM_USBD_EndpointUnconfigure : Unconfigure USB Endpoint.
int32_t (*EndpointStall) (uint8_t ep_addr, bool stall); ///< Pointer to \ref ARM_USBD_EndpointStall : Set/Clear Stall for USB Endpoint.
int32_t (*EndpointTransfer) (uint8_t ep_addr, uint8_t *data, uint32_t num); ///< Pointer to \ref ARM_USBD_EndpointTransfer : Read data from or Write data to USB Endpoint.
uint32_t (*EndpointTransferGetResult) (uint8_t ep_addr); ///< Pointer to \ref ARM_USBD_EndpointTransferGetResult : Get result of USB Endpoint transfer.
int32_t (*EndpointTransferAbort) (uint8_t ep_addr); ///< Pointer to \ref ARM_USBD_EndpointTransferAbort : Abort current USB Endpoint transfer.
uint16_t (*GetFrameNumber) (void); ///< Pointer to \ref ARM_USBD_GetFrameNumber : Get current USB Frame Number.
} const ARM_DRIVER_USBD;
#endif /* __DOXYGEN_MW__ */
#ifdef __cplusplus
}
#endif
#endif /* DRIVER_USBD_H_ */

View File

@@ -0,0 +1,417 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Date: 2. Feb 2017
* $Revision: V2.2
*
* Project: USB Host Driver definitions
*/
/* History:
* Version 2.2
* ARM_USBH_PORT_STATE made volatile
* Version 2.1
* Renamed structure ARM_USBH_EP_HANDLE to ARM_USBH_PIPE_HANDLE
* Renamed functions ARM_USBH_Endpoint... to ARM_USBH_Pipe...
* Renamed function ARM_USBH_SignalEndpointEvent to ARM_USBH_SignalPipeEvent
* Version 2.0
* Replaced function ARM_USBH_PortPowerOnOff with ARM_USBH_PortVbusOnOff
* Changed function ARM_USBH_EndpointCreate parameters
* Replaced function ARM_USBH_EndpointConfigure with ARM_USBH_EndpointModify
* Replaced function ARM_USBH_EndpointClearHalt with ARM_USBH_EndpointReset
* Replaced function ARM_USBH_URB_Submit with ARM_USBH_EndpointTransfer
* Replaced function ARM_USBH_URB_Abort with ARM_USBH_EndpointTransferAbort
* Added function ARM_USBH_EndpointTransferGetResult
* Added function ARM_USBH_GetFrameNumber
* Changed prefix ARM_DRV -> ARM_DRIVER
* Version 1.20
* Added API for OHCI/EHCI Host Controller Interface (HCI)
* Version 1.10
* Namespace prefix ARM_ added
* Version 1.00
* Initial release
*/
#ifndef DRIVER_USBH_H_
#define DRIVER_USBH_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include "Driver_USB.h"
#define ARM_USBH_API_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,2) /* API version */
/**
\brief USB Host Port State
*/
typedef volatile struct _ARM_USBH_PORT_STATE {
uint32_t connected : 1; ///< USB Host Port connected flag
uint32_t overcurrent : 1; ///< USB Host Port overcurrent flag
uint32_t speed : 2; ///< USB Host Port speed setting (ARM_USB_SPEED_xxx)
uint32_t reserved : 28;
} ARM_USBH_PORT_STATE;
/**
\brief USB Host Pipe Handle
*/
typedef uint32_t ARM_USBH_PIPE_HANDLE;
#define ARM_USBH_EP_HANDLE ARM_USBH_PIPE_HANDLE /* Legacy name */
/****** USB Host Packet Information *****/
#define ARM_USBH_PACKET_TOKEN_Pos 0
#define ARM_USBH_PACKET_TOKEN_Msk (0x0FUL << ARM_USBH_PACKET_TOKEN_Pos)
#define ARM_USBH_PACKET_SETUP (0x01UL << ARM_USBH_PACKET_TOKEN_Pos) ///< SETUP Packet
#define ARM_USBH_PACKET_OUT (0x02UL << ARM_USBH_PACKET_TOKEN_Pos) ///< OUT Packet
#define ARM_USBH_PACKET_IN (0x03UL << ARM_USBH_PACKET_TOKEN_Pos) ///< IN Packet
#define ARM_USBH_PACKET_PING (0x04UL << ARM_USBH_PACKET_TOKEN_Pos) ///< PING Packet
#define ARM_USBH_PACKET_DATA_Pos 4
#define ARM_USBH_PACKET_DATA_Msk (0x0FUL << ARM_USBH_PACKET_DATA_Pos)
#define ARM_USBH_PACKET_DATA0 (0x01UL << ARM_USBH_PACKET_DATA_Pos) ///< DATA0 PID
#define ARM_USBH_PACKET_DATA1 (0x02UL << ARM_USBH_PACKET_DATA_Pos) ///< DATA1 PID
#define ARM_USBH_PACKET_SPLIT_Pos 8
#define ARM_USBH_PACKET_SPLIT_Msk (0x0FUL << ARM_USBH_PACKET_SPLIT_Pos)
#define ARM_USBH_PACKET_SSPLIT (0x08UL << ARM_USBH_PACKET_SPLIT_Pos) ///< SSPLIT Packet
#define ARM_USBH_PACKET_SSPLIT_S (0x09UL << ARM_USBH_PACKET_SPLIT_Pos) ///< SSPLIT Packet: Data Start
#define ARM_USBH_PACKET_SSPLIT_E (0x0AUL << ARM_USBH_PACKET_SPLIT_Pos) ///< SSPLIT Packet: Data End
#define ARM_USBH_PACKET_SSPLIT_S_E (0x0BUL << ARM_USBH_PACKET_SPLIT_Pos) ///< SSPLIT Packet: Data All
#define ARM_USBH_PACKET_CSPLIT (0x0CUL << ARM_USBH_PACKET_SPLIT_Pos) ///< CSPLIT Packet
#define ARM_USBH_PACKET_PRE (1UL << 12) ///< PRE Token
/****** USB Host Port Event *****/
#define ARM_USBH_EVENT_CONNECT (1UL << 0) ///< USB Device Connected to Port
#define ARM_USBH_EVENT_DISCONNECT (1UL << 1) ///< USB Device Disconnected from Port
#define ARM_USBH_EVENT_OVERCURRENT (1UL << 2) ///< USB Device caused Overcurrent
#define ARM_USBH_EVENT_RESET (1UL << 3) ///< USB Reset completed
#define ARM_USBH_EVENT_SUSPEND (1UL << 4) ///< USB Suspend occurred
#define ARM_USBH_EVENT_RESUME (1UL << 5) ///< USB Resume occurred
#define ARM_USBH_EVENT_REMOTE_WAKEUP (1UL << 6) ///< USB Device activated Remote Wakeup
/****** USB Host Pipe Event *****/
#define ARM_USBH_EVENT_TRANSFER_COMPLETE (1UL << 0) ///< Transfer completed
#define ARM_USBH_EVENT_HANDSHAKE_NAK (1UL << 1) ///< NAK Handshake received
#define ARM_USBH_EVENT_HANDSHAKE_NYET (1UL << 2) ///< NYET Handshake received
#define ARM_USBH_EVENT_HANDSHAKE_MDATA (1UL << 3) ///< MDATA Handshake received
#define ARM_USBH_EVENT_HANDSHAKE_STALL (1UL << 4) ///< STALL Handshake received
#define ARM_USBH_EVENT_HANDSHAKE_ERR (1UL << 5) ///< ERR Handshake received
#define ARM_USBH_EVENT_BUS_ERROR (1UL << 6) ///< Bus Error detected
#ifndef __DOXYGEN_MW__ // exclude from middleware documentation
// Function documentation
/**
\fn ARM_DRIVER_VERSION ARM_USBH_GetVersion (void)
\brief Get driver version.
\return \ref ARM_DRIVER_VERSION
*/
/**
\fn ARM_USBH_CAPABILITIES ARM_USBH_GetCapabilities (void)
\brief Get driver capabilities.
\return \ref ARM_USBH_CAPABILITIES
*/
/**
\fn int32_t ARM_USBH_Initialize (ARM_USBH_SignalPortEvent_t cb_port_event,
ARM_USBH_SignalPipeEvent_t cb_pipe_event)
\brief Initialize USB Host Interface.
\param[in] cb_port_event Pointer to \ref ARM_USBH_SignalPortEvent
\param[in] cb_pipe_event Pointer to \ref ARM_USBH_SignalPipeEvent
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBH_Uninitialize (void)
\brief De-initialize USB Host Interface.
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBH_PowerControl (ARM_POWER_STATE state)
\brief Control USB Host Interface Power.
\param[in] state Power state
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBH_PortVbusOnOff (uint8_t port, bool vbus)
\brief Root HUB Port VBUS on/off.
\param[in] port Root HUB Port Number
\param[in] vbus
- \b false VBUS off
- \b true VBUS on
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBH_PortReset (uint8_t port)
\brief Do Root HUB Port Reset.
\param[in] port Root HUB Port Number
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBH_PortSuspend (uint8_t port)
\brief Suspend Root HUB Port (stop generating SOFs).
\param[in] port Root HUB Port Number
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBH_PortResume (uint8_t port)
\brief Resume Root HUB Port (start generating SOFs).
\param[in] port Root HUB Port Number
\return \ref execution_status
*/
/**
\fn ARM_USBH_PORT_STATE ARM_USBH_PortGetState (uint8_t port)
\brief Get current Root HUB Port State.
\param[in] port Root HUB Port Number
\return Port State \ref ARM_USBH_PORT_STATE
*/
/**
\fn ARM_USBH_PIPE_HANDLE ARM_USBH_PipeCreate (uint8_t dev_addr,
uint8_t dev_speed,
uint8_t hub_addr,
uint8_t hub_port,
uint8_t ep_addr,
uint8_t ep_type,
uint16_t ep_max_packet_size,
uint8_t ep_interval)
\brief Create Pipe in System.
\param[in] dev_addr Device Address
\param[in] dev_speed Device Speed
\param[in] hub_addr Hub Address
\param[in] hub_port Hub Port
\param[in] ep_addr Endpoint Address
- ep_addr.0..3: Address
- ep_addr.7: Direction
\param[in] ep_type Endpoint Type (ARM_USB_ENDPOINT_xxx)
\param[in] ep_max_packet_size Endpoint Maximum Packet Size
\param[in] ep_interval Endpoint Polling Interval
\return Pipe Handle \ref ARM_USBH_PIPE_HANDLE
*/
/**
\fn int32_t ARM_USBH_PipeModify (ARM_USBH_PIPE_HANDLE pipe_hndl,
uint8_t dev_addr,
uint8_t dev_speed,
uint8_t hub_addr,
uint8_t hub_port,
uint16_t ep_max_packet_size)
\brief Modify Pipe in System.
\param[in] pipe_hndl Pipe Handle
\param[in] dev_addr Device Address
\param[in] dev_speed Device Speed
\param[in] hub_addr Hub Address
\param[in] hub_port Hub Port
\param[in] ep_max_packet_size Endpoint Maximum Packet Size
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBH_PipeDelete (ARM_USBH_PIPE_HANDLE pipe_hndl)
\brief Delete Pipe from System.
\param[in] pipe_hndl Pipe Handle
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBH_PipeReset (ARM_USBH_PIPE_HANDLE pipe_hndl)
\brief Reset Pipe.
\param[in] pipe_hndl Pipe Handle
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBH_PipeTransfer (ARM_USBH_PIPE_HANDLE pipe_hndl,
uint32_t packet,
uint8_t *data,
uint32_t num)
\brief Transfer packets through USB Pipe.
\param[in] pipe_hndl Pipe Handle
\param[in] packet Packet information
\param[in] data Pointer to buffer with data to send or for data to receive
\param[in] num Number of data bytes to transfer
\return \ref execution_status
*/
/**
\fn uint32_t ARM_USBH_PipeTransferGetResult (ARM_USBH_PIPE_HANDLE pipe_hndl)
\brief Get result of USB Pipe transfer.
\param[in] pipe_hndl Pipe Handle
\return number of successfully transferred data bytes
*/
/**
\fn int32_t ARM_USBH_PipeTransferAbort (ARM_USBH_PIPE_HANDLE pipe_hndl)
\brief Abort current USB Pipe transfer.
\param[in] pipe_hndl Pipe Handle
\return \ref execution_status
*/
/**
\fn uint16_t ARM_USBH_GetFrameNumber (void)
\brief Get current USB Frame Number.
\return Frame Number
*/
/**
\fn void ARM_USBH_SignalPortEvent (uint8_t port, uint32_t event)
\brief Signal Root HUB Port Event.
\param[in] port Root HUB Port Number
\param[in] event \ref USBH_port_events
\return none
*/
/**
\fn void ARM_USBH_SignalPipeEvent (ARM_USBH_PIPE_HANDLE pipe_hndl, uint32_t event)
\brief Signal Pipe Event.
\param[in] pipe_hndl Pipe Handle
\param[in] event \ref USBH_pipe_events
\return none
*/
typedef void (*ARM_USBH_SignalPortEvent_t) (uint8_t port, uint32_t event); ///< Pointer to \ref ARM_USBH_SignalPortEvent : Signal Root HUB Port Event.
typedef void (*ARM_USBH_SignalPipeEvent_t) (ARM_USBH_PIPE_HANDLE pipe_hndl, uint32_t event); ///< Pointer to \ref ARM_USBH_SignalPipeEvent : Signal Pipe Event.
#define ARM_USBH_SignalEndpointEvent_t ARM_USBH_SignalPipeEvent_t /* Legacy name */
/**
\brief USB Host Driver Capabilities.
*/
typedef struct _ARM_USBH_CAPABILITIES {
uint32_t port_mask : 15; ///< Root HUB available Ports Mask
uint32_t auto_split : 1; ///< Automatic SPLIT packet handling
uint32_t event_connect : 1; ///< Signal Connect event
uint32_t event_disconnect : 1; ///< Signal Disconnect event
uint32_t event_overcurrent : 1; ///< Signal Overcurrent event
uint32_t reserved : 13; ///< Reserved (must be zero)
} ARM_USBH_CAPABILITIES;
/**
\brief Access structure of USB Host Driver.
*/
typedef struct _ARM_DRIVER_USBH {
ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_USBH_GetVersion : Get driver version.
ARM_USBH_CAPABILITIES (*GetCapabilities) (void); ///< Pointer to \ref ARM_USBH_GetCapabilities : Get driver capabilities.
int32_t (*Initialize) (ARM_USBH_SignalPortEvent_t cb_port_event,
ARM_USBH_SignalPipeEvent_t cb_pipe_event); ///< Pointer to \ref ARM_USBH_Initialize : Initialize USB Host Interface.
int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_USBH_Uninitialize : De-initialize USB Host Interface.
int32_t (*PowerControl) (ARM_POWER_STATE state); ///< Pointer to \ref ARM_USBH_PowerControl : Control USB Host Interface Power.
int32_t (*PortVbusOnOff) (uint8_t port, bool vbus); ///< Pointer to \ref ARM_USBH_PortVbusOnOff : Root HUB Port VBUS on/off.
int32_t (*PortReset) (uint8_t port); ///< Pointer to \ref ARM_USBH_PortReset : Do Root HUB Port Reset.
int32_t (*PortSuspend) (uint8_t port); ///< Pointer to \ref ARM_USBH_PortSuspend : Suspend Root HUB Port (stop generating SOFs).
int32_t (*PortResume) (uint8_t port); ///< Pointer to \ref ARM_USBH_PortResume : Resume Root HUB Port (start generating SOFs).
ARM_USBH_PORT_STATE (*PortGetState) (uint8_t port); ///< Pointer to \ref ARM_USBH_PortGetState : Get current Root HUB Port State.
ARM_USBH_PIPE_HANDLE (*PipeCreate) (uint8_t dev_addr,
uint8_t dev_speed,
uint8_t hub_addr,
uint8_t hub_port,
uint8_t ep_addr,
uint8_t ep_type,
uint16_t ep_max_packet_size,
uint8_t ep_interval); ///< Pointer to \ref ARM_USBH_PipeCreate : Create Pipe in System.
int32_t (*PipeModify) (ARM_USBH_PIPE_HANDLE pipe_hndl,
uint8_t dev_addr,
uint8_t dev_speed,
uint8_t hub_addr,
uint8_t hub_port,
uint16_t ep_max_packet_size); ///< Pointer to \ref ARM_USBH_PipeModify : Modify Pipe in System.
int32_t (*PipeDelete) (ARM_USBH_PIPE_HANDLE pipe_hndl); ///< Pointer to \ref ARM_USBH_PipeDelete : Delete Pipe from System.
int32_t (*PipeReset) (ARM_USBH_PIPE_HANDLE pipe_hndl); ///< Pointer to \ref ARM_USBH_PipeReset : Reset Pipe.
int32_t (*PipeTransfer) (ARM_USBH_PIPE_HANDLE pipe_hndl,
uint32_t packet,
uint8_t *data,
uint32_t num); ///< Pointer to \ref ARM_USBH_PipeTransfer : Transfer packets through USB Pipe.
uint32_t (*PipeTransferGetResult) (ARM_USBH_PIPE_HANDLE pipe_hndl); ///< Pointer to \ref ARM_USBH_PipeTransferGetResult : Get result of USB Pipe transfer.
int32_t (*PipeTransferAbort) (ARM_USBH_PIPE_HANDLE pipe_hndl); ///< Pointer to \ref ARM_USBH_PipeTransferAbort : Abort current USB Pipe transfer.
uint16_t (*GetFrameNumber) (void); ///< Pointer to \ref ARM_USBH_GetFrameNumber : Get current USB Frame Number.
} const ARM_DRIVER_USBH;
// HCI (OHCI/EHCI)
// Function documentation
/**
\fn ARM_DRIVER_VERSION ARM_USBH_HCI_GetVersion (void)
\brief Get USB Host HCI (OHCI/EHCI) driver version.
\return \ref ARM_DRIVER_VERSION
*/
/**
\fn ARM_USBH_HCI_CAPABILITIES ARM_USBH_HCI_GetCapabilities (void)
\brief Get driver capabilities.
\return \ref ARM_USBH_HCI_CAPABILITIES
*/
/**
\fn int32_t ARM_USBH_HCI_Initialize (ARM_USBH_HCI_Interrupt_t *cb_interrupt)
\brief Initialize USB Host HCI (OHCI/EHCI) Interface.
\param[in] cb_interrupt Pointer to Interrupt Handler Routine
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBH_HCI_Uninitialize (void)
\brief De-initialize USB Host HCI (OHCI/EHCI) Interface.
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBH_HCI_PowerControl (ARM_POWER_STATE state)
\brief Control USB Host HCI (OHCI/EHCI) Interface Power.
\param[in] state Power state
\return \ref execution_status
*/
/**
\fn int32_t ARM_USBH_HCI_PortVbusOnOff (uint8_t port, bool vbus)
\brief USB Host HCI (OHCI/EHCI) Root HUB Port VBUS on/off.
\param[in] port Root HUB Port Number
\param[in] vbus
- \b false VBUS off
- \b true VBUS on
\return \ref execution_status
*/
/**
\fn void ARM_USBH_HCI_Interrupt (void)
\brief USB Host HCI Interrupt Handler.
\return none
*/
typedef void (*ARM_USBH_HCI_Interrupt_t) (void); ///< Pointer to Interrupt Handler Routine.
/**
\brief USB Host HCI (OHCI/EHCI) Driver Capabilities.
*/
typedef struct _ARM_USBH_HCI_CAPABILITIES {
uint32_t port_mask : 15; ///< Root HUB available Ports Mask
uint32_t reserved : 17; ///< Reserved (must be zero)
} ARM_USBH_HCI_CAPABILITIES;
/**
\brief Access structure of USB Host HCI (OHCI/EHCI) Driver.
*/
typedef struct _ARM_DRIVER_USBH_HCI {
ARM_DRIVER_VERSION (*GetVersion) (void); ///< Pointer to \ref ARM_USBH_HCI_GetVersion : Get USB Host HCI (OHCI/EHCI) driver version.
ARM_USBH_HCI_CAPABILITIES (*GetCapabilities) (void); ///< Pointer to \ref ARM_USBH_HCI_GetCapabilities : Get driver capabilities.
int32_t (*Initialize) (ARM_USBH_HCI_Interrupt_t cb_interrupt); ///< Pointer to \ref ARM_USBH_HCI_Initialize : Initialize USB Host HCI (OHCI/EHCI) Interface.
int32_t (*Uninitialize) (void); ///< Pointer to \ref ARM_USBH_HCI_Uninitialize : De-initialize USB Host HCI (OHCI/EHCI) Interface.
int32_t (*PowerControl) (ARM_POWER_STATE state); ///< Pointer to \ref ARM_USBH_HCI_PowerControl : Control USB Host HCI (OHCI/EHCI) Interface Power.
int32_t (*PortVbusOnOff) (uint8_t port, bool vbus); ///< Pointer to \ref ARM_USBH_HCI_PortVbusOnOff : USB Host HCI (OHCI/EHCI) Root HUB Port VBUS on/off.
} const ARM_DRIVER_USBH_HCI;
#endif /* __DOXYGEN_MW__ */
#ifdef __cplusplus
}
#endif
#endif /* DRIVER_USBH_H_ */

View File

@@ -0,0 +1,121 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_common_tables.h
* Description: Extern declaration for common tables
*
* $Date: 27. January 2017
* $Revision: V.1.5.1
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ARM_COMMON_TABLES_H
#define _ARM_COMMON_TABLES_H
#include "arm_math.h"
extern const uint16_t armBitRevTable[1024];
extern const q15_t armRecipTableQ15[64];
extern const q31_t armRecipTableQ31[64];
extern const float32_t twiddleCoef_16[32];
extern const float32_t twiddleCoef_32[64];
extern const float32_t twiddleCoef_64[128];
extern const float32_t twiddleCoef_128[256];
extern const float32_t twiddleCoef_256[512];
extern const float32_t twiddleCoef_512[1024];
extern const float32_t twiddleCoef_1024[2048];
extern const float32_t twiddleCoef_2048[4096];
extern const float32_t twiddleCoef_4096[8192];
#define twiddleCoef twiddleCoef_4096
extern const q31_t twiddleCoef_16_q31[24];
extern const q31_t twiddleCoef_32_q31[48];
extern const q31_t twiddleCoef_64_q31[96];
extern const q31_t twiddleCoef_128_q31[192];
extern const q31_t twiddleCoef_256_q31[384];
extern const q31_t twiddleCoef_512_q31[768];
extern const q31_t twiddleCoef_1024_q31[1536];
extern const q31_t twiddleCoef_2048_q31[3072];
extern const q31_t twiddleCoef_4096_q31[6144];
extern const q15_t twiddleCoef_16_q15[24];
extern const q15_t twiddleCoef_32_q15[48];
extern const q15_t twiddleCoef_64_q15[96];
extern const q15_t twiddleCoef_128_q15[192];
extern const q15_t twiddleCoef_256_q15[384];
extern const q15_t twiddleCoef_512_q15[768];
extern const q15_t twiddleCoef_1024_q15[1536];
extern const q15_t twiddleCoef_2048_q15[3072];
extern const q15_t twiddleCoef_4096_q15[6144];
extern const float32_t twiddleCoef_rfft_32[32];
extern const float32_t twiddleCoef_rfft_64[64];
extern const float32_t twiddleCoef_rfft_128[128];
extern const float32_t twiddleCoef_rfft_256[256];
extern const float32_t twiddleCoef_rfft_512[512];
extern const float32_t twiddleCoef_rfft_1024[1024];
extern const float32_t twiddleCoef_rfft_2048[2048];
extern const float32_t twiddleCoef_rfft_4096[4096];
/* floating-point bit reversal tables */
#define ARMBITREVINDEXTABLE_16_TABLE_LENGTH ((uint16_t)20)
#define ARMBITREVINDEXTABLE_32_TABLE_LENGTH ((uint16_t)48)
#define ARMBITREVINDEXTABLE_64_TABLE_LENGTH ((uint16_t)56)
#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208)
#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440)
#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448)
#define ARMBITREVINDEXTABLE_1024_TABLE_LENGTH ((uint16_t)1800)
#define ARMBITREVINDEXTABLE_2048_TABLE_LENGTH ((uint16_t)3808)
#define ARMBITREVINDEXTABLE_4096_TABLE_LENGTH ((uint16_t)4032)
extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE_16_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE_32_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE_64_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE_1024_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE_2048_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE_4096_TABLE_LENGTH];
/* fixed-point bit reversal tables */
#define ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH ((uint16_t)12)
#define ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH ((uint16_t)24)
#define ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH ((uint16_t)56)
#define ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH ((uint16_t)112)
#define ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH ((uint16_t)240)
#define ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH ((uint16_t)480)
#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992)
#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984)
#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032)
extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH];
extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH];
/* Tables for Fast Math Sine and Cosine */
extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1];
extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1];
extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1];
#endif /* ARM_COMMON_TABLES_H */

View File

@@ -0,0 +1,66 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_const_structs.h
* Description: Constant structs that are initialized for user convenience.
* For example, some can be given as arguments to the arm_cfft_f32() function.
*
* $Date: 27. January 2017
* $Revision: V.1.5.1
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ARM_CONST_STRUCTS_H
#define _ARM_CONST_STRUCTS_H
#include "arm_math.h"
#include "arm_common_tables.h"
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048;
extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048;
extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048;
extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,814 @@
/**************************************************************************//**
* @file cmsis_armcc.h
* @brief CMSIS compiler ARMCC (ARM compiler V5) header file
* @version V5.0.2
* @date 13. February 2017
******************************************************************************/
/*
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CMSIS_ARMCC_H
#define __CMSIS_ARMCC_H
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* CMSIS compiler control architecture macros */
#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \
(defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) )
#define __ARM_ARCH_6M__ 1
#endif
#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1))
#define __ARM_ARCH_7M__ 1
#endif
#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1))
#define __ARM_ARCH_7EM__ 1
#endif
/* __ARM_ARCH_8M_BASE__ not applicable */
/* __ARM_ARCH_8M_MAIN__ not applicable */
/* CMSIS compiler specific defines */
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE __inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static __inline
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __declspec(noreturn)
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT __packed struct
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION __packed union
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
#define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x)))
#endif
#ifndef __UNALIGNED_UINT16_WRITE
#define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
#define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr)))
#endif
#ifndef __UNALIGNED_UINT32_WRITE
#define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
#define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __RESTRICT
#define __RESTRICT __restrict
#endif
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
/**
\brief Enable IRQ Interrupts
\details Enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
/* intrinsic void __enable_irq(); */
/**
\brief Disable IRQ Interrupts
\details Disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
/* intrinsic void __disable_irq(); */
/**
\brief Get Control Register
\details Returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/**
\brief Set Control Register
\details Writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/**
\brief Get IPSR Register
\details Returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/**
\brief Get APSR Register
\details Returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/**
\brief Get xPSR Register
\details Returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/**
\brief Get Process Stack Pointer
\details Returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/**
\brief Set Process Stack Pointer
\details Assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/**
\brief Get Main Stack Pointer
\details Returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/**
\brief Set Main Stack Pointer
\details Assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/**
\brief Get Priority Mask
\details Returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/**
\brief Set Priority Mask
\details Assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
/**
\brief Enable FIQ
\details Enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/**
\brief Disable FIQ
\details Disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/**
\brief Get Base Priority
\details Returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/**
\brief Set Base Priority
\details Assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xFFU);
}
/**
\brief Set Base Priority with condition
\details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
or the new value increases the BASEPRI priority level.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
{
register uint32_t __regBasePriMax __ASM("basepri_max");
__regBasePriMax = (basePri & 0xFFU);
}
/**
\brief Get Fault Mask
\details Returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/**
\brief Set Fault Mask
\details Assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1U);
}
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
/**
\brief Get FPSCR
\details Returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0U);
#endif
}
/**
\brief Set FPSCR
\details Assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#else
(void)fpscr;
#endif
}
#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/*@} end of CMSIS_Core_RegAccFunctions */
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
/**
\brief No Operation
\details No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/**
\brief Wait For Interrupt
\details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
*/
#define __WFI __wfi
/**
\brief Wait For Event
\details Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/**
\brief Send Event
\details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/**
\brief Instruction Synchronization Barrier
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or memory,
after the instruction has been completed.
*/
#define __ISB() do {\
__schedule_barrier();\
__isb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Data Synchronization Barrier
\details Acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() do {\
__schedule_barrier();\
__dsb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Data Memory Barrier
\details Ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() do {\
__schedule_barrier();\
__dmb(0xF);\
__schedule_barrier();\
} while (0U)
/**
\brief Reverse byte order (32 bit)
\details Reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/**
\brief Reverse byte order (16 bit)
\details Reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/**
\brief Reverse byte order in signed short value
\details Reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif
/**
\brief Rotate Right in unsigned value (32 bit)
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] op1 Value to rotate
\param [in] op2 Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/**
\brief Breakpoint
\details Causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
/**
\brief Reverse bit order of value
\details Reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
#define __RBIT __rbit
#else
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
int32_t s = (4 /*sizeof(v)*/ * 8) - 1; /* extra shift needed at end */
result = value; /* r will be reversed bits of v; first get LSB of v */
for (value >>= 1U; value; value >>= 1U)
{
result <<= 1U;
result |= value & 1U;
s--;
}
result <<= s; /* shift when v's highest bits are zero */
return(result);
}
#endif
/**
\brief Count leading zeros
\details Counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
/**
\brief LDR Exclusive (8 bit)
\details Executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
#else
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (16 bit)
\details Executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
#else
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief LDR Exclusive (32 bit)
\details Executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
#else
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
#endif
/**
\brief STR Exclusive (8 bit)
\details Executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXB(value, ptr) __strex(value, ptr)
#else
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (16 bit)
\details Executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXH(value, ptr) __strex(value, ptr)
#else
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief STR Exclusive (32 bit)
\details Executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
#define __STREXW(value, ptr) __strex(value, ptr)
#else
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
#endif
/**
\brief Remove the exclusive lock
\details Removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/**
\brief Signed Saturate
\details Saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/**
\brief Unsigned Saturate
\details Saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/**
\brief Rotate Right with Extend (32 bit)
\details Moves each bit of a bitstring right by one bit.
The carry input is shifted in at the left end of the bitstring.
\param [in] value Value to rotate
\return Rotated value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
{
rrx r0, r0
bx lr
}
#endif
/**
\brief LDRT Unprivileged (8 bit)
\details Executes a Unprivileged LDRT instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
/**
\brief LDRT Unprivileged (16 bit)
\details Executes a Unprivileged LDRT instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
/**
\brief LDRT Unprivileged (32 bit)
\details Executes a Unprivileged LDRT instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
/**
\brief STRT Unprivileged (8 bit)
\details Executes a Unprivileged STRT instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRBT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (16 bit)
\details Executes a Unprivileged STRT instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRHT(value, ptr) __strt(value, ptr)
/**
\brief STRT Unprivileged (32 bit)
\details Executes a Unprivileged STRT instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRT(value, ptr) __strt(value, ptr)
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
#define __SADD8 __sadd8
#define __QADD8 __qadd8
#define __SHADD8 __shadd8
#define __UADD8 __uadd8
#define __UQADD8 __uqadd8
#define __UHADD8 __uhadd8
#define __SSUB8 __ssub8
#define __QSUB8 __qsub8
#define __SHSUB8 __shsub8
#define __USUB8 __usub8
#define __UQSUB8 __uqsub8
#define __UHSUB8 __uhsub8
#define __SADD16 __sadd16
#define __QADD16 __qadd16
#define __SHADD16 __shadd16
#define __UADD16 __uadd16
#define __UQADD16 __uqadd16
#define __UHADD16 __uhadd16
#define __SSUB16 __ssub16
#define __QSUB16 __qsub16
#define __SHSUB16 __shsub16
#define __USUB16 __usub16
#define __UQSUB16 __uqsub16
#define __UHSUB16 __uhsub16
#define __SASX __sasx
#define __QASX __qasx
#define __SHASX __shasx
#define __UASX __uasx
#define __UQASX __uqasx
#define __UHASX __uhasx
#define __SSAX __ssax
#define __QSAX __qsax
#define __SHSAX __shsax
#define __USAX __usax
#define __UQSAX __uqsax
#define __UHSAX __uhsax
#define __USAD8 __usad8
#define __USADA8 __usada8
#define __SSAT16 __ssat16
#define __USAT16 __usat16
#define __UXTB16 __uxtb16
#define __UXTAB16 __uxtab16
#define __SXTB16 __sxtb16
#define __SXTAB16 __sxtab16
#define __SMUAD __smuad
#define __SMUADX __smuadx
#define __SMLAD __smlad
#define __SMLADX __smladx
#define __SMLALD __smlald
#define __SMLALDX __smlaldx
#define __SMUSD __smusd
#define __SMUSDX __smusdx
#define __SMLSD __smlsd
#define __SMLSDX __smlsdx
#define __SMLSLD __smlsld
#define __SMLSLDX __smlsldx
#define __SEL __sel
#define __QADD __qadd
#define __QSUB __qsub
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
((int64_t)(ARG3) << 32U) ) >> 32U))
#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
/*@} end of group CMSIS_SIMD_intrinsics */
#endif /* __CMSIS_ARMCC_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,353 @@
/**************************************************************************//**
* @file cmsis_compiler.h
* @brief CMSIS compiler generic header file
* @version V5.0.2
* @date 13. February 2017
******************************************************************************/
/*
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __CMSIS_COMPILER_H
#define __CMSIS_COMPILER_H
#include <stdint.h>
/*
* ARM Compiler 4/5
*/
#if defined ( __CC_ARM )
#include "cmsis_armcc.h"
/*
* ARM Compiler 6 (armclang)
*/
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#include "cmsis_armclang.h"
/*
* GNU Compiler
*/
#elif defined ( __GNUC__ )
#include "cmsis_gcc.h"
/*
* IAR Compiler
*/
#elif defined ( __ICCARM__ )
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#include <cmsis_iar.h>
/* CMSIS compiler control architecture macros */
#if (__CORE__ == __ARM6M__) || (__CORE__ == __ARM6SM__)
#ifndef __ARM_ARCH_6M__
#define __ARM_ARCH_6M__ 1
#endif
#elif (__CORE__ == __ARM7M__)
#ifndef __ARM_ARCH_7M__
#define __ARM_ARCH_7M__ 1
#endif
#elif (__CORE__ == __ARM7EM__)
#ifndef __ARM_ARCH_7EM__
#define __ARM_ARCH_7EM__ 1
#endif
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __noreturn
#endif
#ifndef __USED
#define __USED __root
#endif
#ifndef __WEAK
#define __WEAK __weak
#endif
#ifndef __PACKED
#define __PACKED __packed
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT __packed struct
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION __packed union
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
__packed struct T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
#define __ALIGNED(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
// Workaround for missing __CLZ intrinsic in
// various versions of the IAR compilers.
// __IAR_FEATURE_CLZ__ should be defined by
// the compiler that supports __CLZ internally.
#if (defined (__ARM_ARCH_6M__)) && (__ARM_ARCH_6M__ == 1) && (!defined (__IAR_FEATURE_CLZ__))
__STATIC_INLINE uint32_t __CLZ(uint32_t data)
{
if (data == 0u) { return 32u; }
uint32_t count = 0;
uint32_t mask = 0x80000000;
while ((data & mask) == 0)
{
count += 1u;
mask = mask >> 1u;
}
return (count);
}
#endif
/*
* TI ARM Compiler
*/
#elif defined ( __TI_ARM__ )
#include <cmsis_ccs.h>
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __attribute__((packed))
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __attribute__((packed))
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
/*
* TASKING Compiler
*/
#elif defined ( __TASKING__ )
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#ifndef __ASM
#define __ASM __asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __NO_RETURN
#define __NO_RETURN __attribute__((noreturn))
#endif
#ifndef __USED
#define __USED __attribute__((used))
#endif
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
#ifndef __PACKED
#define __PACKED __packed__
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT struct __packed__
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION union __packed__
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
struct __packed__ T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#define __ALIGNED(x) __align(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
/*
* COSMIC Compiler
*/
#elif defined ( __CSMC__ )
#include <cmsis_csm.h>
#ifndef __ASM
#define __ASM _asm
#endif
#ifndef __INLINE
#define __INLINE inline
#endif
#ifndef __STATIC_INLINE
#define __STATIC_INLINE static inline
#endif
#ifndef __NO_RETURN
// NO RETURN is automatically detected hence no warning here
#define __NO_RETURN
#endif
#ifndef __USED
#warning No compiler specific solution for __USED. __USED is ignored.
#define __USED
#endif
#ifndef __WEAK
#define __WEAK __weak
#endif
#ifndef __PACKED
#define __PACKED @packed
#endif
#ifndef __PACKED_STRUCT
#define __PACKED_STRUCT @packed struct
#endif
#ifndef __PACKED_UNION
#define __PACKED_UNION @packed union
#endif
#ifndef __UNALIGNED_UINT32 /* deprecated */
@packed struct T_UINT32 { uint32_t v; };
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
#endif
#ifndef __UNALIGNED_UINT16_WRITE
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT16_READ
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
#endif
#ifndef __UNALIGNED_UINT32_WRITE
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
#endif
#ifndef __UNALIGNED_UINT32_READ
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
#endif
#ifndef __ALIGNED
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
#define __ALIGNED(x)
#endif
#ifndef __RESTRICT
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
#define __RESTRICT
#endif
#else
#error Unknown compiler.
#endif
#endif /* __CMSIS_COMPILER_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,39 @@
/**************************************************************************//**
* @file cmsis_version.h
* @brief CMSIS Core(M) Version definitions
* @version V5.0.2
* @date 19. April 2017
******************************************************************************/
/*
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CMSIS_VERSION_H
#define __CMSIS_VERSION_H
/* CMSIS Version definitions */
#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */
#define __CM_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS Core(M) sub version */
#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \
__CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,888 @@
/**************************************************************************//**
* @file core_cm0.h
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
* @version V5.0.2
* @date 19. April 2017
******************************************************************************/
/*
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang system_header /* treat file as system include file */
#endif
#ifndef __CORE_CM0_H_GENERIC
#define __CORE_CM0_H_GENERIC
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
CMSIS violates the following MISRA-C:2004 rules:
\li Required Rule 8.5, object/function definition in header file.<br>
Function definitions in header files are used to allow 'inlining'.
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
Unions are used for effective representation of core registers.
\li Advisory Rule 19.7, Function-like macro defined.<br>
Function-like macros are used to allow more efficient code.
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/**
\ingroup Cortex_M0
@{
*/
#include "cmsis_version.h"
/* CMSIS CM0 definitions */
#define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
#define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \
__CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
#define __CORTEX_M (0U) /*!< Cortex-M Core */
/** __FPU_USED indicates whether an FPU is used or not.
This core does not support an FPU at all
*/
#define __FPU_USED 0U
#if defined ( __CC_ARM )
#if defined __TARGET_FPU_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#if defined __ARM_PCS_VFP
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __GNUC__ )
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __ICCARM__ )
#if defined __ARMVFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TI_ARM__ )
#if defined __TI_VFP_SUPPORT__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __TASKING__ )
#if defined __FPU_VFP__
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#elif defined ( __CSMC__ )
#if ( __CSMC__ & 0x400U)
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
#endif
#endif
#include "cmsis_compiler.h" /* CMSIS compiler specific defines */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM0_H_DEPENDANT
#define __CORE_CM0_H_DEPENDANT
#ifdef __cplusplus
extern "C" {
#endif
/* check device defines and use defaults */
#if defined __CHECK_DEVICE_DEFINES
#ifndef __CM0_REV
#define __CM0_REV 0x0000U
#warning "__CM0_REV not defined in device header file; using default!"
#endif
#ifndef __NVIC_PRIO_BITS
#define __NVIC_PRIO_BITS 2U
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
#endif
#ifndef __Vendor_SysTickConfig
#define __Vendor_SysTickConfig 0U
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
#endif
#endif
/* IO definitions (access restrictions to peripheral registers) */
/**
\defgroup CMSIS_glob_defs CMSIS Global Defines
<strong>IO Type Qualifiers</strong> are used
\li to specify the access to peripheral variables.
\li for automatic generation of peripheral register debug information.
*/
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/* following defines should be used for structure members */
#define __IM volatile const /*! Defines 'read only' structure member permissions */
#define __OM volatile /*! Defines 'write only' structure member permissions */
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
/*@} end of group Cortex_M0 */
/*******************************************************************************
* Register Abstraction
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
******************************************************************************/
/**
\defgroup CMSIS_core_register Defines and Type Definitions
\brief Type definitions and defines for Cortex-M processor based devices.
*/
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CORE Status and Control Registers
\brief Core Register type definitions.
@{
*/
/**
\brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} APSR_Type;
/* APSR Register Definitions */
#define APSR_N_Pos 31U /*!< APSR: N Position */
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
#define APSR_C_Pos 29U /*!< APSR: C Position */
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
#define APSR_V_Pos 28U /*!< APSR: V Position */
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
/**
\brief Union type to access the Interrupt Program Status Register (IPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IPSR_Type;
/* IPSR Register Definitions */
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
/**
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} xPSR_Type;
/* xPSR Register Definitions */
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
/**
\brief Union type to access the Control Registers (CONTROL).
*/
typedef union
{
struct
{
uint32_t _reserved0:1; /*!< bit: 0 Reserved */
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CONTROL_Type;
/* CONTROL Register Definitions */
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
/*@} end of group CMSIS_CORE */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
\brief Type definitions for the NVIC Registers
@{
*/
/**
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
*/
typedef struct
{
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31U];
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31U];
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31U];
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31U];
uint32_t RESERVED4[64U];
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SCB System Control Block (SCB)
\brief Type definitions for the System Control Block Registers
@{
*/
/**
\brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
uint32_t RESERVED0;
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED1;
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
} SCB_Type;
/* SCB CPUID Register Definitions */
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
/* SCB System Control Register Definitions */
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
/* SCB Configuration Control Register Definitions */
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/*@} end of group CMSIS_SCB */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
\brief Type definitions for the System Timer Registers.
@{
*/
/**
\brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
\brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
Therefore they are not covered by the Cortex-M0 header file.
@{
*/
/*@} end of group CMSIS_CoreDebug */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_bitfield Core register bit field macros
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
@{
*/
/**
\brief Mask and shift a bit field value for use in a register bit range.
\param[in] field Name of the register bit field.
\param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type.
\return Masked and shifted value.
*/
#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk)
/**
\brief Mask and shift a register value to extract a bit filed value.
\param[in] field Name of the register bit field.
\param[in] value Value of register. This parameter is interpreted as an uint32_t type.
\return Masked and shifted bit field value.
*/
#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos)
/*@} end of group CMSIS_core_bitfield */
/**
\ingroup CMSIS_core_register
\defgroup CMSIS_core_base Core Definitions
\brief Definitions for base addresses, unions, and structures.
@{
*/
/* Memory mapping of Core Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
******************************************************************************/
/**
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
*/
/* ########################## NVIC functions #################################### */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
\brief Functions that manage interrupts and exceptions via the NVIC.
@{
*/
#ifdef CMSIS_NVIC_VIRTUAL
#ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE
#define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h"
#endif
#include CMSIS_NVIC_VIRTUAL_HEADER_FILE
#else
/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for Cortex-M0 */
/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Cortex-M0 */
#define NVIC_EnableIRQ __NVIC_EnableIRQ
#define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ
#define NVIC_DisableIRQ __NVIC_DisableIRQ
#define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ
#define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ
#define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ
/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0 */
#define NVIC_SetPriority __NVIC_SetPriority
#define NVIC_GetPriority __NVIC_GetPriority
#define NVIC_SystemReset __NVIC_SystemReset
#endif /* CMSIS_NVIC_VIRTUAL */
#ifdef CMSIS_VECTAB_VIRTUAL
#ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE
#define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h"
#endif
#include CMSIS_VECTAB_VIRTUAL_HEADER_FILE
#else
#define NVIC_SetVector __NVIC_SetVector
#define NVIC_GetVector __NVIC_GetVector
#endif /* (CMSIS_VECTAB_VIRTUAL) */
#define NVIC_USER_IRQ_OFFSET 16
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
/**
\brief Enable Interrupt
\details Enables a device specific interrupt in the NVIC interrupt controller.
\param [in] IRQn Device specific interrupt number.
\note IRQn must not be negative.
*/
__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
}
/**
\brief Get Interrupt Enable status
\details Returns a device specific interrupt enable status from the NVIC interrupt controller.
\param [in] IRQn Device specific interrupt number.
\return 0 Interrupt is not enabled.
\return 1 Interrupt is enabled.
\note IRQn must not be negative.
*/
__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
}
else
{
return(0U);
}
}
/**
\brief Disable Interrupt
\details Disables a device specific interrupt in the NVIC interrupt controller.
\param [in] IRQn Device specific interrupt number.
\note IRQn must not be negative.
*/
__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
__DSB();
__ISB();
}
}
/**
\brief Get Pending Interrupt
\details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt.
\param [in] IRQn Device specific interrupt number.
\return 0 Interrupt status is not pending.
\return 1 Interrupt status is pending.
\note IRQn must not be negative.
*/
__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
}
else
{
return(0U);
}
}
/**
\brief Set Pending Interrupt
\details Sets the pending bit of a device specific interrupt in the NVIC pending register.
\param [in] IRQn Device specific interrupt number.
\note IRQn must not be negative.
*/
__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
}
/**
\brief Clear Pending Interrupt
\details Clears the pending bit of a device specific interrupt in the NVIC pending register.
\param [in] IRQn Device specific interrupt number.
\note IRQn must not be negative.
*/
__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
}
/**
\brief Set Interrupt Priority
\details Sets the priority of a device specific interrupt or a processor exception.
The interrupt number can be positive to specify a device specific interrupt,
or negative to specify a processor exception.
\param [in] IRQn Interrupt number.
\param [in] priority Priority to set.
\note The priority cannot be set for every processor exception.
*/
__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)(IRQn) >= 0)
{
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
else
{
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
}
}
/**
\brief Get Interrupt Priority
\details Reads the priority of a device specific interrupt or a processor exception.
The interrupt number can be positive to specify a device specific interrupt,
or negative to specify a processor exception.
\param [in] IRQn Interrupt number.
\return Interrupt Priority.
Value is aligned automatically to the implemented priority bits of the microcontroller.
*/
__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn)
{
if ((int32_t)(IRQn) >= 0)
{
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
else
{
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
}
}
/**
\brief Set Interrupt Vector
\details Sets an interrupt vector in SRAM based interrupt vector table.
The interrupt number can be positive to specify a device specific interrupt,
or negative to specify a processor exception.
Address 0 must be mapped to SRAM.
\param [in] IRQn Interrupt number
\param [in] vector Address of interrupt handler function
*/
__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
{
uint32_t *vectors = (uint32_t *)0x0U;
vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector;
}
/**
\brief Get Interrupt Vector
\details Reads an interrupt vector from interrupt vector table.
The interrupt number can be positive to specify a device specific interrupt,
or negative to specify a processor exception.
\param [in] IRQn Interrupt number.
\return Address of interrupt handler function
*/
__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn)
{
uint32_t *vectors = (uint32_t *)0x0U;
return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET];
}
/**
\brief System Reset
\details Initiates a system reset request to reset the MCU.
*/
__STATIC_INLINE void __NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
for(;;) /* wait until reset */
{
__NOP();
}
}
/*@} end of CMSIS_Core_NVICFunctions */
/* ########################## FPU functions #################################### */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_FpuFunctions FPU Functions
\brief Function that provides FPU type.
@{
*/
/**
\brief get FPU type
\details returns the FPU type
\returns
- \b 0: No FPU
- \b 1: Single precision FPU
- \b 2: Double + Single precision FPU
*/
__STATIC_INLINE uint32_t SCB_GetFPUType(void)
{
return 0U; /* No FPU */
}
/*@} end of CMSIS_Core_FpuFunctions */
/* ################################## SysTick function ############################################ */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
\brief Functions that configure the System.
@{
*/
#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U)
/**
\brief System Tick Configuration
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL); /* Reload value impossible */
}
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0UL); /* Function successful */
}
#endif
/*@} end of CMSIS_Core_SysTickFunctions */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CM0_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,182 @@
/******************************************************************************
* @file mpu_armv7.h
* @brief CMSIS MPU API for ARMv7 MPU
* @version V5.0.2
* @date 09. June 2017
******************************************************************************/
/*
* Copyright (c) 2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ARM_MPU_ARMV7_H
#define ARM_MPU_ARMV7_H
#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U)
#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U)
#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U)
#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U)
#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U)
#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U)
#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU)
#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU)
#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU)
#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU)
#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU)
#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU)
#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U)
#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U)
#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U)
#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U)
#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U)
#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U)
#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U)
#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U)
#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U)
#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U)
#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU)
#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU)
#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU)
#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU)
#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU)
#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU)
#define ARM_MPU_AP_NONE 0u
#define ARM_MPU_AP_PRIV 1u
#define ARM_MPU_AP_URO 2u
#define ARM_MPU_AP_FULL 3u
#define ARM_MPU_AP_PRO 5u
#define ARM_MPU_AP_RO 6u
/** MPU Region Base Address Register Value
*
* \param Region The region to be configured, number 0 to 15.
* \param BaseAddress The base address for the region.
*/
#define ARM_MPU_RBAR(Region, BaseAddress) ((BaseAddress & MPU_RBAR_ADDR_Msk) | (Region & MPU_RBAR_REGION_Msk) | (1UL << MPU_RBAR_VALID_Pos))
/**
* MPU Region Attribut and Size Register Value
*
* \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode.
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
* \param IsShareable Region is shareable between multiple bus masters.
* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
* \param SubRegionDisable Sub-region disable field.
* \param Size Region size of the region to be configured, for example 4K, 8K.
*/
#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \
((DisableExec << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \
((AccessPermission << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \
((TypeExtField << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \
((IsShareable << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \
((IsCacheable << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \
((IsBufferable << MPU_RASR_B_Pos) & MPU_RASR_B_Msk) | \
((SubRegionDisable << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \
((Size << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \
((1UL << MPU_RASR_ENABLE_Pos) & MPU_RASR_ENABLE_Msk)
/**
* Struct for a single MPU Region
*/
typedef struct _ARM_MPU_Region_t {
uint32_t RBAR; //!< The region base address register value (RBAR)
uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR
} ARM_MPU_Region_t;
/** Enable the MPU.
* \param MPU_Control Default access permissions for unconfigured regions.
*/
__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
{
__DSB();
__ISB();
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
#endif
}
/** Disable the MPU.
*/
__STATIC_INLINE void ARM_MPU_Disable()
{
__DSB();
__ISB();
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
#endif
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
}
/** Clear and disable the given MPU region.
* \param rnr Region number to be cleared.
*/
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
{
MPU->RNR = rnr;
MPU->RASR = 0u;
}
/** Configure an MPU region.
* \param rbar Value for RBAR register.
* \param rsar Value for RSAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr)
{
MPU->RBAR = rbar;
MPU->RASR = rasr;
}
/** Configure the given MPU region.
* \param rnr Region number to be configured.
* \param rbar Value for RBAR register.
* \param rsar Value for RSAR register.
*/
__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr)
{
MPU->RNR = rnr;
MPU->RBAR = rbar;
MPU->RASR = rasr;
}
/** Memcopy with strictly ordered memory access, e.g. for register targets.
* \param dst Destination data is copied to.
* \param src Source data is copied from.
* \param len Amount of data words to be copied.
*/
__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
{
uint32_t i;
for (i = 0u; i < len; ++i)
{
dst[i] = src[i];
}
}
/** Load the given number of MPU regions from a table.
* \param table Pointer to the MPU configuration table.
* \param cnt Amount of regions to be configured.
*/
__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt)
{
orderedCpy(&(MPU->RBAR), &(table->RBAR), cnt*sizeof(ARM_MPU_Region_t)/4u);
}
#endif

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2015-2016 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ----------------------------------------------------------------------------
*
* $Date: 21. September 2016
* $Revision: V1.0
*
* Project: TrustZone for ARMv8-M
* Title: Context Management for ARMv8-M TrustZone
*
* Version 1.0
* Initial Release
*---------------------------------------------------------------------------*/
#ifndef TZ_CONTEXT_H
#define TZ_CONTEXT_H
#include <stdint.h>
#ifndef TZ_MODULEID_T
#define TZ_MODULEID_T
/// \details Data type that identifies secure software modules called by a process.
typedef uint32_t TZ_ModuleId_t;
#endif
/// \details TZ Memory ID identifies an allocated memory slot.
typedef uint32_t TZ_MemoryId_t;
/// Initialize secure context memory system
/// \return execution status (1: success, 0: error)
uint32_t TZ_InitContextSystem_S (void);
/// Allocate context memory for calling secure software modules in TrustZone
/// \param[in] module identifies software modules called from non-secure mode
/// \return value != 0 id TrustZone memory slot identifier
/// \return value 0 no memory available or internal error
TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module);
/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S
/// \param[in] id TrustZone memory slot identifier
/// \return execution status (1: success, 0: error)
uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id);
/// Load secure context (called on RTOS thread context switch)
/// \param[in] id TrustZone memory slot identifier
/// \return execution status (1: success, 0: error)
uint32_t TZ_LoadContext_S (TZ_MemoryId_t id);
/// Store secure context (called on RTOS thread context switch)
/// \param[in] id TrustZone memory slot identifier
/// \return execution status (1: success, 0: error)
uint32_t TZ_StoreContext_S (TZ_MemoryId_t id);
#endif // TZ_CONTEXT_H

View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,592 @@
/*
** ###################################################################
** Version: rev. 0.1, 2017-01-10
** Build: b180312
**
** Abstract:
** Chip specific module features.
**
** The Clear BSD License
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2018 NXP
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted (subject to the limitations in the
** disclaimer below) provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
**
** * 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.
**
** * 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.
**
** NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
** GRANTED BY THIS LICENSE. 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.
**
** http: www.nxp.com
** mail: support@nxp.com
**
** Revisions:
** - rev. 0.1 (2017-01-10)
** Initial version.
**
** ###################################################################
*/
#ifndef _MIMXRT1052_FEATURES_H_
#define _MIMXRT1052_FEATURES_H_
/* SOC module features */
/* @brief ADC availability on the SoC. */
#define FSL_FEATURE_SOC_ADC_COUNT (2)
/* @brief AIPSTZ availability on the SoC. */
#define FSL_FEATURE_SOC_AIPSTZ_COUNT (4)
/* @brief AOI availability on the SoC. */
#define FSL_FEATURE_SOC_AOI_COUNT (2)
/* @brief CCM availability on the SoC. */
#define FSL_FEATURE_SOC_CCM_COUNT (1)
/* @brief CCM_ANALOG availability on the SoC. */
#define FSL_FEATURE_SOC_CCM_ANALOG_COUNT (1)
/* @brief CMP availability on the SoC. */
#define FSL_FEATURE_SOC_CMP_COUNT (4)
/* @brief CSI availability on the SoC. */
#define FSL_FEATURE_SOC_CSI_COUNT (1)
/* @brief DCDC availability on the SoC. */
#define FSL_FEATURE_SOC_DCDC_COUNT (1)
/* @brief DCP availability on the SoC. */
#define FSL_FEATURE_SOC_DCP_COUNT (1)
/* @brief DMAMUX availability on the SoC. */
#define FSL_FEATURE_SOC_DMAMUX_COUNT (1)
/* @brief EDMA availability on the SoC. */
#define FSL_FEATURE_SOC_EDMA_COUNT (1)
/* @brief ENC availability on the SoC. */
#define FSL_FEATURE_SOC_ENC_COUNT (4)
/* @brief ENET availability on the SoC. */
#define FSL_FEATURE_SOC_ENET_COUNT (1)
/* @brief EWM availability on the SoC. */
#define FSL_FEATURE_SOC_EWM_COUNT (1)
/* @brief FLEXCAN availability on the SoC. */
#define FSL_FEATURE_SOC_FLEXCAN_COUNT (2)
/* @brief FLEXIO availability on the SoC. */
#define FSL_FEATURE_SOC_FLEXIO_COUNT (2)
/* @brief FLEXRAM availability on the SoC. */
#define FSL_FEATURE_SOC_FLEXRAM_COUNT (1)
/* @brief FLEXSPI availability on the SoC. */
#define FSL_FEATURE_SOC_FLEXSPI_COUNT (1)
/* @brief GPC availability on the SoC. */
#define FSL_FEATURE_SOC_GPC_COUNT (1)
/* @brief GPT availability on the SoC. */
#define FSL_FEATURE_SOC_GPT_COUNT (2)
/* @brief I2S availability on the SoC. */
#define FSL_FEATURE_SOC_I2S_COUNT (3)
/* @brief IGPIO availability on the SoC. */
#define FSL_FEATURE_SOC_IGPIO_COUNT (5)
/* @brief IOMUXC availability on the SoC. */
#define FSL_FEATURE_SOC_IOMUXC_COUNT (1)
/* @brief IOMUXC_GPR availability on the SoC. */
#define FSL_FEATURE_SOC_IOMUXC_GPR_COUNT (1)
/* @brief IOMUXC_SNVS availability on the SoC. */
#define FSL_FEATURE_SOC_IOMUXC_SNVS_COUNT (1)
/* @brief KPP availability on the SoC. */
#define FSL_FEATURE_SOC_KPP_COUNT (1)
/* @brief LCDIF availability on the SoC. */
#define FSL_FEATURE_SOC_LCDIF_COUNT (1)
/* @brief LPI2C availability on the SoC. */
#define FSL_FEATURE_SOC_LPI2C_COUNT (4)
/* @brief LPSPI availability on the SoC. */
#define FSL_FEATURE_SOC_LPSPI_COUNT (4)
/* @brief LPUART availability on the SoC. */
#define FSL_FEATURE_SOC_LPUART_COUNT (8)
/* @brief OCOTP availability on the SoC. */
#define FSL_FEATURE_SOC_OCOTP_COUNT (1)
/* @brief PIT availability on the SoC. */
#define FSL_FEATURE_SOC_PIT_COUNT (1)
/* @brief PMU availability on the SoC. */
#define FSL_FEATURE_SOC_PMU_COUNT (1)
/* @brief PWM availability on the SoC. */
#define FSL_FEATURE_SOC_PWM_COUNT (4)
/* @brief PXP availability on the SoC. */
#define FSL_FEATURE_SOC_PXP_COUNT (1)
/* @brief ROMC availability on the SoC. */
#define FSL_FEATURE_SOC_ROMC_COUNT (1)
/* @brief SEMC availability on the SoC. */
#define FSL_FEATURE_SOC_SEMC_COUNT (1)
/* @brief SNVS availability on the SoC. */
#define FSL_FEATURE_SOC_SNVS_COUNT (1)
/* @brief SPDIF availability on the SoC. */
#define FSL_FEATURE_SOC_SPDIF_COUNT (1)
/* @brief SRC availability on the SoC. */
#define FSL_FEATURE_SOC_SRC_COUNT (1)
/* @brief TEMPMON availability on the SoC. */
#define FSL_FEATURE_SOC_TEMPMON_COUNT (1)
/* @brief TMR availability on the SoC. */
#define FSL_FEATURE_SOC_TMR_COUNT (4)
/* @brief TRNG availability on the SoC. */
#define FSL_FEATURE_SOC_TRNG_COUNT (1)
/* @brief TSC availability on the SoC. */
#define FSL_FEATURE_SOC_TSC_COUNT (1)
/* @brief USBHS availability on the SoC. */
#define FSL_FEATURE_SOC_USBHS_COUNT (2)
/* @brief USBNC availability on the SoC. */
#define FSL_FEATURE_SOC_USBNC_COUNT (2)
/* @brief USBPHY availability on the SoC. */
#define FSL_FEATURE_SOC_USBPHY_COUNT (2)
/* @brief USDHC availability on the SoC. */
#define FSL_FEATURE_SOC_USDHC_COUNT (2)
/* @brief WDOG availability on the SoC. */
#define FSL_FEATURE_SOC_WDOG_COUNT (2)
/* @brief XBARA availability on the SoC. */
#define FSL_FEATURE_SOC_XBARA_COUNT (1)
/* @brief XBARB availability on the SoC. */
#define FSL_FEATURE_SOC_XBARB_COUNT (2)
/* @brief XTALOSC24M availability on the SoC. */
#define FSL_FEATURE_SOC_XTALOSC24M_COUNT (1)
/* ADC module features */
/* @brief Remove Hardware Trigger feature. */
#define FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE (0)
/* @brief Remove ALT Clock selection feature. */
#define FSL_FEATURE_ADC_SUPPORT_ALTCLK_REMOVE (1)
/* ADC_ETC module features */
/* @brief Has DMA model control(bit field CTRL[DMA_MODE_SEL]). */
#define FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL (1)
/* AOI module features */
/* @brief Maximum value of input mux. */
#define FSL_FEATURE_AOI_MODULE_INPUTS (4)
/* @brief Number of events related to number of registers AOIx_BFCRT01n/AOIx_BFCRT23n. */
#define FSL_FEATURE_AOI_EVENT_COUNT (4)
/* FLEXCAN module features */
/* @brief Message buffer size */
#define FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(x) (64)
/* @brief Has doze mode support (register bit field MCR[DOZE]). */
#define FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT (0)
/* @brief Has a glitch filter on the receive pin (register bit field MCR[WAKSRC]). */
#define FSL_FEATURE_FLEXCAN_HAS_GLITCH_FILTER (1)
/* @brief Has extended interrupt mask and flag register (register IMASK2, IFLAG2). */
#define FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER (1)
/* @brief Has extended bit timing register (register CBT). */
#define FSL_FEATURE_FLEXCAN_HAS_EXTENDED_TIMING_REGISTER (0)
/* @brief Has a receive FIFO DMA feature (register bit field MCR[DMA]). */
#define FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA (0)
/* @brief Remove CAN Engine Clock Source Selection from unsupported part. */
#define FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE (1)
/* @brief Is affected by errata with ID 5641 (Module does not transmit a message that is enabled to be transmitted at a specific moment during the arbitration process). */
#define FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641 (0)
/* @brief Has CAN with Flexible Data rate (CAN FD) protocol. */
#define FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE (0)
/* @brief Has extra MB interrupt or common one. */
#define FSL_FEATURE_FLEXCAN_HAS_EXTRA_MB_INT (1)
/* CMP module features */
/* @brief Has Trigger mode in CMP (register bit field CR1[TRIGM]). */
#define FSL_FEATURE_CMP_HAS_TRIGGER_MODE (0)
/* @brief Has Window mode in CMP (register bit field CR1[WE]). */
#define FSL_FEATURE_CMP_HAS_WINDOW_MODE (1)
/* @brief Has External sample supported in CMP (register bit field CR1[SE]). */
#define FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT (1)
/* @brief Has DMA support in CMP (register bit field SCR[DMAEN]). */
#define FSL_FEATURE_CMP_HAS_DMA (1)
/* @brief Has Pass Through mode in CMP (register bit field MUXCR[PSTM]). */
#define FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE (0)
/* @brief Has DAC Test function in CMP (register DACTEST). */
#define FSL_FEATURE_CMP_HAS_DAC_TEST (0)
/* EDMA module features */
/* @brief Number of DMA channels (related to number of registers TCD, DCHPRI, bit fields ERQ[ERQn], EEI[EEIn], INT[INTn], ERR[ERRn], HRS[HRSn] and bit field widths ES[ERRCHN], CEEI[CEEI], SEEI[SEEI], CERQ[CERQ], SERQ[SERQ], CDNE[CDNE], SSRT[SSRT], CERR[CERR], CINT[CINT], TCDn_CITER_ELINKYES[LINKCH], TCDn_CSR[MAJORLINKCH], TCDn_BITER_ELINKYES[LINKCH]). (Valid only for eDMA modules.) */
#define FSL_FEATURE_EDMA_MODULE_CHANNEL (32)
/* @brief Total number of DMA channels on all modules. */
#define FSL_FEATURE_EDMA_DMAMUX_CHANNELS (32)
/* @brief Number of DMA channel groups (register bit fields CR[ERGA], CR[GRPnPRI], ES[GPE], DCHPRIn[GRPPRI]). (Valid only for eDMA modules.) */
#define FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT (1)
/* @brief Has DMA_Error interrupt vector. */
#define FSL_FEATURE_EDMA_HAS_ERROR_IRQ (1)
/* @brief Number of DMA channels with asynchronous request capability (register EARS). (Valid only for eDMA modules.) */
#define FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT (32)
/* DMAMUX module features */
/* @brief Number of DMA channels (related to number of register CHCFGn). */
#define FSL_FEATURE_DMAMUX_MODULE_CHANNEL (32)
/* @brief Total number of DMA channels on all modules. */
#define FSL_FEATURE_DMAMUX_DMAMUX_CHANNELS (FSL_FEATURE_SOC_DMAMUX_COUNT * 32)
/* @brief Has the periodic trigger capability for the triggered DMA channel (register bit CHCFG0[TRIG]). */
#define FSL_FEATURE_DMAMUX_HAS_TRIG (1)
/* @brief Has DMA Channel Always ON function (register bit CHCFG0[A_ON]). */
#define FSL_FEATURE_DMAMUX_HAS_A_ON (1)
/* ENET module features */
/* @brief Support Interrupt Coalesce */
#define FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE (1)
/* @brief Queue Size. */
#define FSL_FEATURE_ENET_QUEUE (1)
/* @brief Has AVB Support. */
#define FSL_FEATURE_ENET_HAS_AVB (0)
/* @brief Has Timer Pulse Width control. */
#define FSL_FEATURE_ENET_HAS_TIMER_PWCONTROL (1)
/* @brief Has Extend MDIO Support. */
#define FSL_FEATURE_ENET_HAS_EXTEND_MDIO (1)
/* @brief Has Additional 1588 Timer Channel Interrupt. */
#define FSL_FEATURE_ENET_HAS_ADD_1588_TIMER_CHN_INT (0)
/* FLEXRAM module features */
/* @brief Bank size */
#define FSL_FEATURE_FLEXRAM_INTERNAL_RAM_BANK_SIZE (32 * 1024)
/* @brief Total Bank numbers */
#define FSL_FEATURE_FLEXRAM_INTERNAL_RAM_TOTAL_BANK_NUMBERS (16)
/* FLEXSPI module features */
/* @brief FlexSPI AHB buffer count */
#define FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNTn(x) (4)
/* @brief FlexSPI has no data learn. */
#define FSL_FEATURE_FLEXSPI_HAS_NO_DATA_LEARN (1)
/* GPC module features */
/* @brief Has DVFS0 Change Request. */
#define FSL_FEATURE_GPC_HAS_CNTR_DVFS0CR (0)
/* @brief Has GPC interrupt/event masking. */
#define FSL_FEATURE_GPC_HAS_CNTR_GPCIRQM (0)
/* @brief Has L2 cache power control. */
#define FSL_FEATURE_GPC_HAS_CNTR_L2PGE (0)
/* @brief Has FLEXRAM PDRAM0(bank1-7) power control. */
#define FSL_FEATURE_GPC_HAS_CNTR_PDRAM0PGE (1)
/* @brief Has VADC power control. */
#define FSL_FEATURE_GPC_HAS_CNTR_VADC (0)
/* @brief Has Display power control. */
#define FSL_FEATURE_GPC_HAS_CNTR_DISPLAY (0)
/* @brief Supports IRQ 0-31. */
#define FSL_FEATURE_GPC_HAS_IRQ_0_31 (1)
/* IGPIO module features */
/* @brief Has data register set DR_SET. */
#define FSL_FEATURE_IGPIO_HAS_DR_SET (1)
/* @brief Has data register clear DR_CLEAR. */
#define FSL_FEATURE_IGPIO_HAS_DR_CLEAR (1)
/* @brief Has data register toggle DR_TOGGLE. */
#define FSL_FEATURE_IGPIO_HAS_DR_TOGGLE (1)
/* LCDIF module features */
/* @brief LCDIF does not support alpha support. */
#define FSL_FEATURE_LCDIF_HAS_NO_AS (1)
/* @brief LCDIF does not support output reset pin to LCD panel. */
#define FSL_FEATURE_LCDIF_HAS_NO_RESET_PIN (1)
/* @brief LCDIF supports LUT. */
#define FSL_FEATURE_LCDIF_HAS_LUT (1)
/* LPI2C module features */
/* @brief Has separate DMA RX and TX requests. */
#define FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(x) (0)
/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */
#define FSL_FEATURE_LPI2C_FIFO_SIZEn(x) (4)
/* LPSPI module features */
/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */
#define FSL_FEATURE_LPSPI_FIFO_SIZEn(x) (16)
/* @brief Has separate DMA RX and TX requests. */
#define FSL_FEATURE_LPSPI_HAS_SEPARATE_DMA_RX_TX_REQn(x) (1)
/* LPUART module features */
/* @brief Has receive FIFO overflow detection (bit field CFIFO[RXOFE]). */
#define FSL_FEATURE_LPUART_HAS_IRQ_EXTENDED_FUNCTIONS (0)
/* @brief Has low power features (can be enabled in wait mode via register bit C1[DOZEEN] or CTRL[DOZEEN] if the registers are 32-bit wide). */
#define FSL_FEATURE_LPUART_HAS_LOW_POWER_UART_SUPPORT (1)
/* @brief Has extended data register ED (or extra flags in the DATA register if the registers are 32-bit wide). */
#define FSL_FEATURE_LPUART_HAS_EXTENDED_DATA_REGISTER_FLAGS (1)
/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */
#define FSL_FEATURE_LPUART_HAS_FIFO (1)
/* @brief Has 32-bit register MODIR */
#define FSL_FEATURE_LPUART_HAS_MODIR (1)
/* @brief Hardware flow control (RTS, CTS) is supported. */
#define FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT (1)
/* @brief Infrared (modulation) is supported. */
#define FSL_FEATURE_LPUART_HAS_IR_SUPPORT (1)
/* @brief 2 bits long stop bit is available. */
#define FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT (1)
/* @brief If 10-bit mode is supported. */
#define FSL_FEATURE_LPUART_HAS_10BIT_DATA_SUPPORT (1)
/* @brief If 7-bit mode is supported. */
#define FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT (1)
/* @brief Baud rate fine adjustment is available. */
#define FSL_FEATURE_LPUART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT (0)
/* @brief Baud rate oversampling is available (has bit fields C4[OSR], C5[BOTHEDGE], C5[RESYNCDIS] or BAUD[OSR], BAUD[BOTHEDGE], BAUD[RESYNCDIS] if the registers are 32-bit wide). */
#define FSL_FEATURE_LPUART_HAS_BAUD_RATE_OVER_SAMPLING_SUPPORT (1)
/* @brief Baud rate oversampling is available. */
#define FSL_FEATURE_LPUART_HAS_RX_RESYNC_SUPPORT (1)
/* @brief Baud rate oversampling is available. */
#define FSL_FEATURE_LPUART_HAS_BOTH_EDGE_SAMPLING_SUPPORT (1)
/* @brief Peripheral type. */
#define FSL_FEATURE_LPUART_IS_SCI (1)
/* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */
#define FSL_FEATURE_LPUART_FIFO_SIZEn(x) (4)
/* @brief Maximal data width without parity bit. */
#define FSL_FEATURE_LPUART_MAX_DATA_WIDTH_WITH_NO_PARITY (10)
/* @brief Maximal data width with parity bit. */
#define FSL_FEATURE_LPUART_MAX_DATA_WIDTH_WITH_PARITY (9)
/* @brief Supports two match addresses to filter incoming frames. */
#define FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING (1)
/* @brief Has transmitter/receiver DMA enable bits C5[TDMAE]/C5[RDMAE] (or BAUD[TDMAE]/BAUD[RDMAE] if the registers are 32-bit wide). */
#define FSL_FEATURE_LPUART_HAS_DMA_ENABLE (1)
/* @brief Has transmitter/receiver DMA select bits C4[TDMAS]/C4[RDMAS], resp. C5[TDMAS]/C5[RDMAS] if IS_SCI = 0. */
#define FSL_FEATURE_LPUART_HAS_DMA_SELECT (0)
/* @brief Data character bit order selection is supported (bit field S2[MSBF] or STAT[MSBF] if the registers are 32-bit wide). */
#define FSL_FEATURE_LPUART_HAS_BIT_ORDER_SELECT (1)
/* @brief Has smart card (ISO7816 protocol) support and no improved smart card support. */
#define FSL_FEATURE_LPUART_HAS_SMART_CARD_SUPPORT (0)
/* @brief Has improved smart card (ISO7816 protocol) support. */
#define FSL_FEATURE_LPUART_HAS_IMPROVED_SMART_CARD_SUPPORT (0)
/* @brief Has local operation network (CEA709.1-B protocol) support. */
#define FSL_FEATURE_LPUART_HAS_LOCAL_OPERATION_NETWORK_SUPPORT (0)
/* @brief Has 32-bit registers (BAUD, STAT, CTRL, DATA, MATCH, MODIR) instead of 8-bit (BDH, BDL, C1, S1, D, etc.). */
#define FSL_FEATURE_LPUART_HAS_32BIT_REGISTERS (1)
/* @brief Lin break detect available (has bit BAUD[LBKDIE]). */
#define FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT (1)
/* @brief UART stops in Wait mode available (has bit C1[UARTSWAI]). */
#define FSL_FEATURE_LPUART_HAS_WAIT_MODE_OPERATION (0)
/* @brief Has separate DMA RX and TX requests. */
#define FSL_FEATURE_LPUART_HAS_SEPARATE_DMA_RX_TX_REQn(x) (1)
/* @brief Has separate RX and TX interrupts. */
#define FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ (0)
/* @brief Has LPAURT_PARAM. */
#define FSL_FEATURE_LPUART_HAS_PARAM (1)
/* @brief Has LPUART_VERID. */
#define FSL_FEATURE_LPUART_HAS_VERID (1)
/* @brief Has LPUART_GLOBAL. */
#define FSL_FEATURE_LPUART_HAS_GLOBAL (1)
/* @brief Has LPUART_PINCFG. */
#define FSL_FEATURE_LPUART_HAS_PINCFG (1)
/* interrupt module features */
/* @brief Lowest interrupt request number. */
#define FSL_FEATURE_INTERRUPT_IRQ_MIN (-14)
/* @brief Highest interrupt request number. */
#define FSL_FEATURE_INTERRUPT_IRQ_MAX (159)
/* OCOTP module features */
/* No feature definitions */
/* PIT module features */
/* @brief Number of channels (related to number of registers LDVALn, CVALn, TCTRLn, TFLGn). */
#define FSL_FEATURE_PIT_TIMER_COUNT (4)
/* @brief Has lifetime timer (related to existence of registers LTMR64L and LTMR64H). */
#define FSL_FEATURE_PIT_HAS_LIFETIME_TIMER (1)
/* @brief Has chain mode (related to existence of register bit field TCTRLn[CHN]). */
#define FSL_FEATURE_PIT_HAS_CHAIN_MODE (1)
/* @brief Has shared interrupt handler (has not individual interrupt handler for each channel). */
#define FSL_FEATURE_PIT_HAS_SHARED_IRQ_HANDLER (1)
/* @brief Has timer enable control. */
#define FSL_FEATURE_PIT_HAS_MDIS (1)
/* PMU module features */
/* @brief PMU supports lower power control. */
#define FSL_FEATURE_PMU_HAS_LOWPWR_CTRL (0)
/* PWM module features */
/* @brief Number of each EflexPWM module channels (outputs). */
#define FSL_FEATURE_PWM_CHANNEL_COUNT (12U)
/* @brief Number of EflexPWM module A channels (outputs). */
#define FSL_FEATURE_PWM_CHANNELA_COUNT (4U)
/* @brief Number of EflexPWM module B channels (outputs). */
#define FSL_FEATURE_PWM_CHANNELB_COUNT (4U)
/* @brief Number of EflexPWM module X channels (outputs). */
#define FSL_FEATURE_PWM_CHANNELX_COUNT (4U)
/* @brief Number of each EflexPWM module compare channels interrupts. */
#define FSL_FEATURE_PWM_CMP_INT_HANDLER_COUNT (4U)
/* @brief Number of each EflexPWM module reload channels interrupts. */
#define FSL_FEATURE_PWM_RELOAD_INT_HANDLER_COUNT (4U)
/* @brief Number of each EflexPWM module capture channels interrupts. */
#define FSL_FEATURE_PWM_CAP_INT_HANDLER_COUNT (1U)
/* @brief Number of each EflexPWM module reload error channels interrupts. */
#define FSL_FEATURE_PWM_RERR_INT_HANDLER_COUNT (1U)
/* @brief Number of each EflexPWM module fault channels interrupts. */
#define FSL_FEATURE_PWM_FAULT_INT_HANDLER_COUNT (1U)
/* @brief Number of submodules in each EflexPWM module. */
#define FSL_FEATURE_PWM_SUBMODULE_COUNT (4U)
/* PXP module features */
/* @brief PXP module has dither engine. */
#define FSL_FEATURE_PXP_HAS_DITHER (0)
/* @brief PXP module supports repeat run */
#define FSL_FEATURE_PXP_HAS_EN_REPEAT (1)
/* @brief PXP doesn't have CSC */
#define FSL_FEATURE_PXP_HAS_NO_CSC2 (1)
/* @brief PXP doesn't have LUT */
#define FSL_FEATURE_PXP_HAS_NO_LUT (1)
/* RTWDOG module features */
/* @brief Watchdog is available. */
#define FSL_FEATURE_RTWDOG_HAS_WATCHDOG (1)
/* @brief RTWDOG_CNT can be 32-bit written. */
#define FSL_FEATURE_RTWDOG_HAS_32BIT_ACCESS (1)
/* SAI module features */
/* @brief Receive/transmit FIFO size in item count (register bit fields TCSR[FRDE], TCSR[FRIE], TCSR[FRF], TCR1[TFW], RCSR[FRDE], RCSR[FRIE], RCSR[FRF], RCR1[RFW], registers TFRn, RFRn). */
#define FSL_FEATURE_SAI_FIFO_COUNT (32)
/* @brief Receive/transmit channel number (register bit fields TCR3[TCE], RCR3[RCE], registers TDRn and RDRn). */
#define FSL_FEATURE_SAI_CHANNEL_COUNT (4)
/* @brief Maximum words per frame (register bit fields TCR3[WDFL], TCR4[FRSZ], TMR[TWM], RCR3[WDFL], RCR4[FRSZ], RMR[RWM]). */
#define FSL_FEATURE_SAI_MAX_WORDS_PER_FRAME (32)
/* @brief Has support of combining multiple data channel FIFOs into single channel FIFO (register bit fields TCR3[CFR], TCR4[FCOMB], TFR0[WCP], TFR1[WCP], RCR3[CFR], RCR4[FCOMB], RFR0[RCP], RFR1[RCP]). */
#define FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE (1)
/* @brief Has packing of 8-bit and 16-bit data into each 32-bit FIFO word (register bit fields TCR4[FPACK], RCR4[FPACK]). */
#define FSL_FEATURE_SAI_HAS_FIFO_PACKING (1)
/* @brief Configures when the SAI will continue transmitting after a FIFO error has been detected (register bit fields TCR4[FCONT], RCR4[FCONT]). */
#define FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR (1)
/* @brief Configures if the frame sync is generated internally, a frame sync is only generated when the FIFO warning flag is clear or continuously (register bit fields TCR4[ONDEM], RCR4[ONDEM]). */
#define FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE (1)
/* @brief Simplified bit clock source and asynchronous/synchronous mode selection (register bit fields TCR2[CLKMODE], RCR2[CLKMODE]), in comparison with the exclusively implemented TCR2[SYNC,BCS,BCI,MSEL], RCR2[SYNC,BCS,BCI,MSEL]. */
#define FSL_FEATURE_SAI_HAS_CLOCKING_MODE (0)
/* @brief Has register for configuration of the MCLK divide ratio (register bit fields MDR[FRACT], MDR[DIVIDE]). */
#define FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER (0)
/* @brief Interrupt source number */
#define FSL_FEATURE_SAI_INT_SOURCE_NUM (2)
/* @brief Has register of MCR. */
#define FSL_FEATURE_SAI_HAS_MCR (0)
/* @brief Has register of MDR */
#define FSL_FEATURE_SAI_HAS_MDR (0)
/* SNVS module features */
/* @brief Has Secure Real Time Counter Enabled and Valid (bit field LPCR[SRTC_ENV]). */
#define FSL_FEATURE_SNVS_HAS_SRTC (1)
/* SRC module features */
/* @brief There is MASK_WDOG3_RST bit in SCR register. */
#define FSL_FEATURE_SRC_HAS_SCR_MASK_WDOG3_RST (1)
/* @brief There is MIX_RST_STRCH bit in SCR register. */
#define FSL_FEATURE_SRC_HAS_SCR_MIX_RST_STRCH (0)
/* @brief There is DBG_RST_MSK_PG bit in SCR register. */
#define FSL_FEATURE_SRC_HAS_SCR_DBG_RST_MSK_PG (1)
/* @brief There is WDOG3_RST_OPTN bit in SCR register. */
#define FSL_FEATURE_SRC_HAS_SCR_WDOG3_RST_OPTN (0)
/* @brief There is CORES_DBG_RST bit in SCR register. */
#define FSL_FEATURE_SRC_HAS_SCR_CORES_DBG_RST (0)
/* @brief There is MTSR bit in SCR register. */
#define FSL_FEATURE_SRC_HAS_SCR_MTSR (0)
/* @brief There is CORE0_DBG_RST bit in SCR register. */
#define FSL_FEATURE_SRC_HAS_SCR_CORE0_DBG_RST (1)
/* @brief There is CORE0_RST bit in SCR register. */
#define FSL_FEATURE_SRC_HAS_SCR_CORE0_RST (1)
/* @brief There is LOCKUP_RST bit in SCR register. */
#define FSL_FEATURE_SRC_HAS_SCR_LOCKUP_RST (0)
/* @brief There is SWRC bit in SCR register. */
#define FSL_FEATURE_SRC_HAS_SCR_SWRC (0)
/* @brief There is EIM_RST bit in SCR register. */
#define FSL_FEATURE_SRC_HAS_SCR_EIM_RST (0)
/* @brief There is LUEN bit in SCR register. */
#define FSL_FEATURE_SRC_HAS_SCR_LUEN (0)
/* @brief There is no WRBC bit in SCR register. */
#define FSL_FEATURE_SRC_HAS_NO_SCR_WRBC (1)
/* @brief There is no WRE bit in SCR register. */
#define FSL_FEATURE_SRC_HAS_NO_SCR_WRE (1)
/* @brief There is SISR register. */
#define FSL_FEATURE_SRC_HAS_SISR (0)
/* @brief There is RESET_OUT bit in SRSR register. */
#define FSL_FEATURE_SRC_HAS_SRSR_RESET_OUT (0)
/* @brief There is WDOG3_RST_B bit in SRSR register. */
#define FSL_FEATURE_SRC_HAS_SRSR_WDOG3_RST_B (1)
/* @brief There is SW bit in SRSR register. */
#define FSL_FEATURE_SRC_HAS_SRSR_SW (0)
/* @brief There is IPP_USER_RESET_B bit in SRSR register. */
#define FSL_FEATURE_SRC_HAS_SRSR_IPP_USER_RESET_B (1)
/* @brief There is SNVS bit in SRSR register. */
#define FSL_FEATURE_SRC_HAS_SRSR_SNVS (0)
/* @brief There is CSU_RESET_B bit in SRSR register. */
#define FSL_FEATURE_SRC_HAS_SRSR_CSU_RESET_B (1)
/* @brief There is LOCKUP bit in SRSR register. */
#define FSL_FEATURE_SRC_HAS_SRSR_LOCKUP (0)
/* @brief There is LOCKUP_SYSRESETREQ bit in SRSR register. */
#define FSL_FEATURE_SRC_HAS_SRSR_LOCKUP_SYSRESETREQ (1)
/* @brief There is POR bit in SRSR register. */
#define FSL_FEATURE_SRC_HAS_SRSR_POR (0)
/* @brief There is IPP_RESET_B bit in SRSR register. */
#define FSL_FEATURE_SRC_HAS_SRSR_IPP_RESET_B (1)
/* @brief There is no WBI bit in SCR register. */
#define FSL_FEATURE_SRC_HAS_NO_SRSR_WBI (1)
/* SCB module features */
/* @brief L1 ICACHE line size in byte. */
#define FSL_FEATURE_L1ICACHE_LINESIZE_BYTE (32)
/* @brief L1 DCACHE line size in byte. */
#define FSL_FEATURE_L1DCACHE_LINESIZE_BYTE (32)
/* TRNG module features */
/* @brief TRNG has no TRNG_ACC bitfield. */
#define FSL_FEATURE_TRNG_HAS_NO_TRNG_ACC (1)
/* USBHS module features */
/* @brief EHCI module instance count */
#define FSL_FEATURE_USBHS_EHCI_COUNT (2)
/* @brief Number of endpoints supported */
#define FSL_FEATURE_USBHS_ENDPT_COUNT (8)
/* USDHC module features */
/* @brief Has external DMA support (VEND_SPEC[EXT_DMA_EN]) */
#define FSL_FEATURE_USDHC_HAS_EXT_DMA (0)
/* @brief Has HS400 mode (MIX_CTRL[HS400_MODE]) */
#define FSL_FEATURE_USDHC_HAS_HS400_MODE (0)
/* @brief Has SDR50 support (HOST_CTRL_CAP[SDR50_SUPPORT]) */
#define FSL_FEATURE_USDHC_HAS_SDR50_MODE (1)
/* @brief Has SDR104 support (HOST_CTRL_CAP[SDR104_SUPPORT]) */
#define FSL_FEATURE_USDHC_HAS_SDR104_MODE (1)
/* XBARA module features */
/* @brief DMA_CH_MUX_REQ_30. */
#define FSL_FEATURE_XBARA_OUTPUT_DMA_CH_MUX_REQ_30 (1)
/* @brief DMA_CH_MUX_REQ_31. */
#define FSL_FEATURE_XBARA_OUTPUT_DMA_CH_MUX_REQ_31 (1)
/* @brief DMA_CH_MUX_REQ_94. */
#define FSL_FEATURE_XBARA_OUTPUT_DMA_CH_MUX_REQ_94 (1)
/* @brief DMA_CH_MUX_REQ_95. */
#define FSL_FEATURE_XBARA_OUTPUT_DMA_CH_MUX_REQ_95 (1)
#endif /* _MIMXRT1052_FEATURES_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 2013-2016 ARM Limited. All rights reserved.
* Copyright (c) 2016, Freescale Semiconductor, Inc. Not a Contribution.
* Copyright 2016-2017 NXP. Not a Contribution.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _FSL_LPI2C_CMSIS_H_
#define _FSL_LPI2C_CMSIS_H_
#include "fsl_common.h"
#include "Driver_I2C.h"
#include "RTE_Device.h"
#include "fsl_lpi2c.h"
#if (defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT)
#include "fsl_dmamux.h"
#endif
#if (defined(FSL_FEATURE_SOC_DMA_COUNT) && FSL_FEATURE_SOC_DMA_COUNT)
#include "fsl_lpi2c_dma.h"
#endif
#if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && FSL_FEATURE_SOC_EDMA_COUNT)
#include "fsl_lpi2c_edma.h"
#endif
#if defined(LPI2C0)
extern ARM_DRIVER_I2C Driver_I2C0;
#endif /* LPI2C0 */
#if defined(LPI2C1)
extern ARM_DRIVER_I2C Driver_I2C1;
#endif /* LPI2C1 */
#if defined(LPI2C2)
extern ARM_DRIVER_I2C Driver_I2C2;
#endif /* LPI2C2 */
#if defined(LPI2C3)
extern ARM_DRIVER_I2C Driver_I2C3;
#endif /* LPI2C3 */
#if defined(LPI2C4)
extern ARM_DRIVER_I2C Driver_I2C4;
#endif /* LPI2C4 */
#if defined(LPI2C5)
extern ARM_DRIVER_I2C Driver_I2C5;
#endif /* LPI2C5*/
#if defined(LPI2C6)
extern ARM_DRIVER_I2C Driver_I2C6;
#endif /* LPI2C6 */
/* I2C Driver state flags */
#define I2C_FLAG_UNINIT (0)
#define I2C_FLAG_INIT (1 << 0)
#define I2C_FLAG_POWER (1 << 1)
#endif /* _FSL_LPI2C_CMSIS_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2013-2016 ARM Limited. All rights reserved.
* Copyright (c) 2016, Freescale Semiconductor, Inc. Not a Contribution.
* Copyright 2016-2017 NXP. Not a Contribution.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _FSL_LPSPI_CMSISI_H_
#define _FSL_LPSPI_CMSISI_H_
#include "fsl_common.h"
#include "RTE_Device.h"
#include "Driver_SPI.h"
#if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && FSL_FEATURE_SOC_EDMA_COUNT)
#include "fsl_lpspi_edma.h"
#endif
#if (defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT)
#include "fsl_dmamux.h"
#endif
#if defined(LPSPI0)
extern ARM_DRIVER_SPI Driver_SPI0;
#endif /* LPSPI0 */
#if defined(LPSPI1)
extern ARM_DRIVER_SPI Driver_SPI1;
#endif /* LPSPI1 */
#if defined(LPSPI2)
extern ARM_DRIVER_SPI Driver_SPI2;
#endif /* LPSPI2 */
#if defined(LPSPI3)
extern ARM_DRIVER_SPI Driver_SPI3;
#endif /* LPSPI3 */
#if defined(LPSPI4)
extern ARM_DRIVER_SPI Driver_SPI4;
#endif /* LPSPI4 */
#if defined(LPSPI5)
extern ARM_DRIVER_SPI Driver_SPI5;
#endif /* LPSPI5 */
/* SPI Driver state flags */
#define SPI_FLAG_UNINIT (0)
#define SPI_FLAG_INIT (1 << 0)
#define SPI_FLAG_POWER (1 << 1)
#define SPI_FLAG_CONFIGURED (1 << 2)
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,90 @@
/*
* Copyright (c) 2013-2016 ARM Limited. All rights reserved.
* Copyright (c) 2016, Freescale Semiconductor, Inc. Not a Contribution.
* Copyright 2016-2017 NXP. Not a Contribution.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _FSL_LPUART_CMSIS_H_
#define _FSL_LPUART_CMSIS_H_
#include "fsl_common.h"
#include "Driver_USART.h"
#include "RTE_Device.h"
#include "fsl_lpuart.h"
#if (defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT)
#include "fsl_dmamux.h"
#endif
#if (defined(FSL_FEATURE_SOC_DMA_COUNT) && FSL_FEATURE_SOC_DMA_COUNT)
#include "fsl_lpuart_dma.h"
#endif
#if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && FSL_FEATURE_SOC_EDMA_COUNT)
#include "fsl_lpuart_edma.h"
#endif
#if defined(LPUART0)
extern ARM_DRIVER_USART Driver_USART0;
#endif /* LPUART0 */
#if defined(LPUART1)
extern ARM_DRIVER_USART Driver_USART1;
#endif /* LPUART1 */
#if defined(LPUART2)
extern ARM_DRIVER_USART Driver_USART2;
#endif /* LPUART2 */
#if defined(LPUART3)
extern ARM_DRIVER_USART Driver_USART3;
#endif /* LPUART3 */
#if defined(LPUART4)
extern ARM_DRIVER_USART Driver_USART4;
#endif /* LPUART4 */
#if defined(LPUART5)
extern ARM_DRIVER_USART Driver_USART5;
#endif /* LPUART5 */
#if defined(LPUART6)
extern ARM_DRIVER_USART Driver_USART6;
#endif /* LPUART6 */
#if (FSL_FEATURE_SOC_LPUART_COUNT == 1) && (FSL_FEATURE_SOC_UART_COUNT == 3)
extern ARM_DRIVER_USART Driver_USART3;
#endif
#if (FSL_FEATURE_SOC_LPUART_COUNT == 1) && (FSL_FEATURE_SOC_UART_COUNT == 4)
extern ARM_DRIVER_USART Driver_USART4;
#endif
#if (FSL_FEATURE_SOC_LPUART_COUNT == 1) && (FSL_FEATURE_SOC_UART_COUNT == 5)
extern ARM_DRIVER_USART Driver_USART5;
#endif
/* USART Driver state flags */
#define USART_FLAG_UNINIT (0)
#define USART_FLAG_INIT (1 << 0)
#define USART_FLAG_POWER (1 << 1)
#define USART_FLAG_CONFIGURED (1 << 2)
#endif /* _FSL_LPUART_CMSIS_H_ */

View File

@@ -0,0 +1,300 @@
/*
* The Clear BSD License
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#include "fsl_adc.h"
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get instance number for ADC module.
*
* @param base ADC peripheral base address
*/
static uint32_t ADC_GetInstance(ADC_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to ADC bases for each instance. */
static ADC_Type *const s_adcBases[] = ADC_BASE_PTRS;
/*! @brief Pointers to ADC clocks for each instance. */
static const clock_ip_name_t s_adcClocks[] = ADC_CLOCKS;
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t ADC_GetInstance(ADC_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_adcBases); instance++)
{
if (s_adcBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_adcBases));
return instance;
}
void ADC_Init(ADC_Type *base, const adc_config_t *config)
{
assert(NULL != config);
uint32_t tmp32;
/* Enable the clock. */
CLOCK_EnableClock(s_adcClocks[ADC_GetInstance(base)]);
/* ADCx_CFG */
tmp32 = base->CFG & (ADC_CFG_AVGS_MASK | ADC_CFG_ADTRG_MASK); /* Reserve AVGS and ADTRG bits. */
tmp32 |= ADC_CFG_REFSEL(config->referenceVoltageSource) | ADC_CFG_ADSTS(config->samplePeriodMode) |
ADC_CFG_ADICLK(config->clockSource) | ADC_CFG_ADIV(config->clockDriver) | ADC_CFG_MODE(config->resolution);
if (config->enableOverWrite)
{
tmp32 |= ADC_CFG_OVWREN_MASK;
}
if (config->enableLongSample)
{
tmp32 |= ADC_CFG_ADLSMP_MASK;
}
if (config->enableLowPower)
{
tmp32 |= ADC_CFG_ADLPC_MASK;
}
if (config->enableHighSpeed)
{
tmp32 |= ADC_CFG_ADHSC_MASK;
}
base->CFG = tmp32;
/* ADCx_GC */
tmp32 = base->GC & ~(ADC_GC_ADCO_MASK | ADC_GC_ADACKEN_MASK);
if (config->enableContinuousConversion)
{
tmp32 |= ADC_GC_ADCO_MASK;
}
if (config->enableAsynchronousClockOutput)
{
tmp32 |= ADC_GC_ADACKEN_MASK;
}
base->GC = tmp32;
}
void ADC_Deinit(ADC_Type *base)
{
/* Disable the clock. */
CLOCK_DisableClock(s_adcClocks[ADC_GetInstance(base)]);
}
void ADC_GetDefaultConfig(adc_config_t *config)
{
assert(NULL != config);
config->enableAsynchronousClockOutput = true;
config->enableOverWrite = false;
config->enableContinuousConversion = false;
config->enableHighSpeed = false;
config->enableLowPower = false;
config->enableLongSample = false;
config->referenceVoltageSource = kADC_ReferenceVoltageSourceAlt0;
config->samplePeriodMode = kADC_SamplePeriod2or12Clocks;
config->clockSource = kADC_ClockSourceAD;
config->clockDriver = kADC_ClockDriver1;
config->resolution = kADC_Resolution12Bit;
}
void ADC_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc_channel_config_t *config)
{
assert(NULL != config);
assert(channelGroup < ADC_HC_COUNT);
uint32_t tmp32;
tmp32 = ADC_HC_ADCH(config->channelNumber);
if (config->enableInterruptOnConversionCompleted)
{
tmp32 |= ADC_HC_AIEN_MASK;
}
base->HC[channelGroup] = tmp32;
}
/*
*To complete calibration, the user must follow the below procedure:
* 1. Configure ADC_CFG with actual operating values for maximum accuracy.
* 2. Configure the ADC_GC values along with CAL bit.
* 3. Check the status of CALF bit in ADC_GS and the CAL bit in ADC_GC.
* 4. When CAL bit becomes '0' then check the CALF status and COCO[0] bit status.
*/
status_t ADC_DoAutoCalibration(ADC_Type *base)
{
status_t status = kStatus_Success;
#if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE)
bool bHWTrigger = false;
/* The calibration would be failed when in hardwar mode.
* Remember the hardware trigger state here and restore it later if the hardware trigger is enabled.*/
if (0U != (ADC_CFG_ADTRG_MASK & base->CFG))
{
bHWTrigger = true;
ADC_EnableHardwareTrigger(base, false);
}
#endif
/* Clear the CALF and launch the calibration. */
base->GS = ADC_GS_CALF_MASK; /* Clear the CALF. */
base->GC |= ADC_GC_CAL_MASK; /* Launch the calibration. */
/* Check the status of CALF bit in ADC_GS and the CAL bit in ADC_GC. */
while (0U != (base->GC & ADC_GC_CAL_MASK))
{
/* Check the CALF when the calibration is active. */
if (0U != (ADC_GetStatusFlags(base) & kADC_CalibrationFailedFlag))
{
status = kStatus_Fail;
break;
}
}
/* When CAL bit becomes '0' then check the CALF status and COCO[0] bit status. */
if (0U == ADC_GetChannelStatusFlags(base, 0U)) /* Check the COCO[0] bit status. */
{
status = kStatus_Fail;
}
if (0U != (ADC_GetStatusFlags(base) & kADC_CalibrationFailedFlag)) /* Check the CALF status. */
{
status = kStatus_Fail;
}
/* Clear conversion done flag. */
ADC_GetChannelConversionValue(base, 0U);
#if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE)
/* Restore original trigger mode. */
if (true == bHWTrigger)
{
ADC_EnableHardwareTrigger(base, true);
}
#endif
return status;
}
void ADC_SetOffsetConfig(ADC_Type *base, const adc_offest_config_t *config)
{
assert(NULL != config);
uint32_t tmp32;
tmp32 = ADC_OFS_OFS(config->offsetValue);
if (config->enableSigned)
{
tmp32 |= ADC_OFS_SIGN_MASK;
}
base->OFS = tmp32;
}
void ADC_SetHardwareCompareConfig(ADC_Type *base, const adc_hardware_compare_config_t *config)
{
uint32_t tmp32;
tmp32 = base->GC & ~(ADC_GC_ACFE_MASK | ADC_GC_ACFGT_MASK | ADC_GC_ACREN_MASK);
if (NULL == config) /* Pass "NULL" to disable the feature. */
{
base->GC = tmp32;
return;
}
/* Enable the feature. */
tmp32 |= ADC_GC_ACFE_MASK;
/* Select the hardware compare working mode. */
switch (config->hardwareCompareMode)
{
case kADC_HardwareCompareMode0:
break;
case kADC_HardwareCompareMode1:
tmp32 |= ADC_GC_ACFGT_MASK;
break;
case kADC_HardwareCompareMode2:
tmp32 |= ADC_GC_ACREN_MASK;
break;
case kADC_HardwareCompareMode3:
tmp32 |= ADC_GC_ACFGT_MASK | ADC_GC_ACREN_MASK;
break;
default:
break;
}
base->GC = tmp32;
/* Load the compare values. */
tmp32 = ADC_CV_CV1(config->value1) | ADC_CV_CV2(config->value2);
base->CV = tmp32;
}
void ADC_SetHardwareAverageConfig(ADC_Type *base, adc_hardware_average_mode_t mode)
{
uint32_t tmp32;
if (mode == kADC_HardwareAverageDiasable)
{
base->GC &= ~ADC_GC_AVGE_MASK;
}
else
{
tmp32 = base->CFG & ~ADC_CFG_AVGS_MASK;
tmp32 |= ADC_CFG_AVGS(mode);
base->CFG = tmp32;
base->GC |= ADC_GC_AVGE_MASK; /* Enable the hardware compare. */
}
}
void ADC_ClearStatusFlags(ADC_Type *base, uint32_t mask)
{
uint32_t tmp32 = 0;
if (0U != (mask & kADC_CalibrationFailedFlag))
{
tmp32 |= ADC_GS_CALF_MASK;
}
if (0U != (mask & kADC_ConversionActiveFlag))
{
tmp32 |= ADC_GS_ADACT_MASK;
}
base->GS = tmp32;
}

View File

@@ -0,0 +1,446 @@
/*
* The Clear BSD License
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#ifndef _FSL_ADC_H_
#define _FSL_ADC_H_
#include "fsl_common.h"
/*!
* @addtogroup adc_12b1msps_sar
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief ADC driver version */
#define FSL_ADC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */
/*!
* @brief Converter's status flags.
*/
typedef enum _adc_status_flags
{
kADC_ConversionActiveFlag = ADC_GS_ADACT_MASK, /*!< Conversion is active,not support w1c. */
kADC_CalibrationFailedFlag = ADC_GS_CALF_MASK, /*!< Calibration is failed,support w1c. */
kADC_AsynchronousWakeupInterruptFlag =
ADC_GS_AWKST_MASK, /*!< Asynchronous wakeup interrupt occured, support w1c. */
} adc_status_flags_t;
/*!
* @brief Reference voltage source.
*/
typedef enum _adc_reference_voltage_source
{
kADC_ReferenceVoltageSourceAlt0 = 0U, /*!< For external pins pair of VrefH and VrefL. */
} adc_reference_voltage_source_t;
/*!
* @brief Sample time duration.
*/
typedef enum _adc_sample_period_mode
{
/* This group of enumeration is for internal use which is related to register setting. */
kADC_SamplePeriod2or12Clocks = 0U, /*!< Long sample 12 clocks or short sample 2 clocks. */
kADC_SamplePeriod4or16Clocks = 1U, /*!< Long sample 16 clocks or short sample 4 clocks. */
kADC_SamplePeriod6or20Clocks = 2U, /*!< Long sample 20 clocks or short sample 6 clocks. */
kADC_SamplePeriod8or24Clocks = 3U, /*!< Long sample 24 clocks or short sample 8 clocks. */
/* This group of enumeration is for a public user. */
/* For long sample mode. */
kADC_SamplePeriodLong12Clcoks = kADC_SamplePeriod2or12Clocks, /*!< Long sample 12 clocks. */
kADC_SamplePeriodLong16Clcoks = kADC_SamplePeriod4or16Clocks, /*!< Long sample 16 clocks. */
kADC_SamplePeriodLong20Clcoks = kADC_SamplePeriod6or20Clocks, /*!< Long sample 20 clocks. */
kADC_SamplePeriodLong24Clcoks = kADC_SamplePeriod8or24Clocks, /*!< Long sample 24 clocks. */
/* For short sample mode. */
kADC_SamplePeriodShort2Clocks = kADC_SamplePeriod2or12Clocks, /*!< Short sample 2 clocks. */
kADC_SamplePeriodShort4Clocks = kADC_SamplePeriod4or16Clocks, /*!< Short sample 4 clocks. */
kADC_SamplePeriodShort6Clocks = kADC_SamplePeriod6or20Clocks, /*!< Short sample 6 clocks. */
kADC_SamplePeriodShort8Clocks = kADC_SamplePeriod8or24Clocks, /*!< Short sample 8 clocks. */
} adc_sample_period_mode_t;
/*!
* @brief Clock source.
*/
typedef enum _adc_clock_source
{
kADC_ClockSourceIPG = 0U, /*!< Select IPG clock to generate ADCK. */
kADC_ClockSourceIPGDiv2 = 1U, /*!< Select IPG clock divided by 2 to generate ADCK. */
#if !(defined(FSL_FEATURE_ADC_SUPPORT_ALTCLK_REMOVE) && FSL_FEATURE_ADC_SUPPORT_ALTCLK_REMOVE)
kADC_ClockSourceALT = 2U, /*!< Select alternate clock to generate ADCK. */
#endif
kADC_ClockSourceAD = 3U, /*!< Select Asynchronous clock to generate ADCK. */
} adc_clock_source_t;
/*!
* @brief Clock divider for the converter.
*/
typedef enum _adc_clock_drvier
{
kADC_ClockDriver1 = 0U, /*!< For divider 1 from the input clock to the module. */
kADC_ClockDriver2 = 1U, /*!< For divider 2 from the input clock to the module. */
kADC_ClockDriver4 = 2U, /*!< For divider 4 from the input clock to the module. */
kADC_ClockDriver8 = 3U, /*!< For divider 8 from the input clock to the module. */
} adc_clock_driver_t;
/*!
* @brief Converter's resolution.
*/
typedef enum _adc_resolution
{
kADC_Resolution8Bit = 0U, /*!< Single End 8-bit resolution. */
kADC_Resolution10Bit = 1U, /*!< Single End 10-bit resolution. */
kADC_Resolution12Bit = 2U, /*!< Single End 12-bit resolution. */
} adc_resolution_t;
/*!
* @brief Converter hardware compare mode.
*/
typedef enum _adc_hardware_compare_mode
{
kADC_HardwareCompareMode0 = 0U, /*!< Compare true if the result is less than the value1. */
kADC_HardwareCompareMode1 = 1U, /*!< Compare true if the result is greater than or equal to value1. */
kADC_HardwareCompareMode2 = 2U, /*!< Value1 <= Value2, compare true if the result is less than value1 Or
the result is Greater than value2.
Value1 > Value2, compare true if the result is less than value1 And the
result is greater than value2*/
kADC_HardwareCompareMode3 = 3U, /*!< Value1 <= Value2, compare true if the result is greater than or equal
to value1 And the result is less than or equal to value2.
Value1 > Value2, compare true if the result is greater than or equal to
value1 Or the result is less than or equal to value2. */
} adc_hardware_compare_mode_t;
/*!
* @brief Converter hardware average mode.
*/
typedef enum _adc_hardware_average_mode
{
kADC_HardwareAverageCount4 = 0U, /*!< For hardware average with 4 samples. */
kADC_HardwareAverageCount8 = 1U, /*!< For hardware average with 8 samples. */
kADC_HardwareAverageCount16 = 2U, /*!< For hardware average with 16 samples. */
kADC_HardwareAverageCount32 = 3U, /*!< For hardware average with 32 samples. */
kADC_HardwareAverageDiasable = 4U, /*!< Disable the hardware average function. */
} adc_hardware_average_mode_t;
/*!
* @brief Converter configuration.
*/
typedef struct _adc_config
{
bool enableOverWrite; /*!< Enable the overwriting. */
bool enableContinuousConversion; /*!< Enable the continuous conversion mode. */
bool enableHighSpeed; /*!< Enable the high-speed mode. */
bool enableLowPower; /*!< Enable the low power mode. */
bool enableLongSample; /*!< Enable the long sample mode. */
bool enableAsynchronousClockOutput; /*!< Enable the asynchronous clock output. */
adc_reference_voltage_source_t referenceVoltageSource; /*!< Select the reference voltage source. */
adc_sample_period_mode_t samplePeriodMode; /*!< Select the sample period in long sample mode or short mode. */
adc_clock_source_t clockSource; /*!< Select the input clock source to generate the internal clock ADCK. */
adc_clock_driver_t clockDriver; /*!< Select the divide ratio used by the ADC to generate the internal clock ADCK. */
adc_resolution_t resolution; /*!< Select the ADC resolution mode. */
} adc_config_t;
/*!
* @brief Converter Offset configuration.
*/
typedef struct _adc_offest_config
{
bool enableSigned; /*!< if false,The offset value is added with the raw result.
if true,The offset value is subtracted from the raw converted value. */
uint32_t offsetValue; /*!< User configurable offset value(0-4095). */
} adc_offest_config_t;
/*!
* @brief ADC hardware compare configuration.
*
* In kADC_HardwareCompareMode0, compare true if the result is less than the value1.
* In kADC_HardwareCompareMode1, compare true if the result is greater than or equal to value1.
* In kADC_HardwareCompareMode2, Value1 <= Value2, compare true if the result is less than value1 Or the result is
* Greater than value2.
* Value1 > Value2, compare true if the result is less than value1 And the result is
* Greater than value2.
* In kADC_HardwareCompareMode3, Value1 <= Value2, compare true if the result is greater than or equal to value1 And the
* result is less than or equal to value2.
* Value1 > Value2, compare true if the result is greater than or equal to value1 Or the
* result is less than or equal to value2.
*/
typedef struct _adc_hardware_compare_config
{
adc_hardware_compare_mode_t hardwareCompareMode; /*!< Select the hardware compare mode.
See "adc_hardware_compare_mode_t". */
uint16_t value1; /*!< Setting value1(0-4095) for hardware compare mode. */
uint16_t value2; /*!< Setting value2(0-4095) for hardware compare mode. */
} adc_hardware_compare_config_t;
/*!
* @brief ADC channel conversion configuration.
*/
typedef struct _adc_channel_config
{
uint32_t channelNumber; /*!< Setting the conversion channel number. The available range is 0-31.
See channel connection information for each chip in Reference
Manual document. */
bool enableInterruptOnConversionCompleted; /*!< Generate an interrupt request once the conversion is completed. */
} adc_channel_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Initialization
* @{
*/
/*!
* @brief Initialize the ADC module.
*
* @param base ADC peripheral base address.
* @param config Pointer to "adc_config_t" structure.
*/
void ADC_Init(ADC_Type *base, const adc_config_t *config);
/*!
* @brief De-initializes the ADC module.
*
* @param base ADC peripheral base address.
*/
void ADC_Deinit(ADC_Type *base);
/*!
* @brief Gets an available pre-defined settings for the converter's configuration.
*
* This function initializes the converter configuration structure with available settings. The default values are:
* @code
* config->enableAsynchronousClockOutput = true;
* config->enableOverWrite = false;
* config->enableContinuousConversion = false;
* config->enableHighSpeed = false;
* config->enableLowPower = false;
* config->enableLongSample = false;
* config->referenceVoltageSource = kADC_ReferenceVoltageSourceAlt0;
* config->samplePeriodMode = kADC_SamplePeriod2or12Clocks;
* config->clockSource = kADC_ClockSourceAD;
* config->clockDriver = kADC_ClockDriver1;
* config->resolution = kADC_Resolution12Bit;
* @endcode
* @param base ADC peripheral base address.
* @param config Pointer to the configuration structure.
*/
void ADC_GetDefaultConfig(adc_config_t *config);
/*!
* @brief Configures the conversion channel.
*
* This operation triggers the conversion when in software trigger mode. When in hardware trigger mode, this API
* configures the channel while the external trigger source helps to trigger the conversion.
*
* Note that the "Channel Group" has a detailed description.
* To allow sequential conversions of the ADC to be triggered by internal peripherals, the ADC has more than one
* group of status and control registers, one for each conversion. The channel group parameter indicates which group of
* registers are used, for example channel group 0 is for Group A registers and channel group 1 is for Group B
* registers. The
* channel groups are used in a "ping-pong" approach to control the ADC operation. At any point, only one of
* the channel groups is actively controlling ADC conversions. The channel group 0 is used for both software and
* hardware
* trigger modes. Channel groups 1 and greater indicate potentially multiple channel group registers for
* use only in hardware trigger mode. See the chip configuration information in the appropriate MCU reference manual
* about the
* number of SC1n registers (channel groups) specific to this device. None of the channel groups 1 or greater are used
* for software trigger operation. Therefore, writing to these channel groups does not initiate a new conversion.
* Updating the channel group 0 while a different channel group is actively controlling a conversion is allowed and
* vice versa. Writing any of the channel group registers while that specific channel group is actively controlling a
* conversion aborts the current conversion.
*
* @param base ADC peripheral base address.
* @param channelGroup Channel group index.
* @param config Pointer to the "adc_channel_config_t" structure for the conversion channel.
*/
void ADC_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc_channel_config_t *config);
/*!
* @brief Gets the conversion value.
*
* @param base ADC peripheral base address.
* @param channelGroup Channel group index.
*
* @return Conversion value.
*/
static inline uint32_t ADC_GetChannelConversionValue(ADC_Type *base, uint32_t channelGroup)
{
assert(channelGroup < ADC_R_COUNT);
return base->R[channelGroup];
}
/*!
* @brief Gets the status flags of channel.
*
* A conversion is completed when the result of the conversion is transferred into the data
* result registers. (provided the compare function & hardware averaging is disabled), this is
* indicated by the setting of COCOn. If hardware averaging is enabled, COCOn sets only,
* if the last of the selected number of conversions is complete. If the compare function is
* enabled, COCOn sets and conversion result data is transferred only if the compare
* condition is true. If both hardware averaging and compare functions are enabled, then
* COCOn sets only if the last of the selected number of conversions is complete and the
* compare condition is true.
*
* @param base ADC peripheral base address.
* @param channelGroup Channel group index.
*
* @return Status flags of channel.return 0 means COCO flag is 0,return 1 means COCOflag is 1.
*/
static inline uint32_t ADC_GetChannelStatusFlags(ADC_Type *base, uint32_t channelGroup)
{
assert(channelGroup < ADC_HC_COUNT);
/* If flag is set,return 1,otherwise, return 0. */
return (((base->HS) & (1U << channelGroup)) >> channelGroup);
}
/*!
* @brief Automates the hardware calibration.
*
* This auto calibration helps to adjust the plus/minus side gain automatically.
* Execute the calibration before using the converter. Note that the software trigger should be used
* during calibration.
*
* @param base ADC peripheral base address.
*
* @return Execution status.
* @retval kStatus_Success Calibration is done successfully.
* @retval kStatus_Fail Calibration has failed.
*/
status_t ADC_DoAutoCalibration(ADC_Type *base);
/*!
* @brief Set user defined offset.
*
* @param base ADC peripheral base address.
* @param config Pointer to "adc_offest_config_t" structure.
*/
void ADC_SetOffsetConfig(ADC_Type *base, const adc_offest_config_t *config);
/*!
* @brief Enables generating the DMA trigger when the conversion is complete.
*
* @param base ADC peripheral base address.
* @param enable Switcher of the DMA feature. "true" means enabled, "false" means not enabled.
*/
static inline void ADC_EnableDMA(ADC_Type *base, bool enable)
{
if (enable)
{
base->GC |= ADC_GC_DMAEN_MASK;
}
else
{
base->GC &= ~ADC_GC_DMAEN_MASK;
}
}
/*!
* @brief Enables the hardware trigger mode.
*
* @param base ADC peripheral base address.
* @param enable Switcher of the trigger mode. "true" means hardware tirgger mode,"false" means software mode.
*/
#if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE)
static inline void ADC_EnableHardwareTrigger(ADC_Type *base, bool enable)
{
if (enable)
{
base->CFG |= ADC_CFG_ADTRG_MASK;
}
else
{
base->CFG &= ~ADC_CFG_ADTRG_MASK;
}
}
#endif
/*!
* @brief Configures the hardware compare mode.
*
* The hardware compare mode provides a way to process the conversion result automatically by using hardware. Only the
* result
* in the compare range is available. To compare the range, see "adc_hardware_compare_mode_t" or the appopriate
* reference
* manual for more information.
*
* @param base ADC peripheral base address.
* @param Pointer to "adc_hardware_compare_config_t" structure.
*
*/
void ADC_SetHardwareCompareConfig(ADC_Type *base, const adc_hardware_compare_config_t *config);
/*!
* @brief Configures the hardware average mode.
*
* The hardware average mode provides a way to process the conversion result automatically by using hardware. The
* multiple
* conversion results are accumulated and averaged internally making them easier to read.
*
* @param base ADC peripheral base address.
* @param mode Setting the hardware average mode. See "adc_hardware_average_mode_t".
*/
void ADC_SetHardwareAverageConfig(ADC_Type *base, adc_hardware_average_mode_t mode);
/*!
* @brief Gets the converter's status flags.
*
* @param base ADC peripheral base address.
*
* @return Flags' mask if indicated flags are asserted. See "adc_status_flags_t".
*/
static inline uint32_t ADC_GetStatusFlags(ADC_Type *base)
{
return base->GS;
}
/*!
* @brief Clears the converter's status falgs.
*
* @param base ADC peripheral base address.
* @param mask Mask value for the cleared flags. See "adc_status_flags_t".
*/
void ADC_ClearStatusFlags(ADC_Type *base, uint32_t mask);
#if defined(__cplusplus)
}
#endif
#endif /* _FSL_ADC_H_ */

View File

@@ -0,0 +1,365 @@
/*
* The Clear BSD License
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#include "fsl_adc_etc.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.adc_etc"
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
#if defined(ADC_ETC_CLOCKS)
/*!
* @brief Get instance number for ADC_ETC module.
*
* @param base ADC_ETC peripheral base address
*/
static uint32_t ADC_ETC_GetInstance(ADC_ETC_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to ADC_ETC bases for each instance. */
static ADC_ETC_Type *const s_adcetcBases[] = ADC_ETC_BASE_PTRS;
/*! @brief Pointers to ADC_ETC clocks for each instance. */
static const clock_ip_name_t s_adcetcClocks[] = ADC_ETC_CLOCKS;
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t ADC_ETC_GetInstance(ADC_ETC_Type *base)
{
uint32_t instance = 0U;
uint32_t adcetcArrayCount = (sizeof(s_adcetcBases) / sizeof(s_adcetcBases[0]));
/* Find the instance index from base address mappings. */
for (instance = 0; instance < adcetcArrayCount; instance++)
{
if (s_adcetcBases[instance] == base)
{
break;
}
}
return instance;
}
#endif /* ADC_ETC_CLOCKS */
void ADC_ETC_Init(ADC_ETC_Type *base, const adc_etc_config_t *config)
{
assert(NULL != config);
uint32_t tmp32;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
#if defined(ADC_ETC_CLOCKS)
/* Open clock gate. */
CLOCK_EnableClock(s_adcetcClocks[ADC_ETC_GetInstance(base)]);
#endif /* ADC_ETC_CLOCKS */
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Disable software reset. */
ADC_ETC_DoSoftwareReset(base, false);
/* Set ADC_ETC_CTRL register. */
tmp32 = ADC_ETC_CTRL_EXT0_TRIG_PRIORITY(config->TSC0triggerPriority) |
ADC_ETC_CTRL_EXT1_TRIG_PRIORITY(config->TSC1triggerPriority) |
ADC_ETC_CTRL_PRE_DIVIDER(config->clockPreDivider) | ADC_ETC_CTRL_TRIG_ENABLE(config->XBARtriggerMask)
#if defined(FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL) && FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL
| ADC_ETC_CTRL_DMA_MODE_SEL(config->dmaMode)
#endif /*FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL*/
;
if (config->enableTSCBypass)
{
tmp32 |= ADC_ETC_CTRL_TSC_BYPASS_MASK;
}
if (config->enableTSC0Trigger)
{
tmp32 |= ADC_ETC_CTRL_EXT0_TRIG_ENABLE_MASK;
}
if (config->enableTSC1Trigger)
{
tmp32 |= ADC_ETC_CTRL_EXT1_TRIG_ENABLE_MASK;
}
base->CTRL = tmp32;
}
void ADC_ETC_Deinit(ADC_ETC_Type *base)
{
/* Do software reset to clear all logical. */
ADC_ETC_DoSoftwareReset(base, true);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
#if defined(ADC_ETC_CLOCKS)
/* Close clock gate. */
CLOCK_DisableClock(s_adcetcClocks[ADC_ETC_GetInstance(base)]);
#endif /* ADC_ETC_CLOCKS */
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
void ADC_ETC_GetDefaultConfig(adc_etc_config_t *config)
{
config->enableTSCBypass = true;
config->enableTSC0Trigger = false;
config->enableTSC1Trigger = false;
#if defined(FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL) && FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL
config->dmaMode = kADC_ETC_TrigDMAWithLatchedSignal;
#endif /*FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL*/
config->TSC0triggerPriority = 0U;
config->TSC1triggerPriority = 0U;
config->clockPreDivider = 0U;
config->XBARtriggerMask = 0U;
}
void ADC_ETC_SetTriggerConfig(ADC_ETC_Type *base, uint32_t triggerGroup, const adc_etc_trigger_config_t *config)
{
assert(triggerGroup < ADC_ETC_TRIGn_CTRL_COUNT);
assert(ADC_ETC_TRIGn_COUNTER_COUNT > triggerGroup);
uint32_t tmp32;
/* Set ADC_ETC_TRGn_CTRL register. */
tmp32 = ADC_ETC_TRIGn_CTRL_TRIG_CHAIN(config->triggerChainLength) |
ADC_ETC_TRIGn_CTRL_TRIG_PRIORITY(config->triggerPriority);
if (config->enableSyncMode)
{
tmp32 |= ADC_ETC_TRIGn_CTRL_SYNC_MODE_MASK;
}
if (config->enableSWTriggerMode)
{
tmp32 |= ADC_ETC_TRIGn_CTRL_TRIG_MODE_MASK;
}
base->TRIG[triggerGroup].TRIGn_CTRL = tmp32;
/* Set ADC_ETC_TRGn_COUNTER register. */
tmp32 = ADC_ETC_TRIGn_COUNTER_INIT_DELAY(config->initialDelay) |
ADC_ETC_TRIGn_COUNTER_SAMPLE_INTERVAL(config->sampleIntervalDelay);
base->TRIG[triggerGroup].TRIGn_COUNTER = tmp32;
}
void ADC_ETC_SetTriggerChainConfig(ADC_ETC_Type *base,
uint32_t triggerGroup,
uint32_t chainGroup,
const adc_etc_trigger_chain_config_t *config)
{
assert(triggerGroup < ADC_ETC_TRIGn_CTRL_COUNT);
uint32_t tmp;
uint32_t tmp32;
uint8_t mRemainder = chainGroup % 2U;
/* Set ADC_ETC_TRIGn_CHAINm register. */
tmp = ADC_ETC_TRIGn_CHAIN_1_0_HWTS0(config->ADCHCRegisterSelect) |
ADC_ETC_TRIGn_CHAIN_1_0_CSEL0(config->ADCChannelSelect) |
ADC_ETC_TRIGn_CHAIN_1_0_IE0(config->InterruptEnable);
if (config->enableB2BMode)
{
tmp |= ADC_ETC_TRIGn_CHAIN_1_0_B2B0_MASK;
}
switch (chainGroup / 2U)
{
case 0U: /* Configurate trigger chain0 and chain 1. */
tmp32 = base->TRIG[triggerGroup].TRIGn_CHAIN_1_0;
if (mRemainder == 0U) /* Chain 0. */
{
tmp32 &= ~(ADC_ETC_TRIGn_CHAIN_1_0_CSEL0_MASK | ADC_ETC_TRIGn_CHAIN_1_0_HWTS0_MASK |
ADC_ETC_TRIGn_CHAIN_1_0_B2B0_MASK | ADC_ETC_TRIGn_CHAIN_1_0_IE0_MASK);
tmp32 |= tmp;
}
else /* Chain 1. */
{
tmp32 &= ~(ADC_ETC_TRIGn_CHAIN_1_0_CSEL1_MASK | ADC_ETC_TRIGn_CHAIN_1_0_HWTS1_MASK |
ADC_ETC_TRIGn_CHAIN_1_0_B2B1_MASK | ADC_ETC_TRIGn_CHAIN_1_0_IE1_MASK);
tmp32 |= (tmp << ADC_ETC_TRIGn_CHAIN_1_0_CSEL1_SHIFT);
}
base->TRIG[triggerGroup].TRIGn_CHAIN_1_0 = tmp32;
break;
case 1U: /* Configurate trigger chain2 and chain 3. */
tmp32 = base->TRIG[triggerGroup].TRIGn_CHAIN_3_2;
if (mRemainder == 0U) /* Chain 2. */
{
tmp32 &= ~(ADC_ETC_TRIGn_CHAIN_3_2_CSEL2_MASK | ADC_ETC_TRIGn_CHAIN_3_2_HWTS2_MASK |
ADC_ETC_TRIGn_CHAIN_3_2_B2B2_MASK | ADC_ETC_TRIGn_CHAIN_3_2_IE2_MASK);
tmp32 |= tmp;
}
else /* Chain 3. */
{
tmp32 &= ~(ADC_ETC_TRIGn_CHAIN_3_2_CSEL3_MASK | ADC_ETC_TRIGn_CHAIN_3_2_HWTS3_MASK |
ADC_ETC_TRIGn_CHAIN_3_2_B2B3_MASK | ADC_ETC_TRIGn_CHAIN_3_2_IE3_MASK);
tmp32 |= (tmp << ADC_ETC_TRIGn_CHAIN_3_2_CSEL3_SHIFT);
}
base->TRIG[triggerGroup].TRIGn_CHAIN_3_2 = tmp32;
break;
case 2U: /* Configurate trigger chain4 and chain 5. */
tmp32 = base->TRIG[triggerGroup].TRIGn_CHAIN_5_4;
if (mRemainder == 0U) /* Chain 4. */
{
tmp32 &= ~(ADC_ETC_TRIGn_CHAIN_5_4_CSEL4_MASK | ADC_ETC_TRIGn_CHAIN_5_4_HWTS4_MASK |
ADC_ETC_TRIGn_CHAIN_5_4_B2B4_MASK | ADC_ETC_TRIGn_CHAIN_5_4_IE4_MASK);
tmp32 |= tmp;
}
else /* Chain 5. */
{
tmp32 &= ~(ADC_ETC_TRIGn_CHAIN_5_4_CSEL5_MASK | ADC_ETC_TRIGn_CHAIN_5_4_HWTS5_MASK |
ADC_ETC_TRIGn_CHAIN_5_4_B2B5_MASK | ADC_ETC_TRIGn_CHAIN_5_4_IE5_MASK);
tmp32 |= (tmp << ADC_ETC_TRIGn_CHAIN_5_4_CSEL5_SHIFT);
}
base->TRIG[triggerGroup].TRIGn_CHAIN_5_4 = tmp32;
break;
case 3U: /* Configurate trigger chain6 and chain 7. */
tmp32 = base->TRIG[triggerGroup].TRIGn_CHAIN_7_6;
if (mRemainder == 0U) /* Chain 6. */
{
tmp32 &= ~(ADC_ETC_TRIGn_CHAIN_7_6_CSEL6_MASK | ADC_ETC_TRIGn_CHAIN_7_6_HWTS6_MASK |
ADC_ETC_TRIGn_CHAIN_7_6_B2B6_MASK | ADC_ETC_TRIGn_CHAIN_7_6_IE6_MASK);
tmp32 |= tmp;
}
else /* Chain 7. */
{
tmp32 &= ~(ADC_ETC_TRIGn_CHAIN_7_6_CSEL7_MASK | ADC_ETC_TRIGn_CHAIN_7_6_HWTS7_MASK |
ADC_ETC_TRIGn_CHAIN_7_6_B2B7_MASK | ADC_ETC_TRIGn_CHAIN_7_6_IE7_MASK);
tmp32 |= (tmp << ADC_ETC_TRIGn_CHAIN_7_6_CSEL7_SHIFT);
}
base->TRIG[triggerGroup].TRIGn_CHAIN_7_6 = tmp32;
break;
default:
break;
}
}
uint32_t ADC_ETC_GetInterruptStatusFlags(ADC_ETC_Type *base, adc_etc_external_trigger_source_t sourceIndex)
{
uint32_t tmp32 = 0U;
if (((base->DONE0_1_IRQ) & (ADC_ETC_DONE0_1_IRQ_TRIG0_DONE0_MASK << sourceIndex)) != 0U)
{
tmp32 |= kADC_ETC_Done0StatusFlagMask; /* Customized DONE0 status flags mask, which is defined in fsl_adc_etc.h
file. */
}
if (((base->DONE0_1_IRQ) & (ADC_ETC_DONE0_1_IRQ_TRIG0_DONE1_MASK << sourceIndex)) != 0U)
{
tmp32 |= kADC_ETC_Done1StatusFlagMask; /* Customized DONE1 status flags mask, which is defined in fsl_adc_etc.h
file. */
}
if (((base->DONE2_ERR_IRQ) & (ADC_ETC_DONE2_ERR_IRQ_TRIG0_DONE2_MASK << sourceIndex)) != 0U)
{
tmp32 |= kADC_ETC_Done2StatusFlagMask; /* Customized DONE2 status flags mask, which is defined in fsl_adc_etc.h
file. */
}
if (((base->DONE2_ERR_IRQ) & (ADC_ETC_DONE2_ERR_IRQ_TRIG0_ERR_MASK << sourceIndex)) != 0U)
{
tmp32 |= kADC_ETC_ErrorStatusFlagMask; /* Customized ERROR status flags mask, which is defined in fsl_adc_etc.h
file. */
}
return tmp32;
}
void ADC_ETC_ClearInterruptStatusFlags(ADC_ETC_Type *base, adc_etc_external_trigger_source_t sourceIndex, uint32_t mask)
{
if (0U != (mask & kADC_ETC_Done0StatusFlagMask)) /* Write 1 to clear DONE0 status flags. */
{
base->DONE0_1_IRQ = (ADC_ETC_DONE0_1_IRQ_TRIG0_DONE0_MASK << sourceIndex);
}
if (0U != (mask & kADC_ETC_Done1StatusFlagMask)) /* Write 1 to clear DONE1 status flags. */
{
base->DONE0_1_IRQ = (ADC_ETC_DONE0_1_IRQ_TRIG0_DONE1_MASK << sourceIndex);
}
if (0U != (mask & kADC_ETC_Done2StatusFlagMask)) /* Write 1 to clear DONE2 status flags. */
{
base->DONE2_ERR_IRQ = (ADC_ETC_DONE2_ERR_IRQ_TRIG0_DONE2_MASK << sourceIndex);
}
if (0U != (mask & kADC_ETC_ErrorStatusFlagMask)) /* Write 1 to clear ERROR status flags. */
{
base->DONE2_ERR_IRQ = (ADC_ETC_DONE2_ERR_IRQ_TRIG0_ERR_MASK << sourceIndex);
}
}
uint32_t ADC_ETC_GetADCConversionValue(ADC_ETC_Type *base, uint32_t triggerGroup, uint32_t chainGroup)
{
assert(triggerGroup < ADC_ETC_TRIGn_RESULT_1_0_COUNT);
uint32_t mADCResult;
uint8_t mRemainder = chainGroup % 2U;
switch (chainGroup / 2U)
{
case 0U:
if (0U == mRemainder)
{
mADCResult = ADC_ETC_TRIGn_RESULT_1_0_DATA0_MASK & (base->TRIG[triggerGroup].TRIGn_RESULT_1_0);
}
else
{
mADCResult = (base->TRIG[triggerGroup].TRIGn_RESULT_1_0) >> ADC_ETC_TRIGn_RESULT_1_0_DATA1_SHIFT;
}
break;
case 1U:
if (0U == mRemainder)
{
mADCResult = ADC_ETC_TRIGn_RESULT_3_2_DATA2_MASK & (base->TRIG[triggerGroup].TRIGn_RESULT_3_2);
}
else
{
mADCResult = (base->TRIG[triggerGroup].TRIGn_RESULT_3_2) >> ADC_ETC_TRIGn_RESULT_3_2_DATA3_SHIFT;
}
break;
case 2U:
if (0U == mRemainder)
{
mADCResult = ADC_ETC_TRIGn_RESULT_5_4_DATA4_MASK & (base->TRIG[triggerGroup].TRIGn_RESULT_5_4);
}
else
{
mADCResult = (base->TRIG[triggerGroup].TRIGn_RESULT_5_4) >> ADC_ETC_TRIGn_RESULT_5_4_DATA5_SHIFT;
}
break;
case 3U:
if (0U == mRemainder)
{
mADCResult = ADC_ETC_TRIGn_RESULT_7_6_DATA6_MASK & (base->TRIG[triggerGroup].TRIGn_RESULT_7_6);
}
else
{
mADCResult = (base->TRIG[triggerGroup].TRIGn_RESULT_7_6) >> ADC_ETC_TRIGn_RESULT_7_6_DATA7_SHIFT;
}
break;
default:
return 0U;
}
return mADCResult;
}

View File

@@ -0,0 +1,342 @@
/*
* The Clear BSD License
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#ifndef _FSL_ADC_ETC_H_
#define _FSL_ADC_ETC_H_
#include "fsl_common.h"
/*!
* @addtogroup adc_etc
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief ADC_ETC driver version */
#define FSL_ADC_ETC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */
/*! @brief The mask of status flags cleared by writing 1. */
#define ADC_ETC_DMA_CTRL_TRGn_REQ_MASK 0xFF0000U
/*!
* @brief ADC_ETC customized status flags mask.
*/
enum _adc_etc_status_flag_mask
{
kADC_ETC_Done0StatusFlagMask = 1U,
kADC_ETC_Done1StatusFlagMask = 2U,
kADC_ETC_Done2StatusFlagMask = 4U,
kADC_ETC_ErrorStatusFlagMask = 8U,
};
/*!
* @brief External triggers sources.
*/
typedef enum _adc_etc_external_trigger_source
{
/* External XBAR sources. Support HW or SW mode. */
kADC_ETC_Trg0TriggerSource = 0U, /* External XBAR trigger0 source. */
kADC_ETC_Trg1TriggerSource = 1U, /* External XBAR trigger1 source. */
kADC_ETC_Trg2TriggerSource = 2U, /* External XBAR trigger2 source. */
kADC_ETC_Trg3TriggerSource = 3U, /* External XBAR trigger3 source. */
kADC_ETC_Trg4TriggerSource = 4U, /* External XBAR trigger4 source. */
kADC_ETC_Trg5TriggerSource = 5U, /* External XBAR trigger5 source. */
kADC_ETC_Trg6TriggerSource = 6U, /* External XBAR trigger6 source. */
kADC_ETC_Trg7TriggerSource = 7U, /* External XBAR trigger7 source. */
/* External TSC sources. Only support HW mode. */
kADC_ETC_TSC0TriggerSource = 8U, /* External TSC trigger0 source. */
kADC_ETC_TSC1TriggerSource = 9U, /* External TSC trigger1 source. */
} adc_etc_external_trigger_source_t;
/*!
* @brief Interrupt enable/disable mask.
*/
typedef enum _adc_etc_interrupt_enable
{
kADC_ETC_InterruptDisable = 0U, /* Disable the ADC_ETC interrupt. */
kADC_ETC_Done0InterruptEnable = 1U, /* Enable the DONE0 interrupt when ADC conversions complete. */
kADC_ETC_Done1InterruptEnable = 2U, /* Enable the DONE1 interrupt when ADC conversions complete. */
kADC_ETC_Done2InterruptEnable = 3U, /* Enable the DONE2 interrupt when ADC conversions complete. */
} adc_etc_interrupt_enable_t;
#if defined(FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL) && FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL
/*!
* @brief DMA mode selection.
*/
typedef enum _adc_etc_dma_mode_selection
{
kADC_ETC_TrigDMAWithLatchedSignal = 0U, /* Trig DMA_REQ with latched signal, REQ will be cleared when ACK and source request cleared. */
kADC_ETC_TrigDMAWithPulsedSignal = 1U, /* Trig DMA_REQ with pulsed signal, REQ will be cleared by ACK only. */
} adc_etc_dma_mode_selection_t;
#endif /*FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL*/
/*!
* @brief ADC_ETC configuration.
*/
typedef struct _adc_etc_config
{
bool enableTSCBypass; /* If bypass TSC, TSC would trigger ADC directly.
Otherwise TSC would trigger ADC through ADC_ETC. */
bool enableTSC0Trigger; /* Enable external TSC0 trigger. It is valid when enableTSCBypass = false. */
bool enableTSC1Trigger; /* Enable external TSC1 trigger. It is valid when enableTSCBypass = false.*/
#if defined(FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL) && FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL
adc_etc_dma_mode_selection_t dmaMode; /* Select the ADC_ETC DMA mode. */
#endif /*FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL*/
uint32_t TSC0triggerPriority; /* External TSC0 trigger priority, 7 is highest, 0 is lowest. */
uint32_t TSC1triggerPriority; /* External TSC1 trigger priority, 7 is highest, 0 is lowest. */
uint32_t clockPreDivider; /* Pre-divider for trig delay and interval. Available range is 0-255.
Clock would be divided by (clockPreDivider+1). */
uint32_t XBARtriggerMask; /* Enable the corresponding trigger source. Available range is trigger0:0x01 to
trigger7:0x80
For example, XBARtriggerMask = 0x7U, which means trigger0, trigger1 and trigger2 is
enabled. */
} adc_etc_config_t;
/*!
* @brief ADC_ETC trigger chain configuration.
*/
typedef struct _adc_etc_trigger_chain_config
{
bool enableB2BMode; /* Enable ADC_ETC BackToBack mode. when not enabled B2B mode,
wait until interval delay is reached. */
uint32_t ADCHCRegisterSelect; /* Select relevant ADC_HCx register to trigger. 1U : HC0, 2U: HC1, 4U: HC2 ... */
uint32_t ADCChannelSelect; /* Select ADC sample channel. */
adc_etc_interrupt_enable_t InterruptEnable; /* Enable/disable Interrupt. */
} adc_etc_trigger_chain_config_t;
/*!
* @brief ADC_ETC trigger configuration.
*/
typedef struct _adc_etc_trigger_config
{
bool enableSyncMode; /* Enable the sync Mode, In SyncMode ADC1 and ADC2 are controlled by the same trigger source.
In AsyncMode ADC1 and ADC2 are controlled by separate trigger source. */
bool enableSWTriggerMode; /* Enable the sofware trigger mode. */
uint32_t triggerChainLength; /* TRIG chain length to the ADC. 0: Trig length is 1. ... 7: Trig length is 8. */
uint32_t triggerPriority; /* External trigger priority, 7 is highest, 0 is lowest. */
uint32_t sampleIntervalDelay; /* Set sampling interval delay. */
uint32_t initialDelay; /* Set trigger initial delay. */
} adc_etc_trigger_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Initialization
* @{
*/
/*!
* @brief Initialize the ADC_ETC module.
*
* @param base ADC_ETC peripheral base address.
* @param config Pointer to "adc_etc_config_t" structure.
*/
void ADC_ETC_Init(ADC_ETC_Type *base, const adc_etc_config_t *config);
/*!
* @brief De-Initialize the ADC_ETC module.
*
* @param base ADC_ETC peripheral base address.
*/
void ADC_ETC_Deinit(ADC_ETC_Type *base);
/*!
* @brief Gets an available pre-defined settings for the ADC_ETC's configuration.
* This function initializes the ADC_ETC's configuration structure with available settings. The default values are:
* @code
* config->enableTSCBypass = true;
* config->enableTSC0Trigger = false;
* config->enableTSC1Trigger = false;
* config->TSC0triggerPriority = 0U;
* config->TSC1triggerPriority = 0U;
* config->clockPreDivider = 0U;
* config->XBARtriggerMask = 0U;
* @endCode
*
* @param config Pointer to "adc_etc_config_t" structure.
*/
void ADC_ETC_GetDefaultConfig(adc_etc_config_t *config);
/*!
* @brief Set the external XBAR trigger configuration.
*
* @param base ADC_ETC peripheral base address.
* @param triggerGroup Trigger group index.
* @param config Pointer to "adc_etc_trigger_config_t" structure.
*/
void ADC_ETC_SetTriggerConfig(ADC_ETC_Type *base, uint32_t triggerGroup, const adc_etc_trigger_config_t *config);
/*!
* @brief Set the external XBAR trigger chain configuration.
* For example, if triggerGroup is set to 0U and chainGroup is set to 1U, which means Trigger0 source's chain1 would be
* configurated.
*
* @param base ADC_ETC peripheral base address.
* @param triggerGroup Trigger group index. Available number is 0~7.
* @param chainGroup Trigger chain group index. Available number is 0~7.
* @param config Pointer to "adc_etc_trigger_chain_config_t" structure.
*/
void ADC_ETC_SetTriggerChainConfig(ADC_ETC_Type *base,
uint32_t triggerGroup,
uint32_t chainGroup,
const adc_etc_trigger_chain_config_t *config);
/*!
* @brief Gets the interrupt status flags of external XBAR and TSC triggers.
*
* @param base ADC_ETC peripheral base address.
* @param sourceIndex trigger source index.
*
* @return Status flags mask of trigger. Refer to "_adc_etc_status_flag_mask".
*/
uint32_t ADC_ETC_GetInterruptStatusFlags(ADC_ETC_Type *base, adc_etc_external_trigger_source_t sourceIndex);
/*!
* @brief Clears the ADC_ETC's interrupt status falgs.
*
* @param base ADC_ETC peripheral base address.
* @param sourceIndex trigger source index.
* @param mask Status flags mask of trigger. Refer to "_adc_etc_status_flag_mask".
*/
void ADC_ETC_ClearInterruptStatusFlags(ADC_ETC_Type *base,
adc_etc_external_trigger_source_t sourceIndex,
uint32_t mask);
/*!
* @brief Enable the DMA corresponding to each trigger source.
*
* @param base ADC_ETC peripheral base address.
* @param triggerGroup Trigger group index. Available number is 0~7.
*/
static inline void ADC_ETC_EnableDMA(ADC_ETC_Type *base, uint32_t triggerGroup)
{
/* Avoid clearing status flags at the same time. */
base->DMA_CTRL =
(base->DMA_CTRL | (ADC_ETC_DMA_CTRL_TRIG0_ENABLE_MASK << triggerGroup)) & ~ADC_ETC_DMA_CTRL_TRGn_REQ_MASK;
}
/*!
* @brief Disable the DMA corresponding to each trigger sources.
*
* @param base ADC_ETC peripheral base address.
* @param triggerGroup Trigger group index. Available number is 0~7.
*/
static inline void ADC_ETC_DisableDMA(ADC_ETC_Type *base, uint32_t triggerGroup)
{
/* Avoid clearing status flags at the same time. */
base->DMA_CTRL =
(base->DMA_CTRL & ~(ADC_ETC_DMA_CTRL_TRIG0_ENABLE_MASK << triggerGroup)) & ~ADC_ETC_DMA_CTRL_TRGn_REQ_MASK;
}
/*!
* @brief Get the DMA request status falgs. Only external XBAR sources support DMA request.
*
* @param base ADC_ETC peripheral base address.
* @return Mask of external XBAR tirgger's DMA request asserted flags. Available range is trigger0:0x01 to
* trigger7:0x80.
*/
static inline uint32_t ADC_ETC_GetDMAStatusFlags(ADC_ETC_Type *base)
{
return (((base->DMA_CTRL) & ADC_ETC_DMA_CTRL_TRGn_REQ_MASK) >> ADC_ETC_DMA_CTRL_TRIG0_REQ_SHIFT);
}
/*!
* @brief Clear the DMA request status falgs. Only external XBAR sources support DMA request.
*
* @param base ADC_ETC peripheral base address.
* @param mask Mask of external XBAR tirgger's DMA request asserted flags. Available range is trigger0:0x01 to
* trigger7:0x80.
*/
static inline void ADC_ETC_ClearDMAStatusFlags(ADC_ETC_Type *base, uint32_t mask)
{
base->DMA_CTRL = ((base->DMA_CTRL) & ~ADC_ETC_DMA_CTRL_TRGn_REQ_MASK) | (mask << ADC_ETC_DMA_CTRL_TRIG0_REQ_SHIFT);
}
/*!
* @brief When enable ,all logical will be reset.
*
* @param base ADC_ETC peripheral base address.
* @param enable Enable/Disable the software reset.
*/
static inline void ADC_ETC_DoSoftwareReset(ADC_ETC_Type *base, bool enable)
{
if (enable)
{
base->CTRL |= ADC_ETC_CTRL_SOFTRST_MASK;
}
else
{
base->CTRL &= ~ADC_ETC_CTRL_SOFTRST_MASK;
}
}
/*!
* @brief Do software trigger corresponding to each XBAR trigger sources.
* Each XBAR trigger sources can be configured as HW or SW trigger mode. In hardware trigger mode,
* trigger source is from XBAR. In software mode, trigger source is from software tigger. TSC trigger sources
* can only work in hardware trigger mode.
*
* @param base ADC_ETC peripheral base address.
* @param triggerGroup Trigger group index. Available number is 0~7.
*/
static inline void ADC_ETC_DoSoftwareTrigger(ADC_ETC_Type *base, uint32_t triggerGroup)
{
assert(triggerGroup < ADC_ETC_TRIGn_CTRL_COUNT);
base->TRIG[triggerGroup].TRIGn_CTRL |= ADC_ETC_TRIGn_CTRL_SW_TRIG_MASK;
}
/*!
* @brief Get ADC conversion result from external XBAR sources.
* For example, if triggerGroup is set to 0U and chainGroup is set to 1U, which means the API would
* return Trigger0 source's chain1 conversion result.
*
* @param base ADC_ETC peripheral base address.
* @param triggerGroup Trigger group index. Available number is 0~7.
* @param chainGroup Trigger chain group index. Available number is 0~7.
* @return ADC conversion result value.
*/
uint32_t ADC_ETC_GetADCConversionValue(ADC_ETC_Type *base, uint32_t triggerGroup, uint32_t chainGroup);
#if defined(__cplusplus)
}
#endif
#endif /* _FSL_ADC_ETC_H_ */

View File

@@ -0,0 +1,60 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#include "fsl_aipstz.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
void AIPSTZ_SetMasterPriviledgeLevel(AIPSTZ_Type *base, aipstz_master_t master, uint32_t privilegeConfig)
{
uint32_t mask = ((uint32_t)master >> 8) - 1;
uint32_t shift = (uint32_t)master & 0xFF;
base->MPR = (base->MPR & (~(mask << shift))) | (privilegeConfig << shift);
}
void AIPSTZ_SetPeripheralAccessControl(AIPSTZ_Type *base, aipstz_peripheral_t peripheral, uint32_t accessControl)
{
volatile uint32_t *reg = (uint32_t *)((uint32_t)base + ((uint32_t)peripheral >> 16));
uint32_t mask = (((uint32_t)peripheral & 0xFF00U) >> 8) - 1;
uint32_t shift = (uint32_t)peripheral & 0xFF;
*reg = (*reg & (~(mask << shift))) | ((accessControl & mask) << shift);
}

View File

@@ -0,0 +1,155 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#ifndef _FSL_AIPSTZ_H_
#define _FSL_AIPSTZ_H_
#include "fsl_common.h"
/*!
* @addtogroup aipstz
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
#define FSL_AIPSTZ_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */
/*@}*/
/*! @brief List of AIPSTZ privilege configuration.*/
typedef enum _aipstz_master_privilege_level {
kAIPSTZ_MasterBufferedWriteEnable = (1U << 3), /*!< Write accesses from this master are allowed to be buffered. */
kAIPSTZ_MasterTrustedForReadEnable = (1U << 2), /*!< This master is trusted for read accesses. */
kAIPSTZ_MasterTrustedForWriteEnable = (1U << 1), /*!< This master is trusted for write accesses. */
kAIPSTZ_MasterForceUserModeEnable = 1U /*!< Accesses from this master are forced to user-mode. */
} aipstz_master_privilege_level_t;
/*! @brief List of AIPSTZ masters. Organized by width for the 8-15 bits and shift for lower 8 bits.*/
typedef enum _aipstz_master {
kAIPSTZ_Master0 = (0x400U | 28U),
kAIPSTZ_Master1 = (0x400U | 24U),
kAIPSTZ_Master2 = (0x400U | 20U),
kAIPSTZ_Master3 = (0x400U | 16U),
kAIPSTZ_Master5 = (0x400U | 8U)
} aipstz_master_t;
/*! @brief List of AIPSTZ peripheral access control configuration.*/
typedef enum _aipstz_peripheral_access_control {
kAIPSTZ_PeripheralAllowUntrustedMaster = 1U,
kAIPSTZ_PeripheralWriteProtected = (1U < 1),
kAIPSTZ_PeripheralRequireSupervisor = (1U < 2),
kAIPSTZ_PeripheralAllowBufferedWrite = (1U < 2)
} aipstz_peripheral_access_control_t;
/*! @brief List of AIPSTZ peripherals. Organized by register offset for higher 32 bits, width for the 8-15 bits and shift for lower 8 bits.*/
typedef enum _aipstz_peripheral {
kAIPSTZ_Peripheral0 = ((0x40 << 16) | (4 << 8) | 28),
kAIPSTZ_Peripheral1 = ((0x40 << 16) | (4 << 8) | 24),
kAIPSTZ_Peripheral2 = ((0x40 << 16) | (4 << 8) | 20),
kAIPSTZ_Peripheral3 = ((0x40 << 16) | (4 << 8) | 16),
kAIPSTZ_Peripheral4 = ((0x40 << 16) | (4 << 8) | 12),
kAIPSTZ_Peripheral5 = ((0x40 << 16) | (4 << 8) | 8),
kAIPSTZ_Peripheral6 = ((0x40 << 16) | (4 << 8) | 4),
kAIPSTZ_Peripheral7 = ((0x40 << 16) | (4 << 8) | 0),
kAIPSTZ_Peripheral8 = ((0x44 << 16) | (4 << 8) | 28),
kAIPSTZ_Peripheral9 = ((0x44 << 16) | (4 << 8) | 24),
kAIPSTZ_Peripheral10 = ((0x44 << 16) | (4 << 8) | 20),
kAIPSTZ_Peripheral11 = ((0x44 << 16) | (4 << 8) | 16),
kAIPSTZ_Peripheral12 = ((0x44 << 16) | (4 << 8) | 12),
kAIPSTZ_Peripheral13 = ((0x44 << 16) | (4 << 8) | 8),
kAIPSTZ_Peripheral14 = ((0x44 << 16) | (4 << 8) | 4),
kAIPSTZ_Peripheral15 = ((0x44 << 16) | (4 << 8) | 0),
kAIPSTZ_Peripheral16 = ((0x48 << 16) | (4 << 8) | 28),
kAIPSTZ_Peripheral17 = ((0x48 << 16) | (4 << 8) | 24),
kAIPSTZ_Peripheral18 = ((0x48 << 16) | (4 << 8) | 20),
kAIPSTZ_Peripheral19 = ((0x48 << 16) | (4 << 8) | 16),
kAIPSTZ_Peripheral20 = ((0x48 << 16) | (4 << 8) | 12),
kAIPSTZ_Peripheral21 = ((0x48 << 16) | (4 << 8) | 8),
kAIPSTZ_Peripheral22 = ((0x48 << 16) | (4 << 8) | 4),
kAIPSTZ_Peripheral23 = ((0x48 << 16) | (4 << 8) | 0),
kAIPSTZ_Peripheral24 = ((0x4C << 16) | (4 << 8) | 28),
kAIPSTZ_Peripheral25 = ((0x4C << 16) | (4 << 8) | 24),
kAIPSTZ_Peripheral26 = ((0x4C << 16) | (4 << 8) | 20),
kAIPSTZ_Peripheral27 = ((0x4C << 16) | (4 << 8) | 16),
kAIPSTZ_Peripheral28 = ((0x4C << 16) | (4 << 8) | 12),
kAIPSTZ_Peripheral29 = ((0x4C << 16) | (4 << 8) | 8),
kAIPSTZ_Peripheral30 = ((0x4C << 16) | (4 << 8) | 4),
kAIPSTZ_Peripheral31 = ((0x4C << 16) | (4 << 8) | 0),
kAIPSTZ_Peripheral32 = ((0x50 << 16) | (4 << 8) | 28),
kAIPSTZ_Peripheral33 = ((0x50 << 16) | (4 << 8) | 24)
} aipstz_peripheral_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Configure the privilege level for master.
*
* @param base AIPSTZ peripheral base pointer
* @param master Masters for AIPSTZ.
* @param privilegeConfig Configuration is ORed from @aipstz_master_privilege_level_t.
*/
void AIPSTZ_SetMasterPriviledgeLevel(AIPSTZ_Type *base, aipstz_master_t master, uint32_t privilegeConfig);
/*!
* @brief Configure the access for peripheral.
*
* @param base AIPSTZ peripheral base pointer
* @param master Peripheral for AIPSTZ.
* @param accessControl Configuration is ORed from @aipstz_peripheral_access_control_t.
*/
void AIPSTZ_SetPeripheralAccessControl(AIPSTZ_Type *base, aipstz_peripheral_t peripheral, uint32_t accessControl);
/*! @}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_AIPSTZ_H_ */

View File

@@ -0,0 +1,151 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#include "fsl_aoi.h"
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to aoi bases for each instance. */
static AOI_Type *const s_aoiBases[] = AOI_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to aoi clocks for each instance. */
static const clock_ip_name_t s_aoiClocks[] = AOI_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get instance number for AOI module.
*
* @param base AOI peripheral base address
*
* @return The AOI instance
*/
static uint32_t AOI_GetInstance(AOI_Type *base);
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t AOI_GetInstance(AOI_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_aoiBases); instance++)
{
if (s_aoiBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_aoiBases));
return instance;
}
void AOI_Init(AOI_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the clock gate from clock manager. */
CLOCK_EnableClock(s_aoiClocks[AOI_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
void AOI_Deinit(AOI_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable the clock gate from clock manager */
CLOCK_DisableClock(s_aoiClocks[AOI_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
void AOI_GetEventLogicConfig(AOI_Type *base, aoi_event_t event, aoi_event_config_t *config)
{
assert(event < FSL_FEATURE_AOI_EVENT_COUNT);
assert(config != NULL);
uint16_t value = 0;
/* Read BFCRT01 register at event index. */
value = base->BFCRT[event].BFCRT01;
config->PT0AC = (aoi_input_config_t)((value & AOI_BFCRT01_PT0_AC_MASK) >> AOI_BFCRT01_PT0_AC_SHIFT);
config->PT0BC = (aoi_input_config_t)((value & AOI_BFCRT01_PT0_BC_MASK) >> AOI_BFCRT01_PT0_BC_SHIFT);
config->PT0CC = (aoi_input_config_t)((value & AOI_BFCRT01_PT0_CC_MASK) >> AOI_BFCRT01_PT0_CC_SHIFT);
config->PT0DC = (aoi_input_config_t)((value & AOI_BFCRT01_PT0_DC_MASK) >> AOI_BFCRT01_PT0_DC_SHIFT);
config->PT1AC = (aoi_input_config_t)((value & AOI_BFCRT01_PT1_AC_MASK) >> AOI_BFCRT01_PT1_AC_SHIFT);
config->PT1BC = (aoi_input_config_t)((value & AOI_BFCRT01_PT1_BC_MASK) >> AOI_BFCRT01_PT1_BC_SHIFT);
config->PT1CC = (aoi_input_config_t)((value & AOI_BFCRT01_PT1_CC_MASK) >> AOI_BFCRT01_PT1_CC_SHIFT);
config->PT1DC = (aoi_input_config_t)((value & AOI_BFCRT01_PT1_DC_MASK) >> AOI_BFCRT01_PT1_DC_SHIFT);
/* Read BFCRT23 register at event index. */
value = 0;
value = base->BFCRT[event].BFCRT23;
config->PT2AC = (aoi_input_config_t)((value & AOI_BFCRT23_PT2_AC_MASK) >> AOI_BFCRT23_PT2_AC_SHIFT);
config->PT2BC = (aoi_input_config_t)((value & AOI_BFCRT23_PT2_BC_MASK) >> AOI_BFCRT23_PT2_BC_SHIFT);
config->PT2CC = (aoi_input_config_t)((value & AOI_BFCRT23_PT2_CC_MASK) >> AOI_BFCRT23_PT2_CC_SHIFT);
config->PT2DC = (aoi_input_config_t)((value & AOI_BFCRT23_PT2_DC_MASK) >> AOI_BFCRT23_PT2_DC_SHIFT);
config->PT3AC = (aoi_input_config_t)((value & AOI_BFCRT23_PT3_AC_MASK) >> AOI_BFCRT23_PT3_AC_SHIFT);
config->PT3BC = (aoi_input_config_t)((value & AOI_BFCRT23_PT3_BC_MASK) >> AOI_BFCRT23_PT3_BC_SHIFT);
config->PT3CC = (aoi_input_config_t)((value & AOI_BFCRT23_PT3_CC_MASK) >> AOI_BFCRT23_PT3_CC_SHIFT);
config->PT3DC = (aoi_input_config_t)((value & AOI_BFCRT23_PT3_DC_MASK) >> AOI_BFCRT23_PT3_DC_SHIFT);
}
void AOI_SetEventLogicConfig(AOI_Type *base, aoi_event_t event, const aoi_event_config_t *eventConfig)
{
assert(eventConfig != NULL);
assert(event < FSL_FEATURE_AOI_EVENT_COUNT);
uint16_t value = 0;
/* Calculate value to configure product term 0, 1 */
value = AOI_BFCRT01_PT0_AC(eventConfig->PT0AC) | AOI_BFCRT01_PT0_BC(eventConfig->PT0BC) |
AOI_BFCRT01_PT0_CC(eventConfig->PT0CC) | AOI_BFCRT01_PT0_DC(eventConfig->PT0DC) |
AOI_BFCRT01_PT1_AC(eventConfig->PT1AC) | AOI_BFCRT01_PT1_BC(eventConfig->PT1BC) |
AOI_BFCRT01_PT1_CC(eventConfig->PT1CC) | AOI_BFCRT01_PT1_DC(eventConfig->PT1DC);
/* Write value to register */
base->BFCRT[event].BFCRT01 = value;
/* Reset and calculate value to configure product term 2, 3 */
value = 0;
value = AOI_BFCRT23_PT2_AC(eventConfig->PT2AC) | AOI_BFCRT23_PT2_BC(eventConfig->PT2BC) |
AOI_BFCRT23_PT2_CC(eventConfig->PT2CC) | AOI_BFCRT23_PT2_DC(eventConfig->PT2DC) |
AOI_BFCRT23_PT3_AC(eventConfig->PT3AC) | AOI_BFCRT23_PT3_BC(eventConfig->PT3BC) |
AOI_BFCRT23_PT3_CC(eventConfig->PT3CC) | AOI_BFCRT23_PT3_DC(eventConfig->PT3DC);
/* Write value to register */
base->BFCRT[event].BFCRT23 = value;
}

View File

@@ -0,0 +1,213 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#ifndef _FSL_AOI_H_
#define _FSL_AOI_H_
#include "fsl_common.h"
/*!
* @addtogroup aoi
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
#ifndef AOI
#define AOI AOI0 /*!< AOI peripheral address */
#endif
/*! @name Driver version */
/*@{*/
#define FSL_AOI_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */
/*@}*/
/*!
* @brief AOI input configurations.
*
* The selection item represents the Boolean evaluations.
*/
typedef enum _aoi_input_config
{
kAOI_LogicZero = 0x0U, /*!< Forces the input to logical zero. */
kAOI_InputSignal = 0x1U, /*!< Passes the input signal. */
kAOI_InvInputSignal = 0x2U, /*!< Inverts the input signal. */
kAOI_LogicOne = 0x3U /*!< Forces the input to logical one. */
} aoi_input_config_t;
/*!
* @brief AOI event indexes, where an event is the collection of the four product
* terms (0, 1, 2, and 3) and the four signal inputs (A, B, C, and D).
*/
typedef enum _aoi_event
{
kAOI_Event0 = 0x0U, /*!< Event 0 index */
kAOI_Event1 = 0x1U, /*!< Event 1 index */
kAOI_Event2 = 0x2U, /*!< Event 2 index */
kAOI_Event3 = 0x3U /*!< Event 3 index */
} aoi_event_t;
/*!
* @brief AOI event configuration structure
*
* Defines structure _aoi_event_config and use the AOI_SetEventLogicConfig() function to make
* whole event configuration.
*/
typedef struct _aoi_event_config
{
aoi_input_config_t PT0AC; /*!< Product term 0 input A */
aoi_input_config_t PT0BC; /*!< Product term 0 input B */
aoi_input_config_t PT0CC; /*!< Product term 0 input C */
aoi_input_config_t PT0DC; /*!< Product term 0 input D */
aoi_input_config_t PT1AC; /*!< Product term 1 input A */
aoi_input_config_t PT1BC; /*!< Product term 1 input B */
aoi_input_config_t PT1CC; /*!< Product term 1 input C */
aoi_input_config_t PT1DC; /*!< Product term 1 input D */
aoi_input_config_t PT2AC; /*!< Product term 2 input A */
aoi_input_config_t PT2BC; /*!< Product term 2 input B */
aoi_input_config_t PT2CC; /*!< Product term 2 input C */
aoi_input_config_t PT2DC; /*!< Product term 2 input D */
aoi_input_config_t PT3AC; /*!< Product term 3 input A */
aoi_input_config_t PT3BC; /*!< Product term 3 input B */
aoi_input_config_t PT3CC; /*!< Product term 3 input C */
aoi_input_config_t PT3DC; /*!< Product term 3 input D */
} aoi_event_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus*/
/*!
* @name AOI Initialization
* @{
*/
/*!
* @brief Initializes an AOI instance for operation.
*
* This function un-gates the AOI clock.
*
* @param base AOI peripheral address.
*/
void AOI_Init(AOI_Type *base);
/*!
* @brief Deinitializes an AOI instance for operation.
*
* This function shutdowns AOI module.
*
* @param base AOI peripheral address.
*/
void AOI_Deinit(AOI_Type *base);
/*@}*/
/*!
* @name AOI Get Set Operation
* @{
*/
/*!
* @brief Gets the Boolean evaluation associated.
*
* This function returns the Boolean evaluation associated.
*
* Example:
@code
aoi_event_config_t demoEventLogicStruct;
AOI_GetEventLogicConfig(AOI, kAOI_Event0, &demoEventLogicStruct);
@endcode
*
* @param base AOI peripheral address.
* @param event Index of the event which will be set of type aoi_event_t.
* @param config Selected input configuration .
*/
void AOI_GetEventLogicConfig(AOI_Type *base, aoi_event_t event, aoi_event_config_t *config);
/*!
* @brief Configures an AOI event.
*
* This function configures an AOI event according
* to the aoiEventConfig structure. This function configures all inputs (A, B, C, and D)
* of all product terms (0, 1, 2, and 3) of a desired event.
*
* Example:
@code
aoi_event_config_t demoEventLogicStruct;
demoEventLogicStruct.PT0AC = kAOI_InvInputSignal;
demoEventLogicStruct.PT0BC = kAOI_InputSignal;
demoEventLogicStruct.PT0CC = kAOI_LogicOne;
demoEventLogicStruct.PT0DC = kAOI_LogicOne;
demoEventLogicStruct.PT1AC = kAOI_LogicZero;
demoEventLogicStruct.PT1BC = kAOI_LogicOne;
demoEventLogicStruct.PT1CC = kAOI_LogicOne;
demoEventLogicStruct.PT1DC = kAOI_LogicOne;
demoEventLogicStruct.PT2AC = kAOI_LogicZero;
demoEventLogicStruct.PT2BC = kAOI_LogicOne;
demoEventLogicStruct.PT2CC = kAOI_LogicOne;
demoEventLogicStruct.PT2DC = kAOI_LogicOne;
demoEventLogicStruct.PT3AC = kAOI_LogicZero;
demoEventLogicStruct.PT3BC = kAOI_LogicOne;
demoEventLogicStruct.PT3CC = kAOI_LogicOne;
demoEventLogicStruct.PT3DC = kAOI_LogicOne;
AOI_SetEventLogicConfig(AOI, kAOI_Event0, demoEventLogicStruct);
@endcode
*
* @param base AOI peripheral address.
* @param event Event which will be configured of type aoi_event_t.
* @param eventConfig Pointer to type aoi_event_config_t structure. The user is responsible for
* filling out the members of this structure and passing the pointer to this function.
*/
void AOI_SetEventLogicConfig(AOI_Type *base, aoi_event_t event, const aoi_event_config_t *eventConfig);
#if defined(__cplusplus)
}
#endif /* __cplusplus*/
/*@}*/
/*!* @} */
#endif /* _FSL_AOI_H_*/

View File

@@ -0,0 +1,238 @@
/*
* The Clear BSD License
* Copyright 2017 NXP
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#include "fsl_bee.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
static void aligned_memcpy(void *dst, const void *src, size_t size)
{
register uint32_t *to32 = (uint32_t *)(uintptr_t)dst;
register const uint32_t *from32 = (const uint32_t *)(uintptr_t)src;
while (size >= sizeof(uint32_t))
{
*to32 = *from32;
size -= sizeof(uint32_t);
to32++;
from32++;
}
}
void BEE_Init(BEE_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_EnableClock(kCLOCK_Bee);
#endif
base->CTRL = BEE_CTRL_CTRL_SFTRST_N_MASK | BEE_CTRL_CTRL_CLK_EN_MASK;
}
void BEE_Deinit(BEE_Type *base)
{
base->CTRL &=
~(BEE_CTRL_BEE_ENABLE_MASK | BEE_CTRL_CTRL_SFTRST_N_MASK | BEE_CTRL_CTRL_CLK_EN_MASK | BEE_CTRL_KEY_VALID_MASK);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_DisableClock(kCLOCK_Bee);
#endif
}
void BEE_GetDefaultConfig(bee_region_config_t *config)
{
assert(config);
config->mode = kBEE_AesEcbMode;
config->regionBot = 0U;
config->regionTop = 0U;
config->addrOffset = 0xF0000000U;
config->regionEn = kBEE_RegionDisabled;
}
status_t BEE_SetRegionConfig(BEE_Type *base, bee_region_t region, const bee_region_config_t *config)
{
IOMUXC_GPR_Type *iomuxc = IOMUXC_GPR;
bool reenable = false;
/* Wait until BEE is in idle state */
while (!(BEE_GetStatusFlags(base) & kBEE_IdleFlag))
{
}
/* Disable BEE before region configuration in case it is enabled. */
if ((base->CTRL >> BEE_CTRL_BEE_ENABLE_SHIFT) & 1)
{
BEE_Disable(base);
reenable = true;
}
if (region == kBEE_Region0)
{
/* Region 0 config */
iomuxc->GPR18 = config->regionBot;
iomuxc->GPR19 = config->regionTop;
base->CTRL |= BEE_CTRL_CTRL_AES_MODE_R0(config->mode);
base->ADDR_OFFSET0 = BEE_ADDR_OFFSET0_ADDR_OFFSET0(config->addrOffset);
}
else if (region == kBEE_Region1)
{
/* Region 1 config */
iomuxc->GPR20 = config->regionBot;
iomuxc->GPR21 = config->regionTop;
base->CTRL |= BEE_CTRL_CTRL_AES_MODE_R1(config->mode);
base->ADDR_OFFSET1 = BEE_ADDR_OFFSET1_ADDR_OFFSET0(config->addrOffset);
base->REGION1_BOT = BEE_REGION1_BOT_REGION1_BOT(config->regionBot);
base->REGION1_TOP = BEE_REGION1_TOP_REGION1_TOP(config->regionTop);
}
else
{
return kStatus_InvalidArgument;
}
/* Enable/disable region if desired */
if (config->regionEn == kBEE_RegionEnabled)
{
iomuxc->GPR11 |= IOMUXC_GPR_GPR11_BEE_DE_RX_EN(1 << region);
}
else
{
iomuxc->GPR11 &= ~IOMUXC_GPR_GPR11_BEE_DE_RX_EN(1 << region);
}
/* Reenable BEE if it was enabled before. */
if (reenable)
{
BEE_Enable(base);
}
return kStatus_Success;
}
status_t BEE_SetRegionKey(
BEE_Type *base, bee_region_t region, const uint8_t *key, size_t keySize, const uint8_t *nonce, size_t nonceSize)
{
bool reenable = false;
/* Key must be 32-bit aligned */
if (((uintptr_t)key & 0x3u) || (keySize != 16))
{
return kStatus_InvalidArgument;
}
/* Wait until BEE is in idle state */
while (!(BEE_GetStatusFlags(base) & kBEE_IdleFlag))
{
}
/* Disable BEE before region configuration in case it is enabled. */
if ((base->CTRL >> BEE_CTRL_BEE_ENABLE_SHIFT) & 1)
{
BEE_Disable(base);
reenable = true;
}
if (region == kBEE_Region0)
{
base->CTRL &= ~BEE_CTRL_KEY_REGION_SEL_MASK;
if (nonce)
{
if (nonceSize != 16)
{
return kStatus_InvalidArgument;
}
memcpy((uint32_t *)&base->CTR_NONCE0_W0, nonce, nonceSize);
}
}
else if (region == kBEE_Region1)
{
base->CTRL |= BEE_CTRL_KEY_REGION_SEL_MASK;
if (nonce)
{
if (nonceSize != 16)
{
return kStatus_InvalidArgument;
}
memcpy((uint32_t *)&base->CTR_NONCE1_W0, nonce, nonceSize);
}
}
else
{
return kStatus_InvalidArgument;
}
/* Try to load key. If BEE key selection fuse is programmed to use OTMP key on this device, this operation should
* fail. */
aligned_memcpy((uint32_t *)&base->AES_KEY0_W0, key, keySize);
if (memcmp((uint32_t *)&base->AES_KEY0_W0, key, keySize) != 0)
{
return kStatus_Fail;
}
/* Reenable BEE if it was enabled before. */
if (reenable)
{
BEE_Enable(base);
}
return kStatus_Success;
}
uint32_t BEE_GetStatusFlags(BEE_Type *base)
{
return base->STATUS;
}
void BEE_ClearStatusFlags(BEE_Type *base, uint32_t mask)
{
/* w1c */
base->STATUS |= mask;
}

View File

@@ -0,0 +1,228 @@
/*
* The Clear BSD License
* Copyright 2017 NXP
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#ifndef _FSL_BEE_H_
#define _FSL_BEE_H_
#include "fsl_common.h"
/*******************************************************************************
* Definitions
*******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief BEE driver version. Version 2.0.0.
*
* Current version: 2.0.0
*
* Change log:
* - Version 2.0.0
* - Initial version
*/
#define FSL_BEE_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
/*@}*/
typedef enum _bee_aes_mode
{
kBEE_AesEcbMode = 0U, /*!< AES ECB Mode */
kBEE_AesCtrMode = 1U /*!< AES CTR Mode */
} bee_aes_mode_t;
typedef enum _bee_region
{
kBEE_Region0 = 0U, /*!< BEE region 0 */
kBEE_Region1 = 1U /*!< BEE region 1 */
} bee_region_t;
typedef enum _bee_region_enable
{
kBEE_RegionDisabled = 0U, /*!< BEE region disabled */
kBEE_RegionEnabled = 1U /*!< BEE region enabled */
} bee_region_enable_t;
typedef enum _bee_status_flags
{
kBEE_DisableAbortFlag = 1U, /*!< Disable abort flag. */
kBEE_Reg0ReadSecViolation = 2U, /*!< Region-0 read channel security violation */
kBEE_ReadIllegalAccess = 4U, /*!< Read channel illegal access detected */
kBEE_Reg1ReadSecViolation = 8U, /*!< Region-1 read channel security violation */
kBEE_Reg0AccessViolation = 16U, /*!< Protected region-0 access violation */
kBEE_Reg1AccessViolation = 32U, /*!< Protected region-1 access violation */
kBEE_IdleFlag = BEE_STATUS_BEE_IDLE_MASK /*!< Idle flag */
} bee_status_flags_t;
/*! @brief BEE region configuration structure. */
typedef struct _bee_region_config
{
bee_aes_mode_t mode; /*!< AES mode used for encryption/decryption */
uint32_t regionBot; /*!< Region bottom address */
uint32_t regionTop; /*!< Region top address */
uint32_t addrOffset; /*!< Region address offset */
bee_region_enable_t regionEn; /*!< Region enable/disable */
} bee_region_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Resets BEE module to factory default values.
*
* This function performs hardware reset of BEE module. Attributes and keys from software for both regions are cleared.
*
* @param base BEE peripheral address.
*/
void BEE_Init(BEE_Type *base);
/*!
* @brief Resets BEE module, clears keys for both regions and disables clock to the BEE.
*
* This function performs hardware reset of BEE module and disables clocks. Attributes and keys from software for both
* regions are cleared.
*
* @param base BEE peripheral address.
*/
void BEE_Deinit(BEE_Type *base);
/*!
* @brief Enables BEE decryption.
*
* This function enables decryption using BEE.
*
* @param base BEE peripheral address.
*/
static inline void BEE_Enable(BEE_Type *base)
{
base->CTRL |= BEE_CTRL_BEE_ENABLE_MASK | BEE_CTRL_KEY_VALID_MASK;
}
/*!
* @brief Disables BEE decryption.
*
* This function disables decryption using BEE.
*
* @param base BEE peripheral address.
*/
static inline void BEE_Disable(BEE_Type *base)
{
base->CTRL &= ~BEE_CTRL_BEE_ENABLE_MASK | BEE_CTRL_KEY_VALID_MASK;
}
/*!
* @brief Loads default values to the BEE region configuration structure.
*
* Loads default values to the BEE region configuration structure. The default values are as follows:
* @code
* config->mode = kBEE_AesCbcMode;
* config->regionBot = 0U;
* config->regionTop = 0U;
* config->addrOffset = 0xF0000000U;
* config->regionEn = kBEE_RegionDisabled;
* @endcode
*
* @param config Configuration structure for BEE region.
*/
void BEE_GetDefaultConfig(bee_region_config_t *config);
/*!
* @brief Sets BEE region configuration.
*
* This function sets BEE region settings accorging to given configuration structure.
*
* @param base BEE peripheral address.
* @param region Selection of the BEE region to be configured.
* @param config Configuration structure for BEE region.
*/
status_t BEE_SetRegionConfig(BEE_Type *base, bee_region_t region, const bee_region_config_t *config);
/*!
* @brief Loads the AES key and nonce for selected region into BEE key registers.
*
* This function loads given AES key and nonce(only AES CTR mode) to BEE register for the given region.
*
* Please note, that eFuse BEE_KEYx_SEL must be set accordingly to be able to load and use key loaded in BEE registers.
* Otherwise, key cannot loaded and BEE will use key from OTPMK or SW_GP2.
*
* @param base BEE peripheral address.
* @param region Selection of the BEE region to be configured.
* @param key AES key.
* @param keySize Size of AES key.
* @param nonce AES nonce.
* @param nonceSize Size of AES nonce.
*/
status_t BEE_SetRegionKey(
BEE_Type *base, bee_region_t region, const uint8_t *key, size_t keySize, const uint8_t *nonce, size_t nonceSize);
/*!
* @brief Gets the BEE status flags.
*
* This function returns status of BEE peripheral.
*
* @param base BEE peripheral address.
*
* @return The status flags. This is the logical OR of members of the
* enumeration ::bee_status_flags_t
*/
uint32_t BEE_GetStatusFlags(BEE_Type *base);
/*!
* @brief Clears the BEE status flags.
*
* @param base BEE peripheral base address.
* @param mask The status flags to clear. This is a logical OR of members of the
* enumeration ::bee_status_flags_t
*/
void BEE_ClearStatusFlags(BEE_Type *base, uint32_t mask);
/*!
* @brief Computes offset to be set for specifed memory location.
*
* This function calculates offset that must be set for BEE region to access physical memory location.
*
* @param addressMemory Address of physical memory location.
*/
static inline uint32_t BEE_GetOffset(uint32_t addressMemory)
{
return (addressMemory >> 16);
}
#if defined(__cplusplus)
}
#endif
#endif /* _FSL_BEE_H_ */

View File

@@ -0,0 +1,464 @@
/*
* The Clear BSD License
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#include "fsl_cache.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#if (FSL_FEATURE_SOC_L2CACHEC_COUNT > 0)
#define L2CACHE_OPERATION_TIMEOUT 0xFFFFFU
#define L2CACHE_8WAYS_MASK 0xFFU
#define L2CACHE_16WAYS_MASK 0xFFFFU
#define L2CACHE_SMALLWAYS_NUM 8U
#define L2CACHE_1KBCOVERTOB 1024U
#define L2CACHE_SAMLLWAYS_SIZE 16U
#define L2CACHE_LOCKDOWN_REGNUM 8 /*!< Lock down register numbers.*/
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Set for all ways and waiting for the operation finished.
* This is provided for all the background operations.
*
* @param auxCtlReg The auxiliary control register.
* @param regAddr The register address to be operated.
*/
static void L2CACHE_SetAndWaitBackGroundOperate(uint32_t auxCtlReg, uint32_t regAddr);
/*!
* @brief Invalidates the Level 2 cache line by physical address.
* This function invalidates a cache line by physcial address.
*
* @param address The physical addderss of the cache.
* The format of the address shall be :
* bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
* Tag | index | 0
* Note: the physical address shall be aligned to the line size - 32B (256 bit).
* so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
* If the input address is not aligned, it will be changed to 32-byte aligned address.
* The n is varies according to the index width.
* @return The actual 32-byte aligned physical address be operated.
*/
static uint32_t L2CACHE_InvalidateLineByAddr(uint32_t address);
/*!
* @brief Cleans the Level 2 cache line based on the physical address.
* This function cleans a cache line based on a physcial address.
*
* @param address The physical addderss of the cache.
* The format of the address shall be :
* bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
* Tag | index | 0
* Note: the physical address shall be aligned to the line size - 32B (256 bit).
* so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
* If the input address is not aligned, it will be changed to 32-byte aligned address.
* The n is varies according to the index width.
* @return The actual 32-byte aligned physical address be operated.
*/
static uint32_t L2CACHE_CleanLineByAddr(uint32_t address);
/*!
* @brief Cleans and invalidates the Level 2 cache line based on the physical address.
* This function cleans and invalidates a cache line based on a physcial address.
*
* @param address The physical addderss of the cache.
* The format of the address shall be :
* bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
* Tag | index | 0
* Note: the physical address shall be aligned to the line size - 32B (256 bit).
* so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
* If the input address is not aligned, it will be changed to 32-byte aligned address.
* The n is varies according to the index width.
* @return The actual 32-byte aligned physical address be operated.
*/
static uint32_t L2CACHE_CleanInvalidateLineByAddr(uint32_t address);
/*!
* @brief Gets the number of the Level 2 cache and the way size.
* This function cleans and invalidates a cache line based on a physcial address.
*
* @param num_ways The number of the cache way.
* @param size_way The way size.
*/
static void L2CACHE_GetWayNumSize(uint32_t *num_ways, uint32_t *size_way);
/*******************************************************************************
* Code
******************************************************************************/
static void L2CACHE_SetAndWaitBackGroundOperate(uint32_t auxCtlReg, uint32_t regAddr)
{
uint16_t mask = L2CACHE_8WAYS_MASK;
uint32_t timeout = L2CACHE_OPERATION_TIMEOUT;
/* Check the ways used at first. */
if (auxCtlReg & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK)
{
mask = L2CACHE_16WAYS_MASK;
}
/* Set the opeartion for all ways/entries of the cache. */
*(uint32_t *)regAddr = mask;
/* Waiting for until the operation is complete. */
while ((*(uint32_t *)regAddr & mask) && timeout)
{
__ASM("nop");
timeout--;
}
}
static uint32_t L2CACHE_InvalidateLineByAddr(uint32_t address)
{
/* Align the address first. */
address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
/* Invalidate the cache line by physical address. */
L2CACHEC->REG7_INV_PA = address;
return address;
}
static uint32_t L2CACHE_CleanLineByAddr(uint32_t address)
{
/* Align the address first. */
address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
/* Invalidate the cache line by physical address. */
L2CACHEC->REG7_CLEAN_PA = address;
return address;
}
static uint32_t L2CACHE_CleanInvalidateLineByAddr(uint32_t address)
{
/* Align the address first. */
address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
/* Clean and invalidate the cache line by physical address. */
L2CACHEC->REG7_CLEAN_INV_PA = address;
return address;
}
static void L2CACHE_GetWayNumSize(uint32_t *num_ways, uint32_t *size_way)
{
assert(num_ways);
assert(size_way);
uint32_t number = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
uint32_t size = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_MASK) >>
L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_SHIFT;
*num_ways = (number + 1) * L2CACHE_SMALLWAYS_NUM;
if (!size)
{
/* 0 internally mapped to the same size as 1 - 16KB.*/
size += 1;
}
*size_way = (1 << (size - 1)) * L2CACHE_SAMLLWAYS_SIZE * L2CACHE_1KBCOVERTOB;
}
void L2CACHE_Init(l2cache_config_t *config)
{
assert (config);
uint16_t waysNum = 0xFFU; /* Default use the 8-way mask. */
uint8_t count;
uint32_t auxReg = 0;
/*The aux register must be configured when the cachec is disabled
* So disable first if the cache controller is enabled.
*/
if (L2CACHEC->REG1_CONTROL & L2CACHEC_REG1_CONTROL_CE_MASK)
{
L2CACHE_Disable();
}
/* Unlock all entries. */
if (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK)
{
waysNum = 0xFFFFU;
}
for (count = 0; count < L2CACHE_LOCKDOWN_REGNUM; count ++)
{
L2CACHE_LockdownByWayEnable(count, waysNum, false);
}
/* Set the ways and way-size etc. */
auxReg = L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY(config->wayNum) |
L2CACHEC_REG1_AUX_CONTROL_WAYSIZE(config->waySize) |
L2CACHEC_REG1_AUX_CONTROL_CRP(config->repacePolicy) |
L2CACHEC_REG1_AUX_CONTROL_IPE(config->istrPrefetchEnable) |
L2CACHEC_REG1_AUX_CONTROL_DPE(config->dataPrefetchEnable) |
L2CACHEC_REG1_AUX_CONTROL_NLE(config->nsLockdownEnable) |
L2CACHEC_REG1_AUX_CONTROL_FWA(config->writeAlloc) |
L2CACHEC_REG1_AUX_CONTROL_HPSDRE(config->writeAlloc);
L2CACHEC->REG1_AUX_CONTROL = auxReg;
/* Set the tag/data ram latency. */
if (config->lateConfig)
{
uint32_t data = 0;
/* Tag latency. */
data = L2CACHEC_REG1_TAG_RAM_CONTROL_SL(config->lateConfig->tagSetupLate)|
L2CACHEC_REG1_TAG_RAM_CONTROL_SL(config->lateConfig->tagSetupLate)|
L2CACHEC_REG1_TAG_RAM_CONTROL_RAL(config->lateConfig->tagReadLate)|
L2CACHEC_REG1_TAG_RAM_CONTROL_WAL(config->lateConfig->dataWriteLate);
L2CACHEC->REG1_TAG_RAM_CONTROL = data;
/* Data latency. */
data = L2CACHEC_REG1_DATA_RAM_CONTROL_SL(config->lateConfig->dataSetupLate)|
L2CACHEC_REG1_DATA_RAM_CONTROL_SL(config->lateConfig->dataSetupLate)|
L2CACHEC_REG1_DATA_RAM_CONTROL_RAL(config->lateConfig->dataReadLate)|
L2CACHEC_REG1_DATA_RAM_CONTROL_WAL(config->lateConfig->dataWriteLate);
L2CACHEC->REG1_DATA_RAM_CONTROL = data;
}
}
void L2CACHE_GetDefaultConfig(l2cache_config_t *config)
{
assert(config);
uint32_t number = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
uint32_t size = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_MASK) >>
L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_SHIFT;
/* Get the default value */
config->wayNum = (l2cache_way_num_t)number;
config->waySize = (l2cache_way_size)size;
config->repacePolicy = kL2CACHE_Roundrobin;
config->lateConfig = NULL;
config->istrPrefetchEnable = false;
config->dataPrefetchEnable = false;
config->nsLockdownEnable = false;
config->writeAlloc = kL2CACHE_UseAwcache;
}
void L2CACHE_Enable(void)
{
/* Invalidate first. */
L2CACHE_Invalidate();
/* Enable the level 2 cache controller. */
L2CACHEC->REG1_CONTROL = L2CACHEC_REG1_CONTROL_CE_MASK;
}
void L2CACHE_Disable(void)
{
/* First CleanInvalidate all enties in the cache. */
L2CACHE_CleanInvalidate();
/* Disable the level 2 cache controller. */
L2CACHEC->REG1_CONTROL &= ~L2CACHEC_REG1_CONTROL_CE_MASK;
/* DSB - data sync barrier.*/
__DSB();
}
void L2CACHE_Invalidate(void)
{
/* Invalidate all entries in cache. */
L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_INV_WAY);
/* Cache sync. */
L2CACHEC->REG7_CACHE_SYNC = 0;
}
void L2CACHE_Clean(void)
{
/* Clean all entries of the cache. */
L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_CLEAN_WAY);
/* Cache sync. */
L2CACHEC->REG7_CACHE_SYNC = 0;
}
void L2CACHE_CleanInvalidate(void)
{
/* Clean all entries of the cache. */
L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_CLEAN_INV_WAY);
/* Cache sync. */
L2CACHEC->REG7_CACHE_SYNC = 0;
}
void L2CACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
{
uint32_t endAddr = address + size_byte;
/* Invalidate addresses in the range. */
while (address < endAddr)
{
address = L2CACHE_InvalidateLineByAddr(address);
/* Update the size. */
address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
}
/* Cache sync. */
L2CACHEC->REG7_CACHE_SYNC = 0;
}
void L2CACHE_CleanByRange(uint32_t address, uint32_t size_byte)
{
uint32_t num_ways = 0;
uint32_t size_way = 0;
uint32_t endAddr = address + size_byte;
/* Get the number and size of the cache way. */
L2CACHE_GetWayNumSize(&num_ways, &size_way);
/* Check if the clean size is over the cache size. */
if ((endAddr - address) > num_ways * size_way)
{
L2CACHE_Clean();
return;
}
/* Clean addresses in the range. */
while ((address & ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1)) < endAddr)
{
/* Clean the address in the range. */
address = L2CACHE_CleanLineByAddr(address);
address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
}
L2CACHEC->REG7_CACHE_SYNC = 0;
}
void L2CACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte)
{
uint32_t num_ways = 0;
uint32_t size_way = 0;
uint32_t endAddr = address + size_byte;
/* Get the number and size of the cache way. */
L2CACHE_GetWayNumSize(&num_ways, &size_way);
/* Check if the clean size is over the cache size. */
if ((endAddr - address) > num_ways * size_way)
{
L2CACHE_CleanInvalidate();
return;
}
/* Clean addresses in the range. */
while ((address & ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1)) < endAddr)
{
/* Clean the address in the range. */
address = L2CACHE_CleanInvalidateLineByAddr(address);
address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
}
L2CACHEC->REG7_CACHE_SYNC = 0;
}
void L2CACHE_LockdownByWayEnable(uint32_t masterId, uint32_t mask, bool enable)
{
uint8_t num_ways = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
num_ways = (num_ways + 1) * L2CACHE_SMALLWAYS_NUM;
assert(mask < (1U << num_ways));
assert(masterId < L2CACHE_LOCKDOWN_REGNUM);
uint32_t dataReg = L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN;
uint32_t istrReg = L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN;
if (enable)
{
/* Data lockdown. */
L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN = dataReg | mask;
/* Instruction lockdown. */
L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN = istrReg | mask;
}
else
{
/* Data lockdown. */
L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN = dataReg & ~mask;
/* Instruction lockdown. */
L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN = istrReg & ~mask;
}
}
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT > 0 */
void L1CACHE_InvalidateICacheByRange(uint32_t address, uint32_t size_byte)
{
#if (__DCACHE_PRESENT == 1U)
uint32_t addr = address & (uint32_t)~(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE - 1);
int32_t size = size_byte + address - addr;
uint32_t linesize = 32U;
__DSB();
while (size > 0)
{
SCB->ICIMVAU = addr;
addr += linesize;
size -= linesize;
}
__DSB();
__ISB();
#endif
}
void ICACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
{
#if (FSL_FEATURE_SOC_L2CACHEC_COUNT > 0)
#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
L2CACHE_InvalidateByRange(address, size_byte);
#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT > 0 */
L1CACHE_InvalidateICacheByRange(address, size_byte);
}
void DCACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
{
#if (FSL_FEATURE_SOC_L2CACHEC_COUNT > 0)
#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
L2CACHE_InvalidateByRange(address, size_byte);
#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT > 0 */
L1CACHE_InvalidateDCacheByRange(address, size_byte);
}
void DCACHE_CleanByRange(uint32_t address, uint32_t size_byte)
{
L1CACHE_CleanDCacheByRange(address, size_byte);
#if (FSL_FEATURE_SOC_L2CACHEC_COUNT > 0)
#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
L2CACHE_CleanByRange(address, size_byte);
#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT > 0 */
}
void DCACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte)
{
L1CACHE_CleanInvalidateDCacheByRange(address, size_byte);
#if (FSL_FEATURE_SOC_L2CACHEC_COUNT > 0)
#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
L2CACHE_CleanInvalidateByRange(address, size_byte);
#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT > 0 */
}

View File

@@ -0,0 +1,494 @@
/*
* The Clear BSD License
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#ifndef _FSL_CACHE_H_
#define _FSL_CACHE_H_
#include "fsl_common.h"
/*!
* @addtogroup cache
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief cache driver version 2.0.1. */
#define FSL_CACHE_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
/*@}*/
#if (FSL_FEATURE_SOC_L2CACHEC_COUNT > 0)
#ifndef FSL_SDK_DISBLE_L2CACHE_PRESENT
#define FSL_SDK_DISBLE_L2CACHE_PRESENT 0
#endif
#endif /* (FSL_FEATURE_SOC_L2CACHEC_COUNT > 0) */
/*******************************************************************************
* Definitions
******************************************************************************/
#if (FSL_FEATURE_SOC_L2CACHEC_COUNT > 0)
/*! @brief Number of level 2 cache controller ways. */
typedef enum _l2cache_way_num
{
kL2CACHE_8ways = 0, /*!< 8 ways. */
#if defined(FSL_FEATURE_L2CACHE_SUPPORT_16_WAY_ASSOCIATIVITY) && FSL_FEATURE_L2CACHE_SUPPORT_16_WAY_ASSOCIATIVITY
kL2CACHE_16ways /*!< 16 ways. */
#endif /* FSL_FEATURE_L2CACHE_SUPPORT_16_WAY_ASSOCIATIVITY */
} l2cache_way_num_t;
/*! @brief Level 2 cache controller way size. */
typedef enum _l2cache_way_size
{
kL2CACHE_16KBSize = 1, /*!< 16 KB way size. */
kL2CACHE_32KBSize = 2, /*!< 32 KB way size. */
kL2CACHE_64KBSize = 3, /*!< 64 KB way size. */
kL2CACHE_128KBSize = 4, /*!< 128 KB way size. */
kL2CACHE_256KBSize = 5, /*!< 256 KB way size. */
kL2CACHE_512KBSize = 6 /*!< 512 KB way size. */
} l2cache_way_size;
/*! @brief Level 2 cache controller replacement policy. */
typedef enum _l2cache_replacement
{
kL2CACHE_Pseudorandom = 0U, /*!< Peseudo-random replacement policy using an lfsr. */
kL2CACHE_Roundrobin /*!< Round-robin replacemnt policy. */
} l2cache_replacement_t;
/*! @brief Level 2 cache controller force write allocate options. */
typedef enum _l2cache_writealloc
{
kL2CACHE_UseAwcache = 0, /*!< Use AWCAHE attribute for the write allocate. */
kL2CACHE_NoWriteallocate, /*!< Force no write allocate. */
kL2CACHE_forceWriteallocate /*!< Force write allocate when write misses. */
} l2cache_writealloc_t;
/*! @brief Level 2 cache controller tag/data ram latency. */
typedef enum _l2cache_latency
{
kL2CACHE_1CycleLate = 0, /*!< 1 cycle of latency. */
kL2CACHE_2CycleLate, /*!< 2 cycle of latency. */
kL2CACHE_3CycleLate, /*!< 3 cycle of latency. */
kL2CACHE_4CycleLate, /*!< 4 cycle of latency. */
kL2CACHE_5CycleLate, /*!< 5 cycle of latency. */
kL2CACHE_6CycleLate, /*!< 6 cycle of latency. */
kL2CACHE_7CycleLate, /*!< 7 cycle of latency. */
kL2CACHE_8CycleLate /*!< 8 cycle of latency. */
} l2cache_latency_t;
/*! @brief Level 2 cache controller tag/data ram latency configure structure. */
typedef struct _l2cache_latency_config
{
l2cache_latency_t tagWriteLate; /*!< Tag write latency. */
l2cache_latency_t tagReadLate; /*!< Tag Read latency. */
l2cache_latency_t tagSetupLate; /*!< Tag setup latency. */
l2cache_latency_t dataWriteLate; /*!< Data write latency. */
l2cache_latency_t dataReadLate; /*!< Data Read latency. */
l2cache_latency_t dataSetupLate; /*!< Data setup latency. */
} L2cache_latency_config_t;
/*! @brief Level 2 cache controller configure structure. */
typedef struct _l2cache_config
{
/* ------------------------ l2 cachec basic settings ---------------------------- */
l2cache_way_num_t wayNum; /*!< The number of ways. */
l2cache_way_size waySize; /*!< The way size = Cache Ram size / wayNum. */
l2cache_replacement_t repacePolicy;/*!< Replacemnet policy. */
/* ------------------------ tag/data ram latency settings ----------------------- */
L2cache_latency_config_t *lateConfig; /*!< Tag/data latency configure. Set NUll if not required. */
/* ------------------------ Prefetch enable settings ---------------------------- */
bool istrPrefetchEnable; /*!< Instruction prefetch enable. */
bool dataPrefetchEnable; /*!< Data prefetch enable. */
/* ------------------------ Non-secure access settings -------------------------- */
bool nsLockdownEnable; /*!< None-secure lockdown enable. */
/* ------------------------ other settings -------------------------------------- */
l2cache_writealloc_t writeAlloc;/*!< Write allcoate force option. */
} l2cache_config_t;
#endif /* (FSL_FEATURE_SOC_L2CACHEC_COUNT > 0) */
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Control for cortex-m7 L1 cache
*@{
*/
/*!
* @brief Enables cortex-m7 L1 instruction cache.
*
*/
static inline void L1CACHE_EnableICache(void)
{
SCB_EnableICache();
}
/*!
* @brief Disables cortex-m7 L1 instruction cache.
*
*/
static inline void L1CACHE_DisableICache(void)
{
SCB_DisableICache();
}
/*!
* @brief Invalidate cortex-m7 L1 instruction cache.
*
*/
static inline void L1CACHE_InvalidateICache(void)
{
SCB_InvalidateICache();
}
/*!
* @brief Invalidate cortex-m7 L1 instruction cache by range.
*
* @param address The start address of the memory to be invalidated.
* @param size_byte The memory size.
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE) aligned.
* The startAddr here will be forced to align to L1 I-cache line size if
* startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
void L1CACHE_InvalidateICacheByRange(uint32_t address, uint32_t size_byte);
/*!
* @brief Enables cortex-m7 L1 data cache.
*
*/
static inline void L1CACHE_EnableDCache(void)
{
SCB_EnableDCache();
}
/*!
* @brief Disables cortex-m7 L1 data cache.
*
*/
static inline void L1CACHE_DisableDCache(void)
{
SCB_DisableDCache();
}
/*!
* @brief Invalidates cortex-m7 L1 data cache.
*
*/
static inline void L1CACHE_InvalidateDCache(void)
{
SCB_InvalidateDCache();
}
/*!
* @brief Cleans cortex-m7 L1 data cache.
*
*/
static inline void L1CACHE_CleanDCache(void)
{
SCB_CleanDCache();
}
/*!
* @brief Cleans and Invalidates cortex-m7 L1 data cache.
*
*/
static inline void L1CACHE_CleanInvalidateDCache(void)
{
SCB_CleanInvalidateDCache();
}
/*!
* @brief Invalidates cortex-m7 L1 data cache by range.
*
* @param address The start address of the memory to be invalidated.
* @param size_byte The memory size.
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) aligned.
* The startAddr here will be forced to align to L1 D-cache line size if
* startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
static inline void L1CACHE_InvalidateDCacheByRange(uint32_t address, uint32_t size_byte)
{
uint32_t startAddr = address & (uint32_t)~(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE - 1);
uint32_t size = size_byte + address - startAddr;
SCB_InvalidateDCache_by_Addr((uint32_t *)startAddr, size);
}
/*!
* @brief Cleans cortex-m7 L1 data cache by range.
*
* @param address The start address of the memory to be cleaned.
* @param size_byte The memory size.
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) aligned.
* The startAddr here will be forced to align to L1 D-cache line size if
* startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
static inline void L1CACHE_CleanDCacheByRange(uint32_t address, uint32_t size_byte)
{
uint32_t startAddr = address & (uint32_t)~(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE - 1);
uint32_t size = size_byte + address - startAddr;
SCB_CleanDCache_by_Addr((uint32_t *)startAddr, size);
}
/*!
* @brief Cleans and Invalidates cortex-m7 L1 data cache by range.
*
* @param address The start address of the memory to be clean and invalidated.
* @param size_byte The memory size.
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) aligned.
* The startAddr here will be forced to align to L1 D-cache line size if
* startAddr is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
static inline void L1CACHE_CleanInvalidateDCacheByRange(uint32_t address, uint32_t size_byte)
{
uint32_t startAddr = address & (uint32_t)~(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE - 1);
uint32_t size = size_byte + address - startAddr;
SCB_CleanInvalidateDCache_by_Addr((uint32_t *)startAddr, size);
}
/*@}*/
#if (FSL_FEATURE_SOC_L2CACHEC_COUNT > 0)
/*!
* @name Control for L2 pl310 cache
*@{
*/
/*!
* @brief Initializes the level 2 cache controller module.
*
* @param config Pointer to configuration structure. See "l2cache_config_t".
*/
void L2CACHE_Init(l2cache_config_t *config);
/*!
* @brief Gets an available default settings for the cache controller.
*
* This function initializes the cache controller configuration structure with default settings.
* The default values are:
* @code
* config->waysNum = kL2CACHE_8ways;
* config->waySize = kL2CACHE_32KbSize;
* config->repacePolicy = kL2CACHE_Roundrobin;
* config->lateConfig = NULL;
* config->istrPrefetchEnable = false;
* config->dataPrefetchEnable = false;
* config->nsLockdownEnable = false;
* config->writeAlloc = kL2CACHE_UseAwcache;
* @endcode
* @param config Pointer to the configuration structure.
*/
void L2CACHE_GetDefaultConfig(l2cache_config_t *config);
/*!
* @brief Enables the level 2 cache controller.
* This function enables the cache controller. Must be written using a secure access.
* If write with a Non-secure access will cause a DECERR response.
*
*/
void L2CACHE_Enable(void);
/*!
* @brief Disables the level 2 cache controller.
* This function disables the cache controller. Must be written using a secure access.
* If write with a Non-secure access will cause a DECERR response.
*
*/
void L2CACHE_Disable(void);
/*!
* @brief Invalidates the Level 2 cache.
* This function invalidates all entries in cache.
*
*/
void L2CACHE_Invalidate(void);
/*!
* @brief Invalidates the Level 2 cache lines in the range of two physical addresses.
* This function invalidates all cache lines between two physical addresses.
*
* @param address The start address of the memory to be invalidated.
* @param size_byte The memory size.
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
* The startAddr here will be forced to align to L2 line size if startAddr
* is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
void L2CACHE_InvalidateByRange(uint32_t address, uint32_t size_byte);
/*!
* @brief Cleans the level 2 cache controller.
* This function cleans all entries in the level 2 cache controller.
*
*/
void L2CACHE_Clean(void);
/*!
* @brief Cleans the Level 2 cache lines in the range of two physical addresses.
* This function cleans all cache lines between two physical addresses.
*
* @param address The start address of the memory to be cleaned.
* @param size_byte The memory size.
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
* The startAddr here will be forced to align to L2 line size if startAddr
* is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
void L2CACHE_CleanByRange(uint32_t address, uint32_t size_byte);
/*!
* @brief Cleans and invalidates the level 2 cache controller.
* This function cleans and invalidates all entries in the level 2 cache controller.
*
*/
void L2CACHE_CleanInvalidate(void);
/*!
* @brief Cleans and invalidates the Level 2 cache lines in the range of two physical addresses.
* This function cleans and invalidates all cache lines between two physical addresses.
*
* @param address The start address of the memory to be cleaned and invalidated.
* @param size_byte The memory size.
* @note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
* The startAddr here will be forced to align to L2 line size if startAddr
* is not aligned. For the size_byte, application should make sure the
* alignment or make sure the right operation order if the size_byte is not aligned.
*/
void L2CACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte);
/*!
* @brief Enables or disables to lock down the data and instruction by way.
* This function locks down the cached instruction/data by way and prevent the adresses from
* being allocated and prevent dara from being evicted out of the level 2 cache.
* But the normal cache maintenance operations that invalidate, clean or clean
* and validate cache contents affect the locked-down cache lines as normal.
*
* @param masterId The master id, range from 0 ~ 7.
* @param mask The ways to be enabled or disabled to lockdown.
* each bit in value is related to each way of the cache. for example:
* value: bit 0 ------ way 0.
* value: bit 1 ------ way 1.
* --------------------------
* value: bit 15 ------ way 15.
* Note: please make sure the value setting is align with your supported ways.
* @param enable True enable the lockdown, false to disable the lockdown.
*/
void L2CACHE_LockdownByWayEnable(uint32_t masterId, uint32_t mask, bool enable);
/*@}*/
#endif /* (FSL_FEATURE_SOC_L2CACHEC_COUNT > 0) */
/*!
* @name Unified Cache Control for all caches (cortex-m7 L1 cache + l2 pl310)
* Mainly used for many drivers for easy cache operation.
*@{
*/
/*!
* @brief Invalidates all instruction caches by range.
*
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
*
* @param address The physical address.
* @param size_byte size of the memory to be invalidated.
* @note address and size should be aligned to cache line size
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
*/
void ICACHE_InvalidateByRange(uint32_t address, uint32_t size_byte);
/*!
* @brief Invalidates all data caches by range.
*
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
*
* @param address The physical address.
* @param size_byte size of the memory to be invalidated.
* @note address and size should be aligned to cache line size
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
*/
void DCACHE_InvalidateByRange(uint32_t address, uint32_t size_byte);
/*!
* @brief Cleans all data caches by range.
*
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
*
* @param address The physical address.
* @param size_byte size of the memory to be cleaned.
* @note address and size should be aligned to cache line size
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
*/
void DCACHE_CleanByRange(uint32_t address, uint32_t size_byte);
/*!
* @brief Cleans and Invalidates all data caches by range.
*
* Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
*
* @param address The physical address.
* @param size_byte size of the memory to be cleaned and invalidated.
* @note address and size should be aligned to cache line size
* 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
* to align to the cache line size if startAddr is not aligned. For the size_byte, application should
* make sure the alignment or make sure the right operation order if the size_byte is not aligned.
*/
void DCACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte);
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_CACHE_H_*/

View File

@@ -0,0 +1,843 @@
/*
* The Clear BSD License
* Copyright 2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#include "fsl_common.h"
#include "fsl_clock.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/* External XTAL (OSC) clock frequency. */
uint32_t g_xtalFreq;
/* External RTC XTAL clock frequency. */
uint32_t g_rtcXtalFreq;
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t CLOCK_GetPeriphClkFreq(void)
{
uint32_t freq;
/* Periph_clk2_clk ---> Periph_clk */
if (CCM->CBCDR & CCM_CBCDR_PERIPH_CLK_SEL_MASK)
{
switch (CCM->CBCMR & CCM_CBCMR_PERIPH_CLK2_SEL_MASK)
{
/* Pll3_sw_clk ---> Periph_clk2_clk ---> Periph_clk */
case CCM_CBCMR_PERIPH_CLK2_SEL(0U):
freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1);
break;
/* Osc_clk ---> Periph_clk2_clk ---> Periph_clk */
case CCM_CBCMR_PERIPH_CLK2_SEL(1U):
freq = CLOCK_GetOscFreq();
break;
case CCM_CBCMR_PERIPH_CLK2_SEL(2U):
freq = CLOCK_GetPllFreq(kCLOCK_PllSys);
break;
case CCM_CBCMR_PERIPH_CLK2_SEL(3U):
default:
freq = 0U;
break;
}
freq /= (((CCM->CBCDR & CCM_CBCDR_PERIPH_CLK2_PODF_MASK) >> CCM_CBCDR_PERIPH_CLK2_PODF_SHIFT) + 1U);
}
/* Pre_Periph_clk ---> Periph_clk */
else
{
switch (CCM->CBCMR & CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK)
{
/* PLL2 ---> Pre_Periph_clk ---> Periph_clk */
case CCM_CBCMR_PRE_PERIPH_CLK_SEL(0U):
freq = CLOCK_GetPllFreq(kCLOCK_PllSys);
break;
/* PLL2 PFD2 ---> Pre_Periph_clk ---> Periph_clk */
case CCM_CBCMR_PRE_PERIPH_CLK_SEL(1U):
freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd2);
break;
/* PLL2 PFD0 ---> Pre_Periph_clk ---> Periph_clk */
case CCM_CBCMR_PRE_PERIPH_CLK_SEL(2U):
freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd0);
break;
/* PLL1 divided(/2) ---> Pre_Periph_clk ---> Periph_clk */
case CCM_CBCMR_PRE_PERIPH_CLK_SEL(3U):
freq = CLOCK_GetPllFreq(kCLOCK_PllArm) / (((CCM->CACRR & CCM_CACRR_ARM_PODF_MASK) >> CCM_CACRR_ARM_PODF_SHIFT) + 1U);
break;
default:
freq = 0U;
break;
}
}
return freq;
}
void CLOCK_InitExternalClk(bool bypassXtalOsc)
{
/* This device does not support bypass XTAL OSC. */
assert(!bypassXtalOsc);
CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_XTAL_24M_PWD_MASK; /* Power up */
while ((XTALOSC24M->LOWPWR_CTRL & XTALOSC24M_LOWPWR_CTRL_XTALOSC_PWRUP_STAT_MASK) == 0)
{
}
CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK; /* detect freq */
while ((CCM_ANALOG->MISC0 & CCM_ANALOG_MISC0_OSC_XTALOK_MASK) == 0)
{
}
CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK;
}
void CLOCK_DeinitExternalClk(void)
{
CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_XTAL_24M_PWD_MASK; /* Power down */
}
void CLOCK_SwitchOsc(clock_osc_t osc)
{
if (osc == kCLOCK_RcOsc)
XTALOSC24M->LOWPWR_CTRL_SET = XTALOSC24M_LOWPWR_CTRL_SET_OSC_SEL_MASK;
else
XTALOSC24M->LOWPWR_CTRL_CLR = XTALOSC24M_LOWPWR_CTRL_CLR_OSC_SEL_MASK;
}
void CLOCK_InitRcOsc24M(void)
{
XTALOSC24M->LOWPWR_CTRL |= XTALOSC24M_LOWPWR_CTRL_RC_OSC_EN_MASK;
}
void CLOCK_DeinitRcOsc24M(void)
{
XTALOSC24M->LOWPWR_CTRL &= ~XTALOSC24M_LOWPWR_CTRL_RC_OSC_EN_MASK;
}
uint32_t CLOCK_GetFreq(clock_name_t name)
{
uint32_t freq;
switch (name)
{
case kCLOCK_CpuClk:
/* Periph_clk ---> AHB Clock */
case kCLOCK_AhbClk:
/* Periph_clk ---> AHB Clock */
freq = CLOCK_GetPeriphClkFreq() / (((CCM->CBCDR & CCM_CBCDR_AHB_PODF_MASK) >> CCM_CBCDR_AHB_PODF_SHIFT) + 1U);
break;
case kCLOCK_SemcClk:
/* SEMC alternative clock ---> SEMC Clock */
if (CCM->CBCDR & CCM_CBCDR_SEMC_CLK_SEL_MASK)
{
/* PLL3 PFD1 ---> SEMC alternative clock ---> SEMC Clock */
if (CCM->CBCDR & CCM_CBCDR_SEMC_ALT_CLK_SEL_MASK)
{
freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd1);
}
/* PLL2 PFD2 ---> SEMC alternative clock ---> SEMC Clock */
else
{
freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd2);
}
}
/* Periph_clk ---> SEMC Clock */
else
{
freq = CLOCK_GetPeriphClkFreq();
}
freq /= (((CCM->CBCDR & CCM_CBCDR_SEMC_PODF_MASK) >> CCM_CBCDR_SEMC_PODF_SHIFT) + 1U);
break;
case kCLOCK_IpgClk:
/* Periph_clk ---> AHB Clock ---> IPG Clock */
freq = CLOCK_GetPeriphClkFreq() / (((CCM->CBCDR & CCM_CBCDR_AHB_PODF_MASK) >> CCM_CBCDR_AHB_PODF_SHIFT) + 1U);
freq /= (((CCM->CBCDR & CCM_CBCDR_IPG_PODF_MASK) >> CCM_CBCDR_IPG_PODF_SHIFT) + 1U);
break;
case kCLOCK_OscClk:
freq = CLOCK_GetOscFreq();
break;
case kCLOCK_RtcClk:
freq = CLOCK_GetRtcFreq();
break;
case kCLOCK_ArmPllClk:
freq = CLOCK_GetPllFreq(kCLOCK_PllArm);
break;
case kCLOCK_Usb1PllClk:
freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1);
break;
case kCLOCK_Usb1PllPfd0Clk:
freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd0);
break;
case kCLOCK_Usb1PllPfd1Clk:
freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd1);
break;
case kCLOCK_Usb1PllPfd2Clk:
freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd2);
break;
case kCLOCK_Usb1PllPfd3Clk:
freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd3);
break;
case kCLOCK_Usb2PllClk:
freq = CLOCK_GetPllFreq(kCLOCK_PllUsb2);
break;
case kCLOCK_SysPllClk:
freq = CLOCK_GetPllFreq(kCLOCK_PllSys);
break;
case kCLOCK_SysPllPfd0Clk:
freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd0);
break;
case kCLOCK_SysPllPfd1Clk:
freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd1);
break;
case kCLOCK_SysPllPfd2Clk:
freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd2);
break;
case kCLOCK_SysPllPfd3Clk:
freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd3);
break;
case kCLOCK_EnetPll0Clk:
freq = CLOCK_GetPllFreq(kCLOCK_PllEnet0);
break;
case kCLOCK_EnetPll1Clk:
freq = CLOCK_GetPllFreq(kCLOCK_PllEnet1);
break;
case kCLOCK_AudioPllClk:
freq = CLOCK_GetPllFreq(kCLOCK_PllAudio);
break;
case kCLOCK_VideoPllClk:
freq = CLOCK_GetPllFreq(kCLOCK_PllVideo);
break;
default:
freq = 0U;
break;
}
return freq;
}
void CLOCK_InitArmPll(const clock_arm_pll_config_t *config)
{
CCM_ANALOG->PLL_ARM = CCM_ANALOG_PLL_ARM_ENABLE_MASK |
CCM_ANALOG_PLL_ARM_DIV_SELECT(config->loopDivider);
while ((CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_LOCK_MASK) == 0)
{
}
}
void CLOCK_DeinitArmPll(void)
{
CCM_ANALOG->PLL_ARM = CCM_ANALOG_PLL_ARM_POWERDOWN_MASK;
}
void CLOCK_InitSysPll(const clock_sys_pll_config_t *config)
{
CCM_ANALOG->PLL_SYS = CCM_ANALOG_PLL_SYS_ENABLE_MASK |
CCM_ANALOG_PLL_SYS_DIV_SELECT(config->loopDivider);
while ((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_LOCK_MASK) == 0)
{
}
}
void CLOCK_DeinitSysPll(void)
{
CCM_ANALOG->PLL_SYS = CCM_ANALOG_PLL_SYS_POWERDOWN_MASK;
}
void CLOCK_InitUsb1Pll(const clock_usb_pll_config_t *config)
{
CCM_ANALOG->PLL_USB1 = CCM_ANALOG_PLL_USB1_ENABLE_MASK |
CCM_ANALOG_PLL_USB1_POWER_MASK |
CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK |
CCM_ANALOG_PLL_USB1_DIV_SELECT(config->loopDivider);
while ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_LOCK_MASK) == 0)
{
}
}
void CLOCK_DeinitUsb1Pll(void)
{
CCM_ANALOG->PLL_USB1 = 0U;
}
void CLOCK_InitUsb2Pll(const clock_usb_pll_config_t *config)
{
CCM_ANALOG->PLL_USB2 = CCM_ANALOG_PLL_USB2_ENABLE_MASK |
CCM_ANALOG_PLL_USB2_POWER_MASK |
CCM_ANALOG_PLL_USB2_EN_USB_CLKS_MASK |
CCM_ANALOG_PLL_USB2_DIV_SELECT(config->loopDivider);
while ((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_LOCK_MASK) == 0)
{
}
}
void CLOCK_DeinitUsb2Pll(void)
{
CCM_ANALOG->PLL_USB2 = 0U;
}
void CLOCK_InitAudioPll(const clock_audio_pll_config_t *config)
{
uint32_t pllAudio;
uint32_t misc2 = 0;
CCM_ANALOG->PLL_AUDIO_NUM = CCM_ANALOG_PLL_AUDIO_NUM_A(config->numerator);
CCM_ANALOG->PLL_AUDIO_DENOM = CCM_ANALOG_PLL_AUDIO_DENOM_B(config->denominator);
/*
* Set post divider:
*
* ------------------------------------------------------------------------
* | config->postDivider | PLL_AUDIO[POST_DIV_SELECT] | MISC2[AUDIO_DIV] |
* ------------------------------------------------------------------------
* | 1 | 2 | 0 |
* ------------------------------------------------------------------------
* | 2 | 1 | 0 |
* ------------------------------------------------------------------------
* | 4 | 2 | 3 |
* ------------------------------------------------------------------------
* | 8 | 1 | 3 |
* ------------------------------------------------------------------------
* | 16 | 0 | 3 |
* ------------------------------------------------------------------------
*/
pllAudio = CCM_ANALOG_PLL_AUDIO_ENABLE_MASK | CCM_ANALOG_PLL_AUDIO_DIV_SELECT(config->loopDivider);
switch (config->postDivider)
{
case 16:
pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(0);
misc2 = CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK;
break;
case 8:
pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1);
misc2 = CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK;
break;
case 4:
pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2);
misc2 = CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK;
break;
case 2:
pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1);
break;
default:
pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2);
break;
}
CCM_ANALOG->MISC2 = (CCM_ANALOG->MISC2 & ~(CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK))
| misc2;
CCM_ANALOG->PLL_AUDIO = pllAudio;
while ((CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_LOCK_MASK) == 0)
{
}
}
void CLOCK_DeinitAudioPll(void)
{
CCM_ANALOG->PLL_AUDIO = CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK;
}
void CLOCK_InitVideoPll(const clock_video_pll_config_t *config)
{
uint32_t pllVideo;
uint32_t misc2 = 0;
CCM_ANALOG->PLL_VIDEO_NUM = CCM_ANALOG_PLL_VIDEO_NUM_A(config->numerator);
CCM_ANALOG->PLL_VIDEO_DENOM = CCM_ANALOG_PLL_VIDEO_DENOM_B(config->denominator);
/*
* Set post divider:
*
* ------------------------------------------------------------------------
* | config->postDivider | PLL_VIDEO[POST_DIV_SELECT] | MISC2[VIDEO_DIV] |
* ------------------------------------------------------------------------
* | 1 | 2 | 0 |
* ------------------------------------------------------------------------
* | 2 | 1 | 0 |
* ------------------------------------------------------------------------
* | 4 | 2 | 3 |
* ------------------------------------------------------------------------
* | 8 | 1 | 3 |
* ------------------------------------------------------------------------
* | 16 | 0 | 3 |
* ------------------------------------------------------------------------
*/
pllVideo = CCM_ANALOG_PLL_VIDEO_ENABLE_MASK | CCM_ANALOG_PLL_VIDEO_DIV_SELECT(config->loopDivider);
switch (config->postDivider)
{
case 16:
pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(0);
misc2 = CCM_ANALOG_MISC2_VIDEO_DIV(3);
break;
case 8:
pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1);
misc2 = CCM_ANALOG_MISC2_VIDEO_DIV(3);
break;
case 4:
pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(2);
misc2 = CCM_ANALOG_MISC2_VIDEO_DIV(3);
break;
case 2:
pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1);
break;
default:
pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(2);
break;
}
CCM_ANALOG->MISC2 = (CCM_ANALOG->MISC2 & ~CCM_ANALOG_MISC2_VIDEO_DIV_MASK) | misc2;
CCM_ANALOG->PLL_VIDEO = pllVideo;
while ((CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) == 0)
{
}
}
void CLOCK_DeinitVideoPll(void)
{
CCM_ANALOG->PLL_VIDEO = CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK;
}
void CLOCK_InitEnetPll(const clock_enet_pll_config_t *config)
{
uint32_t enet_pll = CCM_ANALOG_PLL_ENET_DIV_SELECT(config->loopDivider);
if (config->enableClkOutput0)
{
enet_pll |= CCM_ANALOG_PLL_ENET_ENABLE_MASK;
}
if (config->enableClkOutput1)
{
enet_pll |= CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_MASK;
}
CCM_ANALOG->PLL_ENET = enet_pll;
/* Wait for stable */
while ((CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_LOCK_MASK) == 0)
{
}
}
void CLOCK_DeinitEnetPll(void)
{
CCM_ANALOG->PLL_ENET = CCM_ANALOG_PLL_ENET_POWERDOWN_MASK;
}
uint32_t CLOCK_GetPllFreq(clock_pll_t pll)
{
uint32_t freq;
uint32_t divSelect;
uint64_t freqTmp;
const uint32_t enetRefClkFreq[] = {
25000000U, /* 25M */
50000000U, /* 50M */
100000000U, /* 100M */
125000000U /* 125M */
};
/* check if PLL is enabled */
if(!CLOCK_IsPllEnabled(CCM_ANALOG, pll))
{
return 0U;
}
/* get pll reference clock */
freq = CLOCK_GetPllBypassRefClk(CCM_ANALOG, pll);
/* check if pll is bypassed */
if(CLOCK_IsPllBypassed(CCM_ANALOG, pll))
{
return freq;
}
switch (pll)
{
case kCLOCK_PllArm:
freq = ((freq * ((CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK) >>
CCM_ANALOG_PLL_ARM_DIV_SELECT_SHIFT)) >> 1U);
break;
case kCLOCK_PllSys:
/* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */
freqTmp = ((uint64_t)freq * ((uint64_t)(CCM_ANALOG->PLL_SYS_NUM))) / ((uint64_t)(CCM_ANALOG->PLL_SYS_DENOM));
if (CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_DIV_SELECT_MASK)
{
freq *= 22U;
}
else
{
freq *= 20U;
}
freq += (uint32_t)freqTmp;
break;
case kCLOCK_PllUsb1:
freq = (freq * ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK) ? 22U : 20U));
break;
case kCLOCK_PllAudio:
/* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */
divSelect = (CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_AUDIO_DIV_SELECT_SHIFT;
freqTmp = ((uint64_t)freq * ((uint64_t)(CCM_ANALOG->PLL_AUDIO_NUM))) / ((uint64_t)(CCM_ANALOG->PLL_AUDIO_DENOM));
freq = freq * divSelect + (uint32_t)freqTmp;
/* AUDIO PLL output = PLL output frequency / POSTDIV. */
/*
* Post divider:
*
* PLL_AUDIO[POST_DIV_SELECT]:
* 0x00: 4
* 0x01: 2
* 0x02: 1
*
* MISC2[AUDO_DIV]:
* 0x00: 1
* 0x01: 2
* 0x02: 1
* 0x03: 4
*/
switch (CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT_MASK)
{
case CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(0U):
freq = freq >> 2U;
break;
case CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1U):
freq = freq >> 1U;
break;
default:
break;
}
switch (CCM_ANALOG->MISC2 & (CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK))
{
case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(1) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(1):
freq >>= 2U;
break;
case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(0) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(1):
freq >>= 1U;
break;
default:
break;
}
break;
case kCLOCK_PllVideo:
/* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */
divSelect = (CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_VIDEO_DIV_SELECT_SHIFT;
freqTmp = ((uint64_t)freq * ((uint64_t)(CCM_ANALOG->PLL_VIDEO_NUM))) / ((uint64_t)(CCM_ANALOG->PLL_VIDEO_DENOM));
freq = freq * divSelect + (uint32_t)freqTmp;
/* VIDEO PLL output = PLL output frequency / POSTDIV. */
/*
* Post divider:
*
* PLL_VIDEO[POST_DIV_SELECT]:
* 0x00: 4
* 0x01: 2
* 0x02: 1
*
* MISC2[VIDEO_DIV]:
* 0x00: 1
* 0x01: 2
* 0x02: 1
* 0x03: 4
*/
switch (CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT_MASK)
{
case CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(0U):
freq = freq >> 2U;
break;
case CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1U):
freq = freq >> 1U;
break;
default:
break;
}
switch (CCM_ANALOG->MISC2 & CCM_ANALOG_MISC2_VIDEO_DIV_MASK)
{
case CCM_ANALOG_MISC2_VIDEO_DIV(3):
freq >>= 2U;
break;
case CCM_ANALOG_MISC2_VIDEO_DIV(1):
freq >>= 1U;
break;
default:
break;
}
break;
case kCLOCK_PllEnet0:
divSelect = (CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK)
>> CCM_ANALOG_PLL_ENET_DIV_SELECT_SHIFT;
freq = enetRefClkFreq[divSelect];
break;
case kCLOCK_PllEnet1:
/* ref_enetpll1 if fixed at 25MHz. */
freq = 25000000UL;
break;
case kCLOCK_PllUsb2:
freq = (freq * ((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_DIV_SELECT_MASK) ? 22U : 20U));
break;
default:
freq = 0U;
break;
}
return freq;
}
void CLOCK_InitSysPfd(clock_pfd_t pfd, uint8_t pfdFrac)
{
uint32_t pfdIndex = (uint32_t)pfd;
uint32_t pfd528;
pfd528 = CCM_ANALOG->PFD_528 & ~((CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK | CCM_ANALOG_PFD_528_PFD0_FRAC_MASK) << (8 * pfdIndex));
/* Disable the clock output first. */
CCM_ANALOG->PFD_528 = pfd528 | (CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK << (8 * pfdIndex));
/* Set the new value and enable output. */
CCM_ANALOG->PFD_528 = pfd528 | (CCM_ANALOG_PFD_528_PFD0_FRAC(pfdFrac) << (8 * pfdIndex));
}
void CLOCK_DeinitSysPfd(clock_pfd_t pfd)
{
CCM_ANALOG->PFD_528 |= CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK << (8 * pfd);
}
void CLOCK_InitUsb1Pfd(clock_pfd_t pfd, uint8_t pfdFrac)
{
uint32_t pfdIndex = (uint32_t)pfd;
uint32_t pfd480;
pfd480 = CCM_ANALOG->PFD_480 & ~((CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK | CCM_ANALOG_PFD_480_PFD0_FRAC_MASK) << (8 * pfdIndex));
/* Disable the clock output first. */
CCM_ANALOG->PFD_480 = pfd480 | (CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK << (8 * pfdIndex));
/* Set the new value and enable output. */
CCM_ANALOG->PFD_480 = pfd480 | (CCM_ANALOG_PFD_480_PFD0_FRAC(pfdFrac) << (8 * pfdIndex));
}
void CLOCK_DeinitUsb1Pfd(clock_pfd_t pfd)
{
CCM_ANALOG->PFD_480 |= CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK << (8 * pfd);
}
uint32_t CLOCK_GetSysPfdFreq(clock_pfd_t pfd)
{
uint32_t freq = CLOCK_GetPllFreq(kCLOCK_PllSys);
switch (pfd)
{
case kCLOCK_Pfd0:
freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD0_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD0_FRAC_SHIFT);
break;
case kCLOCK_Pfd1:
freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD1_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD1_FRAC_SHIFT);
break;
case kCLOCK_Pfd2:
freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD2_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD2_FRAC_SHIFT);
break;
case kCLOCK_Pfd3:
freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD3_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD3_FRAC_SHIFT);
break;
default:
freq = 0U;
break;
}
freq *= 18U;
return freq;
}
uint32_t CLOCK_GetUsb1PfdFreq(clock_pfd_t pfd)
{
uint32_t freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1);
switch (pfd)
{
case kCLOCK_Pfd0:
freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD0_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD0_FRAC_SHIFT);
break;
case kCLOCK_Pfd1:
freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD1_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD1_FRAC_SHIFT);
break;
case kCLOCK_Pfd2:
freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD2_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD2_FRAC_SHIFT);
break;
case kCLOCK_Pfd3:
freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD3_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD3_FRAC_SHIFT);
break;
default:
freq = 0U;
break;
}
freq *= 18U;
return freq;
}
bool CLOCK_EnableUsbhs0Clock(clock_usb_src_t src, uint32_t freq)
{
CCM->CCGR6 |= CCM_CCGR6_CG0_MASK ;
USB1->USBCMD |= USBHS_USBCMD_RST_MASK;
for (volatile uint32_t i = 0; i < 400000; i++) /* Add a delay between RST and RS so make sure there is a DP pullup sequence*/
{
__ASM("nop");
}
PMU->REG_3P0 = (PMU->REG_3P0 & (~PMU_REG_3P0_OUTPUT_TRG_MASK)) | (PMU_REG_3P0_OUTPUT_TRG(0x17) | PMU_REG_3P0_ENABLE_LINREG_MASK);
return true;
}
bool CLOCK_EnableUsbhs1Clock(clock_usb_src_t src, uint32_t freq)
{
CCM->CCGR6 |= CCM_CCGR6_CG0_MASK ;
USB2->USBCMD |= USBHS_USBCMD_RST_MASK;
for (volatile uint32_t i = 0; i < 400000; i++) /* Add a delay between RST and RS so make sure there is a DP pullup sequence*/
{
__ASM("nop");
}
PMU->REG_3P0 = (PMU->REG_3P0 & (~PMU_REG_3P0_OUTPUT_TRG_MASK)) | (PMU_REG_3P0_OUTPUT_TRG(0x17) | PMU_REG_3P0_ENABLE_LINREG_MASK);
return true;
}
bool CLOCK_EnableUsbhs0PhyPllClock(clock_usb_phy_src_t src, uint32_t freq)
{
const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U};
CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll);
USBPHY1->CTRL &= ~USBPHY_CTRL_SFTRST_MASK; /* release PHY from reset */
USBPHY1->CTRL &= ~USBPHY_CTRL_CLKGATE_MASK;
USBPHY1->PWD = 0;
USBPHY1->CTRL |=
USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK |
USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK |
USBPHY_CTRL_ENUTMILEVEL2_MASK |
USBPHY_CTRL_ENUTMILEVEL3_MASK;
return true;
}
bool CLOCK_EnableUsbhs1PhyPllClock(clock_usb_phy_src_t src, uint32_t freq)
{
const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U};
CLOCK_InitUsb2Pll(&g_ccmConfigUsbPll);
USBPHY2->CTRL &= ~USBPHY_CTRL_SFTRST_MASK; /* release PHY from reset */
USBPHY2->CTRL &= ~USBPHY_CTRL_CLKGATE_MASK;
USBPHY2->PWD = 0;
USBPHY2->CTRL |=
USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK |
USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK |
USBPHY_CTRL_ENUTMILEVEL2_MASK |
USBPHY_CTRL_ENUTMILEVEL3_MASK;
return true;
}
void CLOCK_DisableUsbhs0PhyPllClock(void)
{
CLOCK_DeinitUsb1Pll();
USBPHY1->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* Set to 1U to gate clocks */
}
void CLOCK_DisableUsbhs1PhyPllClock(void)
{
CLOCK_DeinitUsb2Pll();
USBPHY2->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* Set to 1U to gate clocks */
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,289 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#include "fsl_cmp.h"
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get instance number for CMP module.
*
* @param base CMP peripheral base address
*/
static uint32_t CMP_GetInstance(CMP_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to CMP bases for each instance. */
static CMP_Type *const s_cmpBases[] = CMP_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to CMP clocks for each instance. */
static const clock_ip_name_t s_cmpClocks[] = CMP_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*******************************************************************************
* Codes
******************************************************************************/
static uint32_t CMP_GetInstance(CMP_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_cmpBases); instance++)
{
if (s_cmpBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_cmpBases));
return instance;
}
void CMP_Init(CMP_Type *base, const cmp_config_t *config)
{
assert(NULL != config);
uint8_t tmp8;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the clock. */
CLOCK_EnableClock(s_cmpClocks[CMP_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Configure. */
CMP_Enable(base, false); /* Disable the CMP module during configuring. */
/* CMPx_CR1. */
tmp8 = base->CR1 & ~(CMP_CR1_PMODE_MASK | CMP_CR1_INV_MASK | CMP_CR1_COS_MASK | CMP_CR1_OPE_MASK);
if (config->enableHighSpeed)
{
tmp8 |= CMP_CR1_PMODE_MASK;
}
if (config->enableInvertOutput)
{
tmp8 |= CMP_CR1_INV_MASK;
}
if (config->useUnfilteredOutput)
{
tmp8 |= CMP_CR1_COS_MASK;
}
if (config->enablePinOut)
{
tmp8 |= CMP_CR1_OPE_MASK;
}
#if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE
if (config->enableTriggerMode)
{
tmp8 |= CMP_CR1_TRIGM_MASK;
}
else
{
tmp8 &= ~CMP_CR1_TRIGM_MASK;
}
#endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */
base->CR1 = tmp8;
/* CMPx_CR0. */
tmp8 = base->CR0 & ~CMP_CR0_HYSTCTR_MASK;
tmp8 |= CMP_CR0_HYSTCTR(config->hysteresisMode);
base->CR0 = tmp8;
CMP_Enable(base, config->enableCmp); /* Enable the CMP module after configured or not. */
}
void CMP_Deinit(CMP_Type *base)
{
/* Disable the CMP module. */
CMP_Enable(base, false);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable the clock. */
CLOCK_DisableClock(s_cmpClocks[CMP_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
void CMP_GetDefaultConfig(cmp_config_t *config)
{
assert(NULL != config);
config->enableCmp = true; /* Enable the CMP module after initialization. */
config->hysteresisMode = kCMP_HysteresisLevel0;
config->enableHighSpeed = false;
config->enableInvertOutput = false;
config->useUnfilteredOutput = false;
config->enablePinOut = false;
#if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE
config->enableTriggerMode = false;
#endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */
}
void CMP_SetInputChannels(CMP_Type *base, uint8_t positiveChannel, uint8_t negativeChannel)
{
uint8_t tmp8 = base->MUXCR;
tmp8 &= ~(CMP_MUXCR_PSEL_MASK | CMP_MUXCR_MSEL_MASK);
tmp8 |= CMP_MUXCR_PSEL(positiveChannel) | CMP_MUXCR_MSEL(negativeChannel);
base->MUXCR = tmp8;
}
#if defined(FSL_FEATURE_CMP_HAS_DMA) && FSL_FEATURE_CMP_HAS_DMA
void CMP_EnableDMA(CMP_Type *base, bool enable)
{
uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */
if (enable)
{
tmp8 |= CMP_SCR_DMAEN_MASK;
}
else
{
tmp8 &= ~CMP_SCR_DMAEN_MASK;
}
base->SCR = tmp8;
}
#endif /* FSL_FEATURE_CMP_HAS_DMA */
void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config)
{
assert(NULL != config);
uint8_t tmp8;
#if defined(FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT) && FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT
/* Choose the clock source for sampling. */
if (config->enableSample)
{
base->CR1 |= CMP_CR1_SE_MASK; /* Choose the external SAMPLE clock. */
}
else
{
base->CR1 &= ~CMP_CR1_SE_MASK; /* Choose the internal divided bus clock. */
}
#endif /* FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT */
/* Set the filter count. */
tmp8 = base->CR0 & ~CMP_CR0_FILTER_CNT_MASK;
tmp8 |= CMP_CR0_FILTER_CNT(config->filterCount);
base->CR0 = tmp8;
/* Set the filter period. It is used as the divider to bus clock. */
base->FPR = CMP_FPR_FILT_PER(config->filterPeriod);
}
void CMP_SetDACConfig(CMP_Type *base, const cmp_dac_config_t *config)
{
uint8_t tmp8 = 0U;
if (NULL == config)
{
/* Passing "NULL" as input parameter means no available configuration. So the DAC feature is disabled.*/
base->DACCR = 0U;
return;
}
/* CMPx_DACCR. */
tmp8 |= CMP_DACCR_DACEN_MASK; /* Enable the internal DAC. */
if (kCMP_VrefSourceVin2 == config->referenceVoltageSource)
{
tmp8 |= CMP_DACCR_VRSEL_MASK;
}
tmp8 |= CMP_DACCR_VOSEL(config->DACValue);
base->DACCR = tmp8;
}
void CMP_EnableInterrupts(CMP_Type *base, uint32_t mask)
{
uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */
if (0U != (kCMP_OutputRisingInterruptEnable & mask))
{
tmp8 |= CMP_SCR_IER_MASK;
}
if (0U != (kCMP_OutputFallingInterruptEnable & mask))
{
tmp8 |= CMP_SCR_IEF_MASK;
}
base->SCR = tmp8;
}
void CMP_DisableInterrupts(CMP_Type *base, uint32_t mask)
{
uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */
if (0U != (kCMP_OutputRisingInterruptEnable & mask))
{
tmp8 &= ~CMP_SCR_IER_MASK;
}
if (0U != (kCMP_OutputFallingInterruptEnable & mask))
{
tmp8 &= ~CMP_SCR_IEF_MASK;
}
base->SCR = tmp8;
}
uint32_t CMP_GetStatusFlags(CMP_Type *base)
{
uint32_t ret32 = 0U;
if (0U != (CMP_SCR_CFR_MASK & base->SCR))
{
ret32 |= kCMP_OutputRisingEventFlag;
}
if (0U != (CMP_SCR_CFF_MASK & base->SCR))
{
ret32 |= kCMP_OutputFallingEventFlag;
}
if (0U != (CMP_SCR_COUT_MASK & base->SCR))
{
ret32 |= kCMP_OutputAssertEventFlag;
}
return ret32;
}
void CMP_ClearStatusFlags(CMP_Type *base, uint32_t mask)
{
uint8_t tmp8 = base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK); /* To avoid change the w1c bits. */
if (0U != (kCMP_OutputRisingEventFlag & mask))
{
tmp8 |= CMP_SCR_CFR_MASK;
}
if (0U != (kCMP_OutputFallingEventFlag & mask))
{
tmp8 |= CMP_SCR_CFF_MASK;
}
base->SCR = tmp8;
}

View File

@@ -0,0 +1,347 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#ifndef _FSL_CMP_H_
#define _FSL_CMP_H_
#include "fsl_common.h"
/*!
* @addtogroup cmp
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief CMP driver version 2.0.0. */
#define FSL_CMP_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
/*@}*/
/*!
* @brief Interrupt enable/disable mask.
*/
enum _cmp_interrupt_enable
{
kCMP_OutputRisingInterruptEnable = CMP_SCR_IER_MASK, /*!< Comparator interrupt enable rising. */
kCMP_OutputFallingInterruptEnable = CMP_SCR_IEF_MASK, /*!< Comparator interrupt enable falling. */
};
/*!
* @brief Status flags' mask.
*/
enum _cmp_status_flags
{
kCMP_OutputRisingEventFlag = CMP_SCR_CFR_MASK, /*!< Rising-edge on the comparison output has occurred. */
kCMP_OutputFallingEventFlag = CMP_SCR_CFF_MASK, /*!< Falling-edge on the comparison output has occurred. */
kCMP_OutputAssertEventFlag = CMP_SCR_COUT_MASK, /*!< Return the current value of the analog comparator output. */
};
/*!
* @brief CMP Hysteresis mode.
*/
typedef enum _cmp_hysteresis_mode
{
kCMP_HysteresisLevel0 = 0U, /*!< Hysteresis level 0. */
kCMP_HysteresisLevel1 = 1U, /*!< Hysteresis level 1. */
kCMP_HysteresisLevel2 = 2U, /*!< Hysteresis level 2. */
kCMP_HysteresisLevel3 = 3U, /*!< Hysteresis level 3. */
} cmp_hysteresis_mode_t;
/*!
* @brief CMP Voltage Reference source.
*/
typedef enum _cmp_reference_voltage_source
{
kCMP_VrefSourceVin1 = 0U, /*!< Vin1 is selected as a resistor ladder network supply reference Vin. */
kCMP_VrefSourceVin2 = 1U, /*!< Vin2 is selected as a resistor ladder network supply reference Vin. */
} cmp_reference_voltage_source_t;
/*!
* @brief Configures the comparator.
*/
typedef struct _cmp_config
{
bool enableCmp; /*!< Enable the CMP module. */
cmp_hysteresis_mode_t hysteresisMode; /*!< CMP Hysteresis mode. */
bool enableHighSpeed; /*!< Enable High-speed (HS) comparison mode. */
bool enableInvertOutput; /*!< Enable the inverted comparator output. */
bool useUnfilteredOutput; /*!< Set the compare output(COUT) to equal COUTA(true) or COUT(false). */
bool enablePinOut; /*!< The comparator output is available on the associated pin. */
#if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE
bool enableTriggerMode; /*!< Enable the trigger mode. */
#endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */
} cmp_config_t;
/*!
* @brief Configures the filter.
*/
typedef struct _cmp_filter_config
{
#if defined(FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT) && FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT
bool enableSample; /*!< Using the external SAMPLE as a sampling clock input or using a divided bus clock. */
#endif /* FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT */
uint8_t filterCount; /*!< Filter Sample Count. Available range is 1-7; 0 disables the filter.*/
uint8_t filterPeriod; /*!< Filter Sample Period. The divider to the bus clock. Available range is 0-255. */
} cmp_filter_config_t;
/*!
* @brief Configures the internal DAC.
*/
typedef struct _cmp_dac_config
{
cmp_reference_voltage_source_t referenceVoltageSource; /*!< Supply voltage reference source. */
uint8_t DACValue; /*!< Value for the DAC Output Voltage. Available range is 0-63.*/
} cmp_dac_config_t;
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* API
******************************************************************************/
/*!
* @name Initialization
* @{
*/
/*!
* @brief Initializes the CMP.
*
* This function initializes the CMP module. The operations included are as follows.
* - Enabling the clock for CMP module.
* - Configuring the comparator.
* - Enabling the CMP module.
* Note that for some devices, multiple CMP instances share the same clock gate. In this case, to enable the clock for
* any instance enables all CMPs. See the appropriate MCU reference manual for the clock assignment of the CMP.
*
* @param base CMP peripheral base address.
* @param config Pointer to the configuration structure.
*/
void CMP_Init(CMP_Type *base, const cmp_config_t *config);
/*!
* @brief De-initializes the CMP module.
*
* This function de-initializes the CMP module. The operations included are as follows.
* - Disabling the CMP module.
* - Disabling the clock for CMP module.
*
* This function disables the clock for the CMP.
* Note that for some devices, multiple CMP instances share the same clock gate. In this case, before disabling the
* clock for the CMP, ensure that all the CMP instances are not used.
*
* @param base CMP peripheral base address.
*/
void CMP_Deinit(CMP_Type *base);
/*!
* @brief Enables/disables the CMP module.
*
* @param base CMP peripheral base address.
* @param enable Enables or disables the module.
*/
static inline void CMP_Enable(CMP_Type *base, bool enable)
{
if (enable)
{
base->CR1 |= CMP_CR1_EN_MASK;
}
else
{
base->CR1 &= ~CMP_CR1_EN_MASK;
}
}
/*!
* @brief Initializes the CMP user configuration structure.
*
* This function initializes the user configuration structure to these default values.
* @code
* config->enableCmp = true;
* config->hysteresisMode = kCMP_HysteresisLevel0;
* config->enableHighSpeed = false;
* config->enableInvertOutput = false;
* config->useUnfilteredOutput = false;
* config->enablePinOut = false;
* config->enableTriggerMode = false;
* @endcode
* @param config Pointer to the configuration structure.
*/
void CMP_GetDefaultConfig(cmp_config_t *config);
/*!
* @brief Sets the input channels for the comparator.
*
* This function sets the input channels for the comparator.
* Note that two input channels cannot be set the same way in the application. When the user selects the same input
* from the analog mux to the positive and negative port, the comparator is disabled automatically.
*
* @param base CMP peripheral base address.
* @param positiveChannel Positive side input channel number. Available range is 0-7.
* @param negativeChannel Negative side input channel number. Available range is 0-7.
*/
void CMP_SetInputChannels(CMP_Type *base, uint8_t positiveChannel, uint8_t negativeChannel);
/* @} */
/*!
* @name Advanced Features
* @{
*/
#if defined(FSL_FEATURE_CMP_HAS_DMA) && FSL_FEATURE_CMP_HAS_DMA
/*!
* @brief Enables/disables the DMA request for rising/falling events.
*
* This function enables/disables the DMA request for rising/falling events. Either event triggers the generation of
* the DMA request from CMP if the DMA feature is enabled. Both events are ignored for generating the DMA request from the CMP
* if the DMA is disabled.
*
* @param base CMP peripheral base address.
* @param enable Enables or disables the feature.
*/
void CMP_EnableDMA(CMP_Type *base, bool enable);
#endif /* FSL_FEATURE_CMP_HAS_DMA */
#if defined(FSL_FEATURE_CMP_HAS_WINDOW_MODE) && FSL_FEATURE_CMP_HAS_WINDOW_MODE
/*!
* @brief Enables/disables the window mode.
*
* @param base CMP peripheral base address.
* @param enable Enables or disables the feature.
*/
static inline void CMP_EnableWindowMode(CMP_Type *base, bool enable)
{
if (enable)
{
base->CR1 |= CMP_CR1_WE_MASK;
}
else
{
base->CR1 &= ~CMP_CR1_WE_MASK;
}
}
#endif /* FSL_FEATURE_CMP_HAS_WINDOW_MODE */
#if defined(FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE) && FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE
/*!
* @brief Enables/disables the pass through mode.
*
* @param base CMP peripheral base address.
* @param enable Enables or disables the feature.
*/
static inline void CMP_EnablePassThroughMode(CMP_Type *base, bool enable)
{
if (enable)
{
base->MUXCR |= CMP_MUXCR_PSTM_MASK;
}
else
{
base->MUXCR &= ~CMP_MUXCR_PSTM_MASK;
}
}
#endif /* FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE */
/*!
* @brief Configures the filter.
*
* @param base CMP peripheral base address.
* @param config Pointer to the configuration structure.
*/
void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config);
/*!
* @brief Configures the internal DAC.
*
* @param base CMP peripheral base address.
* @param config Pointer to the configuration structure. "NULL" disables the feature.
*/
void CMP_SetDACConfig(CMP_Type *base, const cmp_dac_config_t *config);
/*!
* @brief Enables the interrupts.
*
* @param base CMP peripheral base address.
* @param mask Mask value for interrupts. See "_cmp_interrupt_enable".
*/
void CMP_EnableInterrupts(CMP_Type *base, uint32_t mask);
/*!
* @brief Disables the interrupts.
*
* @param base CMP peripheral base address.
* @param mask Mask value for interrupts. See "_cmp_interrupt_enable".
*/
void CMP_DisableInterrupts(CMP_Type *base, uint32_t mask);
/* @} */
/*!
* @name Results
* @{
*/
/*!
* @brief Gets the status flags.
*
* @param base CMP peripheral base address.
*
* @return Mask value for the asserted flags. See "_cmp_status_flags".
*/
uint32_t CMP_GetStatusFlags(CMP_Type *base);
/*!
* @brief Clears the status flags.
*
* @param base CMP peripheral base address.
* @param mask Mask value for the flags. See "_cmp_status_flags".
*/
void CMP_ClearStatusFlags(CMP_Type *base, uint32_t mask);
/* @} */
#if defined(__cplusplus)
}
#endif
/*!
* @}
*/
#endif /* _FSL_CMP_H_ */

View File

@@ -0,0 +1,166 @@
/*
* The Clear BSD License
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016 NXP
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#include "fsl_common.h"
#define SDK_MEM_MAGIC_NUMBER 12345U
typedef struct _mem_align_control_block
{
uint16_t identifier; /*!< Identifier for the memory control block. */
uint16_t offset; /*!< offset from aligned adress to real address */
} mem_align_cb_t;
#ifndef __GIC_PRIO_BITS
#if defined(ENABLE_RAM_VECTOR_TABLE)
uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler)
{
/* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */
#if defined(__CC_ARM)
extern uint32_t Image$$VECTOR_ROM$$Base[];
extern uint32_t Image$$VECTOR_RAM$$Base[];
extern uint32_t Image$$RW_m_data$$Base[];
#define __VECTOR_TABLE Image$$VECTOR_ROM$$Base
#define __VECTOR_RAM Image$$VECTOR_RAM$$Base
#define __RAM_VECTOR_TABLE_SIZE (((uint32_t)Image$$RW_m_data$$Base - (uint32_t)Image$$VECTOR_RAM$$Base))
#elif defined(__ICCARM__)
extern uint32_t __RAM_VECTOR_TABLE_SIZE[];
extern uint32_t __VECTOR_TABLE[];
extern uint32_t __VECTOR_RAM[];
#elif defined(__GNUC__)
extern uint32_t __VECTOR_TABLE[];
extern uint32_t __VECTOR_RAM[];
extern uint32_t __RAM_VECTOR_TABLE_SIZE_BYTES[];
uint32_t __RAM_VECTOR_TABLE_SIZE = (uint32_t)(__RAM_VECTOR_TABLE_SIZE_BYTES);
#endif /* defined(__CC_ARM) */
uint32_t n;
uint32_t ret;
uint32_t irqMaskValue;
irqMaskValue = DisableGlobalIRQ();
if (SCB->VTOR != (uint32_t)__VECTOR_RAM)
{
/* Copy the vector table from ROM to RAM */
for (n = 0; n < ((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t); n++)
{
__VECTOR_RAM[n] = __VECTOR_TABLE[n];
}
/* Point the VTOR to the position of vector table */
SCB->VTOR = (uint32_t)__VECTOR_RAM;
}
ret = __VECTOR_RAM[irq + 16];
/* make sure the __VECTOR_RAM is noncachable */
__VECTOR_RAM[irq + 16] = irqHandler;
EnableGlobalIRQ(irqMaskValue);
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
return ret;
}
#endif /* ENABLE_RAM_VECTOR_TABLE. */
#endif /* __GIC_PRIO_BITS. */
#ifndef QN908XC_SERIES
#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
void EnableDeepSleepIRQ(IRQn_Type interrupt)
{
uint32_t index = 0;
uint32_t intNumber = (uint32_t)interrupt;
while (intNumber >= 32u)
{
index++;
intNumber -= 32u;
}
SYSCON->STARTERSET[index] = 1u << intNumber;
EnableIRQ(interrupt); /* also enable interrupt at NVIC */
}
void DisableDeepSleepIRQ(IRQn_Type interrupt)
{
uint32_t index = 0;
uint32_t intNumber = (uint32_t)interrupt;
while (intNumber >= 32u)
{
index++;
intNumber -= 32u;
}
DisableIRQ(interrupt); /* also disable interrupt at NVIC */
SYSCON->STARTERCLR[index] = 1u << intNumber;
}
#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
#endif /* QN908XC_SERIES */
void *SDK_Malloc(size_t size, size_t alignbytes)
{
mem_align_cb_t *p_cb = NULL;
uint32_t alignedsize = SDK_SIZEALIGN(size, alignbytes) + alignbytes + sizeof(mem_align_cb_t);
void *p_align_addr, *p_addr = malloc(alignedsize);
if (!p_addr)
{
return NULL;
}
p_align_addr = (void *)SDK_SIZEALIGN((uint32_t)p_addr + sizeof(mem_align_cb_t), alignbytes);
p_cb = (mem_align_cb_t *)((uint32_t)p_align_addr - 4);
p_cb->identifier = SDK_MEM_MAGIC_NUMBER;
p_cb->offset = (uint32_t)p_align_addr - (uint32_t)p_addr;
return (void *)p_align_addr;
}
void SDK_Free(void *ptr)
{
mem_align_cb_t *p_cb = (mem_align_cb_t *)((uint32_t)ptr - 4);
if (p_cb->identifier != SDK_MEM_MAGIC_NUMBER)
{
return;
}
free((void *)((uint32_t)ptr - p_cb->offset));
}

View File

@@ -0,0 +1,542 @@
/*
* The Clear BSD License
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#ifndef _FSL_COMMON_H_
#define _FSL_COMMON_H_
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#if defined(__ICCARM__)
#include <stddef.h>
#endif
#include "fsl_device_registers.h"
/*!
* @addtogroup ksdk_common
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Construct a status code value from a group and code number. */
#define MAKE_STATUS(group, code) ((((group)*100) + (code)))
/*! @brief Construct the version number for drivers. */
#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))
/*! @name Driver version */
/*@{*/
/*! @brief common driver version 2.0.0. */
#define FSL_COMMON_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
/*@}*/
/* Debug console type definition. */
#define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */
#define DEBUG_CONSOLE_DEVICE_TYPE_UART 1U /*!< Debug console base on UART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART 2U /*!< Debug console base on LPUART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI 3U /*!< Debug console base on LPSCI. */
#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console base on USBCDC. */
#define DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM 5U /*!< Debug console base on USBCDC. */
#define DEBUG_CONSOLE_DEVICE_TYPE_IUART 6U /*!< Debug console base on i.MX UART. */
#define DEBUG_CONSOLE_DEVICE_TYPE_VUSART 7U /*!< Debug console base on LPC_USART. */
/*! @brief Status group numbers. */
enum _status_groups
{
kStatusGroup_Generic = 0, /*!< Group number for generic status codes. */
kStatusGroup_FLASH = 1, /*!< Group number for FLASH status codes. */
kStatusGroup_LPSPI = 4, /*!< Group number for LPSPI status codes. */
kStatusGroup_FLEXIO_SPI = 5, /*!< Group number for FLEXIO SPI status codes. */
kStatusGroup_DSPI = 6, /*!< Group number for DSPI status codes. */
kStatusGroup_FLEXIO_UART = 7, /*!< Group number for FLEXIO UART status codes. */
kStatusGroup_FLEXIO_I2C = 8, /*!< Group number for FLEXIO I2C status codes. */
kStatusGroup_LPI2C = 9, /*!< Group number for LPI2C status codes. */
kStatusGroup_UART = 10, /*!< Group number for UART status codes. */
kStatusGroup_I2C = 11, /*!< Group number for UART status codes. */
kStatusGroup_LPSCI = 12, /*!< Group number for LPSCI status codes. */
kStatusGroup_LPUART = 13, /*!< Group number for LPUART status codes. */
kStatusGroup_SPI = 14, /*!< Group number for SPI status code.*/
kStatusGroup_XRDC = 15, /*!< Group number for XRDC status code.*/
kStatusGroup_SEMA42 = 16, /*!< Group number for SEMA42 status code.*/
kStatusGroup_SDHC = 17, /*!< Group number for SDHC status code */
kStatusGroup_SDMMC = 18, /*!< Group number for SDMMC status code */
kStatusGroup_SAI = 19, /*!< Group number for SAI status code */
kStatusGroup_MCG = 20, /*!< Group number for MCG status codes. */
kStatusGroup_SCG = 21, /*!< Group number for SCG status codes. */
kStatusGroup_SDSPI = 22, /*!< Group number for SDSPI status codes. */
kStatusGroup_FLEXIO_I2S = 23, /*!< Group number for FLEXIO I2S status codes */
kStatusGroup_FLEXIO_MCULCD = 24, /*!< Group number for FLEXIO LCD status codes */
kStatusGroup_FLASHIAP = 25, /*!< Group number for FLASHIAP status codes */
kStatusGroup_FLEXCOMM_I2C = 26, /*!< Group number for FLEXCOMM I2C status codes */
kStatusGroup_I2S = 27, /*!< Group number for I2S status codes */
kStatusGroup_IUART = 28, /*!< Group number for IUART status codes */
kStatusGroup_CSI = 29, /*!< Group number for CSI status codes */
kStatusGroup_MIPI_DSI = 30, /*!< Group number for MIPI DSI status codes */
kStatusGroup_SDRAMC = 35, /*!< Group number for SDRAMC status codes. */
kStatusGroup_POWER = 39, /*!< Group number for POWER status codes. */
kStatusGroup_ENET = 40, /*!< Group number for ENET status codes. */
kStatusGroup_PHY = 41, /*!< Group number for PHY status codes. */
kStatusGroup_TRGMUX = 42, /*!< Group number for TRGMUX status codes. */
kStatusGroup_SMARTCARD = 43, /*!< Group number for SMARTCARD status codes. */
kStatusGroup_LMEM = 44, /*!< Group number for LMEM status codes. */
kStatusGroup_QSPI = 45, /*!< Group number for QSPI status codes. */
kStatusGroup_DMA = 50, /*!< Group number for DMA status codes. */
kStatusGroup_EDMA = 51, /*!< Group number for EDMA status codes. */
kStatusGroup_DMAMGR = 52, /*!< Group number for DMAMGR status codes. */
kStatusGroup_FLEXCAN = 53, /*!< Group number for FlexCAN status codes. */
kStatusGroup_LTC = 54, /*!< Group number for LTC status codes. */
kStatusGroup_FLEXIO_CAMERA = 55, /*!< Group number for FLEXIO CAMERA status codes. */
kStatusGroup_LPC_SPI = 56, /*!< Group number for LPC_SPI status codes. */
kStatusGroup_LPC_USART = 57, /*!< Group number for LPC_USART status codes. */
kStatusGroup_DMIC = 58, /*!< Group number for DMIC status codes. */
kStatusGroup_SDIF = 59, /*!< Group number for SDIF status codes.*/
kStatusGroup_SPIFI = 60, /*!< Group number for SPIFI status codes. */
kStatusGroup_OTP = 61, /*!< Group number for OTP status codes. */
kStatusGroup_MCAN = 62, /*!< Group number for MCAN status codes. */
kStatusGroup_CAAM = 63, /*!< Group number for CAAM status codes. */
kStatusGroup_ECSPI = 64, /*!< Group number for ECSPI status codes. */
kStatusGroup_USDHC = 65, /*!< Group number for USDHC status codes.*/
kStatusGroup_LPC_I2C = 66, /*!< Group number for LPC_I2C status codes.*/
kStatusGroup_DCP = 67, /*!< Group number for DCP status codes.*/
kStatusGroup_MSCAN = 68, /*!< Group number for MSCAN status codes.*/
kStatusGroup_ESAI = 69, /*!< Group number for ESAI status codes. */
kStatusGroup_FLEXSPI = 70, /*!< Group number for FLEXSPI status codes. */
kStatusGroup_MMDC = 71, /*!< Group number for MMDC status codes. */
kStatusGroup_MICFIL = 72, /*!< Group number for MIC status codes. */
kStatusGroup_SDMA = 73, /*!< Group number for SDMA status codes. */
kStatusGroup_ICS = 74, /*!< Group number for ICS status codes. */
kStatusGroup_SPDIF = 75, /*!< Group number for SPDIF status codes. */
kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */
kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */
kStatusGroup_SEMC = 100, /*!< Group number for SEMC status codes. */
kStatusGroup_ApplicationRangeStart = 101, /*!< Starting number for application groups. */
};
/*! @brief Generic status return codes. */
enum _generic_status
{
kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0),
kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1),
kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2),
kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3),
kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4),
kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5),
kStatus_NoTransferInProgress = MAKE_STATUS(kStatusGroup_Generic, 6),
};
/*! @brief Type used for all status and error return values. */
typedef int32_t status_t;
/*
* The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t
* defined in previous of this file.
*/
#include "fsl_clock.h"
/*
* Chip level peripheral reset API, for MCUs that implement peripheral reset control external to a peripheral
*/
#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \
(defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0)))
#include "fsl_reset.h"
#endif
/*
* Macro guard for whether to use default weak IRQ implementation in drivers
*/
#ifndef FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ
#define FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ 1
#endif
/*! @name Min/max macros */
/* @{ */
#if !defined(MIN)
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
#if !defined(MAX)
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
/* @} */
/*! @brief Computes the number of elements in an array. */
#if !defined(ARRAY_SIZE)
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
/*! @name UINT16_MAX/UINT32_MAX value */
/* @{ */
#if !defined(UINT16_MAX)
#define UINT16_MAX ((uint16_t)-1)
#endif
#if !defined(UINT32_MAX)
#define UINT32_MAX ((uint32_t)-1)
#endif
/* @} */
/*! @name Timer utilities */
/* @{ */
/*! Macro to convert a microsecond period to raw count value */
#define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)((uint64_t)us * clockFreqInHz / 1000000U)
/*! Macro to convert a raw count value to microsecond */
#define COUNT_TO_USEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000000U / clockFreqInHz)
/*! Macro to convert a millisecond period to raw count value */
#define MSEC_TO_COUNT(ms, clockFreqInHz) (uint64_t)((uint64_t)ms * clockFreqInHz / 1000U)
/*! Macro to convert a raw count value to millisecond */
#define COUNT_TO_MSEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000U / clockFreqInHz)
/* @} */
/*! @name Alignment variable definition macros */
/* @{ */
#if (defined(__ICCARM__))
/**
* Workaround to disable MISRA C message suppress warnings for IAR compiler.
* http://supp.iar.com/Support/?note=24725
*/
_Pragma("diag_suppress=Pm120")
#define SDK_PRAGMA(x) _Pragma(#x)
_Pragma("diag_error=Pm120")
/*! Macro to define a variable with alignbytes alignment */
#define SDK_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
/*! Macro to define a variable with L1 d-cache line size alignment */
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#define SDK_L1DCACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) var
#endif
/*! Macro to define a variable with L2 cache line size alignment */
#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
#define SDK_L2CACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L2CACHE_LINESIZE_BYTE) var
#endif
#elif defined(__ARMCC_VERSION)
/*! Macro to define a variable with alignbytes alignment */
#define SDK_ALIGN(var, alignbytes) __align(alignbytes) var
/*! Macro to define a variable with L1 d-cache line size alignment */
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#define SDK_L1DCACHE_ALIGN(var) __align(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) var
#endif
/*! Macro to define a variable with L2 cache line size alignment */
#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
#define SDK_L2CACHE_ALIGN(var) __align(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) var
#endif
#elif defined(__GNUC__)
/*! Macro to define a variable with alignbytes alignment */
#define SDK_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes)))
/*! Macro to define a variable with L1 d-cache line size alignment */
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#define SDK_L1DCACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)))
#endif
/*! Macro to define a variable with L2 cache line size alignment */
#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
#define SDK_L2CACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)))
#endif
#else
#error Toolchain not supported
#define SDK_ALIGN(var, alignbytes) var
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#define SDK_L1DCACHE_ALIGN(var) var
#endif
#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
#define SDK_L2CACHE_ALIGN(var) var
#endif
#endif
/*! Macro to change a value to a given size aligned value */
#define SDK_SIZEALIGN(var, alignbytes) \
((unsigned int)((var) + ((alignbytes)-1)) & (unsigned int)(~(unsigned int)((alignbytes)-1)))
/* @} */
/*! @name Non-cacheable region definition macros */
/* For initialized non-zero non-cacheable variables, please using "AT_NONCACHEABLE_SECTION_INIT(var) ={xx};" or
* "AT_NONCACHEABLE_SECTION_ALIGN_INIT(var) ={xx};" in your projects to define them, for zero-inited non-cacheable variables,
* please using "AT_NONCACHEABLE_SECTION(var);" or "AT_NONCACHEABLE_SECTION_ALIGN(var);" to define them, these zero-inited variables
* will be initialized to zero in system startup.
*/
/* @{ */
#if (defined(__ICCARM__))
#if defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE)
#define AT_NONCACHEABLE_SECTION(var) var @"NonCacheable"
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable"
#define AT_NONCACHEABLE_SECTION_INIT(var) var @"NonCacheable.init"
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable.init"
#else
#define AT_NONCACHEABLE_SECTION(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
#define AT_NONCACHEABLE_SECTION_INIT(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
#endif
#elif(defined(__ARMCC_VERSION))
#if defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE)
#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"), zero_init)) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
__attribute__((section("NonCacheable"), zero_init)) __align(alignbytes) var
#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
__attribute__((section("NonCacheable.init"))) __align(alignbytes) var
#else
#define AT_NONCACHEABLE_SECTION(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) __align(alignbytes) var
#define AT_NONCACHEABLE_SECTION_INIT(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) __align(alignbytes) var
#endif
#elif(defined(__GNUC__))
/* For GCC, when the non-cacheable section is required, please define "__STARTUP_INITIALIZE_NONCACHEDATA"
* in your projects to make sure the non-cacheable section variables will be initialized in system startup.
*/
#if defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE)
#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
__attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes)))
#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
__attribute__((section("NonCacheable,\"aw\",%nobits @"))) var __attribute__((aligned(alignbytes)))
#else
#define AT_NONCACHEABLE_SECTION(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes)))
#define AT_NONCACHEABLE_SECTION_INIT(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) var __attribute__((aligned(alignbytes)))
#endif
#else
#error Toolchain not supported.
#define AT_NONCACHEABLE_SECTION(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var
#define AT_NONCACHEABLE_SECTION_INIT(var) var
#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) var
#endif
/* @} */
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C"
{
#endif
/*!
* @brief Enable specific interrupt.
*
* Enable LEVEL1 interrupt. For some devices, there might be multiple interrupt
* levels. For example, there are NVIC and intmux. Here the interrupts connected
* to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
* The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
* to NVIC first then routed to core.
*
* This function only enables the LEVEL1 interrupts. The number of LEVEL1 interrupts
* is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
*
* @param interrupt The IRQ number.
* @retval kStatus_Success Interrupt enabled successfully
* @retval kStatus_Fail Failed to enable the interrupt
*/
static inline status_t EnableIRQ(IRQn_Type interrupt)
{
if (NotAvail_IRQn == interrupt)
{
return kStatus_Fail;
}
#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
if (interrupt >= FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
{
return kStatus_Fail;
}
#endif
#if defined(__GIC_PRIO_BITS)
GIC_EnableIRQ(interrupt);
#else
NVIC_EnableIRQ(interrupt);
#endif
return kStatus_Success;
}
/*!
* @brief Disable specific interrupt.
*
* Disable LEVEL1 interrupt. For some devices, there might be multiple interrupt
* levels. For example, there are NVIC and intmux. Here the interrupts connected
* to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
* The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
* to NVIC first then routed to core.
*
* This function only disables the LEVEL1 interrupts. The number of LEVEL1 interrupts
* is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
*
* @param interrupt The IRQ number.
* @retval kStatus_Success Interrupt disabled successfully
* @retval kStatus_Fail Failed to disable the interrupt
*/
static inline status_t DisableIRQ(IRQn_Type interrupt)
{
if (NotAvail_IRQn == interrupt)
{
return kStatus_Fail;
}
#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
if (interrupt >= FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
{
return kStatus_Fail;
}
#endif
#if defined(__GIC_PRIO_BITS)
GIC_DisableIRQ(interrupt);
#else
NVIC_DisableIRQ(interrupt);
#endif
return kStatus_Success;
}
/*!
* @brief Disable the global IRQ
*
* Disable the global interrupt and return the current primask register. User is required to provided the primask
* register for the EnableGlobalIRQ().
*
* @return Current primask value.
*/
static inline uint32_t DisableGlobalIRQ(void)
{
#if defined(CPSR_I_Msk)
uint32_t cpsr = __get_CPSR() & CPSR_I_Msk;
__disable_irq();
return cpsr;
#else
uint32_t regPrimask = __get_PRIMASK();
__disable_irq();
return regPrimask;
#endif
}
/*!
* @brief Enaable the global IRQ
*
* Set the primask register with the provided primask value but not just enable the primask. The idea is for the
* convinience of integration of RTOS. some RTOS get its own management mechanism of primask. User is required to
* use the EnableGlobalIRQ() and DisableGlobalIRQ() in pair.
*
* @param primask value of primask register to be restored. The primask value is supposed to be provided by the
* DisableGlobalIRQ().
*/
static inline void EnableGlobalIRQ(uint32_t primask)
{
#if defined(CPSR_I_Msk)
__set_CPSR((__get_CPSR() & ~CPSR_I_Msk) | primask);
#else
__set_PRIMASK(primask);
#endif
}
#if defined(ENABLE_RAM_VECTOR_TABLE)
/*!
* @brief install IRQ handler
*
* @param irq IRQ number
* @param irqHandler IRQ handler address
* @return The old IRQ handler address
*/
uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler);
#endif /* ENABLE_RAM_VECTOR_TABLE. */
#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
/*!
* @brief Enable specific interrupt for wake-up from deep-sleep mode.
*
* Enable the interrupt for wake-up from deep sleep mode.
* Some interrupts are typically used in sleep mode only and will not occur during
* deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
* those clocks (significantly increasing power consumption in the reduced power mode),
* making these wake-ups possible.
*
* @note This function also enables the interrupt in the NVIC (EnableIRQ() is called internally).
*
* @param interrupt The IRQ number.
*/
void EnableDeepSleepIRQ(IRQn_Type interrupt);
/*!
* @brief Disable specific interrupt for wake-up from deep-sleep mode.
*
* Disable the interrupt for wake-up from deep sleep mode.
* Some interrupts are typically used in sleep mode only and will not occur during
* deep-sleep mode because relevant clocks are stopped. However, it is possible to enable
* those clocks (significantly increasing power consumption in the reduced power mode),
* making these wake-ups possible.
*
* @note This function also disables the interrupt in the NVIC (DisableIRQ() is called internally).
*
* @param interrupt The IRQ number.
*/
void DisableDeepSleepIRQ(IRQn_Type interrupt);
#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
/*!
* @brief Allocate memory with given alignment and aligned size.
*
* This is provided to support the dynamically allocated memory
* used in cache-able region.
* @param size The length required to malloc.
* @param alignbytes The alignment size.
* @retval The allocated memory.
*/
void *SDK_Malloc(size_t size, size_t alignbytes);
/*!
* @brief Free memory.
*
* @param ptr The memory to be release.
*/
void SDK_Free(void *ptr);
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /* _FSL_COMMON_H_ */

View File

@@ -0,0 +1,688 @@
/*
* The Clear BSD License
* Copyright (c) 2017, NXP Semiconductors, Inc.
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#include "fsl_csi.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Two frame buffer loaded to CSI register at most. */
#define CSI_MAX_ACTIVE_FRAME_NUM 2
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get the instance from the base address
*
* @param base CSI peripheral base address
*
* @return The CSI module instance
*/
static uint32_t CSI_GetInstance(CSI_Type *base);
/*!
* @brief Get the delta value of two index in queue.
*
* @param startIdx Start index.
* @param endIdx End index.
*
* @return The delta between startIdx and endIdx in queue.
*/
static uint32_t CSI_TransferGetQueueDelta(uint32_t startIdx, uint32_t endIdx);
/*!
* @brief Increase a index value in queue.
*
* This function increases the index value in the queue, if the index is out of
* the queue range, it is reset to 0.
*
* @param idx The index value to increase.
*
* @return The index value after increase.
*/
static uint32_t CSI_TransferIncreaseQueueIdx(uint32_t idx);
/*!
* @brief Get the empty frame buffer count in queue.
*
* @param base CSI peripheral base address
* @param handle Pointer to CSI driver handle.
*
* @return Number of the empty frame buffer count in queue.
*/
static uint32_t CSI_TransferGetEmptyBufferCount(CSI_Type *base, csi_handle_t *handle);
/*!
* @brief Load one empty frame buffer in queue to CSI module.
*
* Load one empty frame in queue to CSI module, this function could only be called
* when there is empty frame buffer in queue.
*
* @param base CSI peripheral base address
* @param handle Pointer to CSI driver handle.
*/
static void CSI_TransferLoadBufferToDevice(CSI_Type *base, csi_handle_t *handle);
/* Typedef for interrupt handler. */
typedef void (*csi_isr_t)(CSI_Type *base, csi_handle_t *handle);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to CSI bases for each instance. */
static CSI_Type *const s_csiBases[] = CSI_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to CSI clocks for each CSI submodule. */
static const clock_ip_name_t s_csiClocks[] = CSI_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Array for the CSI driver handle. */
static csi_handle_t *s_csiHandle[ARRAY_SIZE(s_csiBases)];
/* Array of CSI IRQ number. */
static const IRQn_Type s_csiIRQ[] = CSI_IRQS;
/* CSI ISR for transactional APIs. */
static csi_isr_t s_csiIsr;
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t CSI_GetInstance(CSI_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_csiBases); instance++)
{
if (s_csiBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_csiBases));
return instance;
}
static uint32_t CSI_TransferGetQueueDelta(uint32_t startIdx, uint32_t endIdx)
{
if (endIdx >= startIdx)
{
return endIdx - startIdx;
}
else
{
return startIdx + CSI_DRIVER_ACTUAL_QUEUE_SIZE - endIdx;
}
}
static uint32_t CSI_TransferIncreaseQueueIdx(uint32_t idx)
{
uint32_t ret;
/*
* Here not use the method:
* ret = (idx+1) % CSI_DRIVER_ACTUAL_QUEUE_SIZE;
*
* Because the mod function might be slow.
*/
ret = idx + 1;
if (ret >= CSI_DRIVER_ACTUAL_QUEUE_SIZE)
{
ret = 0;
}
return ret;
}
static uint32_t CSI_TransferGetEmptyBufferCount(CSI_Type *base, csi_handle_t *handle)
{
return CSI_TransferGetQueueDelta(handle->queueDrvReadIdx, handle->queueUserWriteIdx);
}
static void CSI_TransferLoadBufferToDevice(CSI_Type *base, csi_handle_t *handle)
{
/* Load the frame buffer address to CSI register. */
CSI_SetRxBufferAddr(base, handle->nextBufferIdx, handle->frameBufferQueue[handle->queueDrvReadIdx]);
handle->queueDrvReadIdx = CSI_TransferIncreaseQueueIdx(handle->queueDrvReadIdx);
handle->activeBufferNum++;
/* There are two CSI buffers, so could use XOR to get the next index. */
handle->nextBufferIdx ^= 1U;
}
status_t CSI_Init(CSI_Type *base, const csi_config_t *config)
{
assert(config);
uint32_t reg;
uint32_t imgWidth_Bytes;
imgWidth_Bytes = config->width * config->bytesPerPixel;
/* The image width and frame buffer pitch should be multiple of 8-bytes. */
if ((imgWidth_Bytes & 0x07) | ((uint32_t)config->linePitch_Bytes & 0x07))
{
return kStatus_InvalidArgument;
}
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
uint32_t instance = CSI_GetInstance(base);
CLOCK_EnableClock(s_csiClocks[instance]);
#endif
CSI_Reset(base);
/* Configure CSICR1. CSICR1 has been reset to the default value, so could write it directly. */
reg = ((uint32_t)config->workMode) | config->polarityFlags | CSI_CSICR1_FCC_MASK;
if (config->useExtVsync)
{
reg |= CSI_CSICR1_EXT_VSYNC_MASK;
}
base->CSICR1 = reg;
/*
* Generally, CSIIMAG_PARA[IMAGE_WIDTH] indicates how many data bus cycles per line.
* One special case is when receiving 24-bit pixels through 8-bit data bus, and
* CSICR3[ZERO_PACK_EN] is enabled, in this case, the CSIIMAG_PARA[IMAGE_WIDTH]
* should be set to the pixel number per line.
*
* Currently the CSI driver only support 8-bit data bus, so generally the
* CSIIMAG_PARA[IMAGE_WIDTH] is bytes number per line. When the CSICR3[ZERO_PACK_EN]
* is enabled, CSIIMAG_PARA[IMAGE_WIDTH] is pixel number per line.
*
* NOTE: The CSIIMAG_PARA[IMAGE_WIDTH] setting code should be updated if the
* driver is upgraded to support other data bus width.
*/
if (4U == config->bytesPerPixel)
{
/* Enable zero pack. */
base->CSICR3 |= CSI_CSICR3_ZERO_PACK_EN_MASK;
/* Image parameter. */
base->CSIIMAG_PARA = ((uint32_t)(config->width) << CSI_CSIIMAG_PARA_IMAGE_WIDTH_SHIFT) |
((uint32_t)(config->height) << CSI_CSIIMAG_PARA_IMAGE_HEIGHT_SHIFT);
}
else
{
/* Image parameter. */
base->CSIIMAG_PARA = ((uint32_t)(imgWidth_Bytes) << CSI_CSIIMAG_PARA_IMAGE_WIDTH_SHIFT) |
((uint32_t)(config->height) << CSI_CSIIMAG_PARA_IMAGE_HEIGHT_SHIFT);
}
/* The CSI frame buffer bus is 8-byte width. */
base->CSIFBUF_PARA = (uint32_t)((config->linePitch_Bytes - imgWidth_Bytes) / 8U)
<< CSI_CSIFBUF_PARA_FBUF_STRIDE_SHIFT;
/* Enable auto ECC. */
base->CSICR3 |= CSI_CSICR3_ECC_AUTO_EN_MASK;
/*
* For better performance.
* The DMA burst size could be set to 16 * 8 byte, 8 * 8 byte, or 4 * 8 byte,
* choose the best burst size based on bytes per line.
*/
if (!(imgWidth_Bytes % (8 * 16)))
{
base->CSICR2 = CSI_CSICR2_DMA_BURST_TYPE_RFF(3U);
base->CSICR3 = (CSI->CSICR3 & ~CSI_CSICR3_RxFF_LEVEL_MASK) | ((2U << CSI_CSICR3_RxFF_LEVEL_SHIFT));
}
else if (!(imgWidth_Bytes % (8 * 8)))
{
base->CSICR2 = CSI_CSICR2_DMA_BURST_TYPE_RFF(2U);
base->CSICR3 = (CSI->CSICR3 & ~CSI_CSICR3_RxFF_LEVEL_MASK) | ((1U << CSI_CSICR3_RxFF_LEVEL_SHIFT));
}
else
{
base->CSICR2 = CSI_CSICR2_DMA_BURST_TYPE_RFF(1U);
base->CSICR3 = (CSI->CSICR3 & ~CSI_CSICR3_RxFF_LEVEL_MASK) | ((0U << CSI_CSICR3_RxFF_LEVEL_SHIFT));
}
CSI_ReflashFifoDma(base, kCSI_RxFifo);
return kStatus_Success;
}
void CSI_Deinit(CSI_Type *base)
{
/* Disable transfer first. */
CSI_Stop(base);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
uint32_t instance = CSI_GetInstance(base);
CLOCK_DisableClock(s_csiClocks[instance]);
#endif
}
void CSI_Reset(CSI_Type *base)
{
uint32_t csisr;
/* Disable transfer first. */
CSI_Stop(base);
/* Disable DMA request. */
base->CSICR3 = 0U;
/* Reset the fame count. */
base->CSICR3 |= CSI_CSICR3_FRMCNT_RST_MASK;
while (base->CSICR3 & CSI_CSICR3_FRMCNT_RST_MASK)
{
}
/* Clear the RX FIFO. */
CSI_ClearFifo(base, kCSI_AllFifo);
/* Reflash DMA. */
CSI_ReflashFifoDma(base, kCSI_AllFifo);
/* Clear the status. */
csisr = base->CSISR;
base->CSISR = csisr;
/* Set the control registers to default value. */
base->CSICR1 = CSI_CSICR1_HSYNC_POL_MASK | CSI_CSICR1_EXT_VSYNC_MASK;
base->CSICR2 = 0U;
base->CSICR3 = 0U;
#if defined(CSI_CSICR18_CSI_LCDIF_BUFFER_LINES)
base->CSICR18 = CSI_CSICR18_AHB_HPROT(0x0DU) | CSI_CSICR18_CSI_LCDIF_BUFFER_LINES(0x02U);
#else
base->CSICR18 = CSI_CSICR18_AHB_HPROT(0x0DU);
#endif
base->CSIFBUF_PARA = 0U;
base->CSIIMAG_PARA = 0U;
}
void CSI_GetDefaultConfig(csi_config_t *config)
{
assert(config);
config->width = 320U;
config->height = 240U;
config->polarityFlags = kCSI_HsyncActiveHigh | kCSI_DataLatchOnRisingEdge;
config->bytesPerPixel = 2U;
config->linePitch_Bytes = 320U * 2U;
config->workMode = kCSI_GatedClockMode;
config->dataBus = kCSI_DataBus8Bit;
config->useExtVsync = true;
}
void CSI_SetRxBufferAddr(CSI_Type *base, uint8_t index, uint32_t addr)
{
if (index)
{
base->CSIDMASA_FB2 = addr;
}
else
{
base->CSIDMASA_FB1 = addr;
}
}
void CSI_ClearFifo(CSI_Type *base, csi_fifo_t fifo)
{
uint32_t cr1;
uint32_t mask = 0U;
/* The FIFO could only be cleared when CSICR1[FCC] = 0, so first clear the FCC. */
cr1 = base->CSICR1;
base->CSICR1 = (cr1 & ~CSI_CSICR1_FCC_MASK);
if ((uint32_t)fifo & (uint32_t)kCSI_RxFifo)
{
mask |= CSI_CSICR1_CLR_RXFIFO_MASK;
}
if ((uint32_t)fifo & (uint32_t)kCSI_StatFifo)
{
mask |= CSI_CSICR1_CLR_STATFIFO_MASK;
}
base->CSICR1 = (cr1 & ~CSI_CSICR1_FCC_MASK) | mask;
/* Wait clear completed. */
while (base->CSICR1 & mask)
{
}
/* Recover the FCC. */
base->CSICR1 = cr1;
}
void CSI_ReflashFifoDma(CSI_Type *base, csi_fifo_t fifo)
{
uint32_t cr3 = 0U;
if ((uint32_t)fifo & (uint32_t)kCSI_RxFifo)
{
cr3 |= CSI_CSICR3_DMA_REFLASH_RFF_MASK;
}
if ((uint32_t)fifo & (uint32_t)kCSI_StatFifo)
{
cr3 |= CSI_CSICR3_DMA_REFLASH_SFF_MASK;
}
base->CSICR3 |= cr3;
/* Wait clear completed. */
while (base->CSICR3 & cr3)
{
}
}
void CSI_EnableFifoDmaRequest(CSI_Type *base, csi_fifo_t fifo, bool enable)
{
uint32_t cr3 = 0U;
if ((uint32_t)fifo & (uint32_t)kCSI_RxFifo)
{
cr3 |= CSI_CSICR3_DMA_REQ_EN_RFF_MASK;
}
if ((uint32_t)fifo & (uint32_t)kCSI_StatFifo)
{
cr3 |= CSI_CSICR3_DMA_REQ_EN_SFF_MASK;
}
if (enable)
{
base->CSICR3 |= cr3;
}
else
{
base->CSICR3 &= ~cr3;
}
}
void CSI_EnableInterrupts(CSI_Type *base, uint32_t mask)
{
base->CSICR1 |= (mask & CSI_CSICR1_INT_EN_MASK);
base->CSICR3 |= (mask & CSI_CSICR3_INT_EN_MASK);
base->CSICR18 |= ((mask & CSI_CSICR18_INT_EN_MASK) >> 6U);
}
void CSI_DisableInterrupts(CSI_Type *base, uint32_t mask)
{
base->CSICR1 &= ~(mask & CSI_CSICR1_INT_EN_MASK);
base->CSICR3 &= ~(mask & CSI_CSICR3_INT_EN_MASK);
base->CSICR18 &= ~((mask & CSI_CSICR18_INT_EN_MASK) >> 6U);
}
status_t CSI_TransferCreateHandle(CSI_Type *base,
csi_handle_t *handle,
csi_transfer_callback_t callback,
void *userData)
{
assert(handle);
uint32_t instance;
memset(handle, 0, sizeof(*handle));
/* Set the callback and user data. */
handle->callback = callback;
handle->userData = userData;
/* Get instance from peripheral base address. */
instance = CSI_GetInstance(base);
/* Save the handle in global variables to support the double weak mechanism. */
s_csiHandle[instance] = handle;
s_csiIsr = CSI_TransferHandleIRQ;
/* Enable interrupt. */
EnableIRQ(s_csiIRQ[instance]);
return kStatus_Success;
}
status_t CSI_TransferStart(CSI_Type *base, csi_handle_t *handle)
{
assert(handle);
uint32_t emptyBufferCount;
emptyBufferCount = CSI_TransferGetEmptyBufferCount(base, handle);
if (emptyBufferCount < 2U)
{
return kStatus_CSI_NoEmptyBuffer;
}
handle->nextBufferIdx = 0U;
handle->activeBufferNum = 0U;
/* Write to memory from second completed frame. */
base->CSICR18 = (base->CSICR18 & ~CSI_CSICR18_MASK_OPTION_MASK) | CSI_CSICR18_MASK_OPTION(2);
/* Load the frame buffer to CSI register, there are at least two empty buffers. */
CSI_TransferLoadBufferToDevice(base, handle);
CSI_TransferLoadBufferToDevice(base, handle);
/* After reflash DMA, the CSI saves frame to frame buffer 0. */
CSI_ReflashFifoDma(base, kCSI_RxFifo);
handle->transferStarted = true;
handle->transferOnGoing = true;
CSI_EnableInterrupts(base, kCSI_RxBuffer1DmaDoneInterruptEnable | kCSI_RxBuffer0DmaDoneInterruptEnable);
CSI_Start(base);
return kStatus_Success;
}
status_t CSI_TransferStop(CSI_Type *base, csi_handle_t *handle)
{
assert(handle);
CSI_Stop(base);
CSI_DisableInterrupts(base, kCSI_RxBuffer1DmaDoneInterruptEnable | kCSI_RxBuffer0DmaDoneInterruptEnable);
handle->transferStarted = false;
handle->transferOnGoing = false;
/* Stoped, reset the state flags. */
handle->queueDrvReadIdx = handle->queueDrvWriteIdx;
handle->activeBufferNum = 0U;
return kStatus_Success;
}
status_t CSI_TransferSubmitEmptyBuffer(CSI_Type *base, csi_handle_t *handle, uint32_t frameBuffer)
{
uint32_t csicr1;
if (CSI_DRIVER_QUEUE_SIZE == CSI_TransferGetQueueDelta(handle->queueUserReadIdx, handle->queueUserWriteIdx))
{
return kStatus_CSI_QueueFull;
}
/* Disable the interrupt to protect the index information in handle. */
csicr1 = base->CSICR1;
base->CSICR1 = (csicr1 & ~(CSI_CSICR1_FB2_DMA_DONE_INTEN_MASK | CSI_CSICR1_FB1_DMA_DONE_INTEN_MASK));
/* Save the empty frame buffer address to queue. */
handle->frameBufferQueue[handle->queueUserWriteIdx] = frameBuffer;
handle->queueUserWriteIdx = CSI_TransferIncreaseQueueIdx(handle->queueUserWriteIdx);
base->CSICR1 = csicr1;
if (handle->transferStarted)
{
/*
* If user has started transfer using @ref CSI_TransferStart, and the CSI is
* stopped due to no empty frame buffer in queue, then start the CSI.
*/
if ((!handle->transferOnGoing) && (CSI_TransferGetEmptyBufferCount(base, handle) >= 2U))
{
handle->transferOnGoing = true;
handle->nextBufferIdx = 0U;
/* Load the frame buffers to CSI module. */
CSI_TransferLoadBufferToDevice(base, handle);
CSI_TransferLoadBufferToDevice(base, handle);
CSI_ReflashFifoDma(base, kCSI_RxFifo);
CSI_Start(base);
}
}
return kStatus_Success;
}
status_t CSI_TransferGetFullBuffer(CSI_Type *base, csi_handle_t *handle, uint32_t *frameBuffer)
{
uint32_t csicr1;
/* No full frame buffer. */
if (handle->queueUserReadIdx == handle->queueDrvWriteIdx)
{
return kStatus_CSI_NoFullBuffer;
}
/* Disable the interrupt to protect the index information in handle. */
csicr1 = base->CSICR1;
base->CSICR1 = (csicr1 & ~(CSI_CSICR1_FB2_DMA_DONE_INTEN_MASK | CSI_CSICR1_FB1_DMA_DONE_INTEN_MASK));
*frameBuffer = handle->frameBufferQueue[handle->queueUserReadIdx];
handle->queueUserReadIdx = CSI_TransferIncreaseQueueIdx(handle->queueUserReadIdx);
base->CSICR1 = csicr1;
return kStatus_Success;
}
void CSI_TransferHandleIRQ(CSI_Type *base, csi_handle_t *handle)
{
uint32_t queueDrvWriteIdx;
uint32_t csisr = base->CSISR;
/* Clear the error flags. */
base->CSISR = csisr;
/*
* If both frame buffer 0 and frame buffer 1 flags assert, driver does not
* know which frame buffer ready just now, so reset the CSI transfer to
* start from frame buffer 0.
*/
if ((csisr & (CSI_CSISR_DMA_TSF_DONE_FB2_MASK | CSI_CSISR_DMA_TSF_DONE_FB1_MASK)) ==
(CSI_CSISR_DMA_TSF_DONE_FB2_MASK | CSI_CSISR_DMA_TSF_DONE_FB1_MASK))
{
CSI_Stop(base);
/* Reset the active buffers. */
if (1 <= handle->activeBufferNum)
{
queueDrvWriteIdx = handle->queueDrvWriteIdx;
base->CSIDMASA_FB1 = handle->frameBufferQueue[queueDrvWriteIdx];
if (2U == handle->activeBufferNum)
{
queueDrvWriteIdx = CSI_TransferIncreaseQueueIdx(queueDrvWriteIdx);
base->CSIDMASA_FB2 = handle->frameBufferQueue[queueDrvWriteIdx];
handle->nextBufferIdx = 0U;
}
else
{
handle->nextBufferIdx = 1U;
}
}
CSI_ReflashFifoDma(base, kCSI_RxFifo);
CSI_Start(base);
}
else if (csisr & (CSI_CSISR_DMA_TSF_DONE_FB2_MASK | CSI_CSISR_DMA_TSF_DONE_FB1_MASK))
{
handle->queueDrvWriteIdx = CSI_TransferIncreaseQueueIdx(handle->queueDrvWriteIdx);
handle->activeBufferNum--;
if (handle->callback)
{
handle->callback(base, handle, kStatus_CSI_FrameDone, handle->userData);
}
/* No frame buffer to save incoming data, then stop the CSI module. */
if (!(handle->activeBufferNum))
{
CSI_Stop(base);
handle->transferOnGoing = false;
}
else
{
if (CSI_TransferGetEmptyBufferCount(base, handle))
{
CSI_TransferLoadBufferToDevice(base, handle);
}
}
}
else
{
}
}
#if defined(CSI)
void CSI_DriverIRQHandler(void)
{
s_csiIsr(CSI, s_csiHandle[0]);
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}
#endif
#if defined(CSI0)
void CSI0_DriverIRQHandler(void)
{
s_csiIsr(CSI, s_csiHandle[0]);
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}
#endif

View File

@@ -0,0 +1,562 @@
/*
* The Clear BSD License
* Copyright (c) 2017, NXP Semiconductors, Inc.
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#ifndef _FSL_CSI_H_
#define _FSL_CSI_H_
#include "fsl_common.h"
/*!
* @addtogroup csi_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
#define FSL_CSI_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
/*@}*/
/*! @brief Size of the frame buffer queue used in CSI transactional function. */
#ifndef CSI_DRIVER_QUEUE_SIZE
#define CSI_DRIVER_QUEUE_SIZE 4U
#endif
/*
* There is one empty room in queue, used to distinguish whether the queue
* is full or empty. When header equals tail, the queue is empty; when header
* equals tail + 1, the queue is full.
*/
#define CSI_DRIVER_ACTUAL_QUEUE_SIZE (CSI_DRIVER_QUEUE_SIZE + 1U)
/*
* The interrupt enable bits are in registers CSICR1[16:31], CSICR3[0:7],
* and CSICR18[2:9]. So merge them into an uint32_t value, place CSICR18 control
* bits to [8:15].
*/
#define CSI_CSICR1_INT_EN_MASK 0xFFFF0000U
#define CSI_CSICR3_INT_EN_MASK 0x000000FFU
#define CSI_CSICR18_INT_EN_MASK 0x0000FF00U
#if ((~CSI_CSICR1_INT_EN_MASK) & \
(CSI_CSICR1_EOF_INT_EN_MASK | CSI_CSICR1_COF_INT_EN_MASK | CSI_CSICR1_SF_OR_INTEN_MASK | \
CSI_CSICR1_RF_OR_INTEN_MASK | CSI_CSICR1_SFF_DMA_DONE_INTEN_MASK | CSI_CSICR1_STATFF_INTEN_MASK | \
CSI_CSICR1_FB2_DMA_DONE_INTEN_MASK | CSI_CSICR1_FB1_DMA_DONE_INTEN_MASK | CSI_CSICR1_RXFF_INTEN_MASK | \
CSI_CSICR1_SOF_INTEN_MASK))
#error CSI_CSICR1_INT_EN_MASK could not cover all interrupt bits in CSICR1.
#endif
#if ((~CSI_CSICR3_INT_EN_MASK) & (CSI_CSICR3_ECC_INT_EN_MASK | CSI_CSICR3_HRESP_ERR_EN_MASK))
#error CSI_CSICR3_INT_EN_MASK could not cover all interrupt bits in CSICR3.
#endif
#if ((~CSI_CSICR18_INT_EN_MASK) & ((CSI_CSICR18_FIELD0_DONE_IE_MASK | CSI_CSICR18_DMA_FIELD1_DONE_IE_MASK | CSI_CSICR18_BASEADDR_CHANGE_ERROR_IE_MASK) << 6U))
#error CSI_CSICR18_INT_EN_MASK could not cover all interrupt bits in CSICR18.
#endif
/*! @brief Error codes for the CSI driver. */
enum _csi_status
{
kStatus_CSI_NoEmptyBuffer = MAKE_STATUS(kStatusGroup_CSI, 0), /*!< No empty frame buffer in queue to load to CSI. */
kStatus_CSI_NoFullBuffer = MAKE_STATUS(kStatusGroup_CSI, 1), /*!< No full frame buffer in queue to read out. */
kStatus_CSI_QueueFull = MAKE_STATUS(kStatusGroup_CSI, 2), /*!< Queue is full, no room to save new empty buffer. */
kStatus_CSI_FrameDone = MAKE_STATUS(kStatusGroup_CSI, 3), /*!< New frame received and saved to queue. */
};
/*!
* @brief CSI work mode.
*
* The CCIR656 interlace mode is not supported currently.
*/
typedef enum _csi_work_mode
{
kCSI_GatedClockMode = CSI_CSICR1_GCLK_MODE(1U), /*!< HSYNC, VSYNC, and PIXCLK signals are used. */
kCSI_NonGatedClockMode = 0U, /*!< VSYNC, and PIXCLK signals are used. */
kCSI_CCIR656ProgressiveMode = CSI_CSICR1_CCIR_EN(1U), /*!< CCIR656 progressive mode. */
} csi_work_mode_t;
/*!
* @brief CSI data bus witdh.
*
* Currently only support 8-bit width.
*/
typedef enum _csi_data_bus
{
kCSI_DataBus8Bit, /*!< 8-bit data bus. */
} csi_data_bus_t;
/*! @brief CSI signal polarity. */
enum _csi_polarity_flags
{
kCSI_HsyncActiveLow = 0U, /*!< HSYNC is active low. */
kCSI_HsyncActiveHigh = CSI_CSICR1_HSYNC_POL_MASK, /*!< HSYNC is active high. */
kCSI_DataLatchOnRisingEdge = CSI_CSICR1_REDGE_MASK, /*!< Pixel data latched at rising edge of pixel clock. */
kCSI_DataLatchOnFallingEdge = 0U, /*!< Pixel data latched at falling edge of pixel clock. */
kCSI_VsyncActiveHigh = 0U, /*!< VSYNC is active high. */
kCSI_VsyncActiveLow = CSI_CSICR1_SOF_POL_MASK, /*!< VSYNC is active low. */
};
/*! @brief Configuration to initialize the CSI module. */
typedef struct _csi_config
{
uint16_t width; /*!< Pixels of the input frame. */
uint16_t height; /*!< Lines of the input frame. */
uint32_t polarityFlags; /*!< Timing signal polarity flags, OR'ed value of @ref _csi_polarity_flags. */
uint8_t bytesPerPixel; /*!< Bytes per pixel, valid values are:
- 2: Used for RGB565, YUV422, and so on.
- 3: Used for packed RGB888, packed YUV444, and so on.
- 4: Used for XRGB8888, XYUV444, and so on.
*/
uint16_t linePitch_Bytes; /*!< Frame buffer line pitch, must be 8-byte aligned. */
csi_work_mode_t workMode; /*!< CSI work mode. */
csi_data_bus_t dataBus; /*!< Data bus width. */
bool useExtVsync; /*!< In CCIR656 progressive mode, set true to use external VSYNC signal, set false
to use internal VSYNC signal decoded from SOF. */
} csi_config_t;
/*! @brief The CSI FIFO, used for FIFO operation. */
typedef enum _csi_fifo
{
kCSI_RxFifo = (1U << 0U), /*!< RXFIFO. */
kCSI_StatFifo = (1U << 1U), /*!< STAT FIFO. */
kCSI_AllFifo = 0x01 | 0x02, /*!< Both RXFIFO and STAT FIFO. */
} csi_fifo_t;
/*! @brief CSI feature interrupt source. */
enum _csi_interrupt_enable
{
kCSI_EndOfFrameInterruptEnable = CSI_CSICR1_EOF_INT_EN_MASK, /*!< End of frame interrupt enable. */
kCSI_ChangeOfFieldInterruptEnable = CSI_CSICR1_COF_INT_EN_MASK, /*!< Change of field interrupt enable. */
kCSI_StatFifoOverrunInterruptEnable = CSI_CSICR1_SF_OR_INTEN_MASK, /*!< STAT FIFO overrun interrupt enable. */
kCSI_RxFifoOverrunInterruptEnable = CSI_CSICR1_RF_OR_INTEN_MASK, /*!< RXFIFO overrun interrupt enable. */
kCSI_StatFifoDmaDoneInterruptEnable =
CSI_CSICR1_SFF_DMA_DONE_INTEN_MASK, /*!< STAT FIFO DMA done interrupt enable. */
kCSI_StatFifoFullInterruptEnable = CSI_CSICR1_STATFF_INTEN_MASK, /*!< STAT FIFO full interrupt enable. */
kCSI_RxBuffer1DmaDoneInterruptEnable =
CSI_CSICR1_FB2_DMA_DONE_INTEN_MASK, /*!< RX frame buffer 1 DMA transfer done. */
kCSI_RxBuffer0DmaDoneInterruptEnable =
CSI_CSICR1_FB1_DMA_DONE_INTEN_MASK, /*!< RX frame buffer 0 DMA transfer done. */
kCSI_RxFifoFullInterruptEnable = CSI_CSICR1_RXFF_INTEN_MASK, /*!< RXFIFO full interrupt enable. */
kCSI_StartOfFrameInterruptEnable = CSI_CSICR1_SOF_INTEN_MASK, /*!< Start of frame (SOF) interrupt enable. */
kCSI_EccErrorInterruptEnable = CSI_CSICR3_ECC_INT_EN_MASK, /*!< ECC error detection interrupt enable. */
kCSI_AhbResErrorInterruptEnable = CSI_CSICR3_HRESP_ERR_EN_MASK, /*!< AHB response Error interrupt enable. */
kCSI_BaseAddrChangeErrorInterruptEnable = CSI_CSICR18_BASEADDR_CHANGE_ERROR_IE_MASK << 6U, /*!< The DMA output buffer base address
changes before DMA completed. */
kCSI_Field0DoneInterruptEnable = CSI_CSICR18_FIELD0_DONE_IE_MASK << 6U, /*!< Field 0 done interrupt enable. */
kCSI_Field1DoneInterruptEnable = CSI_CSICR18_DMA_FIELD1_DONE_IE_MASK << 6U, /*!< Field 1 done interrupt enable. */
};
/*!
* @brief CSI status flags.
*
* The following status register flags can be cleared:
* - kCSI_EccErrorFlag
* - kCSI_AhbResErrorFlag
* - kCSI_ChangeOfFieldFlag
* - kCSI_StartOfFrameFlag
* - kCSI_EndOfFrameFlag
* - kCSI_RxBuffer1DmaDoneFlag
* - kCSI_RxBuffer0DmaDoneFlag
* - kCSI_StatFifoDmaDoneFlag
* - kCSI_StatFifoOverrunFlag
* - kCSI_RxFifoOverrunFlag
* - kCSI_Field0DoneFlag
* - kCSI_Field1DoneFlag
* - kCSI_BaseAddrChangeErrorFlag
*/
enum _csi_flags
{
kCSI_RxFifoDataReadyFlag = CSI_CSISR_DRDY_MASK, /*!< RXFIFO data ready. */
kCSI_EccErrorFlag = CSI_CSISR_ECC_INT_MASK, /*!< ECC error detected. */
kCSI_AhbResErrorFlag = CSI_CSISR_HRESP_ERR_INT_MASK, /*!< Hresponse (AHB bus response) Error. */
kCSI_ChangeOfFieldFlag = CSI_CSISR_COF_INT_MASK, /*!< Change of field. */
kCSI_Field0PresentFlag = CSI_CSISR_F1_INT_MASK, /*!< Field 0 present in CCIR mode. */
kCSI_Field1PresentFlag = CSI_CSISR_F2_INT_MASK, /*!< Field 1 present in CCIR mode. */
kCSI_StartOfFrameFlag = CSI_CSISR_SOF_INT_MASK, /*!< Start of frame (SOF) detected. */
kCSI_EndOfFrameFlag = CSI_CSISR_EOF_INT_MASK, /*!< End of frame (EOF) detected. */
kCSI_RxFifoFullFlag = CSI_CSISR_RxFF_INT_MASK, /*!< RXFIFO full (Number of data reaches trigger level). */
kCSI_RxBuffer1DmaDoneFlag = CSI_CSISR_DMA_TSF_DONE_FB2_MASK, /*!< RX frame buffer 1 DMA transfer done. */
kCSI_RxBuffer0DmaDoneFlag = CSI_CSISR_DMA_TSF_DONE_FB1_MASK, /*!< RX frame buffer 0 DMA transfer done. */
kCSI_StatFifoFullFlag = CSI_CSISR_STATFF_INT_MASK, /*!< STAT FIFO full (Reach trigger level). */
kCSI_StatFifoDmaDoneFlag = CSI_CSISR_DMA_TSF_DONE_SFF_MASK, /*!< STAT FIFO DMA transfer done. */
kCSI_StatFifoOverrunFlag = CSI_CSISR_SF_OR_INT_MASK, /*!< STAT FIFO overrun. */
kCSI_RxFifoOverrunFlag = CSI_CSISR_RF_OR_INT_MASK, /*!< RXFIFO overrun. */
kCSI_Field0DoneFlag = CSI_CSISR_DMA_FIELD0_DONE_MASK, /*!< Field 0 transfer done. */
kCSI_Field1DoneFlag = CSI_CSISR_DMA_FIELD1_DONE_MASK, /*!< Field 1 transfer done. */
kCSI_BaseAddrChangeErrorFlag = CSI_CSISR_BASEADDR_CHHANGE_ERROR_MASK, /*!< The DMA output buffer base address
changes before DMA completed. */
};
/* Forward declaration of the handle typedef. */
typedef struct _csi_handle csi_handle_t;
/*!
* @brief CSI transfer callback function.
*
* When a new frame is received and saved to the frame buffer queue, the callback
* is called and the pass the status @ref kStatus_CSI_FrameDone to upper layer.
*/
typedef void (*csi_transfer_callback_t)(CSI_Type *base, csi_handle_t *handle, status_t status, void *userData);
/*!
* @brief CSI handle structure.
*
* Please see the user guide for the details of the CSI driver queue mechanism.
*/
struct _csi_handle
{
uint32_t frameBufferQueue[CSI_DRIVER_ACTUAL_QUEUE_SIZE]; /*!< Frame buffer queue. */
volatile uint8_t queueUserReadIdx; /*!< Application gets full-filled frame buffer from this index. */
volatile uint8_t queueUserWriteIdx; /*!< Application puts empty frame buffer to this index. */
volatile uint8_t queueDrvReadIdx; /*!< Driver gets empty frame buffer from this index. */
volatile uint8_t queueDrvWriteIdx; /*!< Driver puts the full-filled frame buffer to this index. */
volatile uint8_t activeBufferNum; /*!< How many frame buffers are in progres currently. */
volatile uint8_t nextBufferIdx; /*!< The CSI frame buffer index to use for next frame. */
volatile bool transferStarted; /*!< User has called @ref CSI_TransferStart to start frame receiving. */
volatile bool transferOnGoing; /*!< CSI is working and receiving incoming frames. */
csi_transfer_callback_t callback; /*!< Callback function. */
void *userData; /*!< CSI callback function parameter.*/
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Initialize the CSI.
*
* This function enables the CSI peripheral clock, and resets the CSI registers.
*
* @param base CSI peripheral base address.
* @param config Pointer to the configuration structure.
*
* @retval kStatus_Success Initialize successfully.
* @retval kStatus_InvalidArgument Initialize failed because of invalid argument.
*/
status_t CSI_Init(CSI_Type *base, const csi_config_t *config);
/*!
* @brief De-initialize the CSI.
*
* This function disables the CSI peripheral clock.
*
* @param base CSI peripheral base address.
*/
void CSI_Deinit(CSI_Type *base);
/*!
* @brief Reset the CSI.
*
* This function resets the CSI peripheral registers to default status.
*
* @param base CSI peripheral base address.
*/
void CSI_Reset(CSI_Type *base);
/*!
* @brief Get the default configuration for to initialize the CSI.
*
* The default configuration value is:
*
* @code
config->width = 320U;
config->height = 240U;
config->polarityFlags = kCSI_HsyncActiveHigh | kCSI_DataLatchOnRisingEdge;
config->bytesPerPixel = 2U;
config->linePitch_Bytes = 320U * 2U;
config->workMode = kCSI_GatedClockMode;
config->dataBus = kCSI_DataBus8Bit;
config->useExtVsync = true;
@endcode
*
* @param config Pointer to the CSI configuration.
*/
void CSI_GetDefaultConfig(csi_config_t *config);
/* @} */
/*!
* @name Module operation
* @{
*/
/*!
* @brief Clear the CSI FIFO.
*
* This function clears the CSI FIFO.
*
* @param base CSI peripheral base address.
* @param fifo The FIFO to clear.
*/
void CSI_ClearFifo(CSI_Type *base, csi_fifo_t fifo);
/*!
* @brief Reflash the CSI FIFO DMA.
*
* This function reflashes the CSI FIFO DMA.
*
* For RXFIFO, there are two frame buffers. When the CSI module started, it saves
* the frames to frame buffer 0 then frame buffer 1, the two buffers will be
* written by turns. After reflash DMA using this function, the CSI is reset to
* save frame to buffer 0.
*
* @param base CSI peripheral base address.
* @param fifo The FIFO DMA to reflash.
*/
void CSI_ReflashFifoDma(CSI_Type *base, csi_fifo_t fifo);
/*!
* @brief Enable or disable the CSI FIFO DMA request.
*
* @param base CSI peripheral base address.
* @param fifo The FIFO DMA reques to enable or disable.
* @param enable True to enable, false to disable.
*/
void CSI_EnableFifoDmaRequest(CSI_Type *base, csi_fifo_t fifo, bool enable);
/*!
* @brief Start to receive data.
*
* @param base CSI peripheral base address.
*/
static inline void CSI_Start(CSI_Type *base)
{
CSI_EnableFifoDmaRequest(base, kCSI_RxFifo, true);
base->CSICR18 |= CSI_CSICR18_CSI_ENABLE_MASK;
}
/*!
* @brief Stop to receiving data.
*
* @param base CSI peripheral base address.
*/
static inline void CSI_Stop(CSI_Type *base)
{
base->CSICR18 &= ~CSI_CSICR18_CSI_ENABLE_MASK;
CSI_EnableFifoDmaRequest(base, kCSI_RxFifo, false);
}
/*!
* @brief Set the RX frame buffer address.
*
* @param base CSI peripheral base address.
* @param index Buffer index.
* @param addr Frame buffer address to set.
*/
void CSI_SetRxBufferAddr(CSI_Type *base, uint8_t index, uint32_t addr);
/* @} */
/*!
* @name Interrupts
* @{
*/
/*!
* @brief Enables CSI interrupt requests.
*
* @param base CSI peripheral base address.
* @param mask The interrupts to enable, pass in as OR'ed value of @ref _csi_interrupt_enable.
*/
void CSI_EnableInterrupts(CSI_Type *base, uint32_t mask);
/*!
* @brief Disable CSI interrupt requests.
*
* @param base CSI peripheral base address.
* @param mask The interrupts to disable, pass in as OR'ed value of @ref _csi_interrupt_enable.
*/
void CSI_DisableInterrupts(CSI_Type *base, uint32_t mask);
/* @} */
/*!
* @name Status
* @{
*/
/*!
* @brief Gets the CSI status flags.
*
* @param base CSI peripheral base address.
* @return status flag, it is OR'ed value of @ref _csi_flags.
*/
static inline uint32_t CSI_GetStatusFlags(CSI_Type *base)
{
return base->CSISR;
}
/*!
* @brief Clears the CSI status flag.
*
* The flags to clear are passed in as OR'ed value of @ref _csi_flags. The following
* flags are cleared automatically by hardware:
*
* - @ref kCSI_RxFifoFullFlag,
* - @ref kCSI_StatFifoFullFlag,
* - @ref kCSI_Field0PresentFlag,
* - @ref kCSI_Field1PresentFlag,
* - @ref kCSI_RxFifoDataReadyFlag,
*
* @param base CSI peripheral base address.
* @param statusMask The status flags mask, OR'ed value of @ref _csi_flags.
*/
static inline void CSI_ClearStatusFlags(CSI_Type *base, uint32_t statusMask)
{
base->CSISR = statusMask;
}
/* @} */
/*!
* @name Transactional
* @{
*/
/*!
* @brief Initializes the CSI handle.
*
* This function initializes CSI handle, it should be called before any other
* CSI transactional functions.
*
* @param base CSI peripheral base address.
* @param handle Pointer to the handle structure.
* @param callback Callback function for CSI transfer.
* @param userData Callback function parameter.
*
* @retval kStatus_Success Handle created successfully.
*/
status_t CSI_TransferCreateHandle(CSI_Type *base,
csi_handle_t *handle,
csi_transfer_callback_t callback,
void *userData);
/*!
* @brief Start the transfer using transactional functions.
*
* When the empty frame buffers have been submit to CSI driver using function
* @ref CSI_TransferSubmitEmptyBuffer, user could call this function to start
* the transfer. The incoming frame will be saved to the empty frame buffer,
* and user could be optionally notified through callback function.
*
* @param base CSI peripheral base address.
* @param handle Pointer to the handle structure.
*
* @retval kStatus_Success Started successfully.
* @retval kStatus_CSI_NoEmptyBuffer Could not start because no empty frame buffer in queue.
*/
status_t CSI_TransferStart(CSI_Type *base, csi_handle_t *handle);
/*!
* @brief Stop the transfer using transactional functions.
*
* The driver does not clean the full frame buffers in queue. In other words, after
* calling this function, user still could get the full frame buffers in queue
* using function @ref CSI_TransferGetFullBuffer.
*
* @param base CSI peripheral base address.
* @param handle Pointer to the handle structure.
*
* @retval kStatus_Success Stoped successfully.
*/
status_t CSI_TransferStop(CSI_Type *base, csi_handle_t *handle);
/*!
* @brief Submit empty frame buffer to queue.
*
* This function could be called before @ref CSI_TransferStart or after @ref
* CSI_TransferStart. If there is no room in queue to store the empty frame
* buffer, this function returns error.
*
* @param base CSI peripheral base address.
* @param handle Pointer to the handle structure.
* @param frameBuffer Empty frame buffer to submit.
*
* @retval kStatus_Success Started successfully.
* @retval kStatus_CSI_QueueFull Could not submit because there is no room in queue.
*/
status_t CSI_TransferSubmitEmptyBuffer(CSI_Type *base, csi_handle_t *handle, uint32_t frameBuffer);
/*!
* @brief Get one full frame buffer from queue.
*
* After the transfer started using function @ref CSI_TransferStart, the incoming
* frames will be saved to the empty frame buffers in queue. This function gets
* the full-filled frame buffer from the queue. If there is no full frame buffer
* in queue, this function returns error.
*
* @param base CSI peripheral base address.
* @param handle Pointer to the handle structure.
* @param frameBuffer Full frame buffer.
*
* @retval kStatus_Success Started successfully.
* @retval kStatus_CSI_NoFullBuffer There is no full frame buffer in queue.
*/
status_t CSI_TransferGetFullBuffer(CSI_Type *base, csi_handle_t *handle, uint32_t *frameBuffer);
/*!
* @brief CSI IRQ handle function.
*
* This function handles the CSI IRQ request to work with CSI driver transactional
* APIs.
*
* @param base CSI peripheral base address.
* @param handle CSI handle pointer.
*/
void CSI_TransferHandleIRQ(CSI_Type *base, csi_handle_t *handle);
/* @} */
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_CSI_H_ */

View File

@@ -0,0 +1,345 @@
/*
* The Clear BSD License
* Copyright (c) 2017, NXP
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#include "fsl_dcdc.h"
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get instance number for DCDC module.
*
* @param base DCDC peripheral base address
*/
static uint32_t DCDC_GetInstance(DCDC_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to DCDC bases for each instance. */
static DCDC_Type *const s_dcdcBases[] = DCDC_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to DCDC clocks for each instance. */
static const clock_ip_name_t s_dcdcClocks[] = DCDC_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t DCDC_GetInstance(DCDC_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_dcdcBases); instance++)
{
if (s_dcdcBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_dcdcBases));
return instance;
}
void DCDC_Init(DCDC_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the clock. */
CLOCK_EnableClock(s_dcdcClocks[DCDC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
void DCDC_Deinit(DCDC_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable the clock. */
CLOCK_DisableClock(s_dcdcClocks[DCDC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
void DCDC_SetClockSource(DCDC_Type *base, dcdc_clock_source_t clockSource)
{
uint32_t tmp32;
/* Configure the DCDC_REG0 register. */
tmp32 = base->REG0 &
~(DCDC_REG0_XTAL_24M_OK_MASK | DCDC_REG0_DISABLE_AUTO_CLK_SWITCH_MASK | DCDC_REG0_SEL_CLK_MASK |
DCDC_REG0_PWD_OSC_INT_MASK);
switch (clockSource)
{
case kDCDC_ClockInternalOsc:
tmp32 |= DCDC_REG0_DISABLE_AUTO_CLK_SWITCH_MASK;
break;
case kDCDC_ClockExternalOsc:
/* Choose the external clock and disable the internal clock. */
tmp32 |= DCDC_REG0_DISABLE_AUTO_CLK_SWITCH_MASK | DCDC_REG0_SEL_CLK_MASK | DCDC_REG0_PWD_OSC_INT_MASK;
break;
case kDCDC_ClockAutoSwitch:
/* Set to switch from internal ring osc to xtal 24M if auto mode is enabled. */
tmp32 |= DCDC_REG0_XTAL_24M_OK_MASK;
break;
default:
break;
}
base->REG0 = tmp32;
}
void DCDC_GetDefaultDetectionConfig(dcdc_detection_config_t *config)
{
assert(NULL != config);
config->enableXtalokDetection = false;
config->powerDownOverVoltageDetection = true;
config->powerDownLowVlotageDetection = false;
config->powerDownOverCurrentDetection = true;
config->powerDownPeakCurrentDetection = true;
config->powerDownZeroCrossDetection = true;
config->OverCurrentThreshold = kDCDC_OverCurrentThresholdAlt0;
config->PeakCurrentThreshold = kDCDC_PeakCurrentThresholdAlt0;
}
void DCDC_SetDetectionConfig(DCDC_Type *base, const dcdc_detection_config_t *config)
{
assert(NULL != config);
uint32_t tmp32;
/* Configure the DCDC_REG0 register. */
tmp32 = base->REG0 &
~(DCDC_REG0_XTALOK_DISABLE_MASK | DCDC_REG0_PWD_HIGH_VOLT_DET_MASK | DCDC_REG0_PWD_CMP_BATT_DET_MASK |
DCDC_REG0_PWD_OVERCUR_DET_MASK | DCDC_REG0_PWD_CUR_SNS_CMP_MASK | DCDC_REG0_PWD_ZCD_MASK |
DCDC_REG0_CUR_SNS_THRSH_MASK | DCDC_REG0_OVERCUR_TRIG_ADJ_MASK);
tmp32 |= DCDC_REG0_CUR_SNS_THRSH(config->PeakCurrentThreshold) |
DCDC_REG0_OVERCUR_TRIG_ADJ(config->OverCurrentThreshold);
if (false == config->enableXtalokDetection)
{
tmp32 |= DCDC_REG0_XTALOK_DISABLE_MASK;
}
if (config->powerDownOverVoltageDetection)
{
tmp32 |= DCDC_REG0_PWD_HIGH_VOLT_DET_MASK;
}
if (config->powerDownLowVlotageDetection)
{
tmp32 |= DCDC_REG0_PWD_CMP_BATT_DET_MASK;
}
if (config->powerDownOverCurrentDetection)
{
tmp32 |= DCDC_REG0_PWD_OVERCUR_DET_MASK;
}
if (config->powerDownPeakCurrentDetection)
{
tmp32 |= DCDC_REG0_PWD_CUR_SNS_CMP_MASK;
}
if (config->powerDownZeroCrossDetection)
{
tmp32 |= DCDC_REG0_PWD_ZCD_MASK;
}
base->REG0 = tmp32;
}
void DCDC_GetDefaultLowPowerConfig(dcdc_low_power_config_t *config)
{
assert(NULL != config);
config->enableOverloadDetection = true;
config->enableAdjustHystereticValue = false;
config->countChargingTimePeriod = kDCDC_CountChargingTimePeriod8Cycle;
config->countChargingTimeThreshold = kDCDC_CountChargingTimeThreshold32;
}
void DCDC_SetLowPowerConfig(DCDC_Type *base, const dcdc_low_power_config_t *config)
{
assert(NULL != config);
uint32_t tmp32;
/* Configure the DCDC_REG0 register. */
tmp32 = base->REG0 &
~(DCDC_REG0_EN_LP_OVERLOAD_SNS_MASK | DCDC_REG0_LP_HIGH_HYS_MASK | DCDC_REG0_LP_OVERLOAD_FREQ_SEL_MASK |
DCDC_REG0_LP_OVERLOAD_THRSH_MASK);
tmp32 |= DCDC_REG0_LP_OVERLOAD_FREQ_SEL(config->countChargingTimePeriod) |
DCDC_REG0_LP_OVERLOAD_THRSH(config->countChargingTimeThreshold);
if (config->enableOverloadDetection)
{
tmp32 |= DCDC_REG0_EN_LP_OVERLOAD_SNS_MASK;
}
if (config->enableAdjustHystereticValue)
{
tmp32 |= DCDC_REG0_LP_HIGH_HYS_MASK;
}
base->REG0 = tmp32;
}
uint32_t DCDC_GetstatusFlags(DCDC_Type *base)
{
uint32_t tmp32 = 0U;
if (DCDC_REG0_STS_DC_OK_MASK == (DCDC_REG0_STS_DC_OK_MASK & base->REG0))
{
tmp32 |= kDCDC_LockedOKStatus;
}
return tmp32;
}
void DCDC_ResetCurrentAlertSignal(DCDC_Type *base, bool enable)
{
if (enable)
{
base->REG0 |= DCDC_REG0_CURRENT_ALERT_RESET_MASK;
}
else
{
base->REG0 &= ~DCDC_REG0_CURRENT_ALERT_RESET_MASK;
}
}
void DCDC_GetDefaultLoopControlConfig(dcdc_loop_control_config_t *config)
{
assert(NULL != config);
config->enableCommonHysteresis = false;
config->enableCommonThresholdDetection = false;
config->enableInvertHysteresisSign = false;
config->enableRCThresholdDetection = false;
config->enableRCScaleCircuit = 0U;
config->complementFeedForwardStep = 0U;
config->controlParameterMagnitude = 2U;
config->integralProportionalRatio = 2U;
}
void DCDC_SetLoopControlConfig(DCDC_Type *base, const dcdc_loop_control_config_t *config)
{
assert(NULL != config);
uint32_t tmp32;
/* Configure the DCDC_REG1 register. */
tmp32 = base->REG1 & ~(DCDC_REG1_LOOPCTRL_EN_HYST_MASK | DCDC_REG1_LOOPCTRL_HST_THRESH_MASK);
if (config->enableCommonHysteresis)
{
tmp32 |= DCDC_REG1_LOOPCTRL_EN_HYST_MASK;
}
if (config->enableCommonThresholdDetection)
{
tmp32 |= DCDC_REG1_LOOPCTRL_HST_THRESH_MASK;
}
base->REG1 = tmp32;
/* configure the DCDC_REG2 register. */
tmp32 = base->REG2 &
~(DCDC_REG2_LOOPCTRL_HYST_SIGN_MASK | DCDC_REG2_LOOPCTRL_RCSCALE_THRSH_MASK |
DCDC_REG2_LOOPCTRL_EN_RCSCALE_MASK | DCDC_REG2_LOOPCTRL_DC_FF_MASK | DCDC_REG2_LOOPCTRL_DC_R_MASK |
DCDC_REG2_LOOPCTRL_DC_C_MASK);
tmp32 |= DCDC_REG2_LOOPCTRL_DC_FF(config->complementFeedForwardStep) |
DCDC_REG2_LOOPCTRL_DC_R(config->controlParameterMagnitude) |
DCDC_REG2_LOOPCTRL_DC_C(config->integralProportionalRatio) |
DCDC_REG2_LOOPCTRL_EN_RCSCALE(config->enableRCScaleCircuit);
if (config->enableInvertHysteresisSign)
{
tmp32 |= DCDC_REG2_LOOPCTRL_HYST_SIGN_MASK;
}
if (config->enableRCThresholdDetection)
{
tmp32 |= DCDC_REG2_LOOPCTRL_RCSCALE_THRSH_MASK;
}
base->REG2 = tmp32;
}
void DCDC_SetMinPowerConfig(DCDC_Type *base, const dcdc_min_power_config_t *config)
{
assert(NULL != config);
uint32_t tmp32;
tmp32 = base->REG3 & ~DCDC_REG3_MINPWR_DC_HALFCLK_MASK;
if (config->enableUseHalfFreqForContinuous)
{
tmp32 |= DCDC_REG3_MINPWR_DC_HALFCLK_MASK;
}
base->REG3 = tmp32;
}
void DCDC_AdjustTargetVoltage(DCDC_Type *base, uint32_t VDDRun, uint32_t VDDStandby)
{
uint32_t tmp32;
/* Unlock the step for the output. */
base->REG3 &= ~DCDC_REG3_DISABLE_STEP_MASK;
/* Configure the DCDC_REG3 register. */
tmp32 = base->REG3 & ~(DCDC_REG3_TARGET_LP_MASK | DCDC_REG3_TRG_MASK);
tmp32 |= DCDC_REG3_TARGET_LP(VDDStandby) | DCDC_REG3_TRG(VDDRun);
base->REG3 = tmp32;
/* DCDC_STS_DC_OK bit will be de-asserted after target register changes. After output voltage settling to new
* target value, DCDC_STS_DC_OK will be asserted. */
while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & base->REG0))
{
}
}
void DCDC_SetInternalRegulatorConfig(DCDC_Type *base, const dcdc_internal_regulator_config_t *config)
{
assert(NULL != config);
uint32_t tmp32;
/* Configure the DCDC_REG1 register. */
tmp32 = base->REG1 & ~(DCDC_REG1_REG_FBK_SEL_MASK | DCDC_REG1_REG_RLOAD_SW_MASK);
tmp32 |= DCDC_REG1_REG_FBK_SEL(config->feedbackPoint);
if (config->enableLoadResistor)
{
tmp32 |= DCDC_REG1_REG_RLOAD_SW_MASK;
}
base->REG1 = tmp32;
}
void DCDC_BootIntoDCM(DCDC_Type *base)
{
base->REG0 &= ~(DCDC_REG0_PWD_ZCD_MASK | DCDC_REG0_PWD_CMP_OFFSET_MASK);
base->REG2 = (~DCDC_REG2_LOOPCTRL_EN_RCSCALE_MASK & base->REG2) | DCDC_REG2_LOOPCTRL_EN_RCSCALE(0x4U) |
DCDC_REG2_DCM_SET_CTRL_MASK;
}
void DCDC_BootIntoCCM(DCDC_Type *base)
{
base->REG0 = (~DCDC_REG0_PWD_CMP_OFFSET_MASK & base->REG0) | DCDC_REG0_PWD_ZCD_MASK;
base->REG2 = (~DCDC_REG2_LOOPCTRL_EN_RCSCALE_MASK & base->REG2) | DCDC_REG2_LOOPCTRL_EN_RCSCALE(0x3U);
}

View File

@@ -0,0 +1,490 @@
/*
* The Clear BSD License
* Copyright (c) 2017, NXP
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#ifndef __FSL_DCDC_H__
#define __FSL_DCDC_H__
#include "fsl_common.h"
/*!
* @addtogroup dcdc
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief DCDC driver version. */
#define FSL_DCDC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */
/*!
* @brief DCDC status flags.
*/
enum _dcdc_status_flags_t
{
kDCDC_LockedOKStatus = (1U << 0U), /*!< Indicate DCDC status. 1'b1: DCDC already settled 1'b0: DCDC is settling. */
};
/*!
* @brief The current bias of low power comparator.
*/
typedef enum _dcdc_comparator_current_bias
{
kDCDC_ComparatorCurrentBias50nA = 0U, /*!< The current bias of low power comparator is 50nA. */
kDCDC_ComparatorCurrentBias100nA = 1U, /*!< The current bias of low power comparator is 100nA. */
kDCDC_ComparatorCurrentBias200nA = 2U, /*!< The current bias of low power comparator is 200nA. */
kDCDC_ComparatorCurrentBias400nA = 3U, /*!< The current bias of low power comparator is 400nA. */
} dcdc_comparator_current_bias_t;
/*!
* @brief The threshold of over current detection.
*/
typedef enum _dcdc_over_current_threshold
{
kDCDC_OverCurrentThresholdAlt0 = 0U, /*!< 1A in the run mode, 0.25A in the power save mode. */
kDCDC_OverCurrentThresholdAlt1 = 1U, /*!< 2A in the run mode, 0.25A in the power save mode. */
kDCDC_OverCurrentThresholdAlt2 = 2U, /*!< 1A in the run mode, 0.2A in the power save mode. */
kDCDC_OverCurrentThresholdAlt3 = 3U, /*!< 2A in the run mode, 0.2A in the power save mode. */
} dcdc_over_current_threshold_t;
/*!
* @brief The threshold if peak current detection.
*/
typedef enum _dcdc_peak_current_threshold
{
kDCDC_PeakCurrentThresholdAlt0 = 0U, /*!< 150mA peak current threshold. */
kDCDC_PeakCurrentThresholdAlt1 = 1U, /*!< 250mA peak current threshold. */
kDCDC_PeakCurrentThresholdAlt2 = 2U, /*!< 350mA peak current threshold. */
kDCDC_PeakCurrentThresholdAlt3 = 3U, /*!< 450mA peak current threshold. */
kDCDC_PeakCurrentThresholdAlt4 = 4U, /*!< 550mA peak current threshold. */
kDCDC_PeakCurrentThresholdAlt5 = 5U, /*!< 650mA peak current threshold. */
} dcdc_peak_current_threshold_t;
/*!
* @brief The period of counting the charging times in power save mode.
*/
typedef enum _dcdc_count_charging_time_period
{
kDCDC_CountChargingTimePeriod8Cycle = 0U, /*!< Eight 32k cycle. */
kDCDC_CountChargingTimePeriod16Cycle = 1U, /*!< Sixteen 32k cycle. */
} dcdc_count_charging_time_period_t;
/*!
* @brief The threshold of the counting number of charging times
*/
typedef enum _dcdc_count_charging_time_threshold
{
kDCDC_CountChargingTimeThreshold32 = 0U, /*!< 0x0: 32. */
kDCDC_CountChargingTimeThreshold64 = 1U, /*!< 0x1: 64. */
kDCDC_CountChargingTimeThreshold16 = 2U, /*!< 0x2: 16. */
kDCDC_CountChargingTimeThreshold8 = 3U, /*!< 0x3: 8. */
} dcdc_count_charging_time_threshold_t;
/*!
* @brief Oscillator clock option.
*/
typedef enum _dcdc_clock_source
{
kDCDC_ClockAutoSwitch = 0U, /*!< Automatic clock switch from internal oscillator to external clock. */
kDCDC_ClockInternalOsc = 1U, /*!< Use internal oscillator. */
kDCDC_ClockExternalOsc = 2U, /*!< Use external 24M crystal oscillator. */
} dcdc_clock_source_t;
/*!
* @brief Configuration for DCDC detection.
*/
typedef struct _dcdc_detection_config
{
bool enableXtalokDetection; /*!< Enable xtalok detection circuit. */
bool powerDownOverVoltageDetection; /*!< Power down over-voltage detection comparator. */
bool powerDownLowVlotageDetection; /*!< Power down low-voltage detection comparator. */
bool powerDownOverCurrentDetection; /*!< Power down over-current detection. */
bool powerDownPeakCurrentDetection; /*!< Power down peak-current detection. */
bool powerDownZeroCrossDetection; /*!< Power down the zero cross detection function for discontinuous conductor
mode. */
dcdc_over_current_threshold_t OverCurrentThreshold; /*!< The threshold of over current detection. */
dcdc_peak_current_threshold_t PeakCurrentThreshold; /*!< The threshold of peak current detection. */
} dcdc_detection_config_t;
/*!
* @brief Configuration for the loop control.
*/
typedef struct _dcdc_loop_control_config
{
bool enableCommonHysteresis; /*!< Enable hysteresis in switching converter common mode analog comparators.
This feature will improve transient supply ripple and efficiency. */
bool enableCommonThresholdDetection; /*!< Increase the threshold detection for common mode analog comparator. */
bool enableInvertHysteresisSign; /*!< Invert the sign of the hysteresis in DC-DC analog comparators. */
bool enableRCThresholdDetection; /*!< Increase the threshold detection for RC scale circuit. */
uint32_t enableRCScaleCircuit; /*!< Available range is 0~7. Enable analog circuit of DC-DC converter to respond
faster under transient load conditions. */
uint32_t complementFeedForwardStep; /*!< Available range is 0~7. Two's complement feed forward step in duty cycle in
the switching DC-DC converter. Each time this field makes a transition from
0x0, the loop filter of the DC-DC converter is stepped once by a value
proportional to the change. This can be used to force a certain control loop
behavior, such as improving response under known heavy load transients. */
uint32_t controlParameterMagnitude; /*!< Available range is 0~15. Magnitude of proportional control parameter in the
switching DC-DC converter control loop. */
uint32_t integralProportionalRatio; /*!< Available range is 0~3.Ratio of integral control parameter to proportional
control parameter in the switching DC-DC converter, and can be used to
optimize efficiency and loop response. */
} dcdc_loop_control_config_t;
/*!
* @brief Configuration for DCDC low power.
*/
typedef struct _dcdc_low_power_config
{
bool enableOverloadDetection; /*!< Enable the overload detection in power save mode, if current is larger than the
overloading threshold (typical value is 50 mA), DCDC will switch to the run mode
automatically. */
bool enableAdjustHystereticValue; /*!< Adjust hysteretic value in low power from 12.5mV to 25mV. */
dcdc_count_charging_time_period_t
countChargingTimePeriod; /*!< The period of counting the charging times in power save mode. */
dcdc_count_charging_time_threshold_t
countChargingTimeThreshold; /*!< the threshold of the counting number of charging times during
the period that lp_overload_freq_sel sets in power save mode. */
} dcdc_low_power_config_t;
/*!
* @brief Configuration for DCDC internal regulator.
*/
typedef struct _dcdc_internal_regulator_config
{
bool enableLoadResistor; /*!< control the load resistor of the internal regulator of DCDC, the load resistor is
connected as default "true", and need set to "false" to disconnect the load
resistor. */
uint32_t feedbackPoint; /*!< Available range is 0~3. Select the feedback point of the internal regulator. */
} dcdc_internal_regulator_config_t;
/*!
* @brief Configuration for min power setting.
*/
typedef struct _dcdc_min_power_config
{
bool enableUseHalfFreqForContinuous; /*!< Set DCDC clock to half frequency for the continuous mode. */
} dcdc_min_power_config_t;
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* API
******************************************************************************/
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Enable the access to DCDC registers.
*
* @param base DCDC peripheral base address.
*/
void DCDC_Init(DCDC_Type *base);
/*!
* @brief Disable the access to DCDC registers.
*
* @param base DCDC peripheral base address.
*/
void DCDC_Deinit(DCDC_Type *base);
/* @} */
/*!
* @name Status
* @{
*/
/*!
* @brief Get DCDC status flags.
*
* @param base peripheral base address.
* @return Mask of asserted status flags. See to "_dcdc_status_flags_t".
*/
uint32_t DCDC_GetstatusFlags(DCDC_Type *base);
/* @} */
/*!
* @name Misc control.
* @{
*/
/*!
* @brief Enable the output range comparator.
*
* The output range comparator is disabled by default.
*
* @param base DCDC peripheral base address.
* @param enable Enable the feature or not.
*/
static inline void DCDC_EnableOutputRangeComparator(DCDC_Type *base, bool enable)
{
if (enable)
{
base->REG0 &= ~DCDC_REG0_PWD_CMP_OFFSET_MASK;
}
else
{
base->REG0 |= DCDC_REG0_PWD_CMP_OFFSET_MASK;
}
}
/*!
* @brief Configure the DCDC clock source.
*
* @param base DCDC peripheral base address.
* @param clockSource Clock source for DCDC. See to "dcdc_clock_source_t".
*/
void DCDC_SetClockSource(DCDC_Type *base, dcdc_clock_source_t clockSource);
/*!
* @brief Get the default setting for detection configuration.
*
* The default configuration are set according to responding registers' setting when powered on.
* They are:
* @code
* config->enableXtalokDetection = false;
* config->powerDownOverVoltageDetection = true;
* config->powerDownLowVlotageDetection = false;
* config->powerDownOverCurrentDetection = true;
* config->powerDownPeakCurrentDetection = true;
* config->powerDownZeroCrossDetection = true;
* config->OverCurrentThreshold = kDCDC_OverCurrentThresholdAlt0;
* config->PeakCurrentThreshold = kDCDC_PeakCurrentThresholdAlt0;
* @endcode
*
* @param config Pointer to configuration structure. See to "dcdc_detection_config_t"
*/
void DCDC_GetDefaultDetectionConfig(dcdc_detection_config_t *config);
/*!
* @breif Configure the DCDC detection.
*
* @param base DCDC peripheral base address.
* @param config Pointer to configuration structure. See to "dcdc_detection_config_t"
*/
void DCDC_SetDetectionConfig(DCDC_Type *base, const dcdc_detection_config_t *config);
/*!
* @brief Get the default setting for low power configuration.
*
* The default configuration are set according to responding registers' setting when powered on.
* They are:
* @code
* config->enableOverloadDetection = true;
* config->enableAdjustHystereticValue = false;
* config->countChargingTimePeriod = kDCDC_CountChargingTimePeriod8Cycle;
* config->countChargingTimeThreshold = kDCDC_CountChargingTimeThreshold32;
* @endcode
*
* @param config Pointer to configuration structure. See to "dcdc_low_power_config_t"
*/
void DCDC_GetDefaultLowPowerConfig(dcdc_low_power_config_t *config);
/*!
* @brief Configure the DCDC low power.
*
* @param base DCDC peripheral base address.
* @param config Pointer to configuration structure. See to "dcdc_low_power_config_t".
*/
void DCDC_SetLowPowerConfig(DCDC_Type *base, const dcdc_low_power_config_t *config);
/*!
* @brief Reset current alert signal. Alert signal is generate by peak current detection.
*
* @param base DCDC peripheral base address.
* @param enable Switcher to reset signal. True means reset signal. False means don't reset signal.
*/
void DCDC_ResetCurrentAlertSignal(DCDC_Type *base, bool enable);
/*!
* @brief Set the bangap trim value to trim bandgap voltage.
*
* @param base DCDC peripheral base address.
* @param TrimValue The bangap trim value. Available range is 0U-31U.
*/
static inline void DCDC_SetBandgapVoltageTrimValue(DCDC_Type *base, uint32_t trimValue)
{
base->REG1 &= ~DCDC_REG1_VBG_TRIM_MASK;
base->REG1 |= DCDC_REG1_VBG_TRIM(trimValue);
}
/*!
* @brief Get the default setting for loop control configuration.
*
* The default configuration are set according to responding registers' setting when powered on.
* They are:
* @code
* config->enableCommonHysteresis = false;
* config->enableCommonThresholdDetection = false;
* config->enableInvertHysteresisSign = false;
* config->enableRCThresholdDetection = false;
* config->enableRCScaleCircuit = 0U;
* config->complementFeedForwardStep = 0U;
* config->controlParameterMagnitude = 2U;
* config->integralProportionalRatio = 2U;
* @endcode
*
* @param config Pointer to configuration structure. See to "dcdc_loop_control_config_t"
*/
void DCDC_GetDefaultLoopControlConfig(dcdc_loop_control_config_t *config);
/*!
* @brief Configure the DCDC loop control.
*
* @param base DCDC peripheral base address.
* @param config Pointer to configuration structure. See to "dcdc_loop_control_config_t".
*/
void DCDC_SetLoopControlConfig(DCDC_Type *base, const dcdc_loop_control_config_t *config);
/*!
* @brief Configure for the min power.
*
* @param base DCDC peripheral base address.
* @param config Pointer to configuration structure. See to "dcdc_min_power_config_t".
*/
void DCDC_SetMinPowerConfig(DCDC_Type *base, const dcdc_min_power_config_t *config);
/*!
* @brief Set the current bias of low power comparator.
*
* @param base DCDC peripheral base address.
* @param biasVaule The current bias of low power comparator. Refer to "dcdc_comparator_current_bias_t".
*/
static inline void DCDC_SetLPComparatorBiasValue(DCDC_Type *base, dcdc_comparator_current_bias_t biasVaule)
{
base->REG1 &= ~DCDC_REG1_LP_CMP_ISRC_SEL_MASK;
base->REG1 |= DCDC_REG1_LP_CMP_ISRC_SEL(biasVaule);
}
static inline void DCDC_LockTargetVoltage(DCDC_Type *base)
{
base->REG3 |= DCDC_REG3_DISABLE_STEP_MASK;
}
/*!
* @brief Adjust the target voltage of VDD_SOC in run mode and low power mode.
*
* This function is to adjust the target voltage of DCDC output. Change them and finally wait until the output is
* stabled.
* Set the target value of run mode the same as low power mode before entering power save mode, because DCDC will switch
* back to run mode if it detects the current loading is larger than about 50 mA(typical value).
*
* @param base DCDC peripheral base address.
* @param VDDRun Target value in run mode. 25 mV each step from 0x00 to 0x1F. 00 is for 0.8V, 0x1F is for 1.575V.
* @param VDDStandby Target value in low power mode. 25 mV each step from 0x00 to 0x4. 00 is for 0.9V, 0x4 is for 1.0V.
*/
void DCDC_AdjustTargetVoltage(DCDC_Type *base, uint32_t VDDRun, uint32_t VDDStandby);
/*!
* @brief Configure the DCDC internal regulator.
*
* @param base DCDC peripheral base address.
* @param config Pointer to configuration structure. See to "dcdc_internal_regulator_config_t".
*/
void DCDC_SetInternalRegulatorConfig(DCDC_Type *base, const dcdc_internal_regulator_config_t *config);
/*!
* @brief Ajust delay to reduce ground noise.
*
* @param base DCDC peripheral base address.
* @param enable Enable the feature or not.
*/
static inline void DCDC_EnableAdjustDelay(DCDC_Type *base, bool enable)
{
if (enable)
{
base->REG3 |= DCDC_REG3_MISC_DELAY_TIMING_MASK;
}
else
{
base->REG3 &= ~DCDC_REG3_MISC_DELAY_TIMING_MASK;
}
}
/*!
* @brief Enable/Disable to improve the transition from heavy load to light load. It is valid while zero
* cross detection is enabled. If ouput exceeds the threshold, DCDC would return CCM from DCM.
*
* @param base DCDC peripheral base address.
* @param enable Enable the feature or not.
*/
static inline void DCDC_EnableImproveTransition(DCDC_Type *base, bool enable)
{
if (enable)
{
base->REG2 |= DCDC_REG2_DCM_SET_CTRL_MASK;
}
else
{
base->REG2 &= ~DCDC_REG2_DCM_SET_CTRL_MASK;
}
}
/* @} */
/*!
* @name Application guideline.
* @{
*/
/*!
* @brief Boot DCDC into DCM(discontinous conduction mode).
*
* pwd_zcd=0x0;
* pwd_cmp_offset=0x0;
* dcdc_loopctrl_en_rcscale=0x3 or 0x5;
* DCM_set_ctrl=1'b1;
*
* @param base DCDC peripheral base address.
*/
void DCDC_BootIntoDCM(DCDC_Type *base);
/*!
* @brief Boot DCDC into CCM(continous conduction mode).
*
* pwd_zcd=0x1;
* pwd_cmp_offset=0x0;
* dcdc_loopctrl_en_rcscale=0x3;
*
* @param base DCDC peripheral base address.
*/
void DCDC_BootIntoCCM(DCDC_Type *base);
#if defined(__cplusplus)
}
#endif
#endif /* __FSL_DCDC_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,557 @@
/*
* The Clear BSD License
* Copyright 2017 NXP
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#ifndef _FSL_DCP_H_
#define _FSL_DCP_H_
#include "fsl_common.h"
/*! @brief DCP status return codes. */
enum _dcp_status
{
kStatus_DCP_Again = MAKE_STATUS(kStatusGroup_DCP, 0), /*!< Non-blocking function shall be called again. */
};
/*******************************************************************************
* Definitions
*******************************************************************************/
/*!
* @addtogroup dcp_driver
* @{
*/
/*! @name Driver version */
/*@{*/
/*! @brief DCP driver version. Version 2.0.0.
*
* Current version: 2.0.0
*
* Change log:
* - Version 2.0.0
* - Initial version
*/
#define FSL_DCP_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
/*@}*/
/*! @brief DCP channel enable.
*
*/
typedef enum _dcp_ch_enable
{
kDCP_chDisable = 0U, /*!< DCP channel disable */
kDCP_ch0Enable = 1U, /*!< DCP channel 0 enable */
kDCP_ch1Enable = 2U, /*!< DCP channel 1 enable */
kDCP_ch2Enable = 4U, /*!< DCP channel 2 enable */
kDCP_ch3Enable = 8U, /*!< DCP channel 3 enable */
kDCP_chEnableAll = 15U, /*!< DCP channel enable all */
} _dcp_ch_enable_t;
/*! @brief DCP interrupt enable.
*
*/
typedef enum _dcp_ch_int_enable
{
kDCP_chIntDisable = 0U, /*!< DCP interrupts disable */
kDCP_ch0IntEnable = 1U, /*!< DCP channel 0 interrupt enable */
kDCP_ch1IntEnable = 2U, /*!< DCP channel 1 interrupt enable */
kDCP_ch2IntEnable = 4U, /*!< DCP channel 2 interrupt enable */
kDCP_ch3IntEnable = 8U, /*!< DCP channel 3 interrupt enable */
} _dcp_ch_int_enable_t;
/*! @brief DCP channel selection.
*
*/
typedef enum _dcp_channel
{
kDCP_Channel0 = (1u << 16), /*!< DCP channel 0. */
kDCP_Channel1 = (1u << 17), /*!< DCP channel 1. */
kDCP_Channel2 = (1u << 18), /*!< DCP channel 2. */
kDCP_Channel3 = (1u << 19), /*!< DCP channel 3. */
} dcp_channel_t;
/*! @brief DCP key slot selection.
*
*/
typedef enum _dcp_key_slot
{
kDCP_KeySlot0 = 0U, /*!< DCP key slot 0. */
kDCP_KeySlot1 = 1U, /*!< DCP key slot 1. */
kDCP_KeySlot2 = 2U, /*!< DCP key slot 2.*/
kDCP_KeySlot3 = 3U, /*!< DCP key slot 3. */
kDCP_OtpKey = 4U, /*!< DCP OTP key. */
kDCP_OtpUniqueKey = 5U, /*!< DCP unique OTP key. */
kDCP_PayloadKey = 6U, /*!< DCP payload key. */
} dcp_key_slot_t;
/*! @brief DCP's work packet. */
typedef struct _dcp_work_packet
{
uint32_t nextCmdAddress;
uint32_t control0;
uint32_t control1;
uint32_t sourceBufferAddress;
uint32_t destinationBufferAddress;
uint32_t bufferSize;
uint32_t payloadPointer;
uint32_t status;
} dcp_work_packet_t;
/*! @brief Specify DCP's key resource and DCP channel. */
typedef struct _dcp_handle
{
dcp_channel_t channel; /*!< Specify DCP channel. */
dcp_key_slot_t keySlot; /*!< For operations with key (such as AES encryption/decryption), specify DCP key slot. */
uint32_t keyWord[4];
uint32_t iv[4];
} dcp_handle_t;
/*! @brief DCP's context buffer, used by DCP for context switching between channels. */
typedef struct _dcp_context
{
uint32_t x[208 / sizeof(uint32_t)];
} dcp_context_t;
/*! @brief DCP's configuration structure. */
typedef struct _dcp_config
{
bool gatherResidualWrites; /*!< Enable the ragged writes to the unaligned buffers. */
bool enableContextCaching; /*!< Enable the caching of contexts between the operations. */
bool enableContextSwitching; /*!< Enable automatic context switching for the channels. */
uint8_t enableChannel; /*!< DCP channel enable. */
uint8_t enableChannelInterrupt; /*!< Per-channel interrupt enable. */
} dcp_config_t;
/*! @} */
/*******************************************************************************
* AES Definitions
*******************************************************************************/
/*!
* @addtogroup dcp_driver_aes
* @{
*/
/*! AES block size in bytes */
#define DCP_AES_BLOCK_SIZE 16
/*!
*@}
*/ /* end of dcp_driver_aes */
/*******************************************************************************
* HASH Definitions
******************************************************************************/
/*!
* @addtogroup dcp_driver_hash
* @{
*/
/* DCP cannot correctly compute hash for message with zero size. When enabled, driver bypases DCP and returns correct
* hash value. If you are sure, that the driver will never be called with zero sized message, you can disable this
* feature to reduce code size */
#define DCP_HASH_CAVP_COMPATIBLE
/*! @brief Supported cryptographic block cipher functions for HASH creation */
typedef enum _dcp_hash_algo_t
{
kDCP_Sha1, /*!< SHA_1 */
kDCP_Sha256, /*!< SHA_256 */
kDCP_Crc32, /*!< CRC_32 */
} dcp_hash_algo_t;
/*! @brief DCP HASH Context size. */
#define DCP_SHA_BLOCK_SIZE 128 /*!< internal buffer block size */
#define DCP_HASH_BLOCK_SIZE DCP_SHA_BLOCK_SIZE /*!< DCP hash block size */
/*! @brief DCP HASH Context size. */
#define DCP_HASH_CTX_SIZE 58
/*! @brief Storage type used to save hash context. */
typedef struct _dcp_hash_ctx_t
{
uint32_t x[DCP_HASH_CTX_SIZE];
} dcp_hash_ctx_t;
/*!
*@}
*/ /* end of dcp_driver_hash */
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @addtogroup dcp_driver
* @{
*/
/*!
* @brief Enables clock to and enables DCP
*
* Enable DCP clock and configure DCP.
*
* @param base DCP base address
* @param config Pointer to configuration structure.
*/
void DCP_Init(DCP_Type *base, const dcp_config_t *config);
/*!
* @brief Disable DCP clock
*
* Reset DCP and Disable DCP clock.
*
* @param base DCP base address
*/
void DCP_Deinit(DCP_Type *base);
/*!
* @brief Gets the default configuration structure.
*
* This function initializes the DCP configuration structure to a default value. The default
* values are as follows.
* dcpConfig->gatherResidualWrites = true;
* dcpConfig->enableContextCaching = true;
* dcpConfig->enableContextSwitching = true;
* dcpConfig->enableChannnel = kDCP_chEnableAll;
* dcpConfig->enableChannelInterrupt = kDCP_chIntDisable;
*
* @param[out] config Pointer to configuration structure.
*/
void DCP_GetDefaultConfig(dcp_config_t *config);
/*!
* @brief Poll and wait on DCP channel.
*
* Polls the specified DCP channel until current it completes activity.
*
* @param base DCP peripheral base address.
* @param handle Specifies DCP channel.
* @return kStatus_Success When data processing completes without error.
* @return kStatus_Fail When error occurs.
*/
status_t DCP_WaitForChannelComplete(DCP_Type *base, dcp_handle_t *handle);
/*!
*@}
*/ /* end of dcp_driver */
/*******************************************************************************
* AES API
******************************************************************************/
/*!
* @addtogroup dcp_driver_aes
* @{
*/
/*!
* @brief Set AES key to dcp_handle_t struct and optionally to DCP.
*
* Sets the AES key for encryption/decryption with the dcp_handle_t structure.
* The dcp_handle_t input argument specifies keySlot.
* If the keySlot is kDCP_OtpKey, the function will check the OTP_KEY_READY bit and will return it's ready to use
* status.
* For other keySlot selections, the function will copy and hold the key in dcp_handle_t struct.
* If the keySlot is one of the four DCP SRAM-based keys (one of kDCP_KeySlot0, kDCP_KeySlot1, kDCP_KeySlot2,
* kDCP_KeySlot3),
* this function will also load the supplied key to the specified keySlot in DCP.
*
* @param base DCP peripheral base address.
* @param handle Handle used for the request.
* @param key 0-mod-4 aligned pointer to AES key.
* @param keySize AES key size in bytes. Shall equal 16.
* @return status from set key operation
*/
status_t DCP_AES_SetKey(DCP_Type *base, dcp_handle_t *handle, const uint8_t *key, size_t keySize);
/*!
* @brief Encrypts AES on one or multiple 128-bit block(s).
*
* Encrypts AES.
* The source plaintext and destination ciphertext can overlap in system memory.
*
* @param base DCP peripheral base address
* @param handle Handle used for this request.
* @param plaintext Input plain text to encrypt
* @param[out] ciphertext Output cipher text
* @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
* @return Status from encrypt operation
*/
status_t DCP_AES_EncryptEcb(
DCP_Type *base, dcp_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext, size_t size);
/*!
* @brief Decrypts AES on one or multiple 128-bit block(s).
*
* Decrypts AES.
* The source ciphertext and destination plaintext can overlap in system memory.
*
* @param base DCP peripheral base address
* @param handle Handle used for this request.
* @param ciphertext Input plain text to encrypt
* @param[out] plaintext Output cipher text
* @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
* @return Status from decrypt operation
*/
status_t DCP_AES_DecryptEcb(
DCP_Type *base, dcp_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext, size_t size);
/*!
* @brief Encrypts AES using CBC block mode.
*
* Encrypts AES using CBC block mode.
* The source plaintext and destination ciphertext can overlap in system memory.
*
* @param base DCP peripheral base address
* @param handle Handle used for this request.
* @param plaintext Input plain text to encrypt
* @param[out] ciphertext Output cipher text
* @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
* @param iv Input initial vector to combine with the first input block.
* @return Status from encrypt operation
*/
status_t DCP_AES_EncryptCbc(DCP_Type *base,
dcp_handle_t *handle,
const uint8_t *plaintext,
uint8_t *ciphertext,
size_t size,
const uint8_t iv[16]);
/*!
* @brief Decrypts AES using CBC block mode.
*
* Decrypts AES using CBC block mode.
* The source ciphertext and destination plaintext can overlap in system memory.
*
* @param base DCP peripheral base address
* @param handle Handle used for this request.
* @param ciphertext Input cipher text to decrypt
* @param[out] plaintext Output plain text
* @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
* @param iv Input initial vector to combine with the first input block.
* @return Status from decrypt operation
*/
status_t DCP_AES_DecryptCbc(DCP_Type *base,
dcp_handle_t *handle,
const uint8_t *ciphertext,
uint8_t *plaintext,
size_t size,
const uint8_t iv[16]);
/*!
*@}
*/ /* end of dcp_driver_aes */
/*!
* @addtogroup dcp_nonblocking_driver_aes
* @{
*/
/*!
* @brief Encrypts AES using the ECB block mode.
*
* Puts AES ECB encrypt work packet to DCP channel.
*
* @param base DCP peripheral base address
* @param handle Handle used for this request.
* @param[out] dcpPacket Memory for the DCP work packet.
* @param plaintext Input plain text to encrypt.
* @param[out] ciphertext Output cipher text
* @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
* @return kStatus_Success The work packet has been scheduled at DCP channel.
* @return kStatus_DCP_Again The DCP channel is busy processing previous request.
*/
status_t DCP_AES_EncryptEcbNonBlocking(DCP_Type *base,
dcp_handle_t *handle,
dcp_work_packet_t *dcpPacket,
const uint8_t *plaintext,
uint8_t *ciphertext,
size_t size);
/*!
* @brief Decrypts AES using ECB block mode.
*
* Puts AES ECB decrypt dcpPacket to DCP input job ring.
*
* @param base DCP peripheral base address
* @param handle Handle used for this request.
* @param[out] dcpPacket Memory for the DCP work packet.
* @param ciphertext Input cipher text to decrypt
* @param[out] plaintext Output plain text
* @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
* @return kStatus_Success The work packet has been scheduled at DCP channel.
* @return kStatus_DCP_Again The DCP channel is busy processing previous request.
*/
status_t DCP_AES_DecryptEcbNonBlocking(DCP_Type *base,
dcp_handle_t *handle,
dcp_work_packet_t *dcpPacket,
const uint8_t *ciphertext,
uint8_t *plaintext,
size_t size);
/*!
* @brief Encrypts AES using CBC block mode.
*
* Puts AES CBC encrypt dcpPacket to DCP input job ring.
*
* @param base DCP peripheral base address
* @param handle Handle used for this request. Specifies jobRing.
* @param[out] dcpPacket Memory for the DCP work packet.
* @param plaintext Input plain text to encrypt
* @param[out] ciphertext Output cipher text
* @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
* @param iv Input initial vector to combine with the first input block.
* @return kStatus_Success The work packet has been scheduled at DCP channel.
* @return kStatus_DCP_Again The DCP channel is busy processing previous request.
*/
status_t DCP_AES_EncryptCbcNonBlocking(DCP_Type *base,
dcp_handle_t *handle,
dcp_work_packet_t *dcpPacket,
const uint8_t *plaintext,
uint8_t *ciphertext,
size_t size,
const uint8_t *iv);
/*!
* @brief Decrypts AES using CBC block mode.
*
* Puts AES CBC decrypt dcpPacket to DCP input job ring.
*
* @param base DCP peripheral base address
* @param handle Handle used for this request. Specifies jobRing.
* @param[out] dcpPacket Memory for the DCP work packet.
* @param ciphertext Input cipher text to decrypt
* @param[out] plaintext Output plain text
* @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
* @param iv Input initial vector to combine with the first input block.
* @return kStatus_Success The work packet has been scheduled at DCP channel.
* @return kStatus_DCP_Again The DCP channel is busy processing previous request.
*/
status_t DCP_AES_DecryptCbcNonBlocking(DCP_Type *base,
dcp_handle_t *handle,
dcp_work_packet_t *dcpPacket,
const uint8_t *ciphertext,
uint8_t *plaintext,
size_t size,
const uint8_t *iv);
/*!
*@}
*/ /* end of dcp_nonblocking_driver_aes */
/*******************************************************************************
* HASH API
******************************************************************************/
/*!
* @addtogroup dcp_driver_hash
* @{
*/
/*!
* @brief Initialize HASH context
*
* This function initializes the HASH.
*
* @param base DCP peripheral base address
* @param handle Specifies the DCP channel used for hashing.
* @param[out] ctx Output hash context
* @param algo Underlaying algorithm to use for hash computation.
* @return Status of initialization
*/
status_t DCP_HASH_Init(DCP_Type *base, dcp_handle_t *handle, dcp_hash_ctx_t *ctx, dcp_hash_algo_t algo);
/*!
* @brief Add data to current HASH
*
* Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be
* hashed. The functions blocks. If it returns kStatus_Success, the running hash
* has been updated (DCP has processed the input data), so the memory at @ref input pointer
* can be released back to system. The DCP context buffer is updated with the running hash
* and with all necessary information to support possible context switch.
*
* @param base DCP peripheral base address
* @param[in,out] ctx HASH context
* @param input Input data
* @param inputSize Size of input data in bytes
* @return Status of the hash update operation
*/
status_t DCP_HASH_Update(DCP_Type *base, dcp_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize);
/*!
* @brief Finalize hashing
*
* Outputs the final hash (computed by DCP_HASH_Update()) and erases the context.
*
* @param[in,out] ctx Input hash context
* @param[out] output Output hash data
* @param[in,out] outputSize Optional parameter (can be passed as NULL). On function entry, it specifies the size of
* output[] buffer. On function return, it stores the number of updated output bytes.
* @return Status of the hash finish operation
*/
status_t DCP_HASH_Finish(DCP_Type *base, dcp_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize);
/*!
* @brief Create HASH on given data
*
* Perform the full SHA or CRC32 in one function call. The function is blocking.
*
* @param base DCP peripheral base address
* @param handle Handle used for the request.
* @param algo Underlaying algorithm to use for hash computation.
* @param input Input data
* @param inputSize Size of input data in bytes
* @param[out] output Output hash data
* @param[out] outputSize Output parameter storing the size of the output hash in bytes
* @return Status of the one call hash operation.
*/
status_t DCP_HASH(DCP_Type *base,
dcp_handle_t *handle,
dcp_hash_algo_t algo,
const uint8_t *input,
size_t inputSize,
uint8_t *output,
size_t *outputSize);
/*!
*@}
*/ /* end of dcp_driver_hash */
#if defined(__cplusplus)
}
#endif
#endif /* _FSL_DCP_H_ */

View File

@@ -0,0 +1,97 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#include "fsl_dmamux.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get instance number for DMAMUX.
*
* @param base DMAMUX peripheral base address.
*/
static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Array to map DMAMUX instance number to base pointer. */
static DMAMUX_Type *const s_dmamuxBases[] = DMAMUX_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Array to map DMAMUX instance number to clock name. */
static const clock_ip_name_t s_dmamuxClockName[] = DMAMUX_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_dmamuxBases); instance++)
{
if (s_dmamuxBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_dmamuxBases));
return instance;
}
void DMAMUX_Init(DMAMUX_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_EnableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
void DMAMUX_Deinit(DMAMUX_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_DisableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}

View File

@@ -0,0 +1,204 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#ifndef _FSL_DMAMUX_H_
#define _FSL_DMAMUX_H_
#include "fsl_common.h"
/*!
* @addtogroup dmamux
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief DMAMUX driver version 2.0.2. */
#define FSL_DMAMUX_DRIVER_VERSION (MAKE_VERSION(2, 0, 2))
/*@}*/
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/*!
* @name DMAMUX Initialization and de-initialization
* @{
*/
/*!
* @brief Initializes the DMAMUX peripheral.
*
* This function ungates the DMAMUX clock.
*
* @param base DMAMUX peripheral base address.
*
*/
void DMAMUX_Init(DMAMUX_Type *base);
/*!
* @brief Deinitializes the DMAMUX peripheral.
*
* This function gates the DMAMUX clock.
*
* @param base DMAMUX peripheral base address.
*/
void DMAMUX_Deinit(DMAMUX_Type *base);
/* @} */
/*!
* @name DMAMUX Channel Operation
* @{
*/
/*!
* @brief Enables the DMAMUX channel.
*
* This function enables the DMAMUX channel.
*
* @param base DMAMUX peripheral base address.
* @param channel DMAMUX channel number.
*/
static inline void DMAMUX_EnableChannel(DMAMUX_Type *base, uint32_t channel)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->CHCFG[channel] |= DMAMUX_CHCFG_ENBL_MASK;
}
/*!
* @brief Disables the DMAMUX channel.
*
* This function disables the DMAMUX channel.
*
* @note The user must disable the DMAMUX channel before configuring it.
* @param base DMAMUX peripheral base address.
* @param channel DMAMUX channel number.
*/
static inline void DMAMUX_DisableChannel(DMAMUX_Type *base, uint32_t channel)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->CHCFG[channel] &= ~DMAMUX_CHCFG_ENBL_MASK;
}
/*!
* @brief Configures the DMAMUX channel source.
*
* @param base DMAMUX peripheral base address.
* @param channel DMAMUX channel number.
* @param source Channel source, which is used to trigger the DMA transfer.
*/
static inline void DMAMUX_SetSource(DMAMUX_Type *base, uint32_t channel, uint32_t source)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->CHCFG[channel] = ((base->CHCFG[channel] & ~DMAMUX_CHCFG_SOURCE_MASK) | DMAMUX_CHCFG_SOURCE(source));
}
#if defined(FSL_FEATURE_DMAMUX_HAS_TRIG) && FSL_FEATURE_DMAMUX_HAS_TRIG > 0U
/*!
* @brief Enables the DMAMUX period trigger.
*
* This function enables the DMAMUX period trigger feature.
*
* @param base DMAMUX peripheral base address.
* @param channel DMAMUX channel number.
*/
static inline void DMAMUX_EnablePeriodTrigger(DMAMUX_Type *base, uint32_t channel)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->CHCFG[channel] |= DMAMUX_CHCFG_TRIG_MASK;
}
/*!
* @brief Disables the DMAMUX period trigger.
*
* This function disables the DMAMUX period trigger.
*
* @param base DMAMUX peripheral base address.
* @param channel DMAMUX channel number.
*/
static inline void DMAMUX_DisablePeriodTrigger(DMAMUX_Type *base, uint32_t channel)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->CHCFG[channel] &= ~DMAMUX_CHCFG_TRIG_MASK;
}
#endif /* FSL_FEATURE_DMAMUX_HAS_TRIG */
#if (defined(FSL_FEATURE_DMAMUX_HAS_A_ON) && FSL_FEATURE_DMAMUX_HAS_A_ON)
/*!
* @brief Enables the DMA channel to be always ON.
*
* This function enables the DMAMUX channel always ON feature.
*
* @param base DMAMUX peripheral base address.
* @param channel DMAMUX channel number.
* @param enable Switcher of the always ON feature. "true" means enabled, "false" means disabled.
*/
static inline void DMAMUX_EnableAlwaysOn(DMAMUX_Type *base, uint32_t channel, bool enable)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
if (enable)
{
base->CHCFG[channel] |= DMAMUX_CHCFG_A_ON_MASK;
}
else
{
base->CHCFG[channel] &= ~DMAMUX_CHCFG_A_ON_MASK;
}
}
#endif /* FSL_FEATURE_DMAMUX_HAS_A_ON */
/* @} */
#if defined(__cplusplus)
}
#endif /* __cplusplus */
/* @} */
#endif /* _FSL_DMAMUX_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,937 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#ifndef _FSL_EDMA_H_
#define _FSL_EDMA_H_
#include "fsl_common.h"
/*!
* @addtogroup edma
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief eDMA driver version */
#define FSL_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 1, 2)) /*!< Version 2.1.2. */
/*@}*/
/*! @brief Compute the offset unit from DCHPRI3 */
#define DMA_DCHPRI_INDEX(channel) (((channel) & ~0x03U) | (3 - ((channel)&0x03U)))
/*! @brief Get the pointer of DCHPRIn */
#define DMA_DCHPRIn(base, channel) ((volatile uint8_t *)&(base->DCHPRI3))[DMA_DCHPRI_INDEX(channel)]
/*! @brief eDMA transfer configuration */
typedef enum _edma_transfer_size
{
kEDMA_TransferSize1Bytes = 0x0U, /*!< Source/Destination data transfer size is 1 byte every time */
kEDMA_TransferSize2Bytes = 0x1U, /*!< Source/Destination data transfer size is 2 bytes every time */
kEDMA_TransferSize4Bytes = 0x2U, /*!< Source/Destination data transfer size is 4 bytes every time */
kEDMA_TransferSize8Bytes = 0x3U, /*!< Source/Destination data transfer size is 8 bytes every time */
kEDMA_TransferSize16Bytes = 0x4U, /*!< Source/Destination data transfer size is 16 bytes every time */
kEDMA_TransferSize32Bytes = 0x5U, /*!< Source/Destination data transfer size is 32 bytes every time */
} edma_transfer_size_t;
/*! @brief eDMA modulo configuration */
typedef enum _edma_modulo
{
kEDMA_ModuloDisable = 0x0U, /*!< Disable modulo */
kEDMA_Modulo2bytes, /*!< Circular buffer size is 2 bytes. */
kEDMA_Modulo4bytes, /*!< Circular buffer size is 4 bytes. */
kEDMA_Modulo8bytes, /*!< Circular buffer size is 8 bytes. */
kEDMA_Modulo16bytes, /*!< Circular buffer size is 16 bytes. */
kEDMA_Modulo32bytes, /*!< Circular buffer size is 32 bytes. */
kEDMA_Modulo64bytes, /*!< Circular buffer size is 64 bytes. */
kEDMA_Modulo128bytes, /*!< Circular buffer size is 128 bytes. */
kEDMA_Modulo256bytes, /*!< Circular buffer size is 256 bytes. */
kEDMA_Modulo512bytes, /*!< Circular buffer size is 512 bytes. */
kEDMA_Modulo1Kbytes, /*!< Circular buffer size is 1 K bytes. */
kEDMA_Modulo2Kbytes, /*!< Circular buffer size is 2 K bytes. */
kEDMA_Modulo4Kbytes, /*!< Circular buffer size is 4 K bytes. */
kEDMA_Modulo8Kbytes, /*!< Circular buffer size is 8 K bytes. */
kEDMA_Modulo16Kbytes, /*!< Circular buffer size is 16 K bytes. */
kEDMA_Modulo32Kbytes, /*!< Circular buffer size is 32 K bytes. */
kEDMA_Modulo64Kbytes, /*!< Circular buffer size is 64 K bytes. */
kEDMA_Modulo128Kbytes, /*!< Circular buffer size is 128 K bytes. */
kEDMA_Modulo256Kbytes, /*!< Circular buffer size is 256 K bytes. */
kEDMA_Modulo512Kbytes, /*!< Circular buffer size is 512 K bytes. */
kEDMA_Modulo1Mbytes, /*!< Circular buffer size is 1 M bytes. */
kEDMA_Modulo2Mbytes, /*!< Circular buffer size is 2 M bytes. */
kEDMA_Modulo4Mbytes, /*!< Circular buffer size is 4 M bytes. */
kEDMA_Modulo8Mbytes, /*!< Circular buffer size is 8 M bytes. */
kEDMA_Modulo16Mbytes, /*!< Circular buffer size is 16 M bytes. */
kEDMA_Modulo32Mbytes, /*!< Circular buffer size is 32 M bytes. */
kEDMA_Modulo64Mbytes, /*!< Circular buffer size is 64 M bytes. */
kEDMA_Modulo128Mbytes, /*!< Circular buffer size is 128 M bytes. */
kEDMA_Modulo256Mbytes, /*!< Circular buffer size is 256 M bytes. */
kEDMA_Modulo512Mbytes, /*!< Circular buffer size is 512 M bytes. */
kEDMA_Modulo1Gbytes, /*!< Circular buffer size is 1 G bytes. */
kEDMA_Modulo2Gbytes, /*!< Circular buffer size is 2 G bytes. */
} edma_modulo_t;
/*! @brief Bandwidth control */
typedef enum _edma_bandwidth
{
kEDMA_BandwidthStallNone = 0x0U, /*!< No eDMA engine stalls. */
kEDMA_BandwidthStall4Cycle = 0x2U, /*!< eDMA engine stalls for 4 cycles after each read/write. */
kEDMA_BandwidthStall8Cycle = 0x3U, /*!< eDMA engine stalls for 8 cycles after each read/write. */
} edma_bandwidth_t;
/*! @brief Channel link type */
typedef enum _edma_channel_link_type
{
kEDMA_LinkNone = 0x0U, /*!< No channel link */
kEDMA_MinorLink, /*!< Channel link after each minor loop */
kEDMA_MajorLink, /*!< Channel link while major loop count exhausted */
} edma_channel_link_type_t;
/*!@brief eDMA channel status flags. */
enum _edma_channel_status_flags
{
kEDMA_DoneFlag = 0x1U, /*!< DONE flag, set while transfer finished, CITER value exhausted*/
kEDMA_ErrorFlag = 0x2U, /*!< eDMA error flag, an error occurred in a transfer */
kEDMA_InterruptFlag = 0x4U, /*!< eDMA interrupt flag, set while an interrupt occurred of this channel */
};
/*! @brief eDMA channel error status flags. */
enum _edma_error_status_flags
{
kEDMA_DestinationBusErrorFlag = DMA_ES_DBE_MASK, /*!< Bus error on destination address */
kEDMA_SourceBusErrorFlag = DMA_ES_SBE_MASK, /*!< Bus error on the source address */
kEDMA_ScatterGatherErrorFlag = DMA_ES_SGE_MASK, /*!< Error on the Scatter/Gather address, not 32byte aligned. */
kEDMA_NbytesErrorFlag = DMA_ES_NCE_MASK, /*!< NBYTES/CITER configuration error */
kEDMA_DestinationOffsetErrorFlag = DMA_ES_DOE_MASK, /*!< Destination offset not aligned with destination size */
kEDMA_DestinationAddressErrorFlag = DMA_ES_DAE_MASK, /*!< Destination address not aligned with destination size */
kEDMA_SourceOffsetErrorFlag = DMA_ES_SOE_MASK, /*!< Source offset not aligned with source size */
kEDMA_SourceAddressErrorFlag = DMA_ES_SAE_MASK, /*!< Source address not aligned with source size*/
kEDMA_ErrorChannelFlag = DMA_ES_ERRCHN_MASK, /*!< Error channel number of the cancelled channel number */
kEDMA_ChannelPriorityErrorFlag = DMA_ES_CPE_MASK, /*!< Channel priority is not unique. */
kEDMA_TransferCanceledFlag = DMA_ES_ECX_MASK, /*!< Transfer cancelled */
#if defined(FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT) && FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT > 1
kEDMA_GroupPriorityErrorFlag = DMA_ES_GPE_MASK, /*!< Group priority is not unique. */
#endif
kEDMA_ValidFlag = DMA_ES_VLD_MASK, /*!< No error occurred, this bit is 0. Otherwise, it is 1. */
};
/*! @brief eDMA interrupt source */
typedef enum _edma_interrupt_enable
{
kEDMA_ErrorInterruptEnable = 0x1U, /*!< Enable interrupt while channel error occurs. */
kEDMA_MajorInterruptEnable = DMA_CSR_INTMAJOR_MASK, /*!< Enable interrupt while major count exhausted. */
kEDMA_HalfInterruptEnable = DMA_CSR_INTHALF_MASK, /*!< Enable interrupt while major count to half value. */
} edma_interrupt_enable_t;
/*! @brief eDMA transfer type */
typedef enum _edma_transfer_type
{
kEDMA_MemoryToMemory = 0x0U, /*!< Transfer from memory to memory */
kEDMA_PeripheralToMemory, /*!< Transfer from peripheral to memory */
kEDMA_MemoryToPeripheral, /*!< Transfer from memory to peripheral */
} edma_transfer_type_t;
/*! @brief eDMA transfer status */
enum _edma_transfer_status
{
kStatus_EDMA_QueueFull = MAKE_STATUS(kStatusGroup_EDMA, 0), /*!< TCD queue is full. */
kStatus_EDMA_Busy = MAKE_STATUS(kStatusGroup_EDMA, 1), /*!< Channel is busy and can't handle the
transfer request. */
};
/*! @brief eDMA global configuration structure.*/
typedef struct _edma_config
{
bool enableContinuousLinkMode; /*!< Enable (true) continuous link mode. Upon minor loop completion, the channel
activates again if that channel has a minor loop channel link enabled and
the link channel is itself. */
bool enableHaltOnError; /*!< Enable (true) transfer halt on error. Any error causes the HALT bit to set.
Subsequently, all service requests are ignored until the HALT bit is cleared.*/
bool enableRoundRobinArbitration; /*!< Enable (true) round robin channel arbitration method or fixed priority
arbitration is used for channel selection */
bool enableDebugMode; /*!< Enable(true) eDMA debug mode. When in debug mode, the eDMA stalls the start of
a new channel. Executing channels are allowed to complete. */
} edma_config_t;
/*!
* @brief eDMA transfer configuration
*
* This structure configures the source/destination transfer attribute.
*/
typedef struct _edma_transfer_config
{
uint32_t srcAddr; /*!< Source data address. */
uint32_t destAddr; /*!< Destination data address. */
edma_transfer_size_t srcTransferSize; /*!< Source data transfer size. */
edma_transfer_size_t destTransferSize; /*!< Destination data transfer size. */
int16_t srcOffset; /*!< Sign-extended offset applied to the current source address to
form the next-state value as each source read is completed. */
int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to
form the next-state value as each destination write is completed. */
uint32_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/
uint32_t majorLoopCounts; /*!< Major loop iteration count. */
} edma_transfer_config_t;
/*! @brief eDMA channel priority configuration */
typedef struct _edma_channel_Preemption_config
{
bool enableChannelPreemption; /*!< If true: a channel can be suspended by other channel with higher priority */
bool enablePreemptAbility; /*!< If true: a channel can suspend other channel with low priority */
uint8_t channelPriority; /*!< Channel priority */
} edma_channel_Preemption_config_t;
/*! @brief eDMA minor offset configuration */
typedef struct _edma_minor_offset_config
{
bool enableSrcMinorOffset; /*!< Enable(true) or Disable(false) source minor loop offset. */
bool enableDestMinorOffset; /*!< Enable(true) or Disable(false) destination minor loop offset. */
uint32_t minorOffset; /*!< Offset for a minor loop mapping. */
} edma_minor_offset_config_t;
/*!
* @brief eDMA TCD.
*
* This structure is same as TCD register which is described in reference manual,
* and is used to configure the scatter/gather feature as a next hardware TCD.
*/
typedef struct _edma_tcd
{
__IO uint32_t SADDR; /*!< SADDR register, used to save source address */
__IO uint16_t SOFF; /*!< SOFF register, save offset bytes every transfer */
__IO uint16_t ATTR; /*!< ATTR register, source/destination transfer size and modulo */
__IO uint32_t NBYTES; /*!< Nbytes register, minor loop length in bytes */
__IO uint32_t SLAST; /*!< SLAST register */
__IO uint32_t DADDR; /*!< DADDR register, used for destination address */
__IO uint16_t DOFF; /*!< DOFF register, used for destination offset */
__IO uint16_t CITER; /*!< CITER register, current minor loop numbers, for unfinished minor loop.*/
__IO uint32_t DLAST_SGA; /*!< DLASTSGA register, next stcd address used in scatter-gather mode */
__IO uint16_t CSR; /*!< CSR register, for TCD control status */
__IO uint16_t BITER; /*!< BITER register, begin minor loop count. */
} edma_tcd_t;
/*! @brief Callback for eDMA */
struct _edma_handle;
/*! @brief Define callback function for eDMA. */
typedef void (*edma_callback)(struct _edma_handle *handle, void *userData, bool transferDone, uint32_t tcds);
/*! @brief eDMA transfer handle structure */
typedef struct _edma_handle
{
edma_callback callback; /*!< Callback function for major count exhausted. */
void *userData; /*!< Callback function parameter. */
DMA_Type *base; /*!< eDMA peripheral base address. */
edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */
uint8_t channel; /*!< eDMA channel number. */
volatile int8_t header; /*!< The first TCD index. Should point to the next TCD to be loaded into the eDMA engine. */
volatile int8_t tail; /*!< The last TCD index. Should point to the next TCD to be stored into the memory pool. */
volatile int8_t tcdUsed; /*!< The number of used TCD slots. Should reflect the number of TCDs can be used/loaded in
the memory. */
volatile int8_t tcdSize; /*!< The total number of TCD slots in the queue. */
uint8_t flags; /*!< The status of the current channel. */
} edma_handle_t;
/*******************************************************************************
* APIs
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/*!
* @name eDMA initialization and de-initialization
* @{
*/
/*!
* @brief Initializes the eDMA peripheral.
*
* This function ungates the eDMA clock and configures the eDMA peripheral according
* to the configuration structure.
*
* @param base eDMA peripheral base address.
* @param config A pointer to the configuration structure, see "edma_config_t".
* @note This function enables the minor loop map feature.
*/
void EDMA_Init(DMA_Type *base, const edma_config_t *config);
/*!
* @brief Deinitializes the eDMA peripheral.
*
* This function gates the eDMA clock.
*
* @param base eDMA peripheral base address.
*/
void EDMA_Deinit(DMA_Type *base);
/*!
* @brief Push content of TCD structure into hardware TCD register.
*
* @param base EDMA peripheral base address.
* @param channel EDMA channel number.
* @param tcd Point to TCD structure.
*/
void EDMA_InstallTCD(DMA_Type *base, uint32_t channel, edma_tcd_t *tcd);
/*!
* @brief Gets the eDMA default configuration structure.
*
* This function sets the configuration structure to default values.
* The default configuration is set to the following values.
* @code
* config.enableContinuousLinkMode = false;
* config.enableHaltOnError = true;
* config.enableRoundRobinArbitration = false;
* config.enableDebugMode = false;
* @endcode
*
* @param config A pointer to the eDMA configuration structure.
*/
void EDMA_GetDefaultConfig(edma_config_t *config);
/* @} */
/*!
* @name eDMA Channel Operation
* @{
*/
/*!
* @brief Sets all TCD registers to default values.
*
* This function sets TCD registers for this channel to default values.
*
* @param base eDMA peripheral base address.
* @param channel eDMA channel number.
* @note This function must not be called while the channel transfer is ongoing
* or it causes unpredictable results.
* @note This function enables the auto stop request feature.
*/
void EDMA_ResetChannel(DMA_Type *base, uint32_t channel);
/*!
* @brief Configures the eDMA transfer attribute.
*
* This function configures the transfer attribute, including source address, destination address,
* transfer size, address offset, and so on. It also configures the scatter gather feature if the
* user supplies the TCD address.
* Example:
* @code
* edma_transfer_t config;
* edma_tcd_t tcd;
* config.srcAddr = ..;
* config.destAddr = ..;
* ...
* EDMA_SetTransferConfig(DMA0, channel, &config, &stcd);
* @endcode
*
* @param base eDMA peripheral base address.
* @param channel eDMA channel number.
* @param config Pointer to eDMA transfer configuration structure.
* @param nextTcd Point to TCD structure. It can be NULL if users
* do not want to enable scatter/gather feature.
* @note If nextTcd is not NULL, it means scatter gather feature is enabled
* and DREQ bit is cleared in the previous transfer configuration, which
* is set in the eDMA_ResetChannel.
*/
void EDMA_SetTransferConfig(DMA_Type *base,
uint32_t channel,
const edma_transfer_config_t *config,
edma_tcd_t *nextTcd);
/*!
* @brief Configures the eDMA minor offset feature.
*
* The minor offset means that the signed-extended value is added to the source address or destination
* address after each minor loop.
*
* @param base eDMA peripheral base address.
* @param channel eDMA channel number.
* @param config A pointer to the minor offset configuration structure.
*/
void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_minor_offset_config_t *config);
/*!
* @brief Configures the eDMA channel preemption feature.
*
* This function configures the channel preemption attribute and the priority of the channel.
*
* @param base eDMA peripheral base address.
* @param channel eDMA channel number
* @param config A pointer to the channel preemption configuration structure.
*/
static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base,
uint32_t channel,
const edma_channel_Preemption_config_t *config)
{
assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL);
assert(config != NULL);
DMA_DCHPRIn(base, channel) =
(DMA_DCHPRI0_DPA(!config->enablePreemptAbility) | DMA_DCHPRI0_ECP(config->enableChannelPreemption) |
DMA_DCHPRI0_CHPRI(config->channelPriority));
}
/*!
* @brief Sets the channel link for the eDMA transfer.
*
* This function configures either the minor link or the major link mode. The minor link means that the channel link is
* triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is
* exhausted.
*
* @param base eDMA peripheral base address.
* @param channel eDMA channel number.
* @param type A channel link type, which can be one of the following:
* @arg kEDMA_LinkNone
* @arg kEDMA_MinorLink
* @arg kEDMA_MajorLink
* @param linkedChannel The linked channel number.
* @note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid.
*/
void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_type_t type, uint32_t linkedChannel);
/*!
* @brief Sets the bandwidth for the eDMA transfer.
*
* Because the eDMA processes the minor loop, it continuously generates read/write sequences
* until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of
* each read/write access to control the bus request bandwidth seen by the crossbar switch.
*
* @param base eDMA peripheral base address.
* @param channel eDMA channel number.
* @param bandWidth A bandwidth setting, which can be one of the following:
* @arg kEDMABandwidthStallNone
* @arg kEDMABandwidthStall4Cycle
* @arg kEDMABandwidthStall8Cycle
*/
void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWidth);
/*!
* @brief Sets the source modulo and the destination modulo for the eDMA transfer.
*
* This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF)
* calculation is performed or the original register value. It provides the ability to implement a circular data
* queue easily.
*
* @param base eDMA peripheral base address.
* @param channel eDMA channel number.
* @param srcModulo A source modulo value.
* @param destModulo A destination modulo value.
*/
void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, edma_modulo_t destModulo);
#if defined(FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT) && FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT
/*!
* @brief Enables an async request for the eDMA transfer.
*
* @param base eDMA peripheral base address.
* @param channel eDMA channel number.
* @param enable The command to enable (true) or disable (false).
*/
static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, bool enable)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->EARS = (base->EARS & (~(1U << channel))) | ((uint32_t)enable << channel);
}
#endif /* FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT */
/*!
* @brief Enables an auto stop request for the eDMA transfer.
*
* If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request.
*
* @param base eDMA peripheral base address.
* @param channel eDMA channel number.
* @param enable The command to enable (true) or disable (false).
*/
static inline void EDMA_EnableAutoStopRequest(DMA_Type *base, uint32_t channel, bool enable)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->TCD[channel].CSR = (base->TCD[channel].CSR & (~DMA_CSR_DREQ_MASK)) | DMA_CSR_DREQ(enable);
}
/*!
* @brief Enables the interrupt source for the eDMA transfer.
*
* @param base eDMA peripheral base address.
* @param channel eDMA channel number.
* @param mask The mask of interrupt source to be set. Users need to use
* the defined edma_interrupt_enable_t type.
*/
void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask);
/*!
* @brief Disables the interrupt source for the eDMA transfer.
*
* @param base eDMA peripheral base address.
* @param channel eDMA channel number.
* @param mask The mask of the interrupt source to be set. Use
* the defined edma_interrupt_enable_t type.
*/
void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask);
/* @} */
/*!
* @name eDMA TCD Operation
* @{
*/
/*!
* @brief Sets all fields to default values for the TCD structure.
*
* This function sets all fields for this TCD structure to default value.
*
* @param tcd Pointer to the TCD structure.
* @note This function enables the auto stop request feature.
*/
void EDMA_TcdReset(edma_tcd_t *tcd);
/*!
* @brief Configures the eDMA TCD transfer attribute.
*
* The TCD is a transfer control descriptor. The content of the TCD is the same as the hardware TCD registers.
* The STCD is used in the scatter-gather mode.
* This function configures the TCD transfer attribute, including source address, destination address,
* transfer size, address offset, and so on. It also configures the scatter gather feature if the
* user supplies the next TCD address.
* Example:
* @code
* edma_transfer_t config = {
* ...
* }
* edma_tcd_t tcd __aligned(32);
* edma_tcd_t nextTcd __aligned(32);
* EDMA_TcdSetTransferConfig(&tcd, &config, &nextTcd);
* @endcode
*
* @param tcd Pointer to the TCD structure.
* @param config Pointer to eDMA transfer configuration structure.
* @param nextTcd Pointer to the next TCD structure. It can be NULL if users
* do not want to enable scatter/gather feature.
* @note TCD address should be 32 bytes aligned or it causes an eDMA error.
* @note If the nextTcd is not NULL, the scatter gather feature is enabled
* and DREQ bit is cleared in the previous transfer configuration, which
* is set in the EDMA_TcdReset.
*/
void EDMA_TcdSetTransferConfig(edma_tcd_t *tcd, const edma_transfer_config_t *config, edma_tcd_t *nextTcd);
/*!
* @brief Configures the eDMA TCD minor offset feature.
*
* A minor offset is a signed-extended value added to the source address or a destination
* address after each minor loop.
*
* @param tcd A point to the TCD structure.
* @param config A pointer to the minor offset configuration structure.
*/
void EDMA_TcdSetMinorOffsetConfig(edma_tcd_t *tcd, const edma_minor_offset_config_t *config);
/*!
* @brief Sets the channel link for the eDMA TCD.
*
* This function configures either a minor link or a major link. The minor link means the channel link is
* triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is
* exhausted.
*
* @note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid.
* @param tcd Point to the TCD structure.
* @param type Channel link type, it can be one of:
* @arg kEDMA_LinkNone
* @arg kEDMA_MinorLink
* @arg kEDMA_MajorLink
* @param linkedChannel The linked channel number.
*/
void EDMA_TcdSetChannelLink(edma_tcd_t *tcd, edma_channel_link_type_t type, uint32_t linkedChannel);
/*!
* @brief Sets the bandwidth for the eDMA TCD.
*
* Because the eDMA processes the minor loop, it continuously generates read/write sequences
* until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of
* each read/write access to control the bus request bandwidth seen by the crossbar switch.
* @param tcd A pointer to the TCD structure.
* @param bandWidth A bandwidth setting, which can be one of the following:
* @arg kEDMABandwidthStallNone
* @arg kEDMABandwidthStall4Cycle
* @arg kEDMABandwidthStall8Cycle
*/
static inline void EDMA_TcdSetBandWidth(edma_tcd_t *tcd, edma_bandwidth_t bandWidth)
{
assert(tcd != NULL);
assert(((uint32_t)tcd & 0x1FU) == 0);
tcd->CSR = (tcd->CSR & (~DMA_CSR_BWC_MASK)) | DMA_CSR_BWC(bandWidth);
}
/*!
* @brief Sets the source modulo and the destination modulo for the eDMA TCD.
*
* This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF)
* calculation is performed or the original register value. It provides the ability to implement a circular data
* queue easily.
*
* @param tcd A pointer to the TCD structure.
* @param srcModulo A source modulo value.
* @param destModulo A destination modulo value.
*/
void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo);
/*!
* @brief Sets the auto stop request for the eDMA TCD.
*
* If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request.
*
* @param tcd A pointer to the TCD structure.
* @param enable The command to enable (true) or disable (false).
*/
static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable)
{
assert(tcd != NULL);
assert(((uint32_t)tcd & 0x1FU) == 0);
tcd->CSR = (tcd->CSR & (~DMA_CSR_DREQ_MASK)) | DMA_CSR_DREQ(enable);
}
/*!
* @brief Enables the interrupt source for the eDMA TCD.
*
* @param tcd Point to the TCD structure.
* @param mask The mask of interrupt source to be set. Users need to use
* the defined edma_interrupt_enable_t type.
*/
void EDMA_TcdEnableInterrupts(edma_tcd_t *tcd, uint32_t mask);
/*!
* @brief Disables the interrupt source for the eDMA TCD.
*
* @param tcd Point to the TCD structure.
* @param mask The mask of interrupt source to be set. Users need to use
* the defined edma_interrupt_enable_t type.
*/
void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask);
/*! @} */
/*!
* @name eDMA Channel Transfer Operation
* @{
*/
/*!
* @brief Enables the eDMA hardware channel request.
*
* This function enables the hardware channel request.
*
* @param base eDMA peripheral base address.
* @param channel eDMA channel number.
*/
static inline void EDMA_EnableChannelRequest(DMA_Type *base, uint32_t channel)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->SERQ = DMA_SERQ_SERQ(channel);
}
/*!
* @brief Disables the eDMA hardware channel request.
*
* This function disables the hardware channel request.
*
* @param base eDMA peripheral base address.
* @param channel eDMA channel number.
*/
static inline void EDMA_DisableChannelRequest(DMA_Type *base, uint32_t channel)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->CERQ = DMA_CERQ_CERQ(channel);
}
/*!
* @brief Starts the eDMA transfer by using the software trigger.
*
* This function starts a minor loop transfer.
*
* @param base eDMA peripheral base address.
* @param channel eDMA channel number.
*/
static inline void EDMA_TriggerChannelStart(DMA_Type *base, uint32_t channel)
{
assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL);
base->SSRT = DMA_SSRT_SSRT(channel);
}
/*! @} */
/*!
* @name eDMA Channel Status Operation
* @{
*/
/*!
* @brief Gets the remaining major loop count from the eDMA current channel TCD.
*
* This function checks the TCD (Task Control Descriptor) status for a specified
* eDMA channel and returns the the number of major loop count that has not finished.
*
* @param base eDMA peripheral base address.
* @param channel eDMA channel number.
* @return Major loop count which has not been transferred yet for the current TCD.
* @note 1. This function can only be used to get unfinished major loop count of transfer without
* the next TCD, or it might be inaccuracy.
* 2. The unfinished/remaining transfer bytes cannot be obtained directly from registers while
* the channel is running.
* Because to calculate the remaining bytes, the initial NBYTES configured in DMA_TCDn_NBYTES_MLNO
* register is needed while the eDMA IP does not support getting it while a channel is active.
* In another word, the NBYTES value reading is always the actual (decrementing) NBYTES value the dma_engine
* is working with while a channel is running.
* Consequently, to get the remaining transfer bytes, a software-saved initial value of NBYTES (for example
* copied before enabling the channel) is needed. The formula to calculate it is shown below:
* RemainingBytes = RemainingMajorLoopCount * NBYTES(initially configured)
*/
uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel);
/*!
* @brief Gets the eDMA channel error status flags.
*
* @param base eDMA peripheral base address.
* @return The mask of error status flags. Users need to use the
* _edma_error_status_flags type to decode the return variables.
*/
static inline uint32_t EDMA_GetErrorStatusFlags(DMA_Type *base)
{
return base->ES;
}
/*!
* @brief Gets the eDMA channel status flags.
*
* @param base eDMA peripheral base address.
* @param channel eDMA channel number.
* @return The mask of channel status flags. Users need to use the
* _edma_channel_status_flags type to decode the return variables.
*/
uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel);
/*!
* @brief Clears the eDMA channel status flags.
*
* @param base eDMA peripheral base address.
* @param channel eDMA channel number.
* @param mask The mask of channel status to be cleared. Users need to use
* the defined _edma_channel_status_flags type.
*/
void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mask);
/*! @} */
/*!
* @name eDMA Transactional Operation
*/
/*!
* @brief Creates the eDMA handle.
*
* This function is called if using the transactional API for eDMA. This function
* initializes the internal state of the eDMA handle.
*
* @param handle eDMA handle pointer. The eDMA handle stores callback function and
* parameters.
* @param base eDMA peripheral base address.
* @param channel eDMA channel number.
*/
void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel);
/*!
* @brief Installs the TCDs memory pool into the eDMA handle.
*
* This function is called after the EDMA_CreateHandle to use scatter/gather feature.
*
* @param handle eDMA handle pointer.
* @param tcdPool A memory pool to store TCDs. It must be 32 bytes aligned.
* @param tcdSize The number of TCD slots.
*/
void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize);
/*!
* @brief Installs a callback function for the eDMA transfer.
*
* This callback is called in the eDMA IRQ handler. Use the callback to do something after
* the current major loop transfer completes.
*
* @param handle eDMA handle pointer.
* @param callback eDMA callback function pointer.
* @param userData A parameter for the callback function.
*/
void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData);
/*!
* @brief Prepares the eDMA transfer structure.
*
* This function prepares the transfer configuration structure according to the user input.
*
* @param config The user configuration structure of type edma_transfer_t.
* @param srcAddr eDMA transfer source address.
* @param srcWidth eDMA transfer source address width(bytes).
* @param destAddr eDMA transfer destination address.
* @param destWidth eDMA transfer destination address width(bytes).
* @param bytesEachRequest eDMA transfer bytes per channel request.
* @param transferBytes eDMA transfer bytes to be transferred.
* @param type eDMA transfer type.
* @note The data address and the data width must be consistent. For example, if the SRC
* is 4 bytes, the source address must be 4 bytes aligned, or it results in
* source address error (SAE).
*/
void EDMA_PrepareTransfer(edma_transfer_config_t *config,
void *srcAddr,
uint32_t srcWidth,
void *destAddr,
uint32_t destWidth,
uint32_t bytesEachRequest,
uint32_t transferBytes,
edma_transfer_type_t type);
/*!
* @brief Submits the eDMA transfer request.
*
* This function submits the eDMA transfer request according to the transfer configuration structure.
* If submitting the transfer request repeatedly, this function packs an unprocessed request as
* a TCD and enables scatter/gather feature to process it in the next time.
*
* @param handle eDMA handle pointer.
* @param config Pointer to eDMA transfer configuration structure.
* @retval kStatus_EDMA_Success It means submit transfer request succeed.
* @retval kStatus_EDMA_QueueFull It means TCD queue is full. Submit transfer request is not allowed.
* @retval kStatus_EDMA_Busy It means the given channel is busy, need to submit request later.
*/
status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config);
/*!
* @brief eDMA starts transfer.
*
* This function enables the channel request. Users can call this function after submitting the transfer request
* or before submitting the transfer request.
*
* @param handle eDMA handle pointer.
*/
void EDMA_StartTransfer(edma_handle_t *handle);
/*!
* @brief eDMA stops transfer.
*
* This function disables the channel request to pause the transfer. Users can call EDMA_StartTransfer()
* again to resume the transfer.
*
* @param handle eDMA handle pointer.
*/
void EDMA_StopTransfer(edma_handle_t *handle);
/*!
* @brief eDMA aborts transfer.
*
* This function disables the channel request and clear transfer status bits.
* Users can submit another transfer after calling this API.
*
* @param handle DMA handle pointer.
*/
void EDMA_AbortTransfer(edma_handle_t *handle);
/*!
* @brief Get unused TCD slot number.
*
* This function gets current tcd index which is run. If the TCD pool pointer is NULL, it will return 0.
*
* @param handle DMA handle pointer.
* @return The unused tcd slot number.
*/
static inline uint32_t EDMA_GetUnusedTCDNumber(edma_handle_t *handle)
{
return (handle->tcdSize - handle->tcdUsed);
}
/*!
* @brief Get the next tcd address.
*
* This function gets the next tcd address. If this is last TCD, return 0.
*
* @param handle DMA handle pointer.
* @return The next TCD address.
*/
static inline uint32_t EDMA_GetNextTCDAddress(edma_handle_t *handle)
{
return (handle->base->TCD[handle->channel].DLAST_SGA);
}
/*!
* @brief eDMA IRQ handler for the current major loop transfer completion.
*
* This function clears the channel major interrupt flag and calls
* the callback function if it is not NULL.
*
* Note:
* For the case using TCD queue, when the major iteration count is exhausted, additional operations are performed.
* These include the final address adjustments and reloading of the BITER field into the CITER.
* Assertion of an optional interrupt request also occurs at this time, as does a possible fetch of a new TCD from
* memory using the scatter/gather address pointer included in the descriptor (if scatter/gather is enabled).
*
* For instance, when the time interrupt of TCD[0] happens, the TCD[1] has already been loaded into the eDMA engine.
* As sga and sga_index are calculated based on the DLAST_SGA bitfield lies in the TCD_CSR register, the sga_index
* in this case should be 2 (DLAST_SGA of TCD[1] stores the address of TCD[2]). Thus, the "tcdUsed" updated should be
* (tcdUsed - 2U) which indicates the number of TCDs can be loaded in the memory pool (because TCD[0] and TCD[1] have
* been loaded into the eDMA engine at this point already.).
*
* For the last two continuous ISRs in a scatter/gather process, they both load the last TCD (The last ISR does not
* load a new TCD) from the memory pool to the eDMA engine when major loop completes.
* Therefore, ensure that the header and tcdUsed updated are identical for them.
* tcdUsed are both 0 in this case as no TCD to be loaded.
*
* See the "eDMA basic data flow" in the eDMA Functional description section of the Reference Manual for
* further details.
*
* @param handle eDMA handle pointer.
*/
void EDMA_HandleIRQ(edma_handle_t *handle);
/* @} */
#if defined(__cplusplus)
}
#endif /* __cplusplus */
/* @} */
#endif /*_FSL_EDMA_H_*/

View File

@@ -0,0 +1,297 @@
/*
* The Clear BSD License
* Copyright (c) 2017, NXP Semiconductors, Inc.
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#include "fsl_elcdif.h"
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get instance number for ELCDIF module.
*
* @param base ELCDIF peripheral base address
*/
static uint32_t ELCDIF_GetInstance(LCDIF_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to ELCDIF bases for each instance. */
static LCDIF_Type *const s_elcdifBases[] = LCDIF_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to eLCDIF apb_clk for each instance. */
static const clock_ip_name_t s_elcdifApbClocks[] = LCDIF_CLOCKS;
#if defined(LCDIF_PERIPH_CLOCKS)
/*! @brief Pointers to eLCDIF pix_clk for each instance. */
static const clock_ip_name_t s_elcdifPixClocks[] = LCDIF_PERIPH_CLOCKS;
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*! @brief The control register value to select different pixel format. */
elcdif_pixel_format_reg_t s_pixelFormatReg[] = {
/* kELCDIF_PixelFormatRAW8 */
{/* Register CTRL. */
LCDIF_CTRL_WORD_LENGTH(1U),
/* Register CTRL1. */
LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x0FU)},
/* kELCDIF_PixelFormatRGB565 */
{/* Register CTRL. */
LCDIF_CTRL_WORD_LENGTH(0U),
/* Register CTRL1. */
LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x0FU)},
/* kELCDIF_PixelFormatRGB666 */
{/* Register CTRL. */
LCDIF_CTRL_WORD_LENGTH(3U) | LCDIF_CTRL_DATA_FORMAT_24_BIT(1U),
/* Register CTRL1. */
LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x07U)},
/* kELCDIF_PixelFormatXRGB8888 */
{/* Register CTRL. 24-bit. */
LCDIF_CTRL_WORD_LENGTH(3U),
/* Register CTRL1. */
LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x07U)},
/* kELCDIF_PixelFormatRGB888 */
{/* Register CTRL. 24-bit. */
LCDIF_CTRL_WORD_LENGTH(3U),
/* Register CTRL1. */
LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x0FU)},
};
/*******************************************************************************
* Codes
******************************************************************************/
static uint32_t ELCDIF_GetInstance(LCDIF_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_elcdifBases); instance++)
{
if (s_elcdifBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_elcdifBases));
return instance;
}
void ELCDIF_RgbModeInit(LCDIF_Type *base, const elcdif_rgb_mode_config_t *config)
{
assert(config);
assert(config->pixelFormat < ARRAY_SIZE(s_pixelFormatReg));
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
uint32_t instance = ELCDIF_GetInstance(base);
/* Enable the clock. */
CLOCK_EnableClock(s_elcdifApbClocks[instance]);
#if defined(LCDIF_PERIPH_CLOCKS)
CLOCK_EnableClock(s_elcdifPixClocks[instance]);
#endif
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Reset. */
ELCDIF_Reset(base);
base->CTRL = s_pixelFormatReg[(uint32_t)config->pixelFormat].regCtrl | (uint32_t)(config->dataBus) |
LCDIF_CTRL_DOTCLK_MODE_MASK | /* RGB mode. */
LCDIF_CTRL_BYPASS_COUNT_MASK | /* Keep RUN bit set. */
LCDIF_CTRL_MASTER_MASK;
base->CTRL1 = s_pixelFormatReg[(uint32_t)config->pixelFormat].regCtrl1;
base->TRANSFER_COUNT = ((uint32_t)config->panelHeight << LCDIF_TRANSFER_COUNT_V_COUNT_SHIFT) |
((uint32_t)config->panelWidth << LCDIF_TRANSFER_COUNT_H_COUNT_SHIFT);
base->VDCTRL0 = LCDIF_VDCTRL0_ENABLE_PRESENT_MASK | /* Data enable signal. */
LCDIF_VDCTRL0_VSYNC_PERIOD_UNIT_MASK | /* VSYNC period in the unit of display clock. */
LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_UNIT_MASK | /* VSYNC pulse width in the unit of display clock. */
(uint32_t)config->polarityFlags | (uint32_t)config->vsw;
base->VDCTRL1 = config->vsw + config->panelHeight + config->vfp + config->vbp;
base->VDCTRL2 = ((uint32_t)config->hsw << LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH_SHIFT) |
((uint32_t)(config->hfp + config->hbp + config->panelWidth + config->hsw))
<< LCDIF_VDCTRL2_HSYNC_PERIOD_SHIFT;
base->VDCTRL3 = (((uint32_t)config->hbp + config->hsw) << LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT_SHIFT) |
(((uint32_t)config->vbp + config->vsw) << LCDIF_VDCTRL3_VERTICAL_WAIT_CNT_SHIFT);
base->VDCTRL4 = LCDIF_VDCTRL4_SYNC_SIGNALS_ON_MASK |
((uint32_t)config->panelWidth << LCDIF_VDCTRL4_DOTCLK_H_VALID_DATA_CNT_SHIFT);
base->CUR_BUF = config->bufferAddr;
base->NEXT_BUF = config->bufferAddr;
}
void ELCDIF_RgbModeGetDefaultConfig(elcdif_rgb_mode_config_t *config)
{
assert(config);
config->panelWidth = 480U;
config->panelHeight = 272U;
config->hsw = 41;
config->hfp = 4;
config->hbp = 8;
config->vsw = 10;
config->vfp = 4;
config->vbp = 2;
config->polarityFlags = kELCDIF_VsyncActiveLow | kELCDIF_HsyncActiveLow | kELCDIF_DataEnableActiveLow |
kELCDIF_DriveDataOnFallingClkEdge;
config->bufferAddr = 0U;
config->pixelFormat = kELCDIF_PixelFormatRGB888;
config->dataBus = kELCDIF_DataBus24Bit;
}
void ELCDIF_Deinit(LCDIF_Type *base)
{
ELCDIF_Reset(base);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
uint32_t instance = ELCDIF_GetInstance(base);
/* Disable the clock. */
#if defined(LCDIF_PERIPH_CLOCKS)
CLOCK_DisableClock(s_elcdifPixClocks[instance]);
#endif
CLOCK_DisableClock(s_elcdifApbClocks[instance]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
void ELCDIF_RgbModeStop(LCDIF_Type *base)
{
base->CTRL_CLR = LCDIF_CTRL_DOTCLK_MODE_MASK;
/* Wait for data transfer finished. */
while (base->CTRL & LCDIF_CTRL_DOTCLK_MODE_MASK)
{
}
}
void ELCDIF_Reset(LCDIF_Type *base)
{
volatile uint32_t i = 0x100;
/* Disable the clock gate. */
base->CTRL_CLR = LCDIF_CTRL_CLKGATE_MASK;
/* Confirm the clock gate is disabled. */
while (base->CTRL & LCDIF_CTRL_CLKGATE_MASK)
{
}
/* Reset the block. */
base->CTRL_SET = LCDIF_CTRL_SFTRST_MASK;
/* Confirm the reset bit is set. */
while (!(base->CTRL & LCDIF_CTRL_SFTRST_MASK))
{
}
/* Delay for the reset. */
while (i--)
{
}
/* Bring the module out of reset. */
base->CTRL_CLR = LCDIF_CTRL_SFTRST_MASK;
/* Disable the clock gate. */
base->CTRL_CLR = LCDIF_CTRL_CLKGATE_MASK;
}
#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS)
void ELCDIF_SetAlphaSurfaceBufferConfig(LCDIF_Type *base, const elcdif_as_buffer_config_t *config)
{
assert(config);
base->AS_CTRL = (base->AS_CTRL & ~LCDIF_AS_CTRL_FORMAT_MASK) | LCDIF_AS_CTRL_FORMAT(config->pixelFormat);
base->AS_BUF = config->bufferAddr;
base->AS_NEXT_BUF = config->bufferAddr;
}
void ELCDIF_SetAlphaSurfaceBlendConfig(LCDIF_Type *base, const elcdif_as_blend_config_t *config)
{
assert(config);
uint32_t reg;
reg = base->AS_CTRL;
reg &= ~(LCDIF_AS_CTRL_ALPHA_INVERT_MASK | LCDIF_AS_CTRL_ROP_MASK | LCDIF_AS_CTRL_ALPHA_MASK |
LCDIF_AS_CTRL_ALPHA_CTRL_MASK);
reg |= (LCDIF_AS_CTRL_ROP(config->ropMode) | LCDIF_AS_CTRL_ALPHA(config->alpha) |
LCDIF_AS_CTRL_ALPHA_CTRL(config->alphaMode));
if (config->invertAlpha)
{
reg |= LCDIF_AS_CTRL_ALPHA_INVERT_MASK;
}
base->AS_CTRL = reg;
}
#endif /* FSL_FEATURE_LCDIF_HAS_NO_AS */
#if (defined(FSL_FEATURE_LCDIF_HAS_LUT) && FSL_FEATURE_LCDIF_HAS_LUT)
status_t ELCDIF_UpdateLut(
LCDIF_Type *base, elcdif_lut_t lut, uint16_t startIndex, const uint32_t *lutData, uint16_t count)
{
volatile uint32_t *regLutAddr;
volatile uint32_t *regLutData;
uint32_t i;
/* Only has 256 entries. */
if (startIndex + count > ELCDIF_LUT_ENTRY_NUM)
{
return kStatus_InvalidArgument;
}
if (kELCDIF_Lut0 == lut)
{
regLutAddr = &(base->LUT0_ADDR);
regLutData = &(base->LUT0_DATA);
}
else
{
regLutAddr = &(base->LUT1_ADDR);
regLutData = &(base->LUT1_DATA);
}
*regLutAddr = startIndex;
for (i = 0; i < count; i++)
{
*regLutData = lutData[i];
}
return kStatus_Success;
}
#endif /* FSL_FEATURE_LCDIF_HAS_LUT */

View File

@@ -0,0 +1,768 @@
/*
* The Clear BSD License
* Copyright (c) 2017, NXP Semiconductors, Inc.
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#ifndef _FSL_ELCDIF_H_
#define _FSL_ELCDIF_H_
#include "fsl_common.h"
/*!
* @addtogroup elcdif
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief eLCDIF driver version */
#define FSL_ELCDIF_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */
/*@}*/
/* All IRQ flags in CTRL1 register. */
#define ELCDIF_CTRL1_IRQ_MASK \
(LCDIF_CTRL1_BM_ERROR_IRQ_MASK | LCDIF_CTRL1_OVERFLOW_IRQ_MASK | LCDIF_CTRL1_UNDERFLOW_IRQ_MASK | \
LCDIF_CTRL1_CUR_FRAME_DONE_IRQ_MASK | LCDIF_CTRL1_VSYNC_EDGE_IRQ_MASK)
/* All IRQ enable control bits in CTRL1 register. */
#define ELCDIF_CTRL1_IRQ_EN_MASK \
(LCDIF_CTRL1_BM_ERROR_IRQ_EN_MASK | LCDIF_CTRL1_OVERFLOW_IRQ_EN_MASK | LCDIF_CTRL1_UNDERFLOW_IRQ_EN_MASK | \
LCDIF_CTRL1_CUR_FRAME_DONE_IRQ_EN_MASK | LCDIF_CTRL1_VSYNC_EDGE_IRQ_EN_MASK)
/* All IRQ flags in AS_CTRL register. */
#if defined(LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_MASK)
#define ELCDIF_AS_CTRL_IRQ_MASK (LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_MASK)
#else
#define ELCDIF_AS_CTRL_IRQ_MASK 0U
#endif
/* All IRQ enable control bits in AS_CTRL register. */
#if defined(LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_EN_MASK)
#define ELCDIF_AS_CTRL_IRQ_EN_MASK (LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_EN_MASK)
#else
#define ELCDIF_AS_CTRL_IRQ_EN_MASK 0U
#endif
#if ((ELCDIF_CTRL1_IRQ_MASK & ELCDIF_AS_CTRL_IRQ_MASK) || (ELCDIF_AS_CTRL_IRQ_MASK & ELCDIF_AS_CTRL_IRQ_EN_MASK))
#error Interrupt bits overlap, need to update the interrupt functions.
#endif
/* LUT memory entery number. */
#define ELCDIF_LUT_ENTRY_NUM 256
/*!
* @brief eLCDIF signal polarity flags
*/
enum _elcdif_polarity_flags
{
kELCDIF_VsyncActiveLow = 0U, /*!< VSYNC active low. */
kELCDIF_VsyncActiveHigh = LCDIF_VDCTRL0_VSYNC_POL_MASK, /*!< VSYNC active high. */
kELCDIF_HsyncActiveLow = 0U, /*!< HSYNC active low. */
kELCDIF_HsyncActiveHigh = LCDIF_VDCTRL0_HSYNC_POL_MASK, /*!< HSYNC active high. */
kELCDIF_DataEnableActiveLow = 0U, /*!< Data enable line active low. */
kELCDIF_DataEnableActiveHigh = LCDIF_VDCTRL0_ENABLE_POL_MASK, /*!< Data enable line active high. */
kELCDIF_DriveDataOnFallingClkEdge = 0U, /*!< Drive data on falling clock edge, capture data
on rising clock edge. */
kELCDIF_DriveDataOnRisingClkEdge = LCDIF_VDCTRL0_DOTCLK_POL_MASK, /*!< Drive data on falling
clock edge, capture data
on rising clock edge. */
};
/*!
* @brief The eLCDIF interrupts to enable.
*/
enum _elcdif_interrupt_enable
{
kELCDIF_BusMasterErrorInterruptEnable = LCDIF_CTRL1_BM_ERROR_IRQ_EN_MASK, /*!< Bus master error interrupt. */
kELCDIF_TxFifoOverflowInterruptEnable = LCDIF_CTRL1_OVERFLOW_IRQ_EN_MASK, /*!< TXFIFO overflow interrupt. */
kELCDIF_TxFifoUnderflowInterruptEnable = LCDIF_CTRL1_UNDERFLOW_IRQ_EN_MASK, /*!< TXFIFO underflow interrupt. */
kELCDIF_CurFrameDoneInterruptEnable =
LCDIF_CTRL1_CUR_FRAME_DONE_IRQ_EN_MASK, /*!< Interrupt when hardware enters vertical blanking state. */
kELCDIF_VsyncEdgeInterruptEnable =
LCDIF_CTRL1_VSYNC_EDGE_IRQ_EN_MASK, /*!< Interrupt when hardware encounters VSYNC edge. */
#if defined(LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_EN_MASK)
kELCDIF_SciSyncOnInterruptEnable =
LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_EN_MASK, /*!< Interrupt when eLCDIF lock with CSI input. */
#endif
};
/*!
* @brief The eLCDIF interrupt status flags.
*/
enum _elcdif_interrupt_flags
{
kELCDIF_BusMasterError = LCDIF_CTRL1_BM_ERROR_IRQ_MASK, /*!< Bus master error interrupt. */
kELCDIF_TxFifoOverflow = LCDIF_CTRL1_OVERFLOW_IRQ_MASK, /*!< TXFIFO overflow interrupt. */
kELCDIF_TxFifoUnderflow = LCDIF_CTRL1_UNDERFLOW_IRQ_MASK, /*!< TXFIFO underflow interrupt. */
kELCDIF_CurFrameDone =
LCDIF_CTRL1_CUR_FRAME_DONE_IRQ_MASK, /*!< Interrupt when hardware enters vertical blanking state. */
kELCDIF_VsyncEdge = LCDIF_CTRL1_VSYNC_EDGE_IRQ_MASK, /*!< Interrupt when hardware encounters VSYNC edge. */
#if defined(LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_MASK)
kELCDIF_SciSyncOn = LCDIF_AS_CTRL_CSI_SYNC_ON_IRQ_MASK, /*!< Interrupt when eLCDIF lock with CSI input. */
#endif
};
/*!
* @brief eLCDIF status flags
*/
enum _elcdif_status_flags
{
kELCDIF_LFifoFull = LCDIF_STAT_LFIFO_FULL_MASK, /*!< LFIFO full. */
kELCDIF_LFifoEmpty = LCDIF_STAT_LFIFO_EMPTY_MASK, /*!< LFIFO empty. */
kELCDIF_TxFifoFull = LCDIF_STAT_TXFIFO_FULL_MASK, /*!< TXFIFO full. */
kELCDIF_TxFifoEmpty = LCDIF_STAT_TXFIFO_EMPTY_MASK, /*!< TXFIFO empty. */
#if defined(LCDIF_STAT_BUSY_MASK)
kELCDIF_LcdControllerBusy = LCDIF_STAT_BUSY_MASK, /*!< The external LCD controller busy signal. */
#endif
#if defined(LCDIF_STAT_DVI_CURRENT_FIELD_MASK)
kELCDIF_CurDviField2 = LCDIF_STAT_DVI_CURRENT_FIELD_MASK, /*!< Current DVI filed, if set, then current filed is 2,
otherwise current filed is 1. */
#endif
};
/*!
* @brief The pixel format.
*
* This enumerator should be defined together with the array s_pixelFormatReg.
* To support new pixel format, enhance this enumerator and s_pixelFormatReg.
*/
typedef enum _elcdif_pixel_format
{
kELCDIF_PixelFormatRAW8 = 0, /*!< RAW 8 bit, four data use 32 bits. */
kELCDIF_PixelFormatRGB565 = 1, /*!< RGB565, two pixel use 32 bits. */
kELCDIF_PixelFormatRGB666 = 2, /*!< RGB666 unpacked, one pixel uses 32 bits, high byte unused,
upper 2 bits of other bytes unused. */
kELCDIF_PixelFormatXRGB8888 = 3, /*!< XRGB8888 unpacked, one pixel uses 32 bits, high byte unused. */
kELCDIF_PixelFormatRGB888 = 4, /*!< RGB888 packed, one pixel uses 24 bits. */
} elcdif_pixel_format_t;
/*! @brief The LCD data bus type. */
typedef enum _elcdif_lcd_data_bus
{
kELCDIF_DataBus8Bit = LCDIF_CTRL_LCD_DATABUS_WIDTH(1), /*!< 8-bit data bus. */
kELCDIF_DataBus16Bit = LCDIF_CTRL_LCD_DATABUS_WIDTH(0), /*!< 16-bit data bus, support RGB565. */
kELCDIF_DataBus18Bit = LCDIF_CTRL_LCD_DATABUS_WIDTH(2), /*!< 18-bit data bus, support RGB666. */
kELCDIF_DataBus24Bit = LCDIF_CTRL_LCD_DATABUS_WIDTH(3), /*!< 24-bit data bus, support RGB888. */
} elcdif_lcd_data_bus_t;
/*!
* @brief The register value when using different pixel format.
*
* These register bits control the pixel format:
* - CTRL[DATA_FORMAT_24_BIT]
* - CTRL[DATA_FORMAT_18_BIT]
* - CTRL[DATA_FORMAT_16_BIT]
* - CTRL[WORD_LENGTH]
* - CTRL1[BYTE_PACKING_FORMAT]
*/
typedef struct _elcdif_pixel_format_reg
{
uint32_t regCtrl; /*!< Value of register CTRL. */
uint32_t regCtrl1; /*!< Value of register CTRL1. */
} elcdif_pixel_format_reg_t;
/*!
* @brief eLCDIF configure structure for RGB mode (DOTCLK mode).
*/
typedef struct _elcdif_rgb_mode_config
{
uint16_t panelWidth; /*!< Display panel width, pixels per line. */
uint16_t panelHeight; /*!< Display panel height, how many lines per panel. */
uint8_t hsw; /*!< HSYNC pulse width. */
uint8_t hfp; /*!< Horizontal front porch. */
uint8_t hbp; /*!< Horizontal back porch. */
uint8_t vsw; /*!< VSYNC pulse width. */
uint8_t vfp; /*!< Vrtical front porch. */
uint8_t vbp; /*!< Vertical back porch. */
uint32_t polarityFlags; /*!< OR'ed value of @ref _elcdif_polarity_flags, used to contol the signal polarity. */
uint32_t bufferAddr; /*!< Frame buffer address. */
elcdif_pixel_format_t pixelFormat; /*!< Pixel format. */
elcdif_lcd_data_bus_t dataBus; /*!< LCD data bus. */
} elcdif_rgb_mode_config_t;
/*!
* @brief eLCDIF alpha surface pixel format.
*/
typedef enum _elcdif_as_pixel_format
{
kELCDIF_AsPixelFormatARGB8888 = 0x0, /*!< 32-bit pixels with alpha. */
kELCDIF_AsPixelFormatRGB888 = 0x4, /*!< 32-bit pixels without alpha (unpacked 24-bit format) */
kELCDIF_AsPixelFormatARGB1555 = 0x8, /*!< 16-bit pixels with alpha. */
kELCDIF_AsPixelFormatARGB4444 = 0x9, /*!< 16-bit pixels with alpha. */
kELCDIF_AsPixelFormatRGB555 = 0xC, /*!< 16-bit pixels without alpha. */
kELCDIF_AsPixelFormatRGB444 = 0xD, /*!< 16-bit pixels without alpha. */
kELCDIF_AsPixelFormatRGB565 = 0xE, /*!< 16-bit pixels without alpha. */
} elcdif_as_pixel_format_t;
/*!
* @brief eLCDIF alpha surface buffer configuration.
*/
typedef struct _elcdif_as_buffer_config
{
uint32_t bufferAddr; /*!< Buffer address. */
elcdif_as_pixel_format_t pixelFormat; /*!< Pixel format. */
} elcdif_as_buffer_config_t;
/*!
* @brief eLCDIF alpha mode during blending.
*/
typedef enum _elcdif_alpha_mode
{
kELCDIF_AlphaEmbedded, /*!< The alpha surface pixel alpha value will be used for blend. */
kELCDIF_AlphaOverride, /*!< The user defined alpha value will be used for blend directly. */
kELCDIF_AlphaMultiply, /*!< The alpha surface pixel alpha value scaled the user defined
alpha value will be used for blend, for example, pixel alpha set
set to 200, user defined alpha set to 100, then the reault alpha
is 200 * 100 / 255. */
kELCDIF_AlphaRop /*!< Raster operation. */
} elcdif_alpha_mode_t;
/*!
* @brief eLCDIF ROP mode during blending.
*
* Explanation:
* - AS: Alpha surface
* - PS: Process surface
* - nAS: Alpha surface NOT value
* - nPS: Process surface NOT value
*/
typedef enum _elcdif_rop_mode
{
kELCDIF_RopMaskAs = 0x0, /*!< AS AND PS. */
kELCDIF_RopMaskNotAs = 0x1, /*!< nAS AND PS. */
kELCDIF_RopMaskAsNot = 0x2, /*!< AS AND nPS. */
kELCDIF_RopMergeAs = 0x3, /*!< AS OR PS. */
kELCDIF_RopMergeNotAs = 0x4, /*!< nAS OR PS. */
kELCDIF_RopMergeAsNot = 0x5, /*!< AS OR nPS. */
kELCDIF_RopNotCopyAs = 0x6, /*!< nAS. */
kELCDIF_RopNot = 0x7, /*!< nPS. */
kELCDIF_RopNotMaskAs = 0x8, /*!< AS NAND PS. */
kELCDIF_RopNotMergeAs = 0x9, /*!< AS NOR PS. */
kELCDIF_RopXorAs = 0xA, /*!< AS XOR PS. */
kELCDIF_RopNotXorAs = 0xB /*!< AS XNOR PS. */
} elcdif_rop_mode_t;
/*!
* @brief eLCDIF alpha surface blending configuration.
*/
typedef struct _elcdif_as_blend_config
{
uint8_t alpha; /*!< User defined alpha value, only used when @ref alphaMode is @ref kELCDIF_AlphaOverride or @ref
kELCDIF_AlphaRop. */
bool invertAlpha; /*!< Set true to invert the alpha. */
elcdif_alpha_mode_t alphaMode; /*!< Alpha mode. */
elcdif_rop_mode_t ropMode; /*!< ROP mode, only valid when @ref alphaMode is @ref kELCDIF_AlphaRop. */
} elcdif_as_blend_config_t;
/*!
* @brief eLCDIF LUT
*
* The Lookup Table (LUT) is used to expand the 8 bits pixel to 24 bits pixel
* before output to external displayer.
*
* There are two 256x24 bits LUT memory in LCDIF, the LSB of frame buffer address
* determins which memory to use.
*/
typedef enum _elcdif_lut
{
kELCDIF_Lut0 = 0, /*!< LUT 0. */
kELCDIF_Lut1, /*!< LUT 1. */
} elcdif_lut_t;
/*******************************************************************************
* APIs
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/*!
* @name eLCDIF initialization and de-initialization
* @{
*/
/*!
* @brief Initializes the eLCDIF to work in RGB mode (DOTCLK mode).
*
* This function ungates the eLCDIF clock and configures the eLCDIF peripheral according
* to the configuration structure.
*
* @param base eLCDIF peripheral base address.
* @param config Pointer to the configuration structure.
*/
void ELCDIF_RgbModeInit(LCDIF_Type *base, const elcdif_rgb_mode_config_t *config);
/*!
* @brief Gets the eLCDIF default configuration structure for RGB (DOTCLK) mode.
*
* This function sets the configuration structure to default values.
* The default configuration is set to the following values.
* @code
config->panelWidth = 480U;
config->panelHeight = 272U;
config->hsw = 41;
config->hfp = 4;
config->hbp = 8;
config->vsw = 10;
config->vfp = 4;
config->vbp = 2;
config->polarityFlags = kELCDIF_VsyncActiveLow |
kELCDIF_HsyncActiveLow |
kELCDIF_DataEnableActiveLow |
kELCDIF_DriveDataOnFallingClkEdge;
config->bufferAddr = 0U;
config->pixelFormat = kELCDIF_PixelFormatRGB888;
config->dataBus = kELCDIF_DataBus24Bit;
@code
*
* @param config Pointer to the eLCDIF configuration structure.
*/
void ELCDIF_RgbModeGetDefaultConfig(elcdif_rgb_mode_config_t *config);
/*!
* @brief Deinitializes the eLCDIF peripheral.
*
* @param base eLCDIF peripheral base address.
*/
void ELCDIF_Deinit(LCDIF_Type *base);
/* @} */
/*!
* @name Module operation
* @{
*/
/*!
* @brief Start to display in RGB (DOTCLK) mode.
*
* @param base eLCDIF peripheral base address.
*/
static inline void ELCDIF_RgbModeStart(LCDIF_Type *base)
{
base->CTRL_SET = LCDIF_CTRL_RUN_MASK | LCDIF_CTRL_DOTCLK_MODE_MASK;
}
/*!
* @brief Stop display in RGB (DOTCLK) mode and wait until finished.
*
* @param base eLCDIF peripheral base address.
*/
void ELCDIF_RgbModeStop(LCDIF_Type *base);
/*!
* @brief Set the next frame buffer address to display.
*
* @param base eLCDIF peripheral base address.
* @param bufferAddr The frame buffer address to set.
*/
static inline void ELCDIF_SetNextBufferAddr(LCDIF_Type *base, uint32_t bufferAddr)
{
base->NEXT_BUF = bufferAddr;
}
/*!
* @brief Reset the eLCDIF peripheral.
*
* @param base eLCDIF peripheral base address.
*/
void ELCDIF_Reset(LCDIF_Type *base);
#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_RESET_PIN) && FSL_FEATURE_LCDIF_HAS_NO_RESET_PIN)
/*!
* @brief Pull up or down the reset pin for the externel LCD controller.
*
* @param base eLCDIF peripheral base address.
* @param pullUp True to pull up reset pin, false to pull down.
*/
static inline void ELCDIF_PullUpResetPin(LCDIF_Type *base, bool pullUp)
{
if (pullUp)
{
base->CTRL1_SET = LCDIF_CTRL1_RESET_MASK;
}
else
{
base->CTRL1_CLR = LCDIF_CTRL1_RESET_MASK;
}
}
#endif
/*!
* @brief Enable or disable the hand shake with PXP.
*
* @param base eLCDIF peripheral base address.
* @param enable True to enable, false to disable.
*/
static inline void ELCDIF_EnablePxpHandShake(LCDIF_Type *base, bool enable)
{
if (enable)
{
base->CTRL_SET = LCDIF_CTRL_ENABLE_PXP_HANDSHAKE_MASK;
}
else
{
base->CTRL_CLR = LCDIF_CTRL_ENABLE_PXP_HANDSHAKE_MASK;
}
}
/* @} */
/*!
* @name Status
* @{
*/
/*!
* @brief Get the CRC value of the frame sent out.
*
* When a frame is sent complete (the interrupt @ref kELCDIF_CurFrameDone assert), this function
* can be used to get the CRC value of the frame sent.
*
* @param base eLCDIF peripheral base address.
* @return The CRC value.
*
* @note The CRC value is dependent on the LCD_DATABUS_WIDTH.
*/
static inline uint32_t ELCDIF_GetCrcValue(LCDIF_Type *base)
{
return base->CRC_STAT;
}
/*!
* @brief Get the bus master error virtual address.
*
* When bus master error occurs (the interrupt kELCDIF_BusMasterError assert), this function
* can get the virtual address at which the AXI master received an error
* response from the slave.
*
* @param base eLCDIF peripheral base address.
* @return The error virtual address.
*/
static inline uint32_t ELCDIF_GetBusMasterErrorAddr(LCDIF_Type *base)
{
return base->BM_ERROR_STAT;
}
/*!
* @brief Get the eLCDIF status.
*
* The status flags are returned as a mask value, application could check the
* corresponding bit. Example:
*
* @code
uint32_t statusFlags;
statusFlags = ELCDIF_GetStatus(LCDIF);
// If LFIFO is full.
if (kELCDIF_LFifoFull & statusFlags)
{
// ...;
}
// If TXFIFO is empty.
if (kELCDIF_TxFifoEmpty & statusFlags)
{
// ...;
}
@endcode
*
* @param base eLCDIF peripheral base address.
* @return The mask value of status flags, it is OR'ed value of @ref _elcdif_status_flags.
*/
static inline uint32_t ELCDIF_GetStatus(LCDIF_Type *base)
{
return base->STAT & (LCDIF_STAT_LFIFO_FULL_MASK | LCDIF_STAT_LFIFO_EMPTY_MASK | LCDIF_STAT_TXFIFO_FULL_MASK |
LCDIF_STAT_TXFIFO_EMPTY_MASK
#if defined(LCDIF_STAT_BUSY_MASK)
| LCDIF_STAT_BUSY_MASK
#endif
#if defined(LCDIF_STAT_DVI_CURRENT_FIELD_MASK)
| LCDIF_STAT_DVI_CURRENT_FIELD_MASK
#endif
);
}
/*!
* @brief Get current count in Latency buffer (LFIFO).
*
* @param base eLCDIF peripheral base address.
* @return The LFIFO current count
*/
static inline uint32_t ELCDIF_GetLFifoCount(LCDIF_Type *base)
{
return (base->STAT & LCDIF_STAT_LFIFO_COUNT_MASK) >> LCDIF_STAT_LFIFO_COUNT_SHIFT;
}
/* @} */
/*!
* @name Interrupts
* @{
*/
/*!
* @brief Enables eLCDIF interrupt requests.
*
* @param base eLCDIF peripheral base address.
* @param mask interrupt source, OR'ed value of _elcdif_interrupt_enable.
*/
static inline void ELCDIF_EnableInterrupts(LCDIF_Type *base, uint32_t mask)
{
base->CTRL1_SET = (mask & ELCDIF_CTRL1_IRQ_EN_MASK);
#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS)
base->AS_CTRL |= (mask & ELCDIF_AS_CTRL_IRQ_EN_MASK);
#endif
}
/*!
* @brief Disables eLCDIF interrupt requests.
*
* @param base eLCDIF peripheral base address.
* @param mask interrupt source, OR'ed value of _elcdif_interrupt_enable.
*/
static inline void ELCDIF_DisableInterrupts(LCDIF_Type *base, uint32_t mask)
{
base->CTRL1_CLR = (mask & ELCDIF_CTRL1_IRQ_EN_MASK);
#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS)
base->AS_CTRL &= ~(mask & ELCDIF_AS_CTRL_IRQ_EN_MASK);
#endif
}
/*!
* @brief Get eLCDIF interrupt peding status.
*
* @param base eLCDIF peripheral base address.
* @return Interrupt pending status, OR'ed value of _elcdif_interrupt_flags.
*/
static inline uint32_t ELCDIF_GetInterruptStatus(LCDIF_Type *base)
{
uint32_t flags;
flags = (base->CTRL1 & ELCDIF_CTRL1_IRQ_MASK);
#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS)
flags |= (base->AS_CTRL & ELCDIF_AS_CTRL_IRQ_MASK);
#endif
return flags;
}
/*!
* @brief Clear eLCDIF interrupt peding status.
*
* @param base eLCDIF peripheral base address.
* @param mask of the flags to clear, OR'ed value of _elcdif_interrupt_flags.
*/
static inline void ELCDIF_ClearInterruptStatus(LCDIF_Type *base, uint32_t mask)
{
base->CTRL1_CLR = (mask & ELCDIF_CTRL1_IRQ_MASK);
#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS)
base->AS_CTRL &= ~(mask & ELCDIF_AS_CTRL_IRQ_MASK);
#endif
}
/* @} */
#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS)
/*!
* @name Alpha surface
* @{
*/
/*!
* @brief Set the configuration for alpha surface buffer.
*
* @param base eLCDIF peripheral base address.
* @param config Pointer to the configuration structure.
*/
void ELCDIF_SetAlphaSurfaceBufferConfig(LCDIF_Type *base, const elcdif_as_buffer_config_t *config);
/*!
* @brief Set the alpha surface blending configuration.
*
* @param base eLCDIF peripheral base address.
* @param config Pointer to the configuration structure.
*/
void ELCDIF_SetAlphaSurfaceBlendConfig(LCDIF_Type *base, const elcdif_as_blend_config_t *config);
/*!
* @brief Set the next alpha surface buffer address.
*
* @param base eLCDIF peripheral base address.
* @param bufferAddr Alpha surface buffer address.
*/
static inline void ELCDIF_SetNextAlphaSurfaceBufferAddr(LCDIF_Type *base, uint32_t bufferAddr)
{
base->AS_NEXT_BUF = bufferAddr;
}
/*!
* @brief Set the overlay color key.
*
* If a pixel in the current overlay image with a color that falls in the range
* from the @p colorKeyLow to @p colorKeyHigh range, it will use the process surface
* pixel value for that location.
*
* @param base eLCDIF peripheral base address.
* @param colorKeyLow Color key low range.
* @param colorKeyHigh Color key high range.
*
* @note Colorkey operations are higher priority than alpha or ROP operations
*/
static inline void ELCDIF_SetOverlayColorKey(LCDIF_Type *base, uint32_t colorKeyLow, uint32_t colorKeyHigh)
{
base->AS_CLRKEYLOW = colorKeyLow;
base->AS_CLRKEYHIGH = colorKeyHigh;
}
/*!
* @brief Enable or disable the color key.
*
* @param base eLCDIF peripheral base address.
* @param enable True to enable, false to disable.
*/
static inline void ELCDIF_EnableOverlayColorKey(LCDIF_Type *base, bool enable)
{
if (enable)
{
base->AS_CTRL |= LCDIF_AS_CTRL_ENABLE_COLORKEY_MASK;
}
else
{
base->AS_CTRL &= ~LCDIF_AS_CTRL_ENABLE_COLORKEY_MASK;
}
}
/*!
* @brief Enable or disable the alpha surface.
*
* @param base eLCDIF peripheral base address.
* @param enable True to enable, false to disable.
*/
static inline void ELCDIF_EnableAlphaSurface(LCDIF_Type *base, bool enable)
{
if (enable)
{
base->AS_CTRL |= LCDIF_AS_CTRL_AS_ENABLE_MASK;
}
else
{
base->AS_CTRL &= ~LCDIF_AS_CTRL_AS_ENABLE_MASK;
}
}
/*!
* @brief Enable or disable the process surface.
*
* Process surface is the normal frame buffer. The process surface content
* is controlled by @ref ELCDIF_SetNextBufferAddr.
*
* @param base eLCDIF peripheral base address.
* @param enable True to enable, false to disable.
*/
static inline void ELCDIF_EnableProcessSurface(LCDIF_Type *base, bool enable)
{
if (enable)
{
base->AS_CTRL &= ~LCDIF_AS_CTRL_PS_DISABLE_MASK;
}
else
{
base->AS_CTRL |= LCDIF_AS_CTRL_PS_DISABLE_MASK;
}
}
/* @} */
#endif /* FSL_FEATURE_LCDIF_HAS_NO_AS */
#if (defined(FSL_FEATURE_LCDIF_HAS_LUT) && FSL_FEATURE_LCDIF_HAS_LUT)
/*!
* @name LUT
*
* The Lookup Table (LUT) is used to expand the 8 bits pixel to 24 bits pixel
* before output to external displayer.
*
* There are two 256x24 bits LUT memory in LCDIF, the LSB of frame buffer address
* determins which memory to use.
*
* @{
*/
/*!
* @brief Enable or disable the LUT.
*
* @param base eLCDIF peripheral base address.
* @param enable True to enable, false to disable.
*/
static inline void ELCDIF_EnableLut(LCDIF_Type *base, bool enable)
{
if (enable)
{
base->LUT_CTRL &= ~LCDIF_LUT_CTRL_LUT_BYPASS_MASK;
}
else
{
base->LUT_CTRL |= LCDIF_LUT_CTRL_LUT_BYPASS_MASK;
}
}
/*!
* @brief Load the LUT value.
*
* This function loads the LUT value to the specific LUT memory, user can
* specify the start entry index.
*
* @param base eLCDIF peripheral base address.
* @param lut Which LUT to load.
* @param startIndex The start index of the LUT entry to update.
* @param lutData The LUT data to load.
* @param count Count of @p lutData.
* @retval kStatus_Success Initialization success.
* @retval kStatus_InvalidArgument Wrong argument.
*/
status_t ELCDIF_UpdateLut(
LCDIF_Type *base, elcdif_lut_t lut, uint16_t startIndex, const uint32_t *lutData, uint16_t count);
/* @} */
#endif /* FSL_FEATURE_LCDIF_HAS_LUT */
#if defined(__cplusplus)
}
#endif /* __cplusplus */
/* @} */
#endif /*_FSL_ELCDIF_H_*/

View File

@@ -0,0 +1,483 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#include "fsl_enc.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define ENC_CTRL_W1C_FLAGS (ENC_CTRL_HIRQ_MASK | ENC_CTRL_XIRQ_MASK | ENC_CTRL_DIRQ_MASK | ENC_CTRL_CMPIRQ_MASK)
#define ENC_CTRL2_W1C_FLAGS (ENC_CTRL2_SABIRQ_MASK | ENC_CTRL2_ROIRQ_MASK | ENC_CTRL2_RUIRQ_MASK)
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get instance number for ENC module.
*
* @param base ENC peripheral base address
*/
static uint32_t ENC_GetInstance(ENC_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to ENC bases for each instance. */
static ENC_Type *const s_encBases[] = ENC_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to ENC clocks for each instance. */
static const clock_ip_name_t s_encClocks[] = ENC_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t ENC_GetInstance(ENC_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_encBases); instance++)
{
if (s_encBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_encBases));
return instance;
}
void ENC_Init(ENC_Type *base, const enc_config_t *config)
{
assert(NULL != config);
uint32_t tmp16;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the clock. */
CLOCK_EnableClock(s_encClocks[ENC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* ENC_CTRL. */
tmp16 = base->CTRL & (uint16_t)(~(ENC_CTRL_W1C_FLAGS | ENC_CTRL_HIP_MASK | ENC_CTRL_HNE_MASK | ENC_CTRL_REV_MASK |
ENC_CTRL_PH1_MASK | ENC_CTRL_XIP_MASK | ENC_CTRL_XNE_MASK | ENC_CTRL_WDE_MASK));
/* For HOME trigger. */
if (kENC_HOMETriggerDisabled != config->HOMETriggerMode)
{
tmp16 |= ENC_CTRL_HIP_MASK;
if (kENC_HOMETriggerOnFallingEdge == config->HOMETriggerMode)
{
tmp16 |= ENC_CTRL_HNE_MASK;
}
}
/* For encoder work mode. */
if (config->enableReverseDirection)
{
tmp16 |= ENC_CTRL_REV_MASK;
}
if (kENC_DecoderWorkAsSignalPhaseCountMode == config->decoderWorkMode)
{
tmp16 |= ENC_CTRL_PH1_MASK;
}
/* For INDEX trigger. */
if (kENC_INDEXTriggerDisabled != config->INDEXTriggerMode)
{
tmp16 |= ENC_CTRL_XIP_MASK;
if (kENC_INDEXTriggerOnFallingEdge == config->INDEXTriggerMode)
{
tmp16 |= ENC_CTRL_XNE_MASK;
}
}
/* Watchdog. */
if (config->enableWatchdog)
{
tmp16 |= ENC_CTRL_WDE_MASK;
base->WTR = config->watchdogTimeoutValue; /* WDOG can be only available when the feature is enabled. */
}
base->CTRL = tmp16;
/* ENC_FILT. */
base->FILT = ENC_FILT_FILT_CNT(config->filterCount) | ENC_FILT_FILT_PER(config->filterSamplePeriod);
/* ENC_CTRL2. */
tmp16 = base->CTRL2 & (uint16_t)(~(ENC_CTRL2_W1C_FLAGS | ENC_CTRL2_OUTCTL_MASK | ENC_CTRL2_REVMOD_MASK |
ENC_CTRL2_MOD_MASK | ENC_CTRL2_UPDPOS_MASK | ENC_CTRL2_UPDHLD_MASK));
if (kENC_POSMATCHOnReadingAnyPositionCounter == config->positionMatchMode)
{
tmp16 |= ENC_CTRL2_OUTCTL_MASK;
}
if (kENC_RevolutionCountOnRollOverModulus == config->revolutionCountCondition)
{
tmp16 |= ENC_CTRL2_REVMOD_MASK;
}
if (config->enableModuloCountMode)
{
tmp16 |= ENC_CTRL2_MOD_MASK;
/* Set modulus value. */
base->UMOD = (uint16_t)(config->positionModulusValue >> 16U); /* Upper 16 bits. */
base->LMOD = (uint16_t)(config->positionModulusValue); /* Lower 16 bits. */
}
if (config->enableTRIGGERClearPositionCounter)
{
tmp16 |= ENC_CTRL2_UPDPOS_MASK;
}
if (config->enableTRIGGERClearHoldPositionCounter)
{
tmp16 |= ENC_CTRL2_UPDHLD_MASK;
}
base->CTRL2 = tmp16;
/* ENC_UCOMP & ENC_LCOMP. */
base->UCOMP = (uint16_t)(config->positionCompareValue >> 16U); /* Upper 16 bits. */
base->LCOMP = (uint16_t)(config->positionCompareValue); /* Lower 16 bits. */
/* ENC_UINIT & ENC_LINIT. */
base->UINIT = (uint16_t)(config->positionInitialValue >> 16U); /* Upper 16 bits. */
base->LINIT = (uint16_t)(config->positionInitialValue); /* Lower 16 bits. */
}
void ENC_Deinit(ENC_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable the clock. */
CLOCK_DisableClock(s_encClocks[ENC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
void ENC_GetDefaultConfig(enc_config_t *config)
{
assert(NULL != config);
config->enableReverseDirection = false;
config->decoderWorkMode = kENC_DecoderWorkAsNormalMode;
config->HOMETriggerMode = kENC_HOMETriggerDisabled;
config->INDEXTriggerMode = kENC_INDEXTriggerDisabled;
config->enableTRIGGERClearPositionCounter = false;
config->enableTRIGGERClearHoldPositionCounter = false;
config->enableWatchdog = false;
config->watchdogTimeoutValue = 0U;
config->filterCount = 0U;
config->filterSamplePeriod = 0U;
config->positionMatchMode = kENC_POSMATCHOnPositionCounterEqualToComapreValue;
config->positionCompareValue = 0xFFFFFFFFU;
config->revolutionCountCondition = kENC_RevolutionCountOnINDEXPulse;
config->enableModuloCountMode = false;
config->positionModulusValue = 0U;
config->positionInitialValue = 0U;
}
void ENC_DoSoftwareLoadInitialPositionValue(ENC_Type *base)
{
uint16_t tmp16 = base->CTRL & (uint16_t)(~ENC_CTRL_W1C_FLAGS);
tmp16 |= ENC_CTRL_SWIP_MASK; /* Write 1 to trigger the command for loading initial position value. */
base->CTRL = tmp16;
}
void ENC_SetSelfTestConfig(ENC_Type *base, const enc_self_test_config_t *config)
{
uint16_t tmp16 = 0U;
if (NULL == config) /* Pass "NULL" to disable the feature. */
{
base->TST = 0U;
return;
}
tmp16 = ENC_TST_TEN_MASK | ENC_TST_TCE_MASK | ENC_TST_TEST_PERIOD(config->signalPeriod) |
ENC_TST_TEST_COUNT(config->signalCount);
if (kENC_SelfTestDirectionNegative == config->signalDirection)
{
tmp16 |= ENC_TST_QDN_MASK;
}
base->TST = tmp16;
}
void ENC_EnableWatchdog(ENC_Type *base, bool enable)
{
uint16_t tmp16 = base->CTRL & (uint16_t)(~(ENC_CTRL_W1C_FLAGS | ENC_CTRL_WDE_MASK));
if (enable)
{
tmp16 |= ENC_CTRL_WDE_MASK;
}
base->CTRL = tmp16;
}
uint32_t ENC_GetStatusFlags(ENC_Type *base)
{
uint32_t ret32 = 0U;
/* ENC_CTRL. */
if (ENC_CTRL_HIRQ_MASK == (ENC_CTRL_HIRQ_MASK & base->CTRL))
{
ret32 |= kENC_HOMETransitionFlag;
}
if (ENC_CTRL_XIRQ_MASK == (ENC_CTRL_XIRQ_MASK & base->CTRL))
{
ret32 |= kENC_INDEXPulseFlag;
}
if (ENC_CTRL_DIRQ_MASK == (ENC_CTRL_DIRQ_MASK & base->CTRL))
{
ret32 |= kENC_WatchdogTimeoutFlag;
}
if (ENC_CTRL_CMPIRQ_MASK == (ENC_CTRL_CMPIRQ_MASK & base->CTRL))
{
ret32 |= kENC_PositionCompareFlag;
}
/* ENC_CTRL2. */
if (ENC_CTRL2_SABIRQ_MASK == (ENC_CTRL2_SABIRQ_MASK & base->CTRL2))
{
ret32 |= kENC_SimultBothPhaseChangeFlag;
}
if (ENC_CTRL2_ROIRQ_MASK == (ENC_CTRL2_ROIRQ_MASK & base->CTRL2))
{
ret32 |= kENC_PositionRollOverFlag;
}
if (ENC_CTRL2_RUIRQ_MASK == (ENC_CTRL2_RUIRQ_MASK & base->CTRL2))
{
ret32 |= kENC_PositionRollUnderFlag;
}
if (ENC_CTRL2_DIR_MASK == (ENC_CTRL2_DIR_MASK & base->CTRL2))
{
ret32 |= kENC_LastCountDirectionFlag;
}
return ret32;
}
void ENC_ClearStatusFlags(ENC_Type *base, uint32_t mask)
{
uint32_t tmp16 = 0U;
/* ENC_CTRL. */
if (kENC_HOMETransitionFlag == (kENC_HOMETransitionFlag & mask))
{
tmp16 |= ENC_CTRL_HIRQ_MASK;
}
if (kENC_INDEXPulseFlag == (kENC_INDEXPulseFlag & mask))
{
tmp16 |= ENC_CTRL_XIRQ_MASK;
}
if (kENC_WatchdogTimeoutFlag == (kENC_WatchdogTimeoutFlag & mask))
{
tmp16 |= ENC_CTRL_DIRQ_MASK;
}
if (kENC_PositionCompareFlag == (kENC_PositionCompareFlag & mask))
{
tmp16 |= ENC_CTRL_CMPIRQ_MASK;
}
if (0U != tmp16)
{
base->CTRL = (base->CTRL & (uint16_t)(~ENC_CTRL_W1C_FLAGS)) | tmp16;
}
/* ENC_CTRL2. */
tmp16 = 0U;
if (kENC_SimultBothPhaseChangeFlag == (kENC_SimultBothPhaseChangeFlag & mask))
{
tmp16 |= ENC_CTRL2_SABIRQ_MASK;
}
if (kENC_PositionRollOverFlag == (kENC_PositionRollOverFlag & mask))
{
tmp16 |= ENC_CTRL2_ROIRQ_MASK;
}
if (kENC_PositionRollUnderFlag == (kENC_PositionRollUnderFlag & mask))
{
tmp16 |= ENC_CTRL2_RUIRQ_MASK;
}
if (0U != tmp16)
{
base->CTRL2 = (base->CTRL2 & (uint16_t)(~ENC_CTRL2_W1C_FLAGS)) | tmp16;
}
}
void ENC_EnableInterrupts(ENC_Type *base, uint32_t mask)
{
uint32_t tmp16 = 0U;
/* ENC_CTRL. */
if (kENC_HOMETransitionInterruptEnable == (kENC_HOMETransitionInterruptEnable & mask))
{
tmp16 |= ENC_CTRL_HIE_MASK;
}
if (kENC_INDEXPulseInterruptEnable == (kENC_INDEXPulseInterruptEnable & mask))
{
tmp16 |= ENC_CTRL_XIE_MASK;
}
if (kENC_WatchdogTimeoutInterruptEnable == (kENC_WatchdogTimeoutInterruptEnable & mask))
{
tmp16 |= ENC_CTRL_DIE_MASK;
}
if (kENC_PositionCompareInerruptEnable == (kENC_PositionCompareInerruptEnable & mask))
{
tmp16 |= ENC_CTRL_CMPIE_MASK;
}
if (tmp16 != 0U)
{
base->CTRL = (base->CTRL & (uint16_t)(~ENC_CTRL_W1C_FLAGS)) | tmp16;
}
/* ENC_CTRL2. */
tmp16 = 0U;
if (kENC_SimultBothPhaseChangeInterruptEnable == (kENC_SimultBothPhaseChangeInterruptEnable & mask))
{
tmp16 |= ENC_CTRL2_SABIE_MASK;
}
if (kENC_PositionRollOverInterruptEnable == (kENC_PositionRollOverInterruptEnable & mask))
{
tmp16 |= ENC_CTRL2_ROIE_MASK;
}
if (kENC_PositionRollUnderInterruptEnable == (kENC_PositionRollUnderInterruptEnable & mask))
{
tmp16 |= ENC_CTRL2_RUIE_MASK;
}
if (tmp16 != 0U)
{
base->CTRL2 = (base->CTRL2 & (uint16_t)(~ENC_CTRL2_W1C_FLAGS)) | tmp16;
}
}
void ENC_DisableInterrupts(ENC_Type *base, uint32_t mask)
{
uint16_t tmp16 = 0U;
/* ENC_CTRL. */
if (kENC_HOMETransitionInterruptEnable == (kENC_HOMETransitionInterruptEnable & mask))
{
tmp16 |= ENC_CTRL_HIE_MASK;
}
if (kENC_INDEXPulseInterruptEnable == (kENC_INDEXPulseInterruptEnable & mask))
{
tmp16 |= ENC_CTRL_XIE_MASK;
}
if (kENC_WatchdogTimeoutInterruptEnable == (kENC_WatchdogTimeoutInterruptEnable & mask))
{
tmp16 |= ENC_CTRL_DIE_MASK;
}
if (kENC_PositionCompareInerruptEnable == (kENC_PositionCompareInerruptEnable & mask))
{
tmp16 |= ENC_CTRL_CMPIE_MASK;
}
if (0U != tmp16)
{
base->CTRL = (uint16_t)(base->CTRL & (uint16_t)(~ENC_CTRL_W1C_FLAGS)) & (uint16_t)(~tmp16);
}
/* ENC_CTRL2. */
tmp16 = 0U;
if (kENC_SimultBothPhaseChangeInterruptEnable == (kENC_SimultBothPhaseChangeInterruptEnable & mask))
{
tmp16 |= ENC_CTRL2_SABIE_MASK;
}
if (kENC_PositionRollOverInterruptEnable == (kENC_PositionRollOverInterruptEnable & mask))
{
tmp16 |= ENC_CTRL2_ROIE_MASK;
}
if (kENC_PositionRollUnderInterruptEnable == (kENC_PositionRollUnderInterruptEnable & mask))
{
tmp16 |= ENC_CTRL2_RUIE_MASK;
}
if (tmp16 != 0U)
{
base->CTRL2 = (uint16_t)(base->CTRL2 & (uint16_t)(~ENC_CTRL2_W1C_FLAGS)) & (uint16_t)(~tmp16);
}
}
uint32_t ENC_GetEnabledInterrupts(ENC_Type *base)
{
uint32_t ret32 = 0U;
/* ENC_CTRL. */
if (ENC_CTRL_HIE_MASK == (ENC_CTRL_HIE_MASK & base->CTRL))
{
ret32 |= kENC_HOMETransitionInterruptEnable;
}
if (ENC_CTRL_XIE_MASK == (ENC_CTRL_XIE_MASK & base->CTRL))
{
ret32 |= kENC_INDEXPulseInterruptEnable;
}
if (ENC_CTRL_DIE_MASK == (ENC_CTRL_DIE_MASK & base->CTRL))
{
ret32 |= kENC_WatchdogTimeoutInterruptEnable;
}
if (ENC_CTRL_CMPIE_MASK == (ENC_CTRL_CMPIE_MASK & base->CTRL))
{
ret32 |= kENC_PositionCompareInerruptEnable;
}
/* ENC_CTRL2. */
if (ENC_CTRL2_SABIE_MASK == (ENC_CTRL2_SABIE_MASK & base->CTRL2))
{
ret32 |= kENC_SimultBothPhaseChangeInterruptEnable;
}
if (ENC_CTRL2_ROIE_MASK == (ENC_CTRL2_ROIE_MASK & base->CTRL2))
{
ret32 |= kENC_PositionRollOverInterruptEnable;
}
if (ENC_CTRL2_RUIE_MASK == (ENC_CTRL2_RUIE_MASK & base->CTRL2))
{
ret32 |= kENC_PositionRollUnderInterruptEnable;
}
return ret32;
}
void ENC_SetInitialPositionValue(ENC_Type *base, uint32_t value)
{
base->UINIT = (uint16_t)(value >> 16U); /* Set upper 16 bits. */
base->LINIT = (uint16_t)(value); /* Set lower 16 bits. */
}
uint32_t ENC_GetPositionValue(ENC_Type *base)
{
uint32_t ret32;
ret32 = base->UPOS; /* Get upper 16 bits and make a snapshot. */
ret32 <<= 16U;
ret32 |= base->LPOSH; /* Get lower 16 bits from hold register. */
return ret32;
}
uint32_t ENC_GetHoldPositionValue(ENC_Type *base)
{
uint32_t ret32;
ret32 = base->UPOSH; /* Get upper 16 bits and make a snapshot. */
ret32 <<= 16U;
ret32 |= base->LPOSH; /* Get lower 16 bits from hold register. */
return ret32;
}

View File

@@ -0,0 +1,468 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#ifndef _FSL_ENC_H_
#define _FSL_ENC_H_
#include "fsl_common.h"
/*!
* @addtogroup enc
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
#define FSL_ENC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */
/*!
* @brief Interrupt enable/disable mask.
*/
enum _enc_interrupt_enable
{
kENC_HOMETransitionInterruptEnable = (1U << 0U), /*!< HOME interrupt enable. */
kENC_INDEXPulseInterruptEnable = (1U << 1U), /*!< INDEX pulse interrupt enable. */
kENC_WatchdogTimeoutInterruptEnable = (1U << 2U), /*!< Watchdog timeout interrupt enable. */
kENC_PositionCompareInerruptEnable = (1U << 3U), /*!< Position compare interrupt enable. */
kENC_SimultBothPhaseChangeInterruptEnable =
(1U << 4U), /*!< Simultaneous PHASEA and PHASEB change interrupt enable. */
kENC_PositionRollOverInterruptEnable = (1U << 5U), /*!< Roll-over interrupt enable. */
kENC_PositionRollUnderInterruptEnable = (1U << 6U), /*!< Roll-under interrupt enable. */
};
/*!
* @brief Status flag mask.
*
* These flags indicate the counter's events.
*/
enum _enc_status_flags
{
kENC_HOMETransitionFlag = (1U << 0U), /*!< HOME signal transition interrupt request. */
kENC_INDEXPulseFlag = (1U << 1U), /*!< INDEX Pulse Interrupt Request. */
kENC_WatchdogTimeoutFlag = (1U << 2U), /*!< Watchdog timeout interrupt request. */
kENC_PositionCompareFlag = (1U << 3U), /*!< Position compare interrupt request. */
kENC_SimultBothPhaseChangeFlag = (1U << 4U), /*!< Simultaneous PHASEA and PHASEB change interrupt request. */
kENC_PositionRollOverFlag = (1U << 5U), /*!< Roll-over interrupt request. */
kENC_PositionRollUnderFlag = (1U << 6U), /*!< Roll-under interrupt request. */
kENC_LastCountDirectionFlag = (1U << 7U), /*!< Last count was in the up direction, or the down direction. */
};
/*!
* @brief Signal status flag mask.
*
* These flags indicate the counter's signal.
*/
enum _enc_signal_status_flags
{
kENC_RawHOMEStatusFlag = ENC_IMR_HOME_MASK, /*!< Raw HOME input. */
kENC_RawINDEXStatusFlag = ENC_IMR_INDEX_MASK, /*!< Raw INDEX input. */
kENC_RawPHBStatusFlag = ENC_IMR_PHB_MASK, /*!< Raw PHASEB input. */
kENC_RawPHAEXStatusFlag = ENC_IMR_PHA_MASK, /*!< Raw PHASEA input. */
kENC_FilteredHOMEStatusFlag = ENC_IMR_FHOM_MASK, /*!< The filtered version of HOME input. */
kENC_FilteredINDEXStatusFlag = ENC_IMR_FIND_MASK, /*!< The filtered version of INDEX input. */
kENC_FilteredPHBStatusFlag = ENC_IMR_FPHB_MASK, /*!< The filtered version of PHASEB input. */
kENC_FilteredPHAStatusFlag = ENC_IMR_FPHA_MASK, /*!< The filtered version of PHASEA input. */
};
/*!
* @brief Define HOME signal's trigger mode.
*
* The ENC would count the trigger from HOME signal line.
*/
typedef enum _enc_home_trigger_mode
{
kENC_HOMETriggerDisabled = 0U, /*!< HOME signal's trigger is disabled. */
kENC_HOMETriggerOnRisingEdge, /*!< Use positive going edge-to-trigger initialization of position counters. */
kENC_HOMETriggerOnFallingEdge, /*!< Use negative going edge-to-trigger initialization of position counters. */
} enc_home_trigger_mode_t;
/*!
* @brief Define INDEX signal's trigger mode.
*
* The ENC would count the trigger from INDEX signal line.
*/
typedef enum _enc_index_trigger_mode
{
kENC_INDEXTriggerDisabled = 0U, /*!< INDEX signal's trigger is disabled. */
kENC_INDEXTriggerOnRisingEdge, /*!< Use positive going edge-to-trigger initialization of position counters. */
kENC_INDEXTriggerOnFallingEdge, /*!< Use negative going edge-to-trigger initialization of position counters. */
} enc_index_trigger_mode_t;
/*!
* @brief Define type for decoder work mode.
*
* The normal work mode uses the standard quadrature decoder with PHASEA and PHASEB. When in signal phase count mode,
* a positive transition of the PHASEA input generates a count signal while the PHASEB input and the reverse direction
* control the counter direction. If the reverse direction is not enabled, PHASEB = 0 means counting up and PHASEB = 1
* means counting down. Otherwise, the direction is reversed.
*/
typedef enum _enc_decoder_work_mode
{
kENC_DecoderWorkAsNormalMode = 0U, /*!< Use standard quadrature decoder with PHASEA and PHASEB. */
kENC_DecoderWorkAsSignalPhaseCountMode, /*!< PHASEA input generates a count signal while PHASEB input control the
direction. */
} enc_decoder_work_mode_t;
/*!
* @brief Define type for the condition of POSMATCH pulses.
*/
typedef enum _enc_position_match_mode
{
kENC_POSMATCHOnPositionCounterEqualToComapreValue = 0U, /*!< POSMATCH pulses when a match occurs between the
position counters (POS) and the compare value (COMP). */
kENC_POSMATCHOnReadingAnyPositionCounter, /*!< POSMATCH pulses when any position counter register is read. */
} enc_position_match_mode_t;
/*!
* @brief Define type for determining how the revolution counter (REV) is incremented/decremented.
*/
typedef enum _enc_revolution_count_condition
{
kENC_RevolutionCountOnINDEXPulse = 0U, /*!< Use INDEX pulse to increment/decrement revolution counter. */
kENC_RevolutionCountOnRollOverModulus, /*!< Use modulus counting roll-over/under to increment/decrement revolution
counter. */
} enc_revolution_count_condition_t;
/*!
* @brief Define type for direction of self test generated signal.
*/
typedef enum _enc_self_test_direction
{
kENC_SelfTestDirectionPositive = 0U, /*!< Self test generates the signal in positive direction. */
kENC_SelfTestDirectionNegative, /*!< Self test generates the signal in negative direction. */
} enc_self_test_direction_t;
/*!
* @brief Define user configuration structure for ENC module.
*/
typedef struct _enc_config
{
/* Basic counter. */
bool enableReverseDirection; /*!< Enable reverse direction counting. */
enc_decoder_work_mode_t decoderWorkMode; /*!< Enable signal phase count mode. */
/* Signal detection. */
enc_home_trigger_mode_t HOMETriggerMode; /*!< Enable HOME to initialize position counters. */
enc_index_trigger_mode_t INDEXTriggerMode; /*!< Enable INDEX to initialize position counters. */
bool enableTRIGGERClearPositionCounter; /*!< Clear POSD, REV, UPOS and LPOS on rising edge of TRIGGER, or not. */
bool enableTRIGGERClearHoldPositionCounter; /*!< Enable update of hold registers on rising edge of TRIGGER, or not.
*/
/* Watchdog. */
bool enableWatchdog; /*!< Enable the watchdog to detect if the target is moving or not. */
uint16_t watchdogTimeoutValue; /*!< Watchdog timeout count value. It stores the timeout count for the quadrature
decoder module watchdog timer. This field is only available when
"enableWatchdog" = true. The available value is a 16-bit unsigned number.*/
/* Filter for PHASEA, PHASEB, INDEX and HOME. */
uint16_t filterCount; /*!< Input Filter Sample Count. This value should be chosen to reduce the probability of
noisy samples causing an incorrect transition to be recognized. The value represent the
number of consecutive samples that must agree prior to the input filter accepting an
input transition. A value of 0x0 represents 3 samples. A value of 0x7 represents 10
samples. The Available range is 0 - 7.*/
uint16_t filterSamplePeriod; /*!< Input Filter Sample Period. This value should be set such that the sampling period
is larger than the period of the expected noise. This value represents the
sampling period (in IPBus clock cycles) of the decoder input signals.
The available range is 0 - 255. */
/* Position compare. */
enc_position_match_mode_t positionMatchMode; /*!< The condition of POSMATCH pulses. */
uint32_t positionCompareValue; /*!< Position compare value. The available value is a 32-bit number.*/
/* Modulus counting. */
enc_revolution_count_condition_t revolutionCountCondition; /*!< Revolution Counter Modulus Enable. */
bool enableModuloCountMode; /*!< Enable Modulo Counting. */
uint32_t positionModulusValue; /*!< Position modulus value. This value would be available only when
"enableModuloCountMode" = true. The available value is a 32-bit number. */
uint32_t positionInitialValue; /*!< Position initial value. The available value is a 32-bit number. */
} enc_config_t;
/*!
* @brief Define configuration structure for self test module.
*
* The self test module provides a quadrature test signal to the inputs of the quadrature decoder module.
* This is a factory test feature. It is also useful to customers' software development and testing.
*/
typedef struct _enc_self_test_config
{
enc_self_test_direction_t signalDirection; /*!< Direction of self test generated signal. */
uint16_t signalCount; /*!< Hold the number of quadrature advances to generate. The available range is 0 - 255.*/
uint16_t signalPeriod; /*!< Hold the period of quadrature phase in IPBus clock cycles.
The available range is 0 - 31. */
} enc_self_test_config_t;
#if defined(__cplusplus)
extern "C" {
#endif
/*******************************************************************************
* API
******************************************************************************/
/*!
* @name Initialization and De-initialization
* @{
*/
/*!
* @brief Initialization for the ENC module.
*
* This function is to make the initialization for the ENC module. It should be called firstly before any operation to
* the ENC with the operations like:
* - Enable the clock for ENC module.
* - Configure the ENC's working attributes.
*
* @param base ENC peripheral base address.
* @param config Pointer to configuration structure. See to "enc_config_t".
*/
void ENC_Init(ENC_Type *base, const enc_config_t *config);
/*!
* @brief De-initialization for the ENC module.
*
* This function is to make the de-initialization for the ENC module. It could be called when ENC is no longer used with
* the operations like:
* - Disable the clock for ENC module.
*
* @param base ENC peripheral base address.
*/
void ENC_Deinit(ENC_Type *base);
/*!
* @brief Get an available pre-defined settings for ENC's configuration.
*
* This function initializes the ENC configuration structure with an available settings, the default value are:
* @code
* config->enableReverseDirection = false;
* config->decoderWorkMode = kENC_DecoderWorkAsNormalMode;
* config->HOMETriggerMode = kENC_HOMETriggerDisabled;
* config->INDEXTriggerMode = kENC_INDEXTriggerDisabled;
* config->enableTRIGGERClearPositionCounter = false;
* config->enableTRIGGERClearHoldPositionCounter = false;
* config->enableWatchdog = false;
* config->watchdogTimeoutValue = 0U;
* config->filterCount = 0U;
* config->filterSamplePeriod = 0U;
* config->positionMatchMode = kENC_POSMATCHOnPositionCounterEqualToComapreValue;
* config->positionCompareValue = 0xFFFFFFFFU;
* config->revolutionCountCondition = kENC_RevolutionCountOnINDEXPulse;
* config->enableModuloCountMode = false;
* config->positionModulusValue = 0U;
* config->positionInitialValue = 0U;
* @endcode
* @param config Pointer to a variable of configuration structure. See to "enc_config_t".
*/
void ENC_GetDefaultConfig(enc_config_t *config);
/*!
* @brief Load the initial position value to position counter.
*
* This function is to transfer the initial position value (UINIT and LINIT) contents to position counter (UPOS and
* LPOS), so that to provide the consistent operation the position counter registers.
*
* @param base ENC peripheral base address.
*/
void ENC_DoSoftwareLoadInitialPositionValue(ENC_Type *base);
/*!
* @brief Enable and configure the self test function.
*
* This function is to enable and configuration the self test function. It controls and sets the frequency of a
* quadrature signal generator. It provides a quadrature test signal to the inputs of the quadrature decoder module.
* It is a factory test feature; however, it may be useful to customers' software development and testing.
*
* @param base ENC peripheral base address.
* @param config Pointer to configuration structure. See to "enc_self_test_config_t". Pass "NULL" to disable.
*/
void ENC_SetSelfTestConfig(ENC_Type *base, const enc_self_test_config_t *config);
/* @} */
/*!
* @name Status
* @{
*/
/*!
* @brief Get the status flags.
*
* @param base ENC peripheral base address.
*
* @return Mask value of status flags. For available mask, see to "_enc_status_flags".
*/
uint32_t ENC_GetStatusFlags(ENC_Type *base);
/*!
* @brief Clear the status flags.
*
* @param base ENC peripheral base address.
* @param mask Mask value of status flags to be cleared. For available mask, see to "_enc_status_flags".
*/
void ENC_ClearStatusFlags(ENC_Type *base, uint32_t mask);
/*!
* @brief Get the signals' real-time status.
*
* @param base ENC peripheral base address.
*
* @return Mask value of signals' real-time status. For available mask, see to "_enc_signal_status_flags"
*/
static inline uint16_t ENC_GetSignalStatusFlags(ENC_Type *base)
{
return base->IMR;
}
/* @} */
/*!
* @name Interrupts
* @{
*/
/*!
* @brief Enable the interrupts.
*
* @param base ENC peripheral base address.
* @param mask Mask value of interrupts to be enabled. For available mask, see to "_enc_interrupt_enable".
*/
void ENC_EnableInterrupts(ENC_Type *base, uint32_t mask);
/*!
* @brief Disable the interrupts.
*
* @param base ENC peripheral base address.
* @param mask Mask value of interrupts to be disabled. For available mask, see to "_enc_interrupt_enable".
*/
void ENC_DisableInterrupts(ENC_Type *base, uint32_t mask);
/*!
* @brief Get the enabled interrupts' flags.
*
* @param base ENC peripheral base address.
*
* @return Mask value of enabled interrupts.
*/
uint32_t ENC_GetEnabledInterrupts(ENC_Type *base);
/* @} */
/*!
* @name Value Operation
* @{
*/
/*!
* @brief Get the current position counter's value.
*
* @param base ENC peripheral base address.
*
* @return Current position counter's value.
*/
uint32_t ENC_GetPositionValue(ENC_Type *base);
/*!
* @brief Get the hold position counter's value.
*
* When any of the counter registers is read, the contents of each counter register is written to the corresponding hold
* register. Taking a snapshot of the counters' values provides a consistent view of a system position and a velocity to
* be attained.
*
* @param base ENC peripheral base address.
*
* @return Hold position counter's value.
*/
uint32_t ENC_GetHoldPositionValue(ENC_Type *base);
/*!
* @brief Get the position difference counter's value.
*
* @param base ENC peripheral base address.
*
* @return The position difference counter's value.
*/
static inline uint16_t ENC_GetPositionDifferenceValue(ENC_Type *base)
{
return base->POSD;
}
/*!
* @brief Get the hold position difference counter's value.
*
* When any of the counter registers is read, the contents of each counter register is written to the corresponding hold
* register. Taking a snapshot of the counters' values provides a consistent view of a system position and a velocity to
* be attained.
*
* @param base ENC peripheral base address.
*
* @return Hold position difference counter's value.
*/
static inline uint16_t ENC_GetHoldPositionDifferenceValue(ENC_Type *base)
{
return base->POSDH;
}
/*!
* @brief Get the position revolution counter's value.
*
* @param base ENC peripheral base address.
*
* @return The position revolution counter's value.
*/
static inline uint16_t ENC_GetRevolutionValue(ENC_Type *base)
{
return base->REV;
}
/*!
* @brief Get the hold position revolution counter's value.
*
* When any of the counter registers is read, the contents of each counter register is written to the corresponding hold
* register. Taking a snapshot of the counters' values provides a consistent view of a system position and a velocity to
* be attained.
*
* @param base ENC peripheral base address.
*
* @return Hold position revolution counter's value.
*/
static inline uint16_t ENC_GetHoldRevolutionValue(ENC_Type *base)
{
return base->REVH;
}
/* @} */
#if defined(__cplusplus)
}
#endif
/*
* @}
*/
#endif /* _FSL_ENC_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,106 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#include "fsl_ewm.h"
/*******************************************************************************
* Code
******************************************************************************/
void EWM_Init(EWM_Type *base, const ewm_config_t *config)
{
assert(config);
uint32_t value = 0U;
#if !((defined(FSL_FEATURE_SOC_PCC_COUNT) && FSL_FEATURE_SOC_PCC_COUNT) && \
(defined(FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE) && FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE))
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_EnableClock(kCLOCK_Ewm0);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#endif
value = EWM_CTRL_EWMEN(config->enableEwm) | EWM_CTRL_ASSIN(config->setInputAssertLogic) |
EWM_CTRL_INEN(config->enableEwmInput) | EWM_CTRL_INTEN(config->enableInterrupt);
#if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER
base->CLKPRESCALER = config->prescaler;
#endif /* FSL_FEATURE_EWM_HAS_PRESCALER */
#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT
base->CLKCTRL = config->clockSource;
#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT*/
base->CMPL = config->compareLowValue;
base->CMPH = config->compareHighValue;
base->CTRL = value;
}
void EWM_Deinit(EWM_Type *base)
{
EWM_DisableInterrupts(base, kEWM_InterruptEnable);
#if !((defined(FSL_FEATURE_SOC_PCC_COUNT) && FSL_FEATURE_SOC_PCC_COUNT) && \
(defined(FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE) && FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE))
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_DisableClock(kCLOCK_Ewm0);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#endif /* FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE */
}
void EWM_GetDefaultConfig(ewm_config_t *config)
{
assert(config);
config->enableEwm = true;
config->enableEwmInput = false;
config->setInputAssertLogic = false;
config->enableInterrupt = false;
#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT
config->clockSource = kEWM_LpoClockSource0;
#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT*/
#if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER
config->prescaler = 0U;
#endif /* FSL_FEATURE_EWM_HAS_PRESCALER */
config->compareLowValue = 0U;
config->compareHighValue = 0xFEU;
}
void EWM_Refresh(EWM_Type *base)
{
uint32_t primaskValue = 0U;
/* Disable the global interrupt to protect refresh sequence */
primaskValue = DisableGlobalIRQ();
base->SERV = (uint8_t)0xB4U;
base->SERV = (uint8_t)0x2CU;
EnableGlobalIRQ(primaskValue);
}

View File

@@ -0,0 +1,245 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#ifndef _FSL_EWM_H_
#define _FSL_EWM_H_
#include "fsl_common.h"
/*!
* @addtogroup ewm
* @{
*/
/*******************************************************************************
* Definitions
*******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief EWM driver version 2.0.1. */
#define FSL_EWM_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
/*@}*/
/*! @brief Describes EWM clock source. */
#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT
typedef enum _ewm_lpo_clock_source
{
kEWM_LpoClockSource0 = 0U, /*!< EWM clock sourced from lpo_clk[0]*/
kEWM_LpoClockSource1 = 1U, /*!< EWM clock sourced from lpo_clk[1]*/
kEWM_LpoClockSource2 = 2U, /*!< EWM clock sourced from lpo_clk[2]*/
kEWM_LpoClockSource3 = 3U, /*!< EWM clock sourced from lpo_clk[3]*/
} ewm_lpo_clock_source_t;
#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT */
/*!
* @brief Data structure for EWM configuration.
*
* This structure is used to configure the EWM.
*/
typedef struct _ewm_config
{
bool enableEwm; /*!< Enable EWM module */
bool enableEwmInput; /*!< Enable EWM_in input */
bool setInputAssertLogic; /*!< EWM_in signal assertion state */
bool enableInterrupt; /*!< Enable EWM interrupt */
#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT
ewm_lpo_clock_source_t clockSource; /*!< Clock source select */
#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT */
#if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER
uint8_t prescaler; /*!< Clock prescaler value */
#endif /* FSL_FEATURE_EWM_HAS_PRESCALER */
uint8_t compareLowValue; /*!< Compare low-register value */
uint8_t compareHighValue; /*!< Compare high-register value */
} ewm_config_t;
/*!
* @brief EWM interrupt configuration structure with default settings all disabled.
*
* This structure contains the settings for all of EWM interrupt configurations.
*/
enum _ewm_interrupt_enable_t
{
kEWM_InterruptEnable = EWM_CTRL_INTEN_MASK, /*!< Enable the EWM to generate an interrupt*/
};
/*!
* @brief EWM status flags.
*
* This structure contains the constants for the EWM status flags for use in the EWM functions.
*/
enum _ewm_status_flags_t
{
kEWM_RunningFlag = EWM_CTRL_EWMEN_MASK, /*!< Running flag, set when EWM is enabled*/
};
/*******************************************************************************
* API
*******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/*!
* @name EWM initialization and de-initialization
* @{
*/
/*!
* @brief Initializes the EWM peripheral.
*
* This function is used to initialize the EWM. After calling, the EWM
* runs immediately according to the configuration.
* Note that, except for the interrupt enable control bit, other control bits and registers are write once after a
* CPU reset. Modifying them more than once generates a bus transfer error.
*
* This is an example.
* @code
* ewm_config_t config;
* EWM_GetDefaultConfig(&config);
* config.compareHighValue = 0xAAU;
* EWM_Init(ewm_base,&config);
* @endcode
*
* @param base EWM peripheral base address
* @param config The configuration of the EWM
*/
void EWM_Init(EWM_Type *base, const ewm_config_t *config);
/*!
* @brief Deinitializes the EWM peripheral.
*
* This function is used to shut down the EWM.
*
* @param base EWM peripheral base address
*/
void EWM_Deinit(EWM_Type *base);
/*!
* @brief Initializes the EWM configuration structure.
*
* This function initializes the EWM configuration structure to default values. The default
* values are as follows.
* @code
* ewmConfig->enableEwm = true;
* ewmConfig->enableEwmInput = false;
* ewmConfig->setInputAssertLogic = false;
* ewmConfig->enableInterrupt = false;
* ewmConfig->ewm_lpo_clock_source_t = kEWM_LpoClockSource0;
* ewmConfig->prescaler = 0;
* ewmConfig->compareLowValue = 0;
* ewmConfig->compareHighValue = 0xFEU;
* @endcode
*
* @param config Pointer to the EWM configuration structure.
* @see ewm_config_t
*/
void EWM_GetDefaultConfig(ewm_config_t *config);
/* @} */
/*!
* @name EWM functional Operation
* @{
*/
/*!
* @brief Enables the EWM interrupt.
*
* This function enables the EWM interrupt.
*
* @param base EWM peripheral base address
* @param mask The interrupts to enable
* The parameter can be combination of the following source if defined
* @arg kEWM_InterruptEnable
*/
static inline void EWM_EnableInterrupts(EWM_Type *base, uint32_t mask)
{
base->CTRL |= mask;
}
/*!
* @brief Disables the EWM interrupt.
*
* This function enables the EWM interrupt.
*
* @param base EWM peripheral base address
* @param mask The interrupts to disable
* The parameter can be combination of the following source if defined
* @arg kEWM_InterruptEnable
*/
static inline void EWM_DisableInterrupts(EWM_Type *base, uint32_t mask)
{
base->CTRL &= ~mask;
}
/*!
* @brief Gets all status flags.
*
* This function gets all status flags.
*
* This is an example for getting the running flag.
* @code
* uint32_t status;
* status = EWM_GetStatusFlags(ewm_base) & kEWM_RunningFlag;
* @endcode
* @param base EWM peripheral base address
* @return State of the status flag: asserted (true) or not-asserted (false).@see _ewm_status_flags_t
* - True: a related status flag has been set.
* - False: a related status flag is not set.
*/
static inline uint32_t EWM_GetStatusFlags(EWM_Type *base)
{
return (base->CTRL & EWM_CTRL_EWMEN_MASK);
}
/*!
* @brief Services the EWM.
*
* This function resets the EWM counter to zero.
*
* @param base EWM peripheral base address
*/
void EWM_Refresh(EWM_Type *base);
/*@}*/
#if defined(__cplusplus)
}
#endif /* __cplusplus */
/*! @}*/
#endif /* _FSL_EWM_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,315 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#include "fsl_flexio.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*< @brief user configurable flexio handle count. */
#define FLEXIO_HANDLE_COUNT 2
/*******************************************************************************
* Variables
******************************************************************************/
/*< @brief pointer to array of FLEXIO handle. */
static void *s_flexioHandle[FLEXIO_HANDLE_COUNT];
/*< @brief pointer to array of FLEXIO IP types. */
static void *s_flexioType[FLEXIO_HANDLE_COUNT];
/*< @brief pointer to array of FLEXIO Isr. */
static flexio_isr_t s_flexioIsr[FLEXIO_HANDLE_COUNT];
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to flexio clocks for each instance. */
const clock_ip_name_t s_flexioClocks[] = FLEXIO_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*! @brief Pointers to flexio bases for each instance. */
FLEXIO_Type *const s_flexioBases[] = FLEXIO_BASE_PTRS;
/*******************************************************************************
* Codes
******************************************************************************/
uint32_t FLEXIO_GetInstance(FLEXIO_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_flexioBases); instance++)
{
if (s_flexioBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_flexioBases));
return instance;
}
void FLEXIO_Init(FLEXIO_Type *base, const flexio_config_t *userConfig)
{
uint32_t ctrlReg = 0;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_EnableClock(s_flexioClocks[FLEXIO_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
FLEXIO_Reset(base);
ctrlReg = base->CTRL;
ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
ctrlReg |= (FLEXIO_CTRL_DBGE(userConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(userConfig->enableFastAccess) |
FLEXIO_CTRL_FLEXEN(userConfig->enableFlexio));
if (!userConfig->enableInDoze)
{
ctrlReg |= FLEXIO_CTRL_DOZEN_MASK;
}
base->CTRL = ctrlReg;
}
void FLEXIO_Deinit(FLEXIO_Type *base)
{
FLEXIO_Enable(base, false);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
CLOCK_DisableClock(s_flexioClocks[FLEXIO_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
void FLEXIO_GetDefaultConfig(flexio_config_t *userConfig)
{
assert(userConfig);
userConfig->enableFlexio = true;
userConfig->enableInDoze = false;
userConfig->enableInDebug = true;
userConfig->enableFastAccess = false;
}
void FLEXIO_Reset(FLEXIO_Type *base)
{
/*do software reset, software reset operation affect all other FLEXIO registers except CTRL*/
base->CTRL |= FLEXIO_CTRL_SWRST_MASK;
base->CTRL = 0;
}
uint32_t FLEXIO_GetShifterBufferAddress(FLEXIO_Type *base, flexio_shifter_buffer_type_t type, uint8_t index)
{
assert(index < FLEXIO_SHIFTBUF_COUNT);
uint32_t address = 0;
switch (type)
{
case kFLEXIO_ShifterBuffer:
address = (uint32_t) & (base->SHIFTBUF[index]);
break;
case kFLEXIO_ShifterBufferBitSwapped:
address = (uint32_t) & (base->SHIFTBUFBIS[index]);
break;
case kFLEXIO_ShifterBufferByteSwapped:
address = (uint32_t) & (base->SHIFTBUFBYS[index]);
break;
case kFLEXIO_ShifterBufferBitByteSwapped:
address = (uint32_t) & (base->SHIFTBUFBBS[index]);
break;
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP
case kFLEXIO_ShifterBufferNibbleByteSwapped:
address = (uint32_t) & (base->SHIFTBUFNBS[index]);
break;
#endif
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP
case kFLEXIO_ShifterBufferHalfWordSwapped:
address = (uint32_t) & (base->SHIFTBUFHWS[index]);
break;
#endif
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP
case kFLEXIO_ShifterBufferNibbleSwapped:
address = (uint32_t) & (base->SHIFTBUFNIS[index]);
break;
#endif
default:
break;
}
return address;
}
void FLEXIO_SetShifterConfig(FLEXIO_Type *base, uint8_t index, const flexio_shifter_config_t *shifterConfig)
{
base->SHIFTCFG[index] = FLEXIO_SHIFTCFG_INSRC(shifterConfig->inputSource)
#if defined(FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH) && FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH
| FLEXIO_SHIFTCFG_PWIDTH(shifterConfig->parallelWidth)
#endif /* FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH */
| FLEXIO_SHIFTCFG_SSTOP(shifterConfig->shifterStop) |
FLEXIO_SHIFTCFG_SSTART(shifterConfig->shifterStart);
base->SHIFTCTL[index] =
FLEXIO_SHIFTCTL_TIMSEL(shifterConfig->timerSelect) | FLEXIO_SHIFTCTL_TIMPOL(shifterConfig->timerPolarity) |
FLEXIO_SHIFTCTL_PINCFG(shifterConfig->pinConfig) | FLEXIO_SHIFTCTL_PINSEL(shifterConfig->pinSelect) |
FLEXIO_SHIFTCTL_PINPOL(shifterConfig->pinPolarity) | FLEXIO_SHIFTCTL_SMOD(shifterConfig->shifterMode);
}
void FLEXIO_SetTimerConfig(FLEXIO_Type *base, uint8_t index, const flexio_timer_config_t *timerConfig)
{
base->TIMCFG[index] =
FLEXIO_TIMCFG_TIMOUT(timerConfig->timerOutput) | FLEXIO_TIMCFG_TIMDEC(timerConfig->timerDecrement) |
FLEXIO_TIMCFG_TIMRST(timerConfig->timerReset) | FLEXIO_TIMCFG_TIMDIS(timerConfig->timerDisable) |
FLEXIO_TIMCFG_TIMENA(timerConfig->timerEnable) | FLEXIO_TIMCFG_TSTOP(timerConfig->timerStop) |
FLEXIO_TIMCFG_TSTART(timerConfig->timerStart);
base->TIMCMP[index] = FLEXIO_TIMCMP_CMP(timerConfig->timerCompare);
base->TIMCTL[index] = FLEXIO_TIMCTL_TRGSEL(timerConfig->triggerSelect) |
FLEXIO_TIMCTL_TRGPOL(timerConfig->triggerPolarity) |
FLEXIO_TIMCTL_TRGSRC(timerConfig->triggerSource) |
FLEXIO_TIMCTL_PINCFG(timerConfig->pinConfig) | FLEXIO_TIMCTL_PINSEL(timerConfig->pinSelect) |
FLEXIO_TIMCTL_PINPOL(timerConfig->pinPolarity) | FLEXIO_TIMCTL_TIMOD(timerConfig->timerMode);
}
status_t FLEXIO_RegisterHandleIRQ(void *base, void *handle, flexio_isr_t isr)
{
assert(base);
assert(handle);
assert(isr);
uint8_t index = 0;
/* Find the an empty handle pointer to store the handle. */
for (index = 0; index < FLEXIO_HANDLE_COUNT; index++)
{
if (s_flexioHandle[index] == NULL)
{
/* Register FLEXIO simulated driver base, handle and isr. */
s_flexioType[index] = base;
s_flexioHandle[index] = handle;
s_flexioIsr[index] = isr;
break;
}
}
if (index == FLEXIO_HANDLE_COUNT)
{
return kStatus_OutOfRange;
}
else
{
return kStatus_Success;
}
}
status_t FLEXIO_UnregisterHandleIRQ(void *base)
{
assert(base);
uint8_t index = 0;
/* Find the index from base address mappings. */
for (index = 0; index < FLEXIO_HANDLE_COUNT; index++)
{
if (s_flexioType[index] == base)
{
/* Unregister FLEXIO simulated driver handle and isr. */
s_flexioType[index] = NULL;
s_flexioHandle[index] = NULL;
s_flexioIsr[index] = NULL;
break;
}
}
if (index == FLEXIO_HANDLE_COUNT)
{
return kStatus_OutOfRange;
}
else
{
return kStatus_Success;
}
}
void FLEXIO_CommonIRQHandler(void)
{
uint8_t index;
for (index = 0; index < FLEXIO_HANDLE_COUNT; index++)
{
if (s_flexioHandle[index])
{
s_flexioIsr[index](s_flexioType[index], s_flexioHandle[index]);
}
}
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}
void FLEXIO_DriverIRQHandler(void)
{
FLEXIO_CommonIRQHandler();
}
void FLEXIO0_DriverIRQHandler(void)
{
FLEXIO_CommonIRQHandler();
}
void FLEXIO1_DriverIRQHandler(void)
{
FLEXIO_CommonIRQHandler();
}
void UART2_FLEXIO_DriverIRQHandler(void)
{
FLEXIO_CommonIRQHandler();
}
void FLEXIO2_DriverIRQHandler(void)
{
FLEXIO_CommonIRQHandler();
}

View File

@@ -0,0 +1,709 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#ifndef _FSL_FLEXIO_H_
#define _FSL_FLEXIO_H_
#include "fsl_common.h"
/*!
* @addtogroup flexio_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief FlexIO driver version 2.0.1. */
#define FSL_FLEXIO_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
/*@}*/
/*! @brief Calculate FlexIO timer trigger.*/
#define FLEXIO_TIMER_TRIGGER_SEL_PININPUT(x) ((uint32_t)(x) << 1U)
#define FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(x) (((uint32_t)(x) << 2U) | 0x1U)
#define FLEXIO_TIMER_TRIGGER_SEL_TIMn(x) (((uint32_t)(x) << 2U) | 0x3U)
/*! @brief Define time of timer trigger polarity.*/
typedef enum _flexio_timer_trigger_polarity
{
kFLEXIO_TimerTriggerPolarityActiveHigh = 0x0U, /*!< Active high. */
kFLEXIO_TimerTriggerPolarityActiveLow = 0x1U, /*!< Active low. */
} flexio_timer_trigger_polarity_t;
/*! @brief Define type of timer trigger source.*/
typedef enum _flexio_timer_trigger_source
{
kFLEXIO_TimerTriggerSourceExternal = 0x0U, /*!< External trigger selected. */
kFLEXIO_TimerTriggerSourceInternal = 0x1U, /*!< Internal trigger selected. */
} flexio_timer_trigger_source_t;
/*! @brief Define type of timer/shifter pin configuration.*/
typedef enum _flexio_pin_config
{
kFLEXIO_PinConfigOutputDisabled = 0x0U, /*!< Pin output disabled. */
kFLEXIO_PinConfigOpenDrainOrBidirection = 0x1U, /*!< Pin open drain or bidirectional output enable. */
kFLEXIO_PinConfigBidirectionOutputData = 0x2U, /*!< Pin bidirectional output data. */
kFLEXIO_PinConfigOutput = 0x3U, /*!< Pin output. */
} flexio_pin_config_t;
/*! @brief Definition of pin polarity.*/
typedef enum _flexio_pin_polarity
{
kFLEXIO_PinActiveHigh = 0x0U, /*!< Active high. */
kFLEXIO_PinActiveLow = 0x1U, /*!< Active low. */
} flexio_pin_polarity_t;
/*! @brief Define type of timer work mode.*/
typedef enum _flexio_timer_mode
{
kFLEXIO_TimerModeDisabled = 0x0U, /*!< Timer Disabled. */
kFLEXIO_TimerModeDual8BitBaudBit = 0x1U, /*!< Dual 8-bit counters baud/bit mode. */
kFLEXIO_TimerModeDual8BitPWM = 0x2U, /*!< Dual 8-bit counters PWM mode. */
kFLEXIO_TimerModeSingle16Bit = 0x3U, /*!< Single 16-bit counter mode. */
} flexio_timer_mode_t;
/*! @brief Define type of timer initial output or timer reset condition.*/
typedef enum _flexio_timer_output
{
kFLEXIO_TimerOutputOneNotAffectedByReset = 0x0U, /*!< Logic one when enabled and is not affected by timer
reset. */
kFLEXIO_TimerOutputZeroNotAffectedByReset = 0x1U, /*!< Logic zero when enabled and is not affected by timer
reset. */
kFLEXIO_TimerOutputOneAffectedByReset = 0x2U, /*!< Logic one when enabled and on timer reset. */
kFLEXIO_TimerOutputZeroAffectedByReset = 0x3U, /*!< Logic zero when enabled and on timer reset. */
} flexio_timer_output_t;
/*! @brief Define type of timer decrement.*/
typedef enum _flexio_timer_decrement_source
{
kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput = 0x0U, /*!< Decrement counter on FlexIO clock, Shift clock
equals Timer output. */
kFLEXIO_TimerDecSrcOnTriggerInputShiftTimerOutput = 0x1U, /*!< Decrement counter on Trigger input (both edges),
Shift clock equals Timer output. */
kFLEXIO_TimerDecSrcOnPinInputShiftPinInput = 0x2U, /*!< Decrement counter on Pin input (both edges),
Shift clock equals Pin input. */
kFLEXIO_TimerDecSrcOnTriggerInputShiftTriggerInput = 0x3U, /*!< Decrement counter on Trigger input (both edges),
Shift clock equals Trigger input. */
} flexio_timer_decrement_source_t;
/*! @brief Define type of timer reset condition.*/
typedef enum _flexio_timer_reset_condition
{
kFLEXIO_TimerResetNever = 0x0U, /*!< Timer never reset. */
kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput = 0x2U, /*!< Timer reset on Timer Pin equal to Timer Output. */
kFLEXIO_TimerResetOnTimerTriggerEqualToTimerOutput = 0x3U, /*!< Timer reset on Timer Trigger equal to
Timer Output. */
kFLEXIO_TimerResetOnTimerPinRisingEdge = 0x4U, /*!< Timer reset on Timer Pin rising edge. */
kFLEXIO_TimerResetOnTimerTriggerRisingEdge = 0x6U, /*!< Timer reset on Trigger rising edge. */
kFLEXIO_TimerResetOnTimerTriggerBothEdge = 0x7U, /*!< Timer reset on Trigger rising or falling edge. */
} flexio_timer_reset_condition_t;
/*! @brief Define type of timer disable condition.*/
typedef enum _flexio_timer_disable_condition
{
kFLEXIO_TimerDisableNever = 0x0U, /*!< Timer never disabled. */
kFLEXIO_TimerDisableOnPreTimerDisable = 0x1U, /*!< Timer disabled on Timer N-1 disable. */
kFLEXIO_TimerDisableOnTimerCompare = 0x2U, /*!< Timer disabled on Timer compare. */
kFLEXIO_TimerDisableOnTimerCompareTriggerLow = 0x3U, /*!< Timer disabled on Timer compare and Trigger Low. */
kFLEXIO_TimerDisableOnPinBothEdge = 0x4U, /*!< Timer disabled on Pin rising or falling edge. */
kFLEXIO_TimerDisableOnPinBothEdgeTriggerHigh = 0x5U, /*!< Timer disabled on Pin rising or falling edge provided
Trigger is high. */
kFLEXIO_TimerDisableOnTriggerFallingEdge = 0x6U, /*!< Timer disabled on Trigger falling edge. */
} flexio_timer_disable_condition_t;
/*! @brief Define type of timer enable condition.*/
typedef enum _flexio_timer_enable_condition
{
kFLEXIO_TimerEnabledAlways = 0x0U, /*!< Timer always enabled. */
kFLEXIO_TimerEnableOnPrevTimerEnable = 0x1U, /*!< Timer enabled on Timer N-1 enable. */
kFLEXIO_TimerEnableOnTriggerHigh = 0x2U, /*!< Timer enabled on Trigger high. */
kFLEXIO_TimerEnableOnTriggerHighPinHigh = 0x3U, /*!< Timer enabled on Trigger high and Pin high. */
kFLEXIO_TimerEnableOnPinRisingEdge = 0x4U, /*!< Timer enabled on Pin rising edge. */
kFLEXIO_TimerEnableOnPinRisingEdgeTriggerHigh = 0x5U, /*!< Timer enabled on Pin rising edge and Trigger high. */
kFLEXIO_TimerEnableOnTriggerRisingEdge = 0x6U, /*!< Timer enabled on Trigger rising edge. */
kFLEXIO_TimerEnableOnTriggerBothEdge = 0x7U, /*!< Timer enabled on Trigger rising or falling edge. */
} flexio_timer_enable_condition_t;
/*! @brief Define type of timer stop bit generate condition.*/
typedef enum _flexio_timer_stop_bit_condition
{
kFLEXIO_TimerStopBitDisabled = 0x0U, /*!< Stop bit disabled. */
kFLEXIO_TimerStopBitEnableOnTimerCompare = 0x1U, /*!< Stop bit is enabled on timer compare. */
kFLEXIO_TimerStopBitEnableOnTimerDisable = 0x2U, /*!< Stop bit is enabled on timer disable. */
kFLEXIO_TimerStopBitEnableOnTimerCompareDisable = 0x3U, /*!< Stop bit is enabled on timer compare and timer
disable. */
} flexio_timer_stop_bit_condition_t;
/*! @brief Define type of timer start bit generate condition.*/
typedef enum _flexio_timer_start_bit_condition
{
kFLEXIO_TimerStartBitDisabled = 0x0U, /*!< Start bit disabled. */
kFLEXIO_TimerStartBitEnabled = 0x1U, /*!< Start bit enabled. */
} flexio_timer_start_bit_condition_t;
/*! @brief Define type of timer polarity for shifter control. */
typedef enum _flexio_shifter_timer_polarity
{
kFLEXIO_ShifterTimerPolarityOnPositive = 0x0U, /* Shift on positive edge of shift clock. */
kFLEXIO_ShifterTimerPolarityOnNegitive = 0x1U, /* Shift on negative edge of shift clock. */
} flexio_shifter_timer_polarity_t;
/*! @brief Define type of shifter working mode.*/
typedef enum _flexio_shifter_mode
{
kFLEXIO_ShifterDisabled = 0x0U, /*!< Shifter is disabled. */
kFLEXIO_ShifterModeReceive = 0x1U, /*!< Receive mode. */
kFLEXIO_ShifterModeTransmit = 0x2U, /*!< Transmit mode. */
kFLEXIO_ShifterModeMatchStore = 0x4U, /*!< Match store mode. */
kFLEXIO_ShifterModeMatchContinuous = 0x5U, /*!< Match continuous mode. */
#if defined(FSL_FEATURE_FLEXIO_HAS_STATE_MODE) && FSL_FEATURE_FLEXIO_HAS_STATE_MODE
kFLEXIO_ShifterModeState = 0x6U, /*!< SHIFTBUF contents are used for storing
programmable state attributes. */
#endif /* FSL_FEATURE_FLEXIO_HAS_STATE_MODE */
#if defined(FSL_FEATURE_FLEXIO_HAS_LOGIC_MODE) && FSL_FEATURE_FLEXIO_HAS_LOGIC_MODE
kFLEXIO_ShifterModeLogic = 0x7U, /*!< SHIFTBUF contents are used for implementing
programmable logic look up table. */
#endif /* FSL_FEATURE_FLEXIO_HAS_LOGIC_MODE */
} flexio_shifter_mode_t;
/*! @brief Define type of shifter input source.*/
typedef enum _flexio_shifter_input_source
{
kFLEXIO_ShifterInputFromPin = 0x0U, /*!< Shifter input from pin. */
kFLEXIO_ShifterInputFromNextShifterOutput = 0x1U, /*!< Shifter input from Shifter N+1. */
} flexio_shifter_input_source_t;
/*! @brief Define of STOP bit configuration.*/
typedef enum _flexio_shifter_stop_bit
{
kFLEXIO_ShifterStopBitDisable = 0x0U, /*!< Disable shifter stop bit. */
kFLEXIO_ShifterStopBitLow = 0x2U, /*!< Set shifter stop bit to logic low level. */
kFLEXIO_ShifterStopBitHigh = 0x3U, /*!< Set shifter stop bit to logic high level. */
} flexio_shifter_stop_bit_t;
/*! @brief Define type of START bit configuration.*/
typedef enum _flexio_shifter_start_bit
{
kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable = 0x0U, /*!< Disable shifter start bit, transmitter loads
data on enable. */
kFLEXIO_ShifterStartBitDisabledLoadDataOnShift = 0x1U, /*!< Disable shifter start bit, transmitter loads
data on first shift. */
kFLEXIO_ShifterStartBitLow = 0x2U, /*!< Set shifter start bit to logic low level. */
kFLEXIO_ShifterStartBitHigh = 0x3U, /*!< Set shifter start bit to logic high level. */
} flexio_shifter_start_bit_t;
/*! @brief Define FlexIO shifter buffer type*/
typedef enum _flexio_shifter_buffer_type
{
kFLEXIO_ShifterBuffer = 0x0U, /*!< Shifter Buffer N Register. */
kFLEXIO_ShifterBufferBitSwapped = 0x1U, /*!< Shifter Buffer N Bit Byte Swapped Register. */
kFLEXIO_ShifterBufferByteSwapped = 0x2U, /*!< Shifter Buffer N Byte Swapped Register. */
kFLEXIO_ShifterBufferBitByteSwapped = 0x3U, /*!< Shifter Buffer N Bit Swapped Register. */
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP
kFLEXIO_ShifterBufferNibbleByteSwapped = 0x4U, /*!< Shifter Buffer N Nibble Byte Swapped Register. */
#endif /*FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP*/
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP
kFLEXIO_ShifterBufferHalfWordSwapped = 0x5U, /*!< Shifter Buffer N Half Word Swapped Register. */
#endif
#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP
kFLEXIO_ShifterBufferNibbleSwapped = 0x6U, /*!< Shifter Buffer N Nibble Swapped Register. */
#endif
} flexio_shifter_buffer_type_t;
/*! @brief Define FlexIO user configuration structure. */
typedef struct _flexio_config_
{
bool enableFlexio; /*!< Enable/disable FlexIO module */
bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode */
bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode */
bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, fast access requires
the FlexIO clock to be at least twice the frequency of the bus clock. */
} flexio_config_t;
/*! @brief Define FlexIO timer configuration structure. */
typedef struct _flexio_timer_config
{
/* Trigger. */
uint32_t triggerSelect; /*!< The internal trigger selection number using MACROs. */
flexio_timer_trigger_polarity_t triggerPolarity; /*!< Trigger Polarity. */
flexio_timer_trigger_source_t triggerSource; /*!< Trigger Source, internal (see 'trgsel') or external. */
/* Pin. */
flexio_pin_config_t pinConfig; /*!< Timer Pin Configuration. */
uint32_t pinSelect; /*!< Timer Pin number Select. */
flexio_pin_polarity_t pinPolarity; /*!< Timer Pin Polarity. */
/* Timer. */
flexio_timer_mode_t timerMode; /*!< Timer work Mode. */
flexio_timer_output_t timerOutput; /*!< Configures the initial state of the Timer Output and
whether it is affected by the Timer reset. */
flexio_timer_decrement_source_t timerDecrement; /*!< Configures the source of the Timer decrement and the
source of the Shift clock. */
flexio_timer_reset_condition_t timerReset; /*!< Configures the condition that causes the timer counter
(and optionally the timer output) to be reset. */
flexio_timer_disable_condition_t timerDisable; /*!< Configures the condition that causes the Timer to be
disabled and stop decrementing. */
flexio_timer_enable_condition_t timerEnable; /*!< Configures the condition that causes the Timer to be
enabled and start decrementing. */
flexio_timer_stop_bit_condition_t timerStop; /*!< Timer STOP Bit generation. */
flexio_timer_start_bit_condition_t timerStart; /*!< Timer STRAT Bit generation. */
uint32_t timerCompare; /*!< Value for Timer Compare N Register. */
} flexio_timer_config_t;
/*! @brief Define FlexIO shifter configuration structure. */
typedef struct _flexio_shifter_config
{
/* Timer. */
uint32_t timerSelect; /*!< Selects which Timer is used for controlling the
logic/shift register and generating the Shift clock. */
flexio_shifter_timer_polarity_t timerPolarity; /*!< Timer Polarity. */
/* Pin. */
flexio_pin_config_t pinConfig; /*!< Shifter Pin Configuration. */
uint32_t pinSelect; /*!< Shifter Pin number Select. */
flexio_pin_polarity_t pinPolarity; /*!< Shifter Pin Polarity. */
/* Shifter. */
flexio_shifter_mode_t shifterMode; /*!< Configures the mode of the Shifter. */
#if defined(FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH) && FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH
uint32_t parallelWidth; /*!< Configures the parallel width when using parallel mode.*/
#endif /* FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH */
flexio_shifter_input_source_t inputSource; /*!< Selects the input source for the shifter. */
flexio_shifter_stop_bit_t shifterStop; /*!< Shifter STOP bit. */
flexio_shifter_start_bit_t shifterStart; /*!< Shifter START bit. */
} flexio_shifter_config_t;
/*! @brief typedef for FlexIO simulated driver interrupt handler.*/
typedef void (*flexio_isr_t)(void *base, void *handle);
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /*_cplusplus*/
/*!
* @name FlexIO Initialization and De-initialization
* @{
*/
/*!
* @brief Gets the default configuration to configure the FlexIO module. The configuration
* can used directly to call the FLEXIO_Configure().
*
* Example:
@code
flexio_config_t config;
FLEXIO_GetDefaultConfig(&config);
@endcode
*
* @param userConfig pointer to flexio_config_t structure
*/
void FLEXIO_GetDefaultConfig(flexio_config_t *userConfig);
/*!
* @brief Configures the FlexIO with a FlexIO configuration. The configuration structure
* can be filled by the user or be set with default values by FLEXIO_GetDefaultConfig().
*
* Example
@code
flexio_config_t config = {
.enableFlexio = true,
.enableInDoze = false,
.enableInDebug = true,
.enableFastAccess = false
};
FLEXIO_Configure(base, &config);
@endcode
*
* @param base FlexIO peripheral base address
* @param userConfig pointer to flexio_config_t structure
*/
void FLEXIO_Init(FLEXIO_Type *base, const flexio_config_t *userConfig);
/*!
* @brief Gates the FlexIO clock. Call this API to stop the FlexIO clock.
*
* @note After calling this API, call the FLEXO_Init to use the FlexIO module.
*
* @param base FlexIO peripheral base address
*/
void FLEXIO_Deinit(FLEXIO_Type *base);
/* @} */
/*!
* @name FlexIO Basic Operation
* @{
*/
/*!
* @brief Resets the FlexIO module.
*
* @param base FlexIO peripheral base address
*/
void FLEXIO_Reset(FLEXIO_Type *base);
/*!
* @brief Enables the FlexIO module operation.
*
* @param base FlexIO peripheral base address
* @param enable true to enable, false to disable.
*/
static inline void FLEXIO_Enable(FLEXIO_Type *base, bool enable)
{
if (enable)
{
base->CTRL |= FLEXIO_CTRL_FLEXEN_MASK;
}
else
{
base->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK;
}
}
#if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS
/*!
* @brief Reads the input data on each of the FlexIO pins.
*
* @param base FlexIO peripheral base address
* @return FlexIO pin input data
*/
static inline uint32_t FLEXIO_ReadPinInput(FLEXIO_Type *base)
{
return base->PIN;
}
#endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/
#if defined(FSL_FEATURE_FLEXIO_HAS_STATE_MODE) && FSL_FEATURE_FLEXIO_HAS_STATE_MODE
/*!
* @brief Gets the current state pointer for state mode use.
*
* @param base FlexIO peripheral base address
* @return current State pointer
*/
static inline uint8_t FLEXIO_GetShifterState(FLEXIO_Type *base)
{
return ((base->SHIFTSTATE) & FLEXIO_SHIFTSTATE_STATE_MASK);
}
#endif /*FSL_FEATURE_FLEXIO_HAS_STATE_MODE*/
/*!
* @brief Configures the shifter with the shifter configuration. The configuration structure
* covers both the SHIFTCTL and SHIFTCFG registers. To configure the shifter to the proper
* mode, select which timer controls the shifter to shift, whether to generate start bit/stop
* bit, and the polarity of start bit and stop bit.
*
* Example
@code
flexio_shifter_config_t config = {
.timerSelect = 0,
.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive,
.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection,
.pinPolarity = kFLEXIO_PinActiveLow,
.shifterMode = kFLEXIO_ShifterModeTransmit,
.inputSource = kFLEXIO_ShifterInputFromPin,
.shifterStop = kFLEXIO_ShifterStopBitHigh,
.shifterStart = kFLEXIO_ShifterStartBitLow
};
FLEXIO_SetShifterConfig(base, &config);
@endcode
*
* @param base FlexIO peripheral base address
* @param index Shifter index
* @param shifterConfig Pointer to flexio_shifter_config_t structure
*/
void FLEXIO_SetShifterConfig(FLEXIO_Type *base, uint8_t index, const flexio_shifter_config_t *shifterConfig);
/*!
* @brief Configures the timer with the timer configuration. The configuration structure
* covers both the TIMCTL and TIMCFG registers. To configure the timer to the proper
* mode, select trigger source for timer and the timer pin output and the timing for timer.
*
* Example
@code
flexio_timer_config_t config = {
.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(0),
.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow,
.triggerSource = kFLEXIO_TimerTriggerSourceInternal,
.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection,
.pinSelect = 0,
.pinPolarity = kFLEXIO_PinActiveHigh,
.timerMode = kFLEXIO_TimerModeDual8BitBaudBit,
.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset,
.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput,
.timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput,
.timerDisable = kFLEXIO_TimerDisableOnTimerCompare,
.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh,
.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable,
.timerStart = kFLEXIO_TimerStartBitEnabled
};
FLEXIO_SetTimerConfig(base, &config);
@endcode
*
* @param base FlexIO peripheral base address
* @param index Timer index
* @param timerConfig Pointer to the flexio_timer_config_t structure
*/
void FLEXIO_SetTimerConfig(FLEXIO_Type *base, uint8_t index, const flexio_timer_config_t *timerConfig);
/* @} */
/*!
* @name FlexIO Interrupt Operation
* @{
*/
/*!
* @brief Enables the shifter status interrupt. The interrupt generates when the corresponding SSF is set.
*
* @param base FlexIO peripheral base address
* @param mask The shifter status mask which can be calculated by (1 << shifter index)
* @note For multiple shifter status interrupt enable, for example, two shifter status enable, can calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*/
static inline void FLEXIO_EnableShifterStatusInterrupts(FLEXIO_Type *base, uint32_t mask)
{
base->SHIFTSIEN |= mask;
}
/*!
* @brief Disables the shifter status interrupt. The interrupt won't generate when the corresponding SSF is set.
*
* @param base FlexIO peripheral base address
* @param mask The shifter status mask which can be calculated by (1 << shifter index)
* @note For multiple shifter status interrupt enable, for example, two shifter status enable, can calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*/
static inline void FLEXIO_DisableShifterStatusInterrupts(FLEXIO_Type *base, uint32_t mask)
{
base->SHIFTSIEN &= ~mask;
}
/*!
* @brief Enables the shifter error interrupt. The interrupt generates when the corresponding SEF is set.
*
* @param base FlexIO peripheral base address
* @param mask The shifter error mask which can be calculated by (1 << shifter index)
* @note For multiple shifter error interrupt enable, for example, two shifter error enable, can calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*/
static inline void FLEXIO_EnableShifterErrorInterrupts(FLEXIO_Type *base, uint32_t mask)
{
base->SHIFTEIEN |= mask;
}
/*!
* @brief Disables the shifter error interrupt. The interrupt won't generate when the corresponding SEF is set.
*
* @param base FlexIO peripheral base address
* @param mask The shifter error mask which can be calculated by (1 << shifter index)
* @note For multiple shifter error interrupt enable, for example, two shifter error enable, can calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*/
static inline void FLEXIO_DisableShifterErrorInterrupts(FLEXIO_Type *base, uint32_t mask)
{
base->SHIFTEIEN &= ~mask;
}
/*!
* @brief Enables the timer status interrupt. The interrupt generates when the corresponding SSF is set.
*
* @param base FlexIO peripheral base address
* @param mask The timer status mask which can be calculated by (1 << timer index)
* @note For multiple timer status interrupt enable, for example, two timer status enable, can calculate
* the mask by using ((1 << timer index0) | (1 << timer index1))
*/
static inline void FLEXIO_EnableTimerStatusInterrupts(FLEXIO_Type *base, uint32_t mask)
{
base->TIMIEN |= mask;
}
/*!
* @brief Disables the timer status interrupt. The interrupt won't generate when the corresponding SSF is set.
*
* @param base FlexIO peripheral base address
* @param mask The timer status mask which can be calculated by (1 << timer index)
* @note For multiple timer status interrupt enable, for example, two timer status enable, can calculate
* the mask by using ((1 << timer index0) | (1 << timer index1))
*/
static inline void FLEXIO_DisableTimerStatusInterrupts(FLEXIO_Type *base, uint32_t mask)
{
base->TIMIEN &= ~mask;
}
/* @} */
/*!
* @name FlexIO Status Operation
* @{
*/
/*!
* @brief Gets the shifter status flags.
*
* @param base FlexIO peripheral base address
* @return Shifter status flags
*/
static inline uint32_t FLEXIO_GetShifterStatusFlags(FLEXIO_Type *base)
{
return ((base->SHIFTSTAT) & FLEXIO_SHIFTSTAT_SSF_MASK);
}
/*!
* @brief Clears the shifter status flags.
*
* @param base FlexIO peripheral base address
* @param mask The shifter status mask which can be calculated by (1 << shifter index)
* @note For clearing multiple shifter status flags, for example, two shifter status flags, can calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*/
static inline void FLEXIO_ClearShifterStatusFlags(FLEXIO_Type *base, uint32_t mask)
{
base->SHIFTSTAT = mask;
}
/*!
* @brief Gets the shifter error flags.
*
* @param base FlexIO peripheral base address
* @return Shifter error flags
*/
static inline uint32_t FLEXIO_GetShifterErrorFlags(FLEXIO_Type *base)
{
return ((base->SHIFTERR) & FLEXIO_SHIFTERR_SEF_MASK);
}
/*!
* @brief Clears the shifter error flags.
*
* @param base FlexIO peripheral base address
* @param mask The shifter error mask which can be calculated by (1 << shifter index)
* @note For clearing multiple shifter error flags, for example, two shifter error flags, can calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*/
static inline void FLEXIO_ClearShifterErrorFlags(FLEXIO_Type *base, uint32_t mask)
{
base->SHIFTERR = mask;
}
/*!
* @brief Gets the timer status flags.
*
* @param base FlexIO peripheral base address
* @return Timer status flags
*/
static inline uint32_t FLEXIO_GetTimerStatusFlags(FLEXIO_Type *base)
{
return ((base->TIMSTAT) & FLEXIO_TIMSTAT_TSF_MASK);
}
/*!
* @brief Clears the timer status flags.
*
* @param base FlexIO peripheral base address
* @param mask The timer status mask which can be calculated by (1 << timer index)
* @note For clearing multiple timer status flags, for example, two timer status flags, can calculate
* the mask by using ((1 << timer index0) | (1 << timer index1))
*/
static inline void FLEXIO_ClearTimerStatusFlags(FLEXIO_Type *base, uint32_t mask)
{
base->TIMSTAT = mask;
}
/* @} */
/*!
* @name FlexIO DMA Operation
* @{
*/
/*!
* @brief Enables/disables the shifter status DMA. The DMA request generates when the corresponding SSF is set.
*
* @note For multiple shifter status DMA enables, for example, calculate
* the mask by using ((1 << shifter index0) | (1 << shifter index1))
*
* @param base FlexIO peripheral base address
* @param mask The shifter status mask which can be calculated by (1 << shifter index)
* @param enable True to enable, false to disable.
*/
static inline void FLEXIO_EnableShifterStatusDMA(FLEXIO_Type *base, uint32_t mask, bool enable)
{
if (enable)
{
base->SHIFTSDEN |= mask;
}
else
{
base->SHIFTSDEN &= ~mask;
}
}
/*!
* @brief Gets the shifter buffer address for the DMA transfer usage.
*
* @param base FlexIO peripheral base address
* @param type Shifter type of flexio_shifter_buffer_type_t
* @param index Shifter index
* @return Corresponding shifter buffer index
*/
uint32_t FLEXIO_GetShifterBufferAddress(FLEXIO_Type *base, flexio_shifter_buffer_type_t type, uint8_t index);
/*!
* @brief Registers the handle and the interrupt handler for the FlexIO-simulated peripheral.
*
* @param base Pointer to the FlexIO simulated peripheral type.
* @param handle Pointer to the handler for FlexIO simulated peripheral.
* @param isr FlexIO simulated peripheral interrupt handler.
* @retval kStatus_Success Successfully create the handle.
* @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
*/
status_t FLEXIO_RegisterHandleIRQ(void *base, void *handle, flexio_isr_t isr);
/*!
* @brief Unregisters the handle and the interrupt handler for the FlexIO-simulated peripheral.
*
* @param base Pointer to the FlexIO simulated peripheral type.
* @retval kStatus_Success Successfully create the handle.
* @retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
*/
status_t FLEXIO_UnregisterHandleIRQ(void *base);
/* @} */
#if defined(__cplusplus)
}
#endif /*_cplusplus*/
/*@}*/
#endif /*_FSL_FLEXIO_H_*/

View File

@@ -0,0 +1,820 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#include "fsl_flexio_i2c_master.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief FLEXIO I2C transfer state */
enum _flexio_i2c_master_transfer_states
{
kFLEXIO_I2C_Idle = 0x0U, /*!< I2C bus idle */
kFLEXIO_I2C_CheckAddress = 0x1U, /*!< 7-bit address check state */
kFLEXIO_I2C_SendCommand = 0x2U, /*!< Send command byte phase */
kFLEXIO_I2C_SendData = 0x3U, /*!< Send data transfer phase*/
kFLEXIO_I2C_ReceiveDataBegin = 0x4U, /*!< Receive data begin transfer phase*/
kFLEXIO_I2C_ReceiveData = 0x5U, /*!< Receive data transfer phase*/
};
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
extern const clock_ip_name_t s_flexioClocks[];
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
extern FLEXIO_Type *const s_flexioBases[];
/*******************************************************************************
* Prototypes
******************************************************************************/
extern uint32_t FLEXIO_GetInstance(FLEXIO_Type *base);
/*!
* @brief Set up master transfer, send slave address and decide the initial
* transfer state.
*
* @param base pointer to FLEXIO_I2C_Type structure
* @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
* @param transfer pointer to flexio_i2c_master_transfer_t structure
*/
static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
flexio_i2c_master_transfer_t *xfer);
/*!
* @brief Master run transfer state machine to perform a byte of transfer.
*
* @param base pointer to FLEXIO_I2C_Type structure
* @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
* @param statusFlags flexio i2c hardware status
* @retval kStatus_Success Successfully run state machine
* @retval kStatus_FLEXIO_I2C_Nak Receive Nak during transfer
*/
static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
uint32_t statusFlags);
/*!
* @brief Complete transfer, disable interrupt and call callback.
*
* @param base pointer to FLEXIO_I2C_Type structure
* @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
* @param status flexio transfer status
*/
static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
status_t status);
/*******************************************************************************
* Codes
******************************************************************************/
uint32_t FLEXIO_I2C_GetInstance(FLEXIO_I2C_Type *base)
{
return FLEXIO_GetInstance(base->flexioBase);
}
static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
flexio_i2c_master_transfer_t *xfer)
{
bool needRestart;
uint32_t byteCount;
/* Init the handle member. */
handle->transfer.slaveAddress = xfer->slaveAddress;
handle->transfer.direction = xfer->direction;
handle->transfer.subaddress = xfer->subaddress;
handle->transfer.subaddressSize = xfer->subaddressSize;
handle->transfer.data = xfer->data;
handle->transfer.dataSize = xfer->dataSize;
handle->transfer.flags = xfer->flags;
handle->transferSize = xfer->dataSize;
/* Initial state, i2c check address state. */
handle->state = kFLEXIO_I2C_CheckAddress;
/* Clear all status before transfer. */
FLEXIO_I2C_MasterClearStatusFlags(base, kFLEXIO_I2C_ReceiveNakFlag);
/* Calculate whether need to send re-start. */
needRestart = (handle->transfer.subaddressSize != 0) && (handle->transfer.direction == kFLEXIO_I2C_Read);
/* Calculate total byte count in a frame. */
byteCount = 1;
if (!needRestart)
{
byteCount += handle->transfer.dataSize;
}
if (handle->transfer.subaddressSize != 0)
{
byteCount += handle->transfer.subaddressSize;
/* Next state, send command byte. */
handle->state = kFLEXIO_I2C_SendCommand;
}
/* Configure data count. */
if (FLEXIO_I2C_MasterSetTransferCount(base, byteCount) != kStatus_Success)
{
return kStatus_InvalidArgument;
}
while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
{
}
/* Send address byte first. */
if (needRestart)
{
FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Write);
}
else
{
FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, handle->transfer.direction);
}
return kStatus_Success;
}
static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
uint32_t statusFlags)
{
if (statusFlags & kFLEXIO_I2C_ReceiveNakFlag)
{
/* Clear receive nak flag. */
FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]);
if ((!((handle->state == kFLEXIO_I2C_SendData) && (handle->transfer.dataSize == 0U))) &&
(!(((handle->state == kFLEXIO_I2C_ReceiveData) || (handle->state == kFLEXIO_I2C_ReceiveDataBegin)) &&
(handle->transfer.dataSize == 1U))))
{
FLEXIO_I2C_MasterReadByte(base);
FLEXIO_I2C_MasterAbortStop(base);
handle->state = kFLEXIO_I2C_Idle;
return kStatus_FLEXIO_I2C_Nak;
}
}
if (handle->state == kFLEXIO_I2C_CheckAddress)
{
if (handle->transfer.direction == kFLEXIO_I2C_Write)
{
/* Next state, send data. */
handle->state = kFLEXIO_I2C_SendData;
}
else
{
/* Next state, receive data begin. */
handle->state = kFLEXIO_I2C_ReceiveDataBegin;
}
}
if ((statusFlags & kFLEXIO_I2C_RxFullFlag) && (handle->state != kFLEXIO_I2C_ReceiveData))
{
FLEXIO_I2C_MasterReadByte(base);
}
switch (handle->state)
{
case kFLEXIO_I2C_SendCommand:
if (statusFlags & kFLEXIO_I2C_TxEmptyFlag)
{
if (handle->transfer.subaddressSize > 0)
{
handle->transfer.subaddressSize--;
FLEXIO_I2C_MasterWriteByte(
base, ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize)));
if (handle->transfer.subaddressSize == 0)
{
/* Load re-start in advance. */
if (handle->transfer.direction == kFLEXIO_I2C_Read)
{
while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
{
}
FLEXIO_I2C_MasterRepeatedStart(base);
}
}
}
else
{
if (handle->transfer.direction == kFLEXIO_I2C_Write)
{
/* Next state, send data. */
handle->state = kFLEXIO_I2C_SendData;
/* Send first byte of data. */
if (handle->transfer.dataSize > 0)
{
FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data);
handle->transfer.data++;
handle->transfer.dataSize--;
}
}
else
{
FLEXIO_I2C_MasterSetTransferCount(base, (handle->transfer.dataSize + 1));
FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Read);
/* Next state, receive data begin. */
handle->state = kFLEXIO_I2C_ReceiveDataBegin;
}
}
}
break;
/* Send command byte. */
case kFLEXIO_I2C_SendData:
if (statusFlags & kFLEXIO_I2C_TxEmptyFlag)
{
/* Send one byte of data. */
if (handle->transfer.dataSize > 0)
{
FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data);
handle->transfer.data++;
handle->transfer.dataSize--;
}
else
{
FLEXIO_I2C_MasterStop(base);
while (!(FLEXIO_I2C_MasterGetStatusFlags(base) & kFLEXIO_I2C_RxFullFlag))
{
}
FLEXIO_I2C_MasterReadByte(base);
handle->state = kFLEXIO_I2C_Idle;
}
}
break;
case kFLEXIO_I2C_ReceiveDataBegin:
if (statusFlags & kFLEXIO_I2C_RxFullFlag)
{
handle->state = kFLEXIO_I2C_ReceiveData;
/* Send nak at the last receive byte. */
if (handle->transfer.dataSize == 1)
{
FLEXIO_I2C_MasterEnableAck(base, false);
while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
{
}
FLEXIO_I2C_MasterStop(base);
}
else
{
FLEXIO_I2C_MasterEnableAck(base, true);
}
}
else if (statusFlags & kFLEXIO_I2C_TxEmptyFlag)
{
/* Read one byte of data. */
FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
}
else
{
}
break;
case kFLEXIO_I2C_ReceiveData:
if (statusFlags & kFLEXIO_I2C_RxFullFlag)
{
*handle->transfer.data = FLEXIO_I2C_MasterReadByte(base);
handle->transfer.data++;
if (handle->transfer.dataSize--)
{
if (handle->transfer.dataSize == 0)
{
FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_RxFullInterruptEnable);
handle->state = kFLEXIO_I2C_Idle;
}
/* Send nak at the last receive byte. */
if (handle->transfer.dataSize == 1)
{
FLEXIO_I2C_MasterEnableAck(base, false);
while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
{
}
FLEXIO_I2C_MasterStop(base);
}
}
}
else if (statusFlags & kFLEXIO_I2C_TxEmptyFlag)
{
if (handle->transfer.dataSize > 1)
{
FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
}
}
else
{
}
break;
default:
break;
}
return kStatus_Success;
}
static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
status_t status)
{
FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable);
if (handle->completionCallback)
{
handle->completionCallback(base, handle, status, handle->userData);
}
}
status_t FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type *base, flexio_i2c_master_config_t *masterConfig, uint32_t srcClock_Hz)
{
assert(base && masterConfig);
flexio_shifter_config_t shifterConfig;
flexio_timer_config_t timerConfig;
uint32_t controlVal = 0;
uint16_t timerDiv = 0;
status_t result = kStatus_Success;
memset(&shifterConfig, 0, sizeof(shifterConfig));
memset(&timerConfig, 0, sizeof(timerConfig));
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate flexio clock. */
CLOCK_EnableClock(s_flexioClocks[FLEXIO_I2C_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Do hardware configuration. */
/* 1. Configure the shifter 0 for tx. */
shifterConfig.timerSelect = base->timerIndex[1];
shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
shifterConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection;
shifterConfig.pinSelect = base->SDAPinIndex;
shifterConfig.pinPolarity = kFLEXIO_PinActiveLow;
shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh;
shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow;
FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig);
/* 2. Configure the shifter 1 for rx. */
shifterConfig.timerSelect = base->timerIndex[1];
shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
shifterConfig.pinSelect = base->SDAPinIndex;
shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive;
shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
shifterConfig.shifterStop = kFLEXIO_ShifterStopBitLow;
shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig);
/*3. Configure the timer 0 for generating bit clock. */
timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
timerConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection;
timerConfig.pinSelect = base->SCLPinIndex;
timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit;
timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset;
timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
timerConfig.timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput;
timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh;
timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable;
timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
/* Set TIMCMP[7:0] = (baud rate divider / 2) - 1. */
timerDiv = (srcClock_Hz / masterConfig->baudRate_Bps) / 2 - 1;
if (timerDiv > 0xFFU)
{
result = kStatus_InvalidArgument;
return result;
}
timerConfig.timerCompare = timerDiv;
FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig);
/* 4. Configure the timer 1 for controlling shifters. */
timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
timerConfig.pinSelect = base->SCLPinIndex;
timerConfig.pinPolarity = kFLEXIO_PinActiveLow;
timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput;
timerConfig.timerReset = kFLEXIO_TimerResetNever;
timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable;
timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable;
timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerCompare;
timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
/* Set TIMCMP[15:0] = (number of bits x 2) - 1. */
timerConfig.timerCompare = 8 * 2 - 1;
FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig);
/* Configure FLEXIO I2C Master. */
controlVal = base->flexioBase->CTRL;
controlVal &=
~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
controlVal |= (FLEXIO_CTRL_DBGE(masterConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(masterConfig->enableFastAccess) |
FLEXIO_CTRL_FLEXEN(masterConfig->enableMaster));
if (!masterConfig->enableInDoze)
{
controlVal |= FLEXIO_CTRL_DOZEN_MASK;
}
base->flexioBase->CTRL = controlVal;
return result;
}
void FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type *base)
{
base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = 0;
base->flexioBase->SHIFTCTL[base->shifterIndex[0]] = 0;
base->flexioBase->SHIFTCFG[base->shifterIndex[1]] = 0;
base->flexioBase->SHIFTCTL[base->shifterIndex[1]] = 0;
base->flexioBase->TIMCFG[base->timerIndex[0]] = 0;
base->flexioBase->TIMCMP[base->timerIndex[0]] = 0;
base->flexioBase->TIMCTL[base->timerIndex[0]] = 0;
base->flexioBase->TIMCFG[base->timerIndex[1]] = 0;
base->flexioBase->TIMCMP[base->timerIndex[1]] = 0;
base->flexioBase->TIMCTL[base->timerIndex[1]] = 0;
/* Clear the shifter flag. */
base->flexioBase->SHIFTSTAT = (1U << base->shifterIndex[0]);
base->flexioBase->SHIFTSTAT = (1U << base->shifterIndex[1]);
/* Clear the timer flag. */
base->flexioBase->TIMSTAT = (1U << base->timerIndex[0]);
base->flexioBase->TIMSTAT = (1U << base->timerIndex[1]);
}
void FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t *masterConfig)
{
assert(masterConfig);
masterConfig->enableMaster = true;
masterConfig->enableInDoze = false;
masterConfig->enableInDebug = true;
masterConfig->enableFastAccess = false;
/* Default baud rate at 100kbps. */
masterConfig->baudRate_Bps = 100000U;
}
uint32_t FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type *base)
{
uint32_t status = 0;
status =
((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])) >> base->shifterIndex[0]);
status |=
(((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1]))
<< 1U);
status |=
(((FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1]))
<< 2U);
return status;
}
void FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type *base, uint32_t mask)
{
if (mask & kFLEXIO_I2C_TxEmptyFlag)
{
FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[0]);
}
if (mask & kFLEXIO_I2C_RxFullFlag)
{
FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[1]);
}
if (mask & kFLEXIO_I2C_ReceiveNakFlag)
{
FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]);
}
}
void FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask)
{
if (mask & kFLEXIO_I2C_TxEmptyInterruptEnable)
{
FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]);
}
if (mask & kFLEXIO_I2C_RxFullInterruptEnable)
{
FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]);
}
}
void FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask)
{
if (mask & kFLEXIO_I2C_TxEmptyInterruptEnable)
{
FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]);
}
if (mask & kFLEXIO_I2C_RxFullInterruptEnable)
{
FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]);
}
}
void FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
{
uint16_t timerDiv = 0;
uint16_t timerCmp = 0;
FLEXIO_Type *flexioBase = base->flexioBase;
/* Set TIMCMP[7:0] = (baud rate divider / 2) - 1.*/
timerDiv = srcClock_Hz / baudRate_Bps;
timerDiv = timerDiv / 2 - 1U;
timerCmp = flexioBase->TIMCMP[base->timerIndex[0]];
timerCmp &= 0xFF00;
timerCmp |= timerDiv;
flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp;
}
status_t FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type *base, uint8_t count)
{
if (count > 14U)
{
return kStatus_InvalidArgument;
}
uint16_t timerCmp = 0;
uint32_t timerConfig = 0;
FLEXIO_Type *flexioBase = base->flexioBase;
timerCmp = flexioBase->TIMCMP[base->timerIndex[0]];
timerCmp &= 0x00FFU;
timerCmp |= (count * 18 + 1U) << 8U;
flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp;
timerConfig = flexioBase->TIMCFG[base->timerIndex[0]];
timerConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
timerConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare);
flexioBase->TIMCFG[base->timerIndex[0]] = timerConfig;
return kStatus_Success;
}
void FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type *base, uint8_t address, flexio_i2c_direction_t direction)
{
uint32_t data;
data = ((uint32_t)address) << 1U | ((direction == kFLEXIO_I2C_Read) ? 1U : 0U);
FLEXIO_I2C_MasterWriteByte(base, data);
}
void FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type *base)
{
/* Prepare for RESTART condition, no stop.*/
FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
}
void FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type *base)
{
/* Prepare normal stop. */
FLEXIO_I2C_MasterSetTransferCount(base, 0x0U);
FLEXIO_I2C_MasterWriteByte(base, 0x0U);
}
void FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type *base)
{
uint32_t tmpConfig;
/* Prepare abort stop. */
tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[0]];
tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPinBothEdge);
base->flexioBase->TIMCFG[base->timerIndex[0]] = tmpConfig;
}
void FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type *base, bool enable)
{
uint32_t tmpConfig = 0;
tmpConfig = base->flexioBase->SHIFTCFG[base->shifterIndex[0]];
tmpConfig &= ~FLEXIO_SHIFTCFG_SSTOP_MASK;
if (enable)
{
tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitLow);
}
else
{
tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitHigh);
}
base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = tmpConfig;
}
status_t FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type *base, const uint8_t *txBuff, uint8_t txSize)
{
assert(txBuff);
assert(txSize);
uint32_t status;
while (txSize--)
{
FLEXIO_I2C_MasterWriteByte(base, *txBuff++);
/* Wait until data transfer complete. */
while (!((status = FLEXIO_I2C_MasterGetStatusFlags(base)) & kFLEXIO_I2C_RxFullFlag))
{
}
if (status & kFLEXIO_I2C_ReceiveNakFlag)
{
FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]);
return kStatus_FLEXIO_I2C_Nak;
}
}
return kStatus_Success;
}
void FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type *base, uint8_t *rxBuff, uint8_t rxSize)
{
assert(rxBuff);
assert(rxSize);
while (rxSize--)
{
/* Wait until data transfer complete. */
while (!(FLEXIO_I2C_MasterGetStatusFlags(base) & kFLEXIO_I2C_RxFullFlag))
{
}
*rxBuff++ = FLEXIO_I2C_MasterReadByte(base);
}
}
status_t FLEXIO_I2C_MasterTransferBlocking(FLEXIO_I2C_Type *base, flexio_i2c_master_transfer_t *xfer)
{
assert(xfer);
flexio_i2c_master_handle_t tmpHandle;
uint32_t statusFlags;
uint32_t result = kStatus_Success;
/* Zero the handle. */
memset(&tmpHandle, 0, sizeof(tmpHandle));
/* Set up transfer machine. */
FLEXIO_I2C_MasterTransferInitStateMachine(base, &tmpHandle, xfer);
do
{
/* Wait either tx empty or rx full flag is asserted. */
while (!((statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base)) &
(kFLEXIO_I2C_TxEmptyFlag | kFLEXIO_I2C_RxFullFlag)))
{
}
result = FLEXIO_I2C_MasterTransferRunStateMachine(base, &tmpHandle, statusFlags);
} while ((tmpHandle.state != kFLEXIO_I2C_Idle) && (result == kStatus_Success));
return result;
}
status_t FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
flexio_i2c_master_transfer_callback_t callback,
void *userData)
{
assert(handle);
IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
/* Zero the handle. */
memset(handle, 0, sizeof(*handle));
/* Register callback and userData. */
handle->completionCallback = callback;
handle->userData = userData;
/* Enable interrupt in NVIC. */
EnableIRQ(flexio_irqs[FLEXIO_I2C_GetInstance(base)]);
/* Save the context in global variables to support the double weak mechanism. */
return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2C_MasterTransferHandleIRQ);
}
status_t FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
flexio_i2c_master_transfer_t *xfer)
{
assert(handle);
assert(xfer);
if (handle->state != kFLEXIO_I2C_Idle)
{
return kStatus_FLEXIO_I2C_Busy;
}
else
{
/* Set up transfer machine. */
FLEXIO_I2C_MasterTransferInitStateMachine(base, handle, xfer);
/* Enable both tx empty and rxfull interrupt. */
FLEXIO_I2C_MasterEnableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable);
return kStatus_Success;
}
}
void FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle)
{
assert(handle);
/* Disable interrupts. */
FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable);
/* Reset to idle state. */
handle->state = kFLEXIO_I2C_Idle;
}
status_t FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle, size_t *count)
{
if (!count)
{
return kStatus_InvalidArgument;
}
*count = handle->transferSize - handle->transfer.dataSize;
return kStatus_Success;
}
void FLEXIO_I2C_MasterTransferHandleIRQ(void *i2cType, void *i2cHandle)
{
FLEXIO_I2C_Type *base = (FLEXIO_I2C_Type *)i2cType;
flexio_i2c_master_handle_t *handle = (flexio_i2c_master_handle_t *)i2cHandle;
uint32_t statusFlags;
status_t result;
statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base);
result = FLEXIO_I2C_MasterTransferRunStateMachine(base, handle, statusFlags);
if (handle->state == kFLEXIO_I2C_Idle)
{
FLEXIO_I2C_MasterTransferComplete(base, handle, result);
}
}

View File

@@ -0,0 +1,487 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o 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.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* 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.
*/
#ifndef _FSL_FLEXIO_I2C_MASTER_H_
#define _FSL_FLEXIO_I2C_MASTER_H_
#include "fsl_common.h"
#include "fsl_flexio.h"
/*!
* @addtogroup flexio_i2c_master
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief FlexIO I2C master driver version 2.1.2. */
#define FSL_FLEXIO_I2C_MASTER_DRIVER_VERSION (MAKE_VERSION(2, 1, 2))
/*@}*/
/*! @brief FlexIO I2C transfer status*/
enum _flexio_i2c_status
{
kStatus_FLEXIO_I2C_Busy = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 0), /*!< I2C is busy doing transfer. */
kStatus_FLEXIO_I2C_Idle = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 1), /*!< I2C is busy doing transfer. */
kStatus_FLEXIO_I2C_Nak = MAKE_STATUS(kStatusGroup_FLEXIO_I2C, 2), /*!< NAK received during transfer. */
};
/*! @brief Define FlexIO I2C master interrupt mask. */
enum _flexio_i2c_master_interrupt
{
kFLEXIO_I2C_TxEmptyInterruptEnable = 0x1U, /*!< Tx buffer empty interrupt enable. */
kFLEXIO_I2C_RxFullInterruptEnable = 0x2U, /*!< Rx buffer full interrupt enable. */
};
/*! @brief Define FlexIO I2C master status mask. */
enum _flexio_i2c_master_status_flags
{
kFLEXIO_I2C_TxEmptyFlag = 0x1U, /*!< Tx shifter empty flag. */
kFLEXIO_I2C_RxFullFlag = 0x2U, /*!< Rx shifter full/Transfer complete flag. */
kFLEXIO_I2C_ReceiveNakFlag = 0x4U, /*!< Receive NAK flag. */
};
/*! @brief Direction of master transfer.*/
typedef enum _flexio_i2c_direction
{
kFLEXIO_I2C_Write = 0x0U, /*!< Master send to slave. */
kFLEXIO_I2C_Read = 0x1U, /*!< Master receive from slave. */
} flexio_i2c_direction_t;
/*! @brief Define FlexIO I2C master access structure typedef. */
typedef struct _flexio_i2c_type
{
FLEXIO_Type *flexioBase; /*!< FlexIO base pointer. */
uint8_t SDAPinIndex; /*!< Pin select for I2C SDA. */
uint8_t SCLPinIndex; /*!< Pin select for I2C SCL. */
uint8_t shifterIndex[2]; /*!< Shifter index used in FlexIO I2C. */
uint8_t timerIndex[2]; /*!< Timer index used in FlexIO I2C. */
} FLEXIO_I2C_Type;
/*! @brief Define FlexIO I2C master user configuration structure. */
typedef struct _flexio_i2c_master_config
{
bool enableMaster; /*!< Enables the FlexIO I2C peripheral at initialization time. */
bool enableInDoze; /*!< Enable/disable FlexIO operation in doze mode. */
bool enableInDebug; /*!< Enable/disable FlexIO operation in debug mode. */
bool enableFastAccess; /*!< Enable/disable fast access to FlexIO registers, fast access requires
the FlexIO clock to be at least twice the frequency of the bus clock. */
uint32_t baudRate_Bps; /*!< Baud rate in Bps. */
} flexio_i2c_master_config_t;
/*! @brief Define FlexIO I2C master transfer structure. */
typedef struct _flexio_i2c_master_transfer
{
uint32_t flags; /*!< Transfer flag which controls the transfer, reserved for FlexIO I2C. */
uint8_t slaveAddress; /*!< 7-bit slave address. */
flexio_i2c_direction_t direction; /*!< Transfer direction, read or write. */
uint32_t subaddress; /*!< Sub address. Transferred MSB first. */
uint8_t subaddressSize; /*!< Size of command buffer. */
uint8_t volatile *data; /*!< Transfer buffer. */
volatile size_t dataSize; /*!< Transfer size. */
} flexio_i2c_master_transfer_t;
/*! @brief FlexIO I2C master handle typedef. */
typedef struct _flexio_i2c_master_handle flexio_i2c_master_handle_t;
/*! @brief FlexIO I2C master transfer callback typedef. */
typedef void (*flexio_i2c_master_transfer_callback_t)(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
status_t status,
void *userData);
/*! @brief Define FlexIO I2C master handle structure. */
struct _flexio_i2c_master_handle
{
flexio_i2c_master_transfer_t transfer; /*!< FlexIO I2C master transfer copy. */
size_t transferSize; /*!< Total bytes to be transferred. */
uint8_t state; /*!< Transfer state maintained during transfer. */
flexio_i2c_master_transfer_callback_t completionCallback; /*!< Callback function called at transfer event. */
/*!< Callback function called at transfer event. */
void *userData; /*!< Callback parameter passed to callback function. */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /*_cplusplus*/
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Ungates the FlexIO clock, resets the FlexIO module, and configures the FlexIO I2C
* hardware configuration.
*
* Example
@code
FLEXIO_I2C_Type base = {
.flexioBase = FLEXIO,
.SDAPinIndex = 0,
.SCLPinIndex = 1,
.shifterIndex = {0,1},
.timerIndex = {0,1}
};
flexio_i2c_master_config_t config = {
.enableInDoze = false,
.enableInDebug = true,
.enableFastAccess = false,
.baudRate_Bps = 100000
};
FLEXIO_I2C_MasterInit(base, &config, srcClock_Hz);
@endcode
*
* @param base Pointer to FLEXIO_I2C_Type structure.
* @param masterConfig Pointer to flexio_i2c_master_config_t structure.
* @param srcClock_Hz FlexIO source clock in Hz.
* @retval kStatus_Success Initialization successful
* @retval kStatus_InvalidArgument The source clock exceed upper range limitation
*/
status_t FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type *base, flexio_i2c_master_config_t *masterConfig, uint32_t srcClock_Hz);
/*!
* @brief De-initializes the FlexIO I2C master peripheral. Calling this API Resets the FlexIO I2C master
* shifer and timer config, module can't work unless the FLEXIO_I2C_MasterInit is called.
*
* @param base pointer to FLEXIO_I2C_Type structure.
*/
void FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type *base);
/*!
* @brief Gets the default configuration to configure the FlexIO module. The configuration
* can be used directly for calling the FLEXIO_I2C_MasterInit().
*
* Example:
@code
flexio_i2c_master_config_t config;
FLEXIO_I2C_MasterGetDefaultConfig(&config);
@endcode
* @param masterConfig Pointer to flexio_i2c_master_config_t structure.
*/
void FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t *masterConfig);
/*!
* @brief Enables/disables the FlexIO module operation.
*
* @param base Pointer to FLEXIO_I2C_Type structure.
* @param enable Pass true to enable module, false does not have any effect.
*/
static inline void FLEXIO_I2C_MasterEnable(FLEXIO_I2C_Type *base, bool enable)
{
if (enable)
{
base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK;
}
}
/* @} */
/*!
* @name Status
* @{
*/
/*!
* @brief Gets the FlexIO I2C master status flags.
*
* @param base Pointer to FLEXIO_I2C_Type structure
* @return Status flag, use status flag to AND #_flexio_i2c_master_status_flags can get the related status.
*/
uint32_t FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type *base);
/*!
* @brief Clears the FlexIO I2C master status flags.
*
* @param base Pointer to FLEXIO_I2C_Type structure.
* @param mask Status flag.
* The parameter can be any combination of the following values:
* @arg kFLEXIO_I2C_RxFullFlag
* @arg kFLEXIO_I2C_ReceiveNakFlag
*/
void FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type *base, uint32_t mask);
/*@}*/
/*!
* @name Interrupts
* @{
*/
/*!
* @brief Enables the FlexIO i2c master interrupt requests.
*
* @param base Pointer to FLEXIO_I2C_Type structure.
* @param mask Interrupt source.
* Currently only one interrupt request source:
* @arg kFLEXIO_I2C_TransferCompleteInterruptEnable
*/
void FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask);
/*!
* @brief Disables the FlexIO I2C master interrupt requests.
*
* @param base Pointer to FLEXIO_I2C_Type structure.
* @param mask Interrupt source.
*/
void FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask);
/*@}*/
/*!
* @name Bus Operations
* @{
*/
/*!
* @brief Sets the FlexIO I2C master transfer baudrate.
*
* @param base Pointer to FLEXIO_I2C_Type structure
* @param baudRate_Bps the baud rate value in HZ
* @param srcClock_Hz source clock in HZ
*/
void FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz);
/*!
* @brief Sends START + 7-bit address to the bus.
*
* @note This API should be called when the transfer configuration is ready to send a START signal
* and 7-bit address to the bus. This is a non-blocking API, which returns directly after the address
* is put into the data register but the address transfer is not finished on the bus. Ensure that
* the kFLEXIO_I2C_RxFullFlag status is asserted before calling this API.
* @param base Pointer to FLEXIO_I2C_Type structure.
* @param address 7-bit address.
* @param direction transfer direction.
* This parameter is one of the values in flexio_i2c_direction_t:
* @arg kFLEXIO_I2C_Write: Transmit
* @arg kFLEXIO_I2C_Read: Receive
*/
void FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type *base, uint8_t address, flexio_i2c_direction_t direction);
/*!
* @brief Sends the stop signal on the bus.
*
* @param base Pointer to FLEXIO_I2C_Type structure.
*/
void FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type *base);
/*!
* @brief Sends the repeated start signal on the bus.
*
* @param base Pointer to FLEXIO_I2C_Type structure.
*/
void FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type *base);
/*!
* @brief Sends the stop signal when transfer is still on-going.
*
* @param base Pointer to FLEXIO_I2C_Type structure.
*/
void FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type *base);
/*!
* @brief Configures the sent ACK/NAK for the following byte.
*
* @param base Pointer to FLEXIO_I2C_Type structure.
* @param enable True to configure send ACK, false configure to send NAK.
*/
void FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type *base, bool enable);
/*!
* @brief Sets the number of bytes to be transferred from a start signal to a stop signal.
*
* @note Call this API before a transfer begins because the timer generates a number of clocks according
* to the number of bytes that need to be transferred.
*
* @param base Pointer to FLEXIO_I2C_Type structure.
* @param count Number of bytes need to be transferred from a start signal to a re-start/stop signal
* @retval kStatus_Success Successfully configured the count.
* @retval kStatus_InvalidArgument Input argument is invalid.
*/
status_t FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type *base, uint8_t count);
/*!
* @brief Writes one byte of data to the I2C bus.
*
* @note This is a non-blocking API, which returns directly after the data is put into the
* data register but the data transfer is not finished on the bus. Ensure that
* the TxEmptyFlag is asserted before calling this API.
*
* @param base Pointer to FLEXIO_I2C_Type structure.
* @param data a byte of data.
*/
static inline void FLEXIO_I2C_MasterWriteByte(FLEXIO_I2C_Type *base, uint32_t data)
{
base->flexioBase->SHIFTBUFBBS[base->shifterIndex[0]] = data;
}
/*!
* @brief Reads one byte of data from the I2C bus.
*
* @note This is a non-blocking API, which returns directly after the data is read from the
* data register. Ensure that the data is ready in the register.
*
* @param base Pointer to FLEXIO_I2C_Type structure.
* @return data byte read.
*/
static inline uint8_t FLEXIO_I2C_MasterReadByte(FLEXIO_I2C_Type *base)
{
return base->flexioBase->SHIFTBUFBIS[base->shifterIndex[1]];
}
/*!
* @brief Sends a buffer of data in bytes.
*
* @note This function blocks via polling until all bytes have been sent.
*
* @param base Pointer to FLEXIO_I2C_Type structure.
* @param txBuff The data bytes to send.
* @param txSize The number of data bytes to send.
* @retval kStatus_Success Successfully write data.
* @retval kStatus_FLEXIO_I2C_Nak Receive NAK during writing data.
*/
status_t FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type *base, const uint8_t *txBuff, uint8_t txSize);
/*!
* @brief Receives a buffer of bytes.
*
* @note This function blocks via polling until all bytes have been received.
*
* @param base Pointer to FLEXIO_I2C_Type structure.
* @param rxBuff The buffer to store the received bytes.
* @param rxSize The number of data bytes to be received.
*/
void FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type *base, uint8_t *rxBuff, uint8_t rxSize);
/*!
* @brief Performs a master polling transfer on the I2C bus.
*
* @note The API does not return until the transfer succeeds or fails due
* to receiving NAK.
*
* @param base pointer to FLEXIO_I2C_Type structure.
* @param xfer pointer to flexio_i2c_master_transfer_t structure.
* @return status of status_t.
*/
status_t FLEXIO_I2C_MasterTransferBlocking(FLEXIO_I2C_Type *base, flexio_i2c_master_transfer_t *xfer);
/*@}*/
/*Transactional APIs*/
/*!
* @name Transactional
* @{
*/
/*!
* @brief Initializes the I2C handle which is used in transactional functions.
*
* @param base Pointer to FLEXIO_I2C_Type structure.
* @param handle Pointer to flexio_i2c_master_handle_t structure to store the transfer state.
* @param callback Pointer to user callback function.
* @param userData User param passed to the callback function.
* @retval kStatus_Success Successfully create the handle.
* @retval kStatus_OutOfRange The FlexIO type/handle/isr table out of range.
*/
status_t FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
flexio_i2c_master_transfer_callback_t callback,
void *userData);
/*!
* @brief Performs a master interrupt non-blocking transfer on the I2C bus.
*
* @note The API returns immediately after the transfer initiates.
* Call FLEXIO_I2C_MasterGetTransferCount to poll the transfer status to check whether
* the transfer is finished. If the return status is not kStatus_FLEXIO_I2C_Busy, the transfer
* is finished.
*
* @param base Pointer to FLEXIO_I2C_Type structure
* @param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state
* @param xfer pointer to flexio_i2c_master_transfer_t structure
* @retval kStatus_Success Successfully start a transfer.
* @retval kStatus_FLEXIO_I2C_Busy FlexIO I2C is not idle, is running another transfer.
*/
status_t FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type *base,
flexio_i2c_master_handle_t *handle,
flexio_i2c_master_transfer_t *xfer);
/*!
* @brief Gets the master transfer status during a interrupt non-blocking transfer.
*
* @param base Pointer to FLEXIO_I2C_Type structure.
* @param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state.
* @param count Number of bytes transferred so far by the non-blocking transaction.
* @retval kStatus_InvalidArgument count is Invalid.
* @retval kStatus_Success Successfully return the count.
*/
status_t FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle, size_t *count);
/*!
* @brief Aborts an interrupt non-blocking transfer early.
*
* @note This API can be called at any time when an interrupt non-blocking transfer initiates
* to abort the transfer early.
*
* @param base Pointer to FLEXIO_I2C_Type structure
* @param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state
*/
void FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle);
/*!
* @brief Master interrupt handler.
*
* @param i2cType Pointer to FLEXIO_I2C_Type structure
* @param i2cHandle Pointer to flexio_i2c_master_transfer_t structure
*/
void FLEXIO_I2C_MasterTransferHandleIRQ(void *i2cType, void *i2cHandle);
/*@}*/
#if defined(__cplusplus)
}
#endif /*_cplusplus*/
/*@}*/
#endif /*_FSL_FLEXIO_I2C_MASTER_H_*/

Some files were not shown because too many files have changed in this diff Show More